Skip to content

Instantly share code, notes, and snippets.

@reszelaz
Last active August 1, 2022 10:15
Show Gist options
  • Save reszelaz/1dfc10ca1caa5b0123483d1dfa57d18c to your computer and use it in GitHub Desktop.
Save reszelaz/1dfc10ca1caa5b0123483d1dfa57d18c to your computer and use it in GitHub Desktop.
Simple script to interrogate sardana servers to extract info about 3rd party plugins (macros or controllers)
import json
import os.path
import collections
try:
import argparse
except ImportError:
from taurus.external import argparse
import taurus
from sardana.taurus.core.tango.sardana import registerExtensions
from sardana.taurus.core.tango.sardana.pool import Pool
def read_lib(file_path, grep=None):
if grep is not None:
print("\tOccurrences of {}:".format(grep))
with open(file_path, "r") as lib_file:
line_nb = 0
while True:
line = lib_file.readline()
if not line:
break
line = line.lstrip()
if line.startswith("#"):
continue
line_nb += 1
if grep is not None and grep in line:
print("\t\t" + line[:-1])
return line_nb
def controller(pool, path, output, verbose, grep=None):
total_ctrl_lib_nb = 0
total_ctrl_klass_nb = 0
total_ctrl_line_nb = 0
file_to_ctrls = {}
klass_to_ctrls = {}
file_and_klass_to_ctrls = {}
for name, ctrl in pool.getElementsOfType("Controller").items():
file_name = ctrl.file_name
file_ctrls = file_to_ctrls.get(file_name, [])
file_ctrls.append(ctrl.name)
file_to_ctrls[file_name] = file_ctrls
klass_ctrls = klass_to_ctrls.get(ctrl.klass, [])
klass_ctrls.append(ctrl.name)
klass_to_ctrls[ctrl.klass] = klass_ctrls
# Sardana allows to use controller class which is
# overridden - see sardana#1459.
# For that reason keep a map based on <lib:class> key.
file_and_klass = "{0}:{1}".format(file_name, ctrl.klass)
ctrls = file_and_klass_to_ctrls.get(file_and_klass, [])
ctrls.append(ctrl.name)
file_and_klass_to_ctrls[file_and_klass] = ctrls
hwinfo = pool.getHWObj().info()
info = dict(name=pool.getFullName(), ctrls=[], host=hwinfo.server_host, server=hwinfo.server_id)
for name, lib in pool.getElementsOfType("ControllerLibrary").items():
file_name = lib.file_name
if file_name not in file_to_ctrls:
continue # skip ctrls which are not instantiated
file_path = lib.file_path
if file_path is None:
continue
sardana_ctrl_path = os.path.join(path, "sardana/pool/poolcontrollers")
if file_path.startswith(sardana_ctrl_path):
continue # skip sardana controllers
total_ctrl_lib_nb += 1
print("Controller library: {0}".format(file_path))
if verbose:
print("\tDescription: {0}".format(lib.description))
print("\tController classes:")
klasses = collections.defaultdict(list)
for klass in lib.elements:
file_and_klass = "{0}:{1}".format(lib.file_name, klass)
if file_and_klass in file_and_klass_to_ctrls:
ctrls = file_and_klass_to_ctrls[file_and_klass]
total_ctrl_klass_nb += 1
if ctrls:
klasses[klass] = ctrls
print("\t\t{0} {1}".format(klass, ctrls))
if not verbose:
continue
klass_fullname = "{0}.{1}".format(lib.name, klass)
klass = pool.getElementsOfType("ControllerClass")[klass_fullname]
print("\t\t\tDescription: {0}".format(klass.description))
print("\t\t\tTypes: {0}".format(klass.types))
line_nb = read_lib(file_path, grep)
total_ctrl_line_nb += line_nb
print("\tNumber of lines: {0}".format(line_nb))
print("")
ctrl_info = dict(name=os.path.basename(file_path),
path=file_path,
classes=klasses)
info['ctrls'].append(ctrl_info)
print("")
print("Total number of ctrl libraries: {0}".format(total_ctrl_lib_nb))
print("Total number of ctrl classes: {0}".format(total_ctrl_klass_nb))
print("Total number of lines: {0}".format(total_ctrl_line_nb))
print("Output at: {0}".format(output))
info['total_ctrl_libs'] = total_ctrl_lib_nb
info['total_ctrl_classes'] = total_ctrl_klass_nb
info['total_ctrl_lines'] = total_ctrl_line_nb
with open(output, 'wt') as fobj:
json.dump(info, fobj, indent=2)
def macro(ms, path, output, verbose, grep=None):
total_macro_lib_nb = 0
total_macro_nb = 0
total_macro_line_nb = 0
hwinfo = ms.getHWObj().info()
info = dict(name=ms.getFullName(), libs=[], host=hwinfo.server_host, server=hwinfo.server_id)
for name, lib in ms.getElementsOfType("MacroLibrary").items():
file_path = lib.file_path
if file_path is None:
continue
sardana_macro_path = os.path.join(path, "sardana/macroserver/macros")
if file_path.startswith(sardana_macro_path):
continue # skip sardana macros
total_macro_lib_nb += 1
print("Macro library: {0}".format(file_path))
if verbose:
print("\tDescription: {0}".format(lib.description))
klasses = lib.elements
total_macro_nb += len(klasses)
print("\tMacro classes: {0}".format(klasses))
line_nb = read_lib(file_path, grep)
total_macro_line_nb += line_nb
print("\tNumber of lines: {0}".format(line_nb))
print("")
lib_info = dict(name=os.path.basename(file_path),
path=file_path,
classes=klasses)
info['libs'].append(lib_info)
print("")
print("Total number of macro libraries: {0}".format(total_macro_lib_nb))
print("Total number of macros: {0}".format(total_macro_nb))
print("Total number of lines: {0}".format(total_macro_line_nb))
print("Output at: {0}".format(output))
info['total_macro_libs'] = total_macro_lib_nb
info['total_macros'] = total_macro_nb
info['total_macro_lines'] = total_macro_line_nb
with open(output, 'wt') as fobj:
json.dump(info, fobj, indent=2)
def main():
parser = argparse.ArgumentParser(
description="Interrogate sardana servers to extract info about 3rd "
"party plugins"
)
parser.add_argument("model", type=str,
help="either Pool or MacroServer (depends on "
"the plugin type)",)
parser.add_argument("path", nargs='?', action="store", type=str,
default='/homelocal/sicilia/lib/python/site-packages',
help="path to sardana install directory")
parser.add_argument("--output", type=str)
parser.add_argument("--verbose", action="store_true")
parser.add_argument("--grep", type=str,
help="look for string in the code (line by line)")
args = parser.parse_args()
registerExtensions()
device = taurus.Device(args.model)
if args.output is None:
args.output = os.path.join('/tmp', args.model.replace('/', '_')+'.txt')
if isinstance(device, Pool):
controller(device, args.path, args.output, args.verbose, args.grep)
else:
macro(device, args.path, args.output, args.verbose, args.grep)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment