Source code for blacs.plugins

#####################################################################
#                                                                   #
# /plugins/__init__.py                                              #
#                                                                   #
# Copyright 2013, Monash University                                 #
#                                                                   #
# This file is part of the program BLACS, in the labscript suite    #
# (see http://labscriptsuite.org), and is licensed under the        #
# Simplified BSD License. See the license.txt file in the root of   #
# the project for the full license.                                 #
#                                                                   #
#####################################################################
import os
import sys
import logging
import importlib
from types import MethodType
from collections import defaultdict
from labscript_utils.labconfig import LabConfig
from blacs import BLACS_DIR
PLUGINS_DIR = os.path.join(BLACS_DIR, 'plugins')

default_plugins = ['connection_table', 'general', 'theme']

logger = logging.getLogger('BLACS.plugins')

DEFAULT_PRIORITY = 10

[docs] class Callback(object): """Class wrapping a callable. At present only differs from a regular function in that it has a "priority" attribute - lower numbers means higher priority. If there are multiple callbacks triggered by the same event, they will be returned in order of priority by get_callbacks"""
[docs] def __init__(self, func, priority=DEFAULT_PRIORITY): self.priority = priority self.func = func
def __get__(self, instance, class_): """Make sure our callable binds like an instance method. Otherwise __call__ doesn't get the instance argument.""" if instance is None: return self else: return MethodType(self, instance) def __call__(self, *args, **kwargs): return self.func(*args, **kwargs)
[docs] class callback(object): """Decorator to turn a function into a Callback object. Presently optional, and only required if the callback needs to have a non-default priority set""" # Instantiate the decorator:
[docs] def __init__(self, priority=DEFAULT_PRIORITY): self.priority = priority
# Call the decorator def __call__(self, func): return Callback(func, self.priority)
[docs] def get_callbacks(name): """Return all the callbacks for a particular name, in order of priority""" import __main__ BLACS = __main__.app callbacks = [] for plugin in BLACS.plugins.values(): try: plugin_callbacks = plugin.get_callbacks() if plugin_callbacks is not None: if name in plugin_callbacks: callbacks.append(plugin_callbacks[name]) except Exception: logger.exception('Error getting callbacks from %s.' % str(plugin)) # Sort all callbacks by priority: callbacks.sort(key=lambda callback: getattr(callback, 'priority', DEFAULT_PRIORITY)) return callbacks
exp_config = LabConfig() if not exp_config.has_section('BLACS/plugins'): exp_config.add_section('BLACS/plugins') modules = {} for module_name in os.listdir(PLUGINS_DIR): if os.path.isdir(os.path.join(PLUGINS_DIR, module_name)) and module_name != '__pycache__': # is it a new plugin? # If so lets add it to the config if not module_name in [name for name, val in exp_config.items('BLACS/plugins')]: exp_config.set('BLACS/plugins', module_name, str(module_name in default_plugins)) # only load activated plugins if exp_config.getboolean('BLACS/plugins', module_name): try: module = importlib.import_module('blacs.plugins.'+module_name) except Exception: logger.exception('Could not import plugin \'%s\'. Skipping.'%module_name) else: modules[module_name] = module