コード例 #1
0
ファイル: hangoutbot.py プロジェクト: carlostse/hangout-bot
    def run(self):
        with open(path.join('config', self.env + '.yaml')) as cfg_file:
            cfg = yaml_load(cfg_file)

        bot = Bot(cfg['token'])
        PluginManager.load(bot, cfg)
        bot.run(debug=self.debug, reload=False)
コード例 #2
0
ファイル: test_plugins.py プロジェクト: torgaming/Cardinal
    def test_load_nonexistent_plugin_fails(self):
        name = 'nonexistent'
        plugins = [name]

        manager = PluginManager(Mock())
        failed_plugins = manager.load(plugins)
        assert failed_plugins == plugins
        assert manager.plugins == {}
コード例 #3
0
ファイル: test_plugins.py プロジェクト: torgaming/Cardinal
    def test_unload_plugins_never_loaded_plugin_fails(self):
        name = 'test_never_loaded_plugin'
        plugins = [name]

        manager = PluginManager(Mock())
        failed_plugins = manager.unload(plugins)

        assert failed_plugins == plugins
        assert manager.plugins == {}
コード例 #4
0
ファイル: test_plugins.py プロジェクト: torgaming/Cardinal
    def test_load_setup_too_many_arguments_fails(self):
        name = 'setup_too_many_arguments'
        plugins = [name]

        manager = PluginManager(Mock(),
                                _plugin_module_import_prefix='fake_plugins')

        failed_plugins = manager.load(plugins)
        assert failed_plugins == plugins
        assert manager.plugins.keys() == []
コード例 #5
0
class TestPluginManager(unittest.TestCase):

	""" Unit test for PluginManager """

	def setUp(self):
		self.manager = PluginManager()
		self.manager.add_plugin_dir("/tmp/slog/share/slog/plugins")

	def testSearchPlugins(self):
		self.manager.scan_for_plugins()
		self.assertEqual(3, len(self.manager.get_available()))
コード例 #6
0
ファイル: test_plugins.py プロジェクト: torgaming/Cardinal
    def test_load_bad_callback_fails(self, mock):
        name = 'valid'
        plugins = [name]

        manager = PluginManager(Mock(),
                                _plugin_module_import_prefix='fake_plugins')
        mock.side_effect = Exception()

        failed_plugins = manager.load(plugins)

        assert failed_plugins == plugins
        assert manager.plugins == {}
コード例 #7
0
ファイル: test_plugins.py プロジェクト: torgaming/Cardinal
    def test_load_ambiguous_config_fails(self, mock):
        name = 'valid'
        plugins = [name]

        manager = PluginManager(Mock(),
                                _plugin_module_import_prefix='fake_plugins')
        mock.side_effect = AmbiguousConfigError()

        failed_plugins = manager.load(plugins)

        mock.assert_called_with(name)
        assert failed_plugins == plugins
        assert manager.plugins == {}
コード例 #8
0
ファイル: test_plugins.py プロジェクト: torgaming/Cardinal
    def test_unload_clean_close_succeeds(self):
        name = 'clean_close'
        plugins = [name]

        manager = PluginManager(Mock(),
                                _plugin_module_import_prefix='fake_plugins')

        failed_plugins = manager.load(plugins)
        assert failed_plugins == []
        assert manager.plugins.keys() == plugins

        failed_plugins = manager.unload(plugins)

        assert failed_plugins == []
        assert manager.plugins.keys() == []
コード例 #9
0
ファイル: run.py プロジェクト: rtm-python/choicer
def run_admin():
    """
	Run PluginManager to administrate application.
	"""
    logging.basicConfig(format=CONFIG.get('logging'), level='INFO')
    source_path = os.path.dirname(__file__)
    PluginManager('admin', source_path=source_path).execute('configure')
コード例 #10
0
ファイル: run.py プロジェクト: rtm-python/choicer
def run_identica():
    """
	Run PluginManager to communicate with application identica bot.
	"""
    logging.basicConfig(format=CONFIG.get('logging'), level='INFO')
    PluginManager('identica',
                  domain_url='http://192.168.44.150:5000').execute('run')
コード例 #11
0
ファイル: app.py プロジェクト: 1egoman/quail-flask
  def __init__(self, **flask_args):

    cfgpath = os.path.join(self.get_root(), "config", "quail.json")

    # see if config exists
    if not os.path.exists(cfgpath):
      os.mkdir( os.path.dirname(cfgpath) )
      with open( cfgpath, 'w' ) as f:
        f.write(DEFAULTCONFIG)

    # read in config
    with open( cfgpath, 'r' ) as f:
      self.config = loads( f.read() )


    # add all api hooks
    self.add_api_hooks()

    # last plugin
    self.lastplugin = None

    # create plugin manager
    self.manager = PluginManager(self)
    self.manager.load_all()

    # create stack
    self.stack = []

    # start listener thread
    thrd = listener.listenerThread(self, self.manager.plugins)
    thrd.setName("threadListener")
    thrd.daemon = True
    thrd.start()

    self.run(**flask_args)
コード例 #12
0
ファイル: models.py プロジェクト: os2git/documentbroker
    def generate_document(self, template_id, field_data):
        """Return URL to the generated document - throw exception if not
        possible."""
        # Check user system is allowed to use template.
        ts = TemplateServer(TEMPLATE_URL)
        """
        templates = ts.get_templates(self._user_system_id)
        template_dict = {t[1]: t[2] for t in templates}
        do_pdf_dict = {t[1]: t[3] for t in templates}

        try:
            url = template_dict[template_id]
            do_pdf = do_pdf_dict[template_id]
        except KeyError:
            url = None
            raise RuntimeError(
                'Template {0} not available for client.'.format(
                    template_id)
            )
        """
        template = ts.get_template(self._user_system_id, template_id)
        if template is None:
            raise RuntimeError(
                "Template {0} not available for client.".format(template_id))
        url = template[0]
        do_pdf = template[1]
        # Retrieve template from template server.
        real_url = TEMPLATE_BASE_URL + url
        file_base, extension = os.path.splitext(url)
        file_base = file_base.split('/').pop()
        tmp_name = '/tmp/{0}{1}'.format(template_id, extension)
        (fn, headers) = urllib.urlretrieve(real_url, tmp_name)

        # Finally generate document, store in appropriate place and
        # return URL.

        # Get plugin.
        plugin_mapping = PluginMapping.objects.filter(
            extension=extension.strip('.').upper())[0]
        plugin = PluginManager.get_plugin(plugin_mapping.plugin)

        # Get fields from template system
        fields = ts.get_template_fields(template_id)
        # Get output file name
        unique_url = get_unique_token()
        output_dir = os.path.join(settings.MEDIA_ROOT, 'files')
        extension = 'pdf' if do_pdf else plugin_mapping.output_type
        output_file = '.'.join([unique_url, extension])
        output_path = os.path.join(output_dir, output_file)
        # TODO: Validate that fields in call exist in template, etc.
        output_url = settings.MEDIA_URL + 'files/' + output_file
        #raise RuntimeError("Not implemented: {0}".format(output_url))
        plugin.generate_document(tmp_name, output_path, field_data, do_pdf)
        # Calculate SHA1 hash of output file
        sha1 = hashlib.sha1()
        with open(output_path, 'rb') as f:
            sha1.update(f.read())
        hash = sha1.hexdigest()

        return (BROKER_BASE_URL + output_url, hash)
コード例 #13
0
ファイル: test_plugins.py プロジェクト: torgaming/Cardinal
    def test_unload_unregister_plugin_callbacks_error_succeeds(self, mock):
        name = 'clean_close'
        plugins = [name]

        manager = PluginManager(Mock(),
                                _plugin_module_import_prefix='fake_plugins')

        failed_plugins = manager.load(plugins)
        assert failed_plugins == []
        assert manager.plugins.keys() == plugins

        mock.side_effect = Exception()
        failed_plugins = manager.unload(plugins)

        assert failed_plugins == []
        assert manager.plugins.keys() == []

        mock.assert_called_with(name)
コード例 #14
0
    def test_01_Singleton(self):
        """ 1. Checking whether PluginManger class is singleton. """
        self.pluginmanager.test_arg = 1
        secondPluginManager = PluginManager()

        self.assertEqual(id(secondPluginManager), id(self.pluginmanager),
                         'Different IDs in references to PluginManager objects (not a singleton)')
        self.assertEqual(secondPluginManager.test_arg, 1,
                         'References point to different PluginManager objects (not a singleton')
コード例 #15
0
ファイル: test_plugins.py プロジェクト: torgaming/Cardinal
    def test_reload_unclean_close_succeeds(self):
        name = 'unclean_close'
        plugins = [name]

        cardinal = Mock(CardinalBot)
        cardinal.reloads = 0

        manager = PluginManager(cardinal,
                                _plugin_module_import_prefix='fake_plugins')

        failed_plugins = manager.load(plugins)
        assert failed_plugins == []
        assert manager.plugins.keys() == plugins

        failed_plugins = manager.load(plugins)
        assert failed_plugins == []
        assert manager.plugins.keys() == plugins

        assert cardinal.reloads == 1
コード例 #16
0
ファイル: test_plugins.py プロジェクト: torgaming/Cardinal
    def test_load_valid_list(self):
        name = 'valid'
        plugins = [name]

        manager = PluginManager(Mock(),
                                _plugin_module_import_prefix='fake_plugins')

        failed_plugins = manager.load(plugins)
        assert failed_plugins == []
        assert manager.plugins.keys() == plugins

        assert manager.plugins[name]['name'] == name
        assert inspect.ismodule(manager.plugins[name]['module'])
        assert isinstance(manager.plugins[name]['instance'],
                          manager.plugins[name]['module'].TestValidPlugin)
        assert manager.plugins[name]['commands'] == []
        assert manager.plugins[name]['callbacks'] == []
        assert manager.plugins[name]['callback_ids'] == {}
        assert manager.plugins[name]['config'] is None
        assert manager.plugins[name]['blacklist'] == []
コード例 #17
0
ファイル: models.py プロジェクト: os2git/documentbroker
    def generate_template_image(self, template_id, resolusion, image_type,
                                file_name):
        """
        Return a URL to the generated preview.
        """
        # Check user system is allowed to use template.
        ts = TemplateServer(TEMPLATE_URL)
        templates = ts.get_templates(self._user_system_id)
        template_dict = {t[1]: t[2] for t in templates}
        do_pdf_dict = {t[1]: t[3] for t in templates}

        try:
            url = template_dict[template_id]
            do_pdf = do_pdf_dict[template_id]
        except KeyError:
            url = None
            raise RuntimeError(
                'Template {0} not available for client.'.format(template_id))
        # Retrieve template from template server.
        real_url = TEMPLATE_BASE_URL + url
        file_base, extension = os.path.splitext(url)
        file_base = file_base.split('/').pop()
        tmp_name = '/tmp/{0}{1}'.format(template_id, extension)
        (fn, headers) = urllib.urlretrieve(real_url, tmp_name)

        # Finally generate document, store in appropriate place and
        # return URL.

        # Get plugin.
        plugin_mapping = PluginMapping.objects.filter(
            extension=extension.strip('.').upper())[0]
        plugin = PluginManager.get_plugin(plugin_mapping.plugin)

        # Get fields from template system
        fields = ts.get_template_fields(template_id)
        # Get output file name
        unique_url = get_unique_token()
        output_dir = os.path.join(settings.MEDIA_ROOT, 'files')
        extension = ".png"
        output_file = file_name[:file_name.rfind('.')] + "_" + image_type
        output_file += extension
        output_path = os.path.join(output_dir, output_file)
        # TODO: Validate that fields in call exist in template, etc.
        output_url = settings.MEDIA_URL + 'files/' + output_file
        print "generate_template_image IS RUN"
        plugin.generate_template_image(tmp_name, output_path, resolusion,
                                       image_type, fields)

        # Calculate SHA1 hash of output file
        sha1 = hashlib.sha1()
        with open(output_path, 'rb') as f:
            sha1.update(f.read())
        hash = sha1.hexdigest()
        return (BROKER_BASE_URL + output_url, hash)
コード例 #18
0
ファイル: nparse.py プロジェクト: cfurgang/nparse
    def __init__(self, *args):
        super().__init__(*args)

        # Plugin support
        self.plugins = PluginManager(self)
        self.plugins.discover_plugins(enable_all=config.data['general']['enable_plugins'])
        # End plugin support

        # Updates
        self._toggled = False
        self._log_reader = None

        # Load Parsers
        self._load_parsers()
        self._settings = SettingsWindow()

        # Tray Icon
        self._system_tray = QSystemTrayIcon()
        self._system_tray.setIcon(QIcon(resource_path('data/ui/icon.png')))
        self._system_tray.setToolTip("nParse")
        # self._system_tray.setContextMenu(self._create_menu())
        self._system_tray.activated.connect(self._menu)
        self._system_tray.show()

        # Turn On
        self._toggle()

        if self.new_version_available():
            self._system_tray.showMessage(
                "nParse Update".format(ONLINE_VERSION),
                "New version available!\ncurrent: {}\nonline: {}".format(
                    CURRENT_VERSION,
                    ONLINE_VERSION
                ),
                msecs=3000
            )

        self.plugins.hook(Plugin.on_app_start, self)
コード例 #19
0
class PluginMapping(models.Model):
    """This class maps from file name extensions to document plugins. This
    means we use the extensions to specify the plugin. This also mean we don't
    allow these extensions to overlap, e.g. if one soite wishes to use them in
    a non-standard way. If this ever becomes a problem, the plugin spec should
    follow the document, not the extension."""
    plugins = PluginManager.list_plugins()
    extension = models.CharField(_('Extension'), max_length=16, unique=True)
    output_type = models.CharField(_('Output Type'), max_length=16)
    plugin = models.CharField(
        _('Plugin'),
        max_length=255,
        choices=[(k, v.__doc__) for k, v in plugins.items()])

    def __unicode__(self):
        return self.extension
コード例 #20
0
 def __init__(self, pcfg, clientsock, dsthost, dstport):
     """Open connection to dsthost:dstport, and return client and server proxies."""
     logger.info("creating proxy from client to %s:%d" % (dsthost, dstport))
     self.srv_proxy = None
     try:
         serversock = socket.create_connection((dsthost, dstport))
         self.cli_proxy = MinecraftProxy(clientsock)
     except Exception as e:
         clientsock.close()
         logger.error("Couldn't connect to %s:%d - %s", dsthost, dstport,
                      str(e))
         logger.info(traceback.format_exc())
         return
     self.srv_proxy = MinecraftProxy(serversock, self.cli_proxy)
     self.plugin_mgr = PluginManager(pcfg, self.cli_proxy, self.srv_proxy)
     self.cli_proxy.plugin_mgr = self.plugin_mgr
     self.srv_proxy.plugin_mgr = self.plugin_mgr
コード例 #21
0
ファイル: proxy.py プロジェクト: meta1203/mc3p
 def handle(self, cli_sock, addr):
     logger.info('Incoming connection from %s' % repr(addr))
     try:
         srv_sock = create_connection((self.target_host, self.target_port))
         cli_proxy = MinecraftProxy(cli_sock)
     except Exception as e:
         cli_sock.close()
         logger.error("Couldn't connect to %s:%d - %s", self.target_host,
                      self.target_port, str(e))
         logger.info(traceback.format_exc())
         return
     srv_proxy = MinecraftProxy(srv_sock, cli_proxy)
     plugin_mgr = PluginManager(pcfg, cli_proxy, srv_proxy)
     cli_proxy.plugin_mgr = plugin_mgr
     srv_proxy.plugin_mgr = plugin_mgr
     cli_proxy.start()
     srv_proxy.start()
コード例 #22
0
ファイル: models.py プロジェクト: os2git/documentbroker
    def generate_fo_template(self, template_id, fo_file):
        """
        Return a URL to the generated preview.
        """
        # Check user system is allowed to use template.
        ts = TemplateServer(TEMPLATE_URL)
        templates = ts.get_templates(self._user_system_id)
        template_dict = {t[1]: t[2] for t in templates}
        do_pdf_dict = {t[1]: t[3] for t in templates}
        print "TEMPLATE_ID: " + template_id
        print "TEMPLATES: " + str(template_dict)

        try:
            url = template_dict[template_id]
            do_pdf = do_pdf_dict[template_id]
        except KeyError:
            url = None
            raise RuntimeError(
                'Template {0} not available for client.'.format(template_id))
        # Retrieve template from template server.
        real_url = TEMPLATE_BASE_URL + url
        file_base, extension = os.path.splitext(url)
        file_base = file_base.split('/').pop()
        tmp_name = '/tmp/{0}{1}'.format(template_id, extension)
        (fn, headers) = urllib.urlretrieve(real_url, tmp_name)

        # Get plugin.
        plugin_mapping = PluginMapping.objects.filter(
            extension=extension.strip('.').upper())[0]
        plugin = PluginManager.get_plugin(plugin_mapping.plugin)

        # Get output file name
        unique_url = get_unique_token()
        output_dir = os.path.join(settings.MEDIA_ROOT, 'files')
        extension = "fo"
        output_file = '.'.join([unique_url, extension])
        output_path = os.path.join(output_dir, output_file)
        output_url = settings.MEDIA_URL + 'files/' + output_file
        plugin.generate_xsl_fo_ghost_document(tmp_name, output_path)

        # Calculate SHA1 hash of output file
        sha1 = hashlib.sha1()
        with open(output_path, 'rb') as f:
            sha1.update(f.read())
        hash = sha1.hexdigest()
        return (BROKER_BASE_URL + output_url, hash)
コード例 #23
0
import sys, os, plat, config
from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import QApplication
from plugins import PluginManager
from host import Host

if plat.Supports.hotkeys: import hotkeys

# For easier usage calculate the path relative to here.
here = os.path.abspath(os.path.dirname(__file__))

app = QApplication(sys.argv)
app.setQuitOnLastWindowClosed(False)

# Add kill-switch for development testing
if DEBUG and plat.Supports.hotkeys:
	hotkeys.default.registerCommand('kill', app.exit)
	hotkeys.default._bind('ctrl+shift+k', 'kill')
#endif

plugHost = Host()

pm = PluginManager(plugHost)
pm.load(os.path.join(here, 'plugins'))

hotkeys.default.load()

app.exec_()
config.default.save()
コード例 #24
0
ファイル: Echo.py プロジェクト: RobertTheMagnificent/scrib
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from plugins import PluginManager

# User command
alias = "echo"
command = { alias: "Usage: !echo message\nMake the bot mimic your message." }

# Plugin Action
class EchoPlugin(PluginManager.Load):
	def action(self, cmds, scrib, c):
		if cmds[0] == command and len(cmds) >= 1:
			phrase=""
			for x in xrange (1, len (cmds)):
				phrase = phrase + str(cmds[x]) + " "
			return phrase

PluginManager.addPlugin( command, alias, EchoPlugin() )
コード例 #25
0
# User Alias and Command
sleep_alias = "sleep"
sleep_command = { sleep_alias: "Usage: !sleep \nMake the bot stop talking." }

# Plugin Action
class SleepPlugin(PluginManager.Load):
	def action(self, cmds, scrib, c):
		scrib.barf('ACT', 'Sleep called.')
		if cmds[0] == sleep_cmd and len(cmds)==1:
			msg = "Going to sleep. Goodnight!"
			scrib.settings.muted = 1
		else:
			msg = "Zzz..."
		return msg

wake_alias = "wake"
wake_command = { wake_alias: "Owner command. Usage: !wake\nAllow the bot to talk." }

class WakePlugin(PluginManager.Load):
	def action(self, cmds, scrib, c):
		scrib.barf('ACT', 'Wake called.')
		if cmds[0] == wake_cmd and scrib.settings.muted == 1:
			scrib.settings.muted = 0
			msg = "Whoohoo!"
		else:
			msg = "But I'm already awake..."
		return msg

PluginManager.addPlugin( sleep_command, sleep_alias, SleepPlugin() )
PluginManager.addPlugin( wake_command, wake_alias, WakePlugin() )
コード例 #26
0
ファイル: test_plugins.py プロジェクト: torgaming/Cardinal
 def test_constructor_plugins_not_a_list_typeerror(self, plugins):
     with pytest.raises(TypeError):
         PluginManager(Mock(), plugins)
コード例 #27
0
class Gallery:

    def __init__(self, config, root_path):
        self.config = config
        self.root_path = root_path
        self.source_image_path = os.path.join(root_path, "source_images")
        self.source_video_path = os.path.join(root_path, "source_videos")
        self.theme_name = config.get("gallery", "theme")
        self.themes_path = os.path.join(root_path, "themes")
        self.theme_path = os.path.join(self.themes_path, self.theme_name)

        if not os.path.exists(self.theme_path):
            raise Exception("theme '%s' not found " % self.theme_name)

        themeconfigpath = os.path.join(self.theme_path, "config.txt")

        if not os.path.exists(themeconfigpath):
            raise Exception("couldn't find theme config.txt")

        self.config.read(themeconfigpath)

        self.templates_path = os.path.join(self.theme_path, "templates")

        self.template_path = os.path.join(root_path, "templates")
        self.output_path = os.path.join(root_path, "output")

        self.small_size = self.config.get("gallery",
                                          "small_image_size").split(",")
        self.large_size = self.config.get("gallery",
                                          "large_image_size").split(",")

        self.video_size = self.config.get("gallery",
                                          "video_max_size").split(",")

        self.configure_templates()
        self.discover_plugins()

    def discover_plugins(self):
        self.plugin_manager = PluginManager()
        self.plugin_manager.discover_plugins(
            os.path.join(self.root_path, "plugins"))

    def configure_templates(self):
        self.tempEnv = Environment(
            loader=FileSystemLoader(self.templates_path))

    def get_template(self, templateName):
        return self.tempEnv.get_template(templateName)

    def generate(self):
        images = self.discover_images()

        videos = self.process_videos()

        print videos

        images = self.generate_images(images)

        # plugin call point - pre page generation, with images as
        # arguments (to provide extra context for pages)
        extra_context = self.plugin_manager.prePageGeneration(
            self.config,
            self.source_image_path,
            self.source_video_path,
            images,
            videos)

        self.generate_pages(images, videos, extra_context)
        self.copy_static_content()

    def upload(self):
        # plugin call point, generation complete - upload
        self.plugin_manager.upload(self.config, self.output_path)

        # plugin call point, generation complete - notify
        self.plugin_manager.notify(self.config, self.output_path)

    def copy_static_content(self):
        static_path = os.path.join(self.theme_path, "static")
        static_output_path = os.path.join(self.output_path, "static")
        if os.path.exists(static_output_path):
            shutil.rmtree(static_output_path)
        shutil.copytree(static_path, static_output_path)

    def discover_images(self):
        images = []
        for filename in os.listdir(self.source_image_path):
            if filename.lower().find(".jpg") != -1:
                image = MediaObject(
                    source_path=os.path.join(
                        self.source_image_path,
                        filename),
                    filename=filename,
                    output_path=self.output_path)
                image.target_small_size = self.small_size
                image.target_large_size = self.large_size
                images.append(image)

        print "%s images found" % len(images)
        return images

    def process_videos(self):
        videos = []
        vp = videoprocessing.VideoProcessor()

        for filename in os.listdir(self.source_video_path):
            video = MediaObject(type=MediaObject.TYPE_VIDEO,
                                filename=filename,
                                source_path=os.path.join(
                                    self.source_video_path, filename),
                                output_path=self.output_path)

            videos.append(video)

            if video.transcoded:
                # copy already transcoded video
                target_path = os.path.join(self.output_path, video.filename)
                print "copying m4v video: %s" % video.source_path
                shutil.copy(video.source_path, target_path)
            else:
                # transcode the others
                target_filename = video.filename[
                    :video.filename.find(".")] + ".m4v"
                video.filename = target_filename
                target_path = os.path.join(self.output_path, target_filename)

                print "transcoding %s to %s" % (video.source_path, target_path)
                params = vp.getSizeAndDuration(video.source_path)
                vp.trancodeRawVideo(
                    video.source_path, target_path, params, self.video_size)

            video.thumb_path = vp.getScreencap(
                video.source_path, self.output_path)
            video.thumb_filename = os.path.split(video.thumb_path)[1]

            # get dimensions and duration
            params = vp.getSizeAndDuration(
                os.path.join(self.output_path, video.filename))
            video.width = params.get('width', None)
            video.height = params.get('height', None)
            video.hours = params.get('hours', None)
            video.minutes = params.get('minutes', None)
            video.seconds = params.get('seconds', None)
            video.title = filename

        return videos

    def generate_pages(self, images, videos, extra_context):
        try:
            themeMode = self.config.get("theme", "THEME_MODE")
        except ConfigParser.NoOptionError:
            themeMode = 'static'

        # merge video and photo records
        media = []
        media.extend(videos)
        media.extend(images)
        for mediaobject in media:
            if mediaobject.type == MediaObject.TYPE_PHOTO:
                mediaobject.page = "view_photo_%s.html" % mediaobject.id
            elif mediaobject.type == MediaObject.TYPE_VIDEO:
                mediaobject.page = "view_video_%s.html" % mediaobject.id

        if themeMode == 'ajax':
            return self.generate_ajax_pages(media, extra_context)
        elif themeMode == 'static':
            return self.generate_plain_pages(media, extra_context)
        else:
            raise Exception("unknown mode in theme")

    def generate_ajax_pages(self, media, extra_context):

        page_context = {
            'root_url': self.config.get("gallery", "ROOT_URL"),
            'imagecount': len(media),
            'media': media,
            'gallerytitle': self.config.get("gallery", "title"),
        }

        page_context.update(extra_context)

        self.render_page("index.html", "index.html", page_context)

        # create video embed pages
        for mediaitem in media:
            if mediaitem.type == MediaObject.TYPE_VIDEO:
                local_page_context = {
                    'video': mediaitem,
                    'root_url': self.config.get("gallery", "ROOT_URL"),
                }
                self.render_page("embedvideo.html", "embed_%s.html" %
                                mediaitem.filename, local_page_context)

        self.render_static_pages(page_context)

    def generate_plain_pages(self, media, extra_context):
        indexIsAlbumPage = self.config.getboolean(
            "theme", "INDEX_IS_ALBUM_PAGE")
        imagesPerPage = int(self.config.get("theme", "IMAGES_PER_PAGE"))

        # set up previous and next links
        for i in range(len(media)):
            prevlink = None
            nextlink = None
            if i > 0:
                prevlink = media[i - 1].page
            if i < (len(media) - 1):
                nextlink = media[i + 1].page
            media[i].next_link = nextlink
            media[i].prev_link = prevlink

        pages = int(math.ceil((len(media) / float(imagesPerPage))))

        page_context = {
            'root_url': self.config.get("gallery", "ROOT_URL"),
            'images_per_page': imagesPerPage,
            'pages': pages,
            'imagecount': len(media),
            'gallerytitle': self.config.get("gallery", "title"),
        }

        page_context.update(extra_context)

        pagelinks = []
        for page in range(pages):
            if page == 0 and indexIsAlbumPage:
                pagelinks.append(
                    {'title': (int(page) + 1), 'link': "index.html"})
            else:
                pagelinks.append(
                    {'title': (int(page) + 1), 'link': "page%s.html" % (int(page) + 1)})
        page_context['pagelinks'] = pagelinks

        # generate album pages
        if indexIsAlbumPage:
            currPageName = "index.html"
        else:
            currPageName = "page1.html"
        for page in range(pages):
            pageno = page + 1
            print "generating page %s" % pageno
            page_media = media[page * imagesPerPage:pageno * imagesPerPage]

            # set the owner page for the media items
            for mediaitem in page_media:
                mediaitem.home_page = currPageName

            page_context['media'] = page_media
            page_context['pageno'] = pageno

            prevlink = None
            if page > 0:
                prevlink = "page%s.html" % page
            nextlink = None
            if pageno < pages:
                nextlink = "page%s.html" % (int(pageno) + 1)

            page_context['prevlink'] = prevlink
            page_context['nextlink'] = nextlink

            self.render_page("albumpage.html", currPageName, page_context)

            currPageName = "page%s.html" % (pageno + 1)

        # generate image and video view pages
        for mediaitem in media:
            if mediaitem.type == MediaObject.TYPE_PHOTO:
                local_page_context = {
                    'img': mediaitem,
                    'root_url': self.config.get("gallery", "ROOT_URL"),
                }
                self.render_page(
                    "viewimage.html", mediaitem.page, local_page_context)

            if mediaitem.type == MediaObject.TYPE_VIDEO:
                local_page_context = {
                    'video': mediaitem,
                    'root_url': self.config.get("gallery", "ROOT_URL"),
                }
                self.render_page(
                    "viewvideo.html", mediaitem.page, local_page_context)

        self.render_static_pages(page_context)

    def render_static_pages(self, context):
        indexIsAlbumPage = self.config.getboolean(
            "theme", "INDEX_IS_ALBUM_PAGE")

        if not indexIsAlbumPage:
            self.render_page("index.html", "index.html", context)

        # render any other template not in the list of reserved names
        for template in self.tempEnv.list_templates():
            if template not in RESERVED_TEMPLATES:
                print "rendering static page - %s" % template
                self.render_page(template, template, context)

    def render_page(self, templateName, outputName, context):
        page_template = self.get_template(templateName)

        html = page_template.render(context)
        outfile = open(os.path.join(self.output_path, outputName), "w")
        outfile.write(html)
        outfile.close()

    def generate_images(self, images):
        p = Pool()

        images = p.map(process_image, [[image] for image in images])

        print images

        return images
コード例 #28
0
ファイル: models.py プロジェクト: os2git/documentbroker
    def save(self, *args, **kwargs):
        fo_file_path = ""
        bs = BrokerServer(document_broker_settings.BROKER_URL)
        set_broker_server(bs)
        # Before save
        if self.file != self._old_file:
            self.version = self.version + 1
            """
            We check if template contains HTML input fields.
            """
            file_contents = self.file.read()
            if not "#[HTML]" in file_contents:
                """
                Couldn't make the commit keyword work on the save method.
                pre_save=
                super(Template, self).save(commit=False, *args, **kwargs)
                Except: save() got an unexpected keyword argument 'commit'

                This is a dirty way to find the next file:
                """
                found = True
                i = 0
                while found:
                    """
                    We traverse the files with this name and set the fo output
                    file to be the next one in the row.
                    """
                    wo_ext = str(self.file.name)
                    wo_ext = wo_ext[:str(self.file.name).rfind(".")]
                    ext = str(self.file.name)[str(self.file.name).rfind("."):]
                    if i == 0:
                        file_name = "files/"
                        file_name += wo_ext
                    else:
                        file_name += wo_ext
                        file_name += "_" + str(i)
                    try:
                        the_file = os.path.join(
                            settings.MEDIA_ROOT,
                            file_name + ext
                        )
                        with open(the_file, 'r') as f:
                            file_name = "files/"
                            found = True
                    except Exception as e:
                        fo_file_path = file_name + ".fo"
                        found = False
                    i += 1
                self.precompiled_file = fo_file_path
        plugin_mappings = bs.get_plugin_mappings()
        # Actual save
        super(Template, self).save(*args, **kwargs)
        # After save - extract field if file changed.
        if self.file != self._old_file:
            # Get plugin name from mapping
            (_, extension) = os.path.splitext(self.file.path)
            extension = extension.strip('.').upper()
            db = DocumentBroker(document_broker_settings.BROKER_URL)
            plugin_mappings = db.get_plugin_mappings()
            plugin = PluginManager.get_plugin(plugin_mappings[extension])
            fields = plugin.extract_document_fields(str(self.file.path))
            existing_fields = Field.objects.filter(document=self)

            for name, content_type in fields:
                if name not in [f.name for f in existing_fields]:
                    """ We set the default input type to be text. """
                    input_type = "TEXT"
                    """
                    We check if the field take HTML input and declare the input
                    type alike.
                    """
                    if len(name) > 7:
                        if name[:6] == "[HTML]":
                            input_type = "HTML"
                            self.precompiled_file = None
                    Field.objects.create(
                        name=name, type=input_type,
                        content_type="string", document=self)
コード例 #29
0
ファイル: nparse.py プロジェクト: cfurgang/nparse
class NomnsParse(QApplication):
    """Application Control."""

    def __init__(self, *args):
        super().__init__(*args)

        # Plugin support
        self.plugins = PluginManager(self)
        self.plugins.discover_plugins(enable_all=config.data['general']['enable_plugins'])
        # End plugin support

        # Updates
        self._toggled = False
        self._log_reader = None

        # Load Parsers
        self._load_parsers()
        self._settings = SettingsWindow()

        # Tray Icon
        self._system_tray = QSystemTrayIcon()
        self._system_tray.setIcon(QIcon(resource_path('data/ui/icon.png')))
        self._system_tray.setToolTip("nParse")
        # self._system_tray.setContextMenu(self._create_menu())
        self._system_tray.activated.connect(self._menu)
        self._system_tray.show()

        # Turn On
        self._toggle()

        if self.new_version_available():
            self._system_tray.showMessage(
                "nParse Update".format(ONLINE_VERSION),
                "New version available!\ncurrent: {}\nonline: {}".format(
                    CURRENT_VERSION,
                    ONLINE_VERSION
                ),
                msecs=3000
            )

        self.plugins.hook(Plugin.on_app_start, self)

    def _load_parsers(self):
        self._parsers = [
            parsers.Maps(),
            parsers.Spells()
        ]
        for parser in self._parsers:
            self.plugins.hook(Plugin.on_parser_load, parser)
            if parser.name in config.data.keys() and 'geometry' in config.data[parser.name].keys():
                g = config.data[parser.name]['geometry']
                parser.setGeometry(g[0], g[1], g[2], g[3])
            if config.data[parser.name]['toggled']:
                parser.toggle()

    def _toggle(self):
        if not self._toggled:
            try:
                config.verify_paths()
            except ValueError as error:
                self._system_tray.showMessage(
                    error.args[0], error.args[1], msecs=3000)

            else:
                self._log_reader = logreader.LogReader(
                    config.data['general']['eq_log_dir'])
                self._log_reader.new_line.connect(self._parse)
                self._toggled = True
        else:
            if self._log_reader:
                self._log_reader.deleteLater()
                self._log_reader = None
            self._toggled = False

    def _parse(self, new_line):
        if new_line:
            timestamp, text, charname = new_line  # (datetime, text)
            #  don't send parse to non toggled items, except maps.  always parse maps
            for parser in [parser for parser in self._parsers if config.data[parser.name]['toggled'] or parser.name == 'maps']:
                parser.parse(timestamp, text, charname)

    def _menu(self, event):
        """Returns a new QMenu for system tray."""
        menu = QMenu()
        menu.setAttribute(Qt.WA_DeleteOnClose)
        # check online for new version
        new_version_text = ""
        if self.new_version_available():
            new_version_text = "Update Available {}".format(ONLINE_VERSION)
        else:
            new_version_text = "Version {}".format(CURRENT_VERSION)

        check_version_action = menu.addAction(new_version_text)
        menu.addSeparator()
        get_eq_dir_action = menu.addAction('Select EQ Logs Directory')
        menu.addSeparator()

        parser_toggles = set()
        for parser in self._parsers:
            toggle = menu.addAction(parser.name.title())
            toggle.setCheckable(True)
            toggle.setChecked(config.data[parser.name]['toggled'])
            parser_toggles.add(toggle)

        menu.addSeparator()
        settings_action = menu.addAction('Settings')

        # Plugin support for adding menu items
        if self.plugins.has_plugins():
            menu.addSeparator()
        plugin_options = self.plugins.prepare_plugin_menu(menu)
        self.plugins.hook(Plugin.on_menu_display, menu)
        # End plugin support

        menu.addSeparator()
        quit_action = menu.addAction('Quit')

        # Show the menu
        action = menu.exec_(QCursor.pos())

        # Plugin support for handling menu actions
        if plugin_options:
            plugin_options(action)
        self.plugins.hook(Plugin.on_menu_click, action)
        # End plugin support

        if action == check_version_action:
            webbrowser.open('https://github.com/nomns/nparse/releases')

        elif action == get_eq_dir_action:
            dir_path = str(QFileDialog.getExistingDirectory(
                None, 'Select Everquest Logs Directory'))
            if dir_path:
                config.data['general']['eq_log_dir'] = dir_path
                config.save()
                self._toggle()

        elif action == settings_action:
            if self._settings.exec_():
                # Update required settings
                for parser in self._parsers:
                    if parser.windowOpacity() != config.data['general']['parser_opacity']:
                        parser.setWindowOpacity(
                            config.data['general']['parser_opacity'] / 100)
                        parser.settings_updated()
            # some settings are saved within other settings automatically
            # force update
            for parser in self._parsers:
                if parser.name == "spells":
                    parser.load_custom_timers()

        elif action == quit_action:
            if self._toggled:
                self._toggle()

            # save parser geometry
            for parser in self._parsers:
                g = parser.geometry()
                config.data[parser.name]['geometry'] = [
                    g.x(), g.y(), g.width(), g.height()
                ]
                config.save()

            self._system_tray.setVisible(False)

            # Plugin support
            self.plugins.hook(Plugin.on_app_quit, self)

            self.quit()

        elif action in parser_toggles:
            parser = [
                parser for parser in self._parsers if parser.name == action.text().lower()][0]
            parser.toggle()

    def new_version_available(self):
        # this will only work if numbers go up
        try:
            for (o, c) in zip(ONLINE_VERSION.split('.'), CURRENT_VERSION.split('.')):
                if int(o) > int(c):
                    return True
        except:
            return False
コード例 #30
0
ファイル: discbot.py プロジェクト: TinkerersGuild/discbot
    myComm.__name__ = name
    return myComm


# 1
from discord.ext import commands
log = logging.getLogger("Rotating Log")

load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
passwd = os.getenv('passwd')
dbname = os.getenv('dbname')
username = os.getenv('username')
prefix = os.getenv('prefix')
dbconn = DataBase(dbname, username, passwd)
pg = PluginManager(log, dbconn, prefix)
commander = pg.get_plugins()
# 2
bot = commands.Bot(command_prefix='!')
for (kw, comm) in commander.items():

    botcomms = bindfunction(kw, comm)
    myhelp = getattr(comm, "myhelp", "No help provided")
    bot.add_command(commands.Command(botcomms, name=kw, help=myhelp))


@bot.event
async def on_ready():
    #print(f'{bot.user.name} has connected to Discord!')
    pass
コード例 #31
0
ファイル: Control.py プロジェクト: RobertTheMagnificent/scrib
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from plugins import PluginManager

# User command
alias = "control"
command = { alias: "Usage: !control password\nAllow user to have access to bot commands." }

# Plugin Action
class ControlPlugin(PluginManager.Load):
	def action(self, cmds, scrib, c):
		if cmds[0] == command and len(cmds) > 1 and scrib.source not in scrib.owners:
			msg = ""
			if cmds[1] == scrib.settings.password:
				scrib.owners.append(scrib.source)
				msg = "You've been added to controllers list."
			else:
				msg = "Try again."
			return msg

PluginManager.addPlugin( command, alias, ControlPlugin() )
コード例 #32
0
 def setUp(self):
     self.pluginmanager = PluginManager()
コード例 #33
0
ファイル: test_plugins.py プロジェクト: Arpaxad/lightlang
	def setUp(self):
		self.manager = PluginManager()
		self.manager.add_plugin_dir("/tmp/slog/share/slog/plugins")
コード例 #34
0
ファイル: Fortune.py プロジェクト: RobertTheMagnificent/scrib
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from plugins import PluginManager
import os

# User command
alias = "fortune"
command = { alias: "See your fortune." }

# Plugin Action
class FortunePlugin(PluginManager.Load):
	def action(self, cmds, scrib, c):
		if scrib.scrib.settings.debug == 1:
			PluginManager.barf(PluginManager.DBG, "Fortune Plugin activated.")
		if cmds[0] == command and len(cmds) >= 1:
			msg = "".join([i for i in os.popen('fortune').readlines()]).replace('\n\n','\n').replace('\n', ' ')
			msg = self.filter(msg)

PluginManager.addPlugin( command, alias, FortunePlugin() )
コード例 #35
0
 def discover_plugins(self):
     self.plugin_manager = PluginManager()
     self.plugin_manager.discover_plugins(
         os.path.join(self.root_path, "plugins"))
コード例 #36
0
ファイル: Fortune.py プロジェクト: RobertTheMagnificent/scrib
	def action(self, cmds, scrib, c):
		if scrib.scrib.settings.debug == 1:
			PluginManager.barf(PluginManager.DBG, "Fortune Plugin activated.")
		if cmds[0] == command and len(cmds) >= 1:
			msg = "".join([i for i in os.popen('fortune').readlines()]).replace('\n\n','\n').replace('\n', ' ')
			msg = self.filter(msg)
コード例 #37
0
ファイル: app.py プロジェクト: 1egoman/quail-flask
class App(object):
  """ This class is the main app class, which starts Quail """
  flask = Flask(__name__)
  """ Contains the main flask instance """

  # quail version
  VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH = 1, 6, 'B'

  def __init__(self, **flask_args):

    cfgpath = os.path.join(self.get_root(), "config", "quail.json")

    # see if config exists
    if not os.path.exists(cfgpath):
      os.mkdir( os.path.dirname(cfgpath) )
      with open( cfgpath, 'w' ) as f:
        f.write(DEFAULTCONFIG)

    # read in config
    with open( cfgpath, 'r' ) as f:
      self.config = loads( f.read() )


    # add all api hooks
    self.add_api_hooks()

    # last plugin
    self.lastplugin = None

    # create plugin manager
    self.manager = PluginManager(self)
    self.manager.load_all()

    # create stack
    self.stack = []

    # start listener thread
    thrd = listener.listenerThread(self, self.manager.plugins)
    thrd.setName("threadListener")
    thrd.daemon = True
    thrd.start()

    self.run(**flask_args)


  def do_query(self, query="", plugin_name=None, n=0):
    """ Perform a query. Can be called by flask or another process """

    # get information about the user
    n = n or request.args.get("n") or 0
    self.user_type = request.args.get("type") or "human"

    # are we autorized?
    response = None

    if len(query):

      # check the last used plugin first
      if self.lastplugin: 
        response = self.run_plugin(self.lastplugin, query)

      # locate correct plugin
      if not response:
        for plugin in self.manager.plugins:
          response = self.run_plugin(plugin, query)
          if response: 
            break

      # if there is no response, try and parse something from wolfram alpha
      if not response: response = wolfram.parse(query, self.config["wa-api-key"])

      # still no response: error
      if not response:
        response = Packet()
        response["status"] = STATUS_NO_HIT


      # add the response to the stack
      out = response.format()
      self.stack.append(out)
    
    # n is the amount of packets to return
    if n == 0:
      # return all of them
      out = self.stack
      self.stack = []
    else:
      # return 'n' packets
      out = self.stack[-n:]
      self.stack = self.stack[:-n]


    
    # return the response
    return Response(dumps(out),  mimetype='application/json')

  def run_plugin(self, plugin, query):
    """ Run a plugin if it can accept the query """
    # set new query, and validate
    plugin["instance"].new_query(query)
    if plugin["instance"].validate():

      # add to history, if human-made
      if "human" in self.user_type:
        self.lastplugin = plugin

      # parse the query
      plugin["instance"].parse()
      return plugin["instance"].resp
    return None

  def upload_resource(self, secret): 
    """ Upload a resource to quail so it can be parsed/used in a query """
    response = Packet()
    if request.method == 'POST':
      file = request.files['file']
      filename = secure_filename(file.filename)
      if fileg:
        file.save(os.path.join(self.config["upload-folder"], filename))

        response["status"] = STATUS_OK
        response["text"] = filename
        return Response(dumps( response.format() ),  mimetype='application/json')

  def web_gui(self, secret, plugin=None, path="/"):
    """ Web interface for quail interaction """
    html = ""
    root = ""

    # quail's site
    if not plugin:

      if request.args.has_key("query"):
        text = request.args.get("query")
        q = loads(self.do_query(self.config["secret"], query=text, n=1).data)
        html = render_template(  os.path.join(root, "old/query.html"), query=q  )

      elif path == "/":
        t = ""
        for plugin in self.manager.plugins:
          html = plugin["instance"].html_provider()
          if html:
            t += "<div class=\"plugin\"><div class=\"title\">%s</div><div class=\"data\">%s</div></div>" % (plugin["instance"].__class__.__name__, html)
        html = render_template( os.path.join(root, "old/index.html"), body=t)

    return html




  def calendar(self, month=0, year=0):
    """ Web interface for quail interaction """
    root = ""
    
    # format events to be displayed
    out = []
    now = datetime.datetime.today()


    # find year
    if year: 
      now = now.replace(year=int(year))


    # find months
    if month: 
      now = now.replace(month=int(month))



    # get previous month
    one_day = datetime.timedelta(days=1)
    last_month = now - one_day
    while last_month.month == now.month or last_month.day > now.day:
      last_month -= one_day

    try:
      days_in_month = (datetime.date(now.year, now.month+1, 1) - datetime.date(now.year, now.month, 1)).days
    except ValueError:
      days_in_month = 31 # must be december

    try:
      day_in_last_month = (datetime.date(last_month.year, last_month.month+1, 1) - datetime.date(last_month.year, last_month.month, 1)).days
    except ValueError:
      day_in_last_month = 31 # must be december



    # all days into a list
    for i in xrange(0, days_in_month+1):
      events_for_day = self.calender.events.year(now.year).month(now.month).day(i+1)

      today = {"day": i+1, "events": events_for_day, "month": "in"}
      out.append(today)
    


    # prepend previous month days
    for i in xrange( 0, int(datetime.date(now.year, now.month, 1).strftime('%w')) ):
      events_for_day = self.calender.events.year(now.year).month(now.month-1).day(i+1)

      today = {"day": day_in_last_month-i, "events": events_for_day, "month": "out"}
      out.insert(0, today)




    # split the output into weeks
    weeksout = []
    week_ct = -1;
    for i in xrange(0, days_in_month+i+1):
      if i%7 == 0:
        week_ct += 1
        weeksout.append([])
      try:
        weeksout[week_ct].append(out[i])
      except IndexError: pass


    # render output
    return render_template( os.path.join(root, "cal.html"), events=weeksout, title=now.strftime("%B %Y"),now=now)


  def web(self):
    """ Web interface for quail interaction """
    root = ""
    
    # first time?
    if not self.config.has_key("welcome") or (self.config.has_key("welcome") and not self.config["welcome"]):
      return render_template( os.path.join(root, "welcome.html"))
    else:
      return render_template( os.path.join(root, "index.html"))


  def updatequaildotjson(self):
    """ Update config/quail.json file """
    cfgpath = os.path.join(self.get_root(), "config", "quail.json")

    if request.args.get("data") and self.config["welcome"] == False:
      with open( cfgpath, 'w' ) as f:
        try:
          data = loads( request.args.get("data") )
          data["welcome"] = True
          self.config["welcome"] = True
          f.write( dumps(data) )
        except TypeError:
          f.write( dumps(self.config) )
          return "BAD"

      return "OK"
    return "NO DATA OR PERMISSION DENIED"


  def web_query(self):
    q = self.do_query( request.args.get('q') )
    return render_template( "query.html", query=loads(q.data) )
    
  def run(self, **flask_args):
    """ Sets all the flask options behind the scenes, and starte Flask """

    # multiple rules for a query
    self.flask.add_url_rule("/v2/<secret>/query", "query", view_func=self.do_query)
    self.flask.add_url_rule("/v2/<secret>/query/<query>", "query", view_func=self.do_query)
    self.flask.add_url_rule("/v2/<secret>/query/<query>/<int:n>", "query", view_func=self.do_query)
    self.flask.add_url_rule("/v2/<secret>/query/<query>/use/<plugin_name>", "query", view_func=self.do_query)
    self.flask.add_url_rule("/v2/<secret>/query/<query>/use/<plugin_name>/<int:n>", "query", view_func=self.do_query)

    # uploading of files
    self.flask.add_url_rule("/v2/<secret>/upload", "upload", methods=["POST"], view_func=self.upload_resource)

    # web interface
    self.flask.add_url_rule("/v2/<secret>/web", "web", view_func=self.web_gui)
    self.flask.add_url_rule("/v2/<secret>/web/<path>", "web", view_func=self.web_gui)
    self.flask.add_url_rule("/v2/<secret>/<plugin>/web", "web", view_func=self.web_gui)
    self.flask.add_url_rule("/v2/<secret>/<plugin>/web/<path>", "web", view_func=self.web_gui)

    # web interface
    self.flask.add_url_rule("/", "newweb", view_func=self.web)

    self.flask.add_url_rule("/cal", "web_cal", view_func=self.calendar)
    self.flask.add_url_rule("/cal/<int:month>", "web_cal", view_func=self.calendar)
    self.flask.add_url_rule("/cal/<int:month>/<int:year>", "web_cal", view_func=self.calendar)

    self.flask.add_url_rule("/search", "query_search", view_func=self.web_query)
    self.flask.add_url_rule("/quail.json", "updatequaildotjson", view_func=self.updatequaildotjson)

    # run flask
    self.flask.run(host=self.config["host"], port=self.config["port"], **flask_args)

  def get_root(self):
    """ Get root Quail directory """
    return os.path.dirname( os.path.dirname( os.path.abspath(__file__) ) )

  def add_api_hooks(self):
    """ Add api hooks for plugins to access later on, like people, events, etc """
    self.calender = Calender(self)
    self.files = UserFiles(self)
    self.people = PeopleContainer(self)
コード例 #38
0
ファイル: test_plugins.py プロジェクト: torgaming/Cardinal
 def test_load_plugins_not_a_list_or_string_typeerror(self, plugins):
     manager = PluginManager(Mock())
     with pytest.raises(TypeError):
         manager.load(plugins)