Example #1
0
def winrate_app(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-type', 'text/html'),
                        ('Cache-Control', 'no-cache'),
                        ('Cache-Control', 'must-revalidate')]
    start_response(status, response_headers)

    engine = Engine(loader=FileLoader(['']), extensions=[CoreExtension()])
    template = engine.get_template('winrate_template.html')

    player_wins = winrate.download_current_player_wins()
    leaderboard = winrate.compute_win_rate_leaderboard(player_wins)
    ranked_leaderboard = [
        (str(index + 1), name, "{:.2f}%".format(probability * 100))
        for index, (name, probability) in enumerate(leaderboard)
    ]

    preview_leaderboard = ""
    for rank, name, percentile in ranked_leaderboard[:3]:
        preview_leaderboard += "{}. {} {} ".format(rank, name, percentile)

    response_body = template.render({
        "preview_leaderboard": preview_leaderboard,
        "leaderboard": ranked_leaderboard
    })

    yield response_body.encode()
Example #2
0
 def setUp(self):
     from wheezy.template.engine import Engine
     from wheezy.template.ext.core import CoreExtension
     from wheezy.template.loader import DictLoader
     self.templates = {}
     self.engine = Engine(loader=DictLoader(templates=self.templates),
                          extensions=[CoreExtension()])
Example #3
0
 def tohtml(self):
     # TODO temporary
     path = os.path.join(os.path.dirname(__file__), 'reader.html.template')
     loader = DictLoader({'reader': open(path).read()})
     engine = Engine(loader=loader, extensions=[CoreExtension()])
     template = engine.get_template('reader')
     return template.render({'feed': self}).encode('utf-8')
Example #4
0
    def __init__(self,
                 output_filename,
                 mz_dtype=np.float64,
                 intensity_dtype=np.float32):
        self.mz_dtype = mz_dtype
        self.intensity_dtype = intensity_dtype
        self.run_id = os.path.splitext(output_filename)[0]
        self.filename = self.run_id + ".imzML"
        self.ibd_filename = self.run_id + ".ibd"
        self.xml = open(self.filename, 'w')
        self.ibd = open(self.ibd_filename, 'w')
        self.sha1 = hashlib.sha1()
        self.ibd_offset = 0
        self.uuid = uuid.uuid4()

        self._write_ibd(self.uuid.bytes_le)

        self.wheezy_engine = Engine(loader=DictLoader(
            {'imzml': IMZML_TEMPLATE}),
                                    extensions=[CoreExtension()])
        self.imzml_template = self.wheezy_engine.get_template('imzml')

        self.spectra = []

        from collections import namedtuple
        self.Spectrum = namedtuple('Spectrum', [
            'coords', 'mz_len', 'mz_offset', 'mz_enc_len', 'int_len',
            'int_offset', 'int_enc_len'
        ])
Example #5
0
class EngineTestCase(unittest.TestCase):
    """Test the ``Engine``."""

    def setUp(self) -> None:
        self.templates: typing.Dict[str, str] = {"a": ""}
        self.engine = Engine(
            loader=DictLoader(templates=self.templates),
            extensions=[CoreExtension()],
        )

    def test_template_not_found(self) -> None:
        """Raises IOError."""
        self.assertRaises(IOError, lambda: self.engine.get_template("x"))

    def test_import_not_found(self) -> None:
        """Raises IOError."""
        self.assertRaises(IOError, lambda: self.engine.import_name("x"))

    def test_remove_unknown_name(self) -> None:
        """Invalidate name that is not known to engine."""
        self.engine.remove("x")

    def test_remove_name(self) -> None:
        """Invalidate name that is known to engine."""
        # self.templates["a"] = ""
        self.engine.compile_import("a")
        self.engine.compile_template("a")
        self.engine.remove("a")
Example #6
0
class EngineSyntaxErrorTestCase(unittest.TestCase):
    """Test the ``Engine``."""

    def setUp(self) -> None:
        self.templates: typing.Dict[str, str] = {}
        self.engine = Engine(
            loader=DictLoader(templates=self.templates),
            extensions=[CoreExtension()],
        )

    def test_compile_template_error(self) -> None:
        """Raises SyntaxError."""
        self.templates[
            "x"
        ] = """
            @if :
            @end
        """
        self.assertRaises(
            SyntaxError, lambda: self.engine.compile_template("x")
        )

    def test_compile_import_error(self) -> None:
        """Raises SyntaxError."""
        self.templates[
            "m"
        ] = """
            @def x():
                @# ignore
                @if :
                @end
            @end
        """
        self.assertRaises(SyntaxError, lambda: self.engine.compile_import("m"))
Example #7
0
    def tohtml(self):
        if DictLoader is None:
            raise ImportError('dep wheezy.template needed')

        loader = DictLoader({'reader': open('reader.html.template').read()})
        engine = Engine(loader=loader, extensions=[CoreExtension()])
        template = engine.get_template('reader')
        return template.render({'feed': self}).encode('utf-8')
Example #8
0
 def render(self, source, ctx=None):
     from wheezy.template.engine import Engine
     from wheezy.template.ext.core import CoreExtension
     from wheezy.template.loader import DictLoader
     loader = DictLoader({'test.html': source})
     engine = Engine(loader=loader, extensions=[CoreExtension()])
     template = engine.get_template('test.html')
     return template.render(ctx or {})
Example #9
0
    def render(self, result):
        """Take the function return value and renders a html document."""
        templateFile = result["templatePath"]
        context = result["context"]

        searchPath = [""]
        engine = Engine(loader=FileLoader(searchPath), extensions=[CoreExtension(), CodeExtension()])
        template = engine.get_template(templateFile)
        return template.render(context)
Example #10
0
 def render(
     self,
     source: str,
     ctx: typing.Optional[typing.Mapping[str, typing.Any]] = None,
 ) -> str:
     loader = DictLoader({"test.html": source})
     engine = Engine(loader=loader, extensions=[CoreExtension()])
     template = engine.get_template("test.html")
     return template.render(ctx or {})
Example #11
0
    def tohtml(self):
        if DictLoader is None:
            raise ImportError('dep wheezy.template needed')

        path = os.path.join(os.path.dirname(__file__), 'reader.html.template')
        loader = DictLoader({'reader': open(path).read()})
        engine = Engine(loader=loader, extensions=[CoreExtension()])
        template = engine.get_template('reader')
        return template.render({'feed': self}).encode('utf-8')
Example #12
0
 def content(self, source, filename):
     engine = Engine(
         loader=Loader(source),
         extensions=[
             CoreExtension(token_start='\\$'),
             CodeExtension(token_start='\\$'),
         ])
     engine.global_vars.update({'warn': warn})
     return engine.get_template(filename).render({})
Example #13
0
def generate_source(argsstring, options, version, enums, functions_by_category,
                    passthru, extensions, types, raw_enums):
    template_pattern = re.compile("(.*).template")

    # Sort by categories and sort the functions inside the categories
    functions_by_category = sorted(functions_by_category, key=lambda x: x[0])
    functions_by_category = list(
        map(lambda c: (c[0], sorted(c[1], key=lambda x: x.name)),
            functions_by_category))

    template_namespace = {
        'passthru': passthru,
        'functions': functions_by_category,
        'enums': enums,
        'options': options,
        'version': version,
        'extensions': extensions,
        'types': types,
        'raw_enums': raw_enums,
        'args': argsstring
    }
    if not os.path.isdir(options.template_dir):
        print('%s is not a directory' % options.template_dir)
        exit(1)

    if os.path.exists(options.outdir) and not os.path.isdir(options.outdir):
        print('%s is not a directory' % options.outdir)
        exit(1)

    if not os.path.exists(options.outdir):
        os.mkdir(options.outdir)

    engine = Engine(loader=FileLoader([options.template_dir]),
                    extensions=[CoreExtension(),
                                CodeExtension()])

    generatedFiles = 0
    allFiles = 0

    for template_path in glob('%s/*.template' %
                              os.path.abspath(options.template_dir)):

        infile = os.path.basename(template_path)
        outfile = '%s/%s' % (options.outdir,
                             template_pattern.match(infile).group(1))

        template = engine.get_template(infile)

        allFiles += 1

        with open(outfile, 'w') as out:
            out.write(template.render(template_namespace))
            print("Successfully generated %s" % outfile)
            generatedFiles += 1

    print("Generated %d of %d files" % (generatedFiles, allFiles))
Example #14
0
 def render(self, source, ctx=None):
     from wheezy.template.engine import Engine
     from wheezy.template.ext.core import CoreExtension
     from wheezy.template.loader import DictLoader
     loader = DictLoader({'test.html': source})
     engine = Engine(
         loader=loader,
         extensions=[CoreExtension()])
     template = engine.get_template('test.html')
     return template.render(ctx or {})
Example #15
0
def main(name):
    searchpath = [name]
    engine = Engine(loader=FileLoader(searchpath),
                    extensions=[CoreExtension(token_start='#')])
    engine = Engine(loader=PreprocessLoader(engine),
                    extensions=[CoreExtension()])
    engine.global_vars.update({'h': escape})

    template = engine.get_template('welcome.html')
    return template.render
Example #16
0
def init_templates():
	""" Initialize all templates.
	"""
	global g_template_dic
	searchpath = ['mportal/templates']
	engine = Engine(loader=FileLoader(searchpath),extensions=[CoreExtension()])
	
	g_template_dic['login'] = engine.get_template('login.html')
	g_template_dic['console'] = engine.get_template('console.html')
	g_template_dic['not_found'] = engine.get_template('not_found.html')
	g_template_dic['redirect'] = engine.get_template('redirect.html')
def build_modo_bash(commands=[], headless="", render_range={}):
    searchpath = [TEMPLATES]
    engine = Engine(loader=FileLoader(searchpath),
                    extensions=[CoreExtension()])
    template = engine.get_template('modo_batch.sh')

    return template.render({
        'modo_cl': headless,
        'commands': commands,
        'render_range': render_range
    })
def build_modo_preview_render_command(pathaliases=None, scenes={}):
    searchpath = [TEMPLATES]
    engine = Engine(loader=FileLoader(searchpath),
                    extensions=[CoreExtension()])
    template = engine.get_template('modo_preview_render_commands.txt')

    if pathaliases:
        for key in pathaliases:
            '{} "{}"'.format(key, os.path.normpath(pathaliases[key]))

    return template.render({'pathaliases': pathaliases, 'scenes': scenes})
Example #19
0
def main(argv: typing.Optional[typing.List[str]] = None) -> int:
    args = parse_args(argv or sys.argv[1:])
    if not args:
        return 2
    ts = args.token_start
    extensions = [CoreExtension(ts), CodeExtension(ts)]
    extensions.extend(args.extensions)
    engine = Engine(FileLoader(args.searchpath), extensions)
    engine.global_vars.update({"h": escape})
    t = engine.get_template(args.template)
    sys.stdout.write(t.render(load_context(args.context)))
    return 0
Example #20
0
    def get(self):
        fortunes = db_session.query(Fortune).all()
        fortunes.append(Fortune(id=0, message="Additional fortune added at request time."))
        fortunes.sort(key=attrgetter("message"))
        engine = Engine(loader=FileLoader(["views"]), extensions=[CoreExtension()])
        template = engine.get_template("fortune.html")
        for f in fortunes:
            f.message = bleach.clean(f.message)
        template_html = template.render({"fortunes": fortunes})		

        response = HTTPResponse()
        response.write(template_html)
        return response
Example #21
0
    def __init__(self, path):
        self.path = path

        template_dct = {
            'docker': templates.docker,
        }
        engine = Engine(loader=DictLoader(template_dct),
                        extensions=[CoreExtension(),
                                    CodeExtension()])
        self.templates = {
            name: engine.get_template(name)
            for name in template_dct
        }
Example #22
0
	def to_autopkg(self, outfile):		
		searchpath = [os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')]
		engine = Engine(
			loader=FileLoader(searchpath),
			extensions=[CoreExtension()]
		)
		template = engine.get_template('redist-packages.autopkg')
		autopkg = template.render({'package': self})
		
		with open(outfile, 'w') as f:
			f.write(autopkg)
		
		return autopkg
def build_modo_render_command_win(pathaliases=None, scenes={}):
    searchpath = [TEMPLATES]
    engine = Engine(loader=FileLoader(searchpath),
                    extensions=[CoreExtension()])
    template = engine.get_template('modo_render_commands_win.txt')

    if pathaliases:
        for key in pathaliases:
            '{} "{}"'.format(key, os.path.normpath(pathaliases[key]))

    for scene in scenes:
        scenes[scene]['path'] = format_filename(scenes[scene]['path'], 'win32')

    return template.render({'pathaliases': pathaliases, 'scenes': scenes})
Example #24
0
def generate(filename, serial_no, settings, data):
    path = Path(__file__).parent / 'views'
    searchpath = [str(path)]
    engine = Engine(loader=FileLoader(searchpath),
                    extensions=[CoreExtension()])
    engine.global_vars.update({'format_value': format_value})
    template = engine.get_template('template.html')
    with open(filename, 'w') as f:
        f.write(
            template.render({
                'data': data,
                'serial_no': serial_no,
                'noun': settings['dut']
            }))
Example #25
0
    def to_autopkg(self, outfile):
        searchpath = [
            os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'templates')
        ]
        engine = Engine(loader=FileLoader(searchpath),
                        extensions=[CoreExtension()])
        template = engine.get_template('redist-packages.autopkg')
        autopkg = template.render({'package': self})

        with open(outfile, 'w') as f:
            f.write(autopkg)

        return autopkg
Example #26
0
def main(args=None):
    if not json:  # pragma: nocover
        print('error: json module is not available')
        return 1
    args = parse_args(args or sys.argv[1:])
    if not args:
        return 2
    ts = args.token_start
    extensions = [CoreExtension(ts), CodeExtension(ts)]
    extensions.extend(args.extensions)
    engine = Engine(FileLoader(args.searchpath), extensions)
    engine.global_vars.update({'h': escape})
    t = engine.get_template(args.template)
    sys.stdout.write(t.render(load_context(args.context)))
    return 0
Example #27
0
def generate_source(options, version, enums, functions_by_category, passthru, extensions, types, raw_enums):
    template_pattern = re.compile("(.*).template")

    # Sort by categories and sort the functions inside the categories
    functions_by_category = sorted(functions_by_category
                                  ,key=lambda x: x[0])
    functions_by_category = list(map(lambda c: (c[0], sorted(c[1], key=lambda x: x.name))
                                ,functions_by_category))

    template_namespace = {'passthru'  : passthru,
                          'functions' : functions_by_category,
                          'enums'     : enums,
                          'options'   : options,
                          'version'   : version,
                          'extensions': extensions,
                          'types': types,
                          'raw_enums': raw_enums}
    if not os.path.isdir(options.template_dir):
        print ('%s is not a directory' % options.template_dir)
        exit(1)

    if os.path.exists(options.outdir) and not os.path.isdir(options.outdir):
        print ('%s is not a directory' % options.outdir)
        exit(1)

    if not os.path.exists(options.outdir):
        os.mkdir(options.outdir)

    engine = Engine(loader=FileLoader([options.template_dir]),extensions=[CoreExtension(),CodeExtension()])

    generatedFiles = 0
    allFiles       = 0;

    for template_path in glob('%s/*.template' % os.path.abspath(options.template_dir)):

        infile = os.path.basename(template_path)
        outfile = '%s/%s' % (options.outdir, template_pattern.match(infile).group(1))

        template = engine.get_template(infile)

        allFiles += 1

        with open(outfile, 'w') as out:
            out.write(template.render(template_namespace))
            print("Successfully generated %s" % outfile)
            generatedFiles += 1;

    print("Generated %d of %d files" % (generatedFiles, allFiles))
Example #28
0
    def __init__(self, path):
        self.path = path

        template_dct = {
            'docker': templates.docker,
        }
        engine = Engine(
            loader=DictLoader(template_dct),
            extensions=[
                CoreExtension(),
                CodeExtension()
            ]
        )
        self.templates = {
            name: engine.get_template(name) for name in template_dct
        }
Example #29
0
 def preprocess_template(
     self,
     runtime_engine: Engine,
     name: str,
     ctx: typing.Mapping[str, typing.Any],
 ) -> None:
     self.lock.acquire(True)
     try:
         if name not in runtime_engine.renders:
             source = self.engine.render(name, ctx, {}, {})
             loader = runtime_engine.loader.loaders[0]  # type: ignore
             loader.templates[name] = source
             runtime_engine.compile_template(name)
             del loader.templates[name]
     finally:
         self.lock.release()
Example #30
0
    def post_setup(self, path=None, name=None):  # Post setup hook

        if path:
            self.path = path
        else:
            self.path = os.path.dirname(inspect.getfile(self.__class__))

        if name:
            self.name = name
        else:
            self.name = "%s %s " % (self.default_workspace_category, "Plugin")

        self.name = name

        # Plugin personal template engine
        self.templateEngine = Engine(
            loader=FileLoader([self.path, os.path.join(utils.scriptdir, 'html')]),
            extensions=[CoreExtension(), CodeExtension()]
        )

        help_path = os.path.join(self.path, 'readme.html')
        if os.path.exists(help_path):
            self.help_tab_html_filename = 'readme.html'
        else:
            self.help_tab_html_filename = None
Example #31
0
 def setUp(self) -> None:
     templates = {"tmpl1.html": "x1", "shared/master.html": "x2"}
     engine = Engine(
         loader=DictLoader(templates=templates),
         extensions=[CoreExtension()],
     )
     self.loader = PreprocessLoader(engine, {"x": 1})
class Wheezy(BaseEngine):
    app_dirname = 'wheezy_templates'

    def __init__(self, params):
        params = params.copy()
        options = params.pop('OPTIONS').copy()
        super().__init__(params)

        self.template_context_processors = options.pop('context_processors',
                                                       [])
        if 'loader' not in options:
            options['loader'] = FileLoader(self.template_dirs)
        options.setdefault('autoescape', True)
        options.setdefault('auto_reload', settings.DEBUG)
        self.engine = Engine(loader=options['loader'],
                             extensions=[CoreExtension()])

        self.engine.global_vars.update({
            'e': escape,
            'escape': escape,
            'static': static
        })

    def get_template(self, template_name):
        try:
            return Template(self.engine.get_template(template_name), self)
        except OSError as exc:
            raise TemplateDoesNotExist(template_name, backend=self) from exc
def build_modo_batch(commands=[], headless=""):
    import ntpath
    searchpath = [TEMPLATES]
    engine = Engine(loader=FileLoader(searchpath),
                    extensions=[CoreExtension()])
    template = engine.get_template('modo_batch.bat')
    win_commands = []
    for command in commands:
        win_commands.append(ntpath.normpath(format_filename(command, 'win32')))

    headless = ntpath.normpath(
        r"C:\Program Files\Luxology\modo\11.0v1\modo_cl.exe")

    return template.render({
        'modo_cl': ntpath.normpath(headless),
        'commands': win_commands
    })
Example #34
0
 def runtime_engine_factory(loader: Loader) -> Engine:
     engine = Engine(
         loader=loader,
         extensions=[
             CoreExtension(),
         ],
     )
     return engine
Example #35
0
 def setUp(self):
     from wheezy.template.engine import Engine
     from wheezy.template.ext.core import CoreExtension
     from wheezy.template.loader import DictLoader
     self.templates = {}
     self.engine = Engine(
         loader=DictLoader(templates=self.templates),
         extensions=[CoreExtension()])
Example #36
0
 def parse_toplevel_config(self, config):
     super().parse_toplevel_config(config)
     if GIFormatter.engine is None:
         module_path = os.path.dirname(__file__)
         searchpath = [os.path.join(module_path, "html_templates")] + Formatter.engine.loader.searchpath
         GIFormatter.engine = Engine(
                 loader=FileLoader(searchpath, encoding='UTF-8'),
                 extensions=[CoreExtension(), CodeExtension()])
         GIFormatter.engine.global_vars.update({'e': html.escape})
Example #37
0
    def __init__(self, searchpath):
        Formatter.__init__(self)

        self._symbol_formatters = {
            FunctionSymbol: self._format_function,
            FunctionMacroSymbol: self._format_function_macro,
            CallbackSymbol: self._format_callback,
            ConstantSymbol: self._format_constant,
            ExportedVariableSymbol: self._format_constant,
            AliasSymbol: self._format_alias,
            StructSymbol: self._format_struct,
            EnumSymbol: self._format_enum,
            ParameterSymbol: self._format_parameter_symbol,
            ReturnItemSymbol: self._format_return_item_symbol,
            FieldSymbol: self._format_field_symbol,
            SignalSymbol: self._format_signal_symbol,
            VFunctionSymbol: self._format_vfunction_symbol,
            PropertySymbol: self._format_property_symbol,
            ClassSymbol: self._format_class_symbol,
            InterfaceSymbol: self._format_interface_symbol,
        }

        self._ordering = [InterfaceSymbol, ClassSymbol, FunctionSymbol,
                          FunctionMacroSymbol, SignalSymbol,
                          PropertySymbol, StructSymbol,
                          VFunctionSymbol, EnumSymbol, ConstantSymbol,
                          ExportedVariableSymbol, AliasSymbol, CallbackSymbol]

        if HtmlFormatter.theme_path:
            self.__load_theme_templates(searchpath,
                                        HtmlFormatter.theme_path)
        if HtmlFormatter.extra_theme_path:
            self.__load_theme_templates(searchpath,
                                        HtmlFormatter.extra_theme_path)

        searchpath.append(os.path.join(HERE, "html_templates"))
        self.engine = Engine(
            loader=FileLoader(searchpath, encoding='UTF-8'),
            extensions=[CoreExtension(), CodeExtension()]
        )

        self.all_scripts = set()
        self.all_stylesheets = set()
        self._docstring_formatter = GtkDocStringFormatter()
Example #38
0
    def parse_config(self, config):
        """Banana banana
        """
        self.add_anchors = bool(config.get("html_add_anchors"))
        self.number_headings = bool(config.get("html_number_headings"))

        if self.theme_path:
            self.__load_theme_templates(self.searchpath, self.theme_path)
        if self.extra_theme_path:
            self.__load_theme_templates(self.searchpath, self.extra_theme_path)

        self.searchpath.append(os.path.join(HERE, "templates"))
        self.engine = Engine(loader=FileLoader(self.searchpath,
                                               encoding='UTF-8'),
                             extensions=[CoreExtension(),
                                         CodeExtension()])
        self.engine.global_vars.update({'e': html.escape})

        self._docstring_formatter.parse_config(config)
Example #39
0
def generate_source(options, version, enums, functions_by_category, passthru, extensions):
    generated_warning = '/* WARNING: This file was automatically generated */\n/* Do not edit. */\n'
    template_pattern = re.compile("(.*).template")

    template_namespace = {'passthru'  : passthru,
                          'functions' : functions_by_category,
                          'enums'     : enums,
                          'options'   : options,
                          'version'   : version,
                          'extensions': extensions}
    if not os.path.isdir(options.template_dir):
        print ('%s is not a directory' % options.template_dir)
        exit(1)

    if os.path.exists(options.outdir) and not os.path.isdir(options.outdir):
        print ('%s is not a directory' % options.outdir)
        exit(1)

    if not os.path.exists(options.outdir):
        os.mkdir(options.outdir)

    engine = Engine(loader=FileLoader([options.template_dir]), extensions=[CoreExtension()])
    
    generatedFiles = 0
    allFiles       = 0;

    for template_path in glob('%s/*.template' % os.path.abspath(options.template_dir)):

        infile = os.path.basename(template_path)
        outfile = '%s/%s' % (options.outdir, template_pattern.match(infile).group(1))

        template = engine.get_template(infile)

        allFiles += 1

        with open(outfile, 'w') as out:
            out.write(generated_warning)
            out.write(template.render(template_namespace))
            print("Successfully generated %s" % outfile)
            generatedFiles += 1;

    print("Generated %d of %d files" % (generatedFiles, allFiles))
Example #40
0
File: nikki.py Project: z411/nikki
def render(outname, templatename, newcontext=None):
  engine = Engine(
    loader=FileLoader(['templates'], 'UTF-8'),
    extensions=[CoreExtension()]
  )
  template = engine.get_template(templatename)
  context = {
    'title': WLOG_TITLE,
    'wlog_url': WLOG_URL,
    'site_url': SITE_URL,
    'version': VERSION,
    'categories': MAIN_CATEGORIES,
  }
  if newcontext:
    context.update(newcontext)
  
  output = template.render(context)
  
  with open("output/{}.html".format(outname), 'w') as f:
    f.write(output.encode('utf-8'))
Example #41
0
class EngineTestCase(unittest.TestCase):
    """ Test the ``Engine``.
    """

    def setUp(self):
        from wheezy.template.engine import Engine
        from wheezy.template.loader import DictLoader
        self.engine = Engine(
            loader=DictLoader(templates={}),
            extensions=[])

    def test_template_not_found(self):
        """ Raises IOError.
        """
        self.assertRaises(IOError, lambda: self.engine.get_template('x'))

    def test_import_not_found(self):
        """ Raises IOError.
        """
        self.assertRaises(IOError, lambda: self.engine.import_name('x'))

    def test_remove_unknown_name(self):
        """ Invalidate name that is not known to engine.
        """
        self.engine.remove('x')

    def test_remove_name(self):
        """ Invalidate name that is known to engine.
        """
        self.engine.templates['x'] = 'x'
        self.engine.renders['x'] = 'x'
        self.engine.modules['x'] = 'x'
        self.engine.remove('x')
Example #42
0
    def generate_html(self, filename, template_file="Default.html"):
        
        engine = Engine(
            loader=FileLoader(['templates']),
            extensions=[CoreExtension()]
            )
        
        template = engine.get_template(template_file)
        
        try:
            file = open(filename, "w")
            try:

                clients_list_descendant = list(reversed(sorted(self.clients_hours.items(), key=lambda x: x[1])))
                file.write(template.render({'clients_hours':clients_list_descendant,
                                            'total_hours':str(self.total_hours_booked),
                                            'unbooked_timeranges':self.get_unbooked_hours(),
                                            'total_hours_unbooked': self.total_hours_unbooked}))
            finally:
                file.close()
        except IOError:
            pass
Example #43
0
    def __init__(self, searchpath):
        Formatter.__init__(self)

        self._symbol_formatters = {
            FunctionSymbol: self._format_function,
            FunctionMacroSymbol: self._format_function_macro,
            CallbackSymbol: self._format_callback,
            ConstantSymbol: self._format_constant,
            ExportedVariableSymbol: self._format_constant,
            AliasSymbol: self._format_alias,
            StructSymbol: self._format_struct,
            EnumSymbol: self._format_enum,
            ParameterSymbol: self._format_parameter_symbol,
            ReturnItemSymbol: self._format_return_item_symbol,
            FieldSymbol: self._format_field_symbol,
            SignalSymbol: self._format_signal_symbol,
            VFunctionSymbol: self._format_vfunction_symbol,
            PropertySymbol: self._format_property_symbol,
            ClassSymbol: self._format_class_symbol,
            InterfaceSymbol: self._format_interface_symbol,
        }

        self._ordering = [InterfaceSymbol, ClassSymbol, FunctionSymbol,
                          FunctionMacroSymbol, SignalSymbol,
                          PropertySymbol, StructSymbol,
                          VFunctionSymbol, EnumSymbol, ConstantSymbol,
                          ExportedVariableSymbol, AliasSymbol, CallbackSymbol]

        if HtmlFormatter.theme_path:
            theme_templates_path = os.path.join(
                HtmlFormatter.theme_path, 'templates')

            if os.path.exists(theme_templates_path):
                searchpath.insert(0, theme_templates_path)

        searchpath.append(os.path.join(HERE, "html_templates"))
        self.engine = Engine(
            loader=FileLoader(searchpath, encoding='UTF-8'),
            extensions=[CoreExtension(), CodeExtension()]
        )

        self.all_scripts = set()
        self.all_stylesheets = set()
        self._docstring_formatter = GtkDocStringFormatter()
Example #44
0
class TemplateTestCase(unittest.TestCase):
    """ Test the ``CodeExtension`` compiled templates.
    """

    def setUp(self):
        from wheezy.template.engine import Engine
        from wheezy.template.ext.code import CodeExtension
        from wheezy.template.ext.core import CoreExtension
        from wheezy.template.loader import DictLoader
        self.templates = {}
        self.engine = Engine(
            loader=DictLoader(templates=self.templates),
            extensions=[CoreExtension(), CodeExtension()])

    def render(self, source):
        self.templates['test.html'] = source
        template = self.engine.get_template('test.html')
        return template.render({})

    def test_code_single_line(self):
        assert '1' == self.render('@(i = 1)@i!s')

    def test_code_continue_newline(self):
        assert '1' == self.render('@(i = 1)\\\n@i!s')

    def test_code_separated_lines(self):
        assert '\n1' == self.render('@(i = 1)\n@i!s')

    def test_code_with_markup1(self):
        assert 'x = 1' == self.render('x@(i = 1) = @i!s')

    def test_code_with_markup2(self):
        assert 'x = 1' == self.render('x @(i = 1)= @i!s')

    def test_code_multiline(self):
        assert 'x = 1' == self.render("""\
x \
@(
    i = 1
)\
= @i!s""")
Example #45
0
    def __init__(self, output_filename, mz_dtype=np.float64, intensity_dtype=np.float32):
        self.mz_dtype = mz_dtype
        self.intensity_dtype = intensity_dtype
        self.run_id = os.path.splitext(output_filename)[0]
        self.filename =  self.run_id + ".imzML"
        self.ibd_filename = self.run_id + ".ibd"
        self.xml = open(self.filename, 'w')
        self.ibd = open(self.ibd_filename, 'w')
        self.sha1 = hashlib.sha1()
        self.ibd_offset = 0
        self.uuid = uuid.uuid4()

        self._write_ibd(self.uuid.bytes_le)

        self.wheezy_engine = Engine(loader=DictLoader({'imzml': IMZML_TEMPLATE}), extensions=[CoreExtension()])
        self.imzml_template = self.wheezy_engine.get_template('imzml')

        self.spectra = []

        from collections import namedtuple
        self.Spectrum = namedtuple('Spectrum', ['coords', 'mz_len', 'mz_offset', 'mz_enc_len', 'int_len', 'int_offset', 'int_enc_len'])
Example #46
0
    def __init__(self, searchpath):
        Formatter.__init__(self)
        self._symbol_formatters = {
                FunctionSymbol: self._format_function,
                FunctionMacroSymbol: self._format_function_macro,
                CallbackSymbol: self._format_callback,
                ConstantSymbol: self._format_constant,
                ExportedVariableSymbol: self._format_constant,
                AliasSymbol: self._format_alias,
                StructSymbol: self._format_struct,
                EnumSymbol: self._format_enum,
                ClassSymbol: self._format_class,
                SectionSymbol: self._format_class,
                ParameterSymbol: self._format_parameter_symbol,
                ReturnValueSymbol : self._format_return_value_symbol,
                FieldSymbol: self._format_field_symbol,
                }

        self._summary_formatters = {
                FunctionSymbol: self._format_function_summary,
                FunctionMacroSymbol: self._format_function_macro_summary,
                CallbackSymbol: self._format_callback_summary,
                ConstantSymbol: self._format_constant_summary,
                ExportedVariableSymbol: self._format_exported_variable_summary,
                AliasSymbol: self._format_alias_summary,
                StructSymbol: self._format_struct_summary,
                EnumSymbol: self._format_enum_summary,
                }

        self._ordering = [FunctionSymbol, FunctionMacroSymbol,
                StructSymbol, EnumSymbol, ConstantSymbol, ExportedVariableSymbol,
                AliasSymbol, CallbackSymbol]

        module_path = os.path.dirname(__file__)
        searchpath.append (os.path.join(module_path, "templates"))
        self.engine = Engine(
            loader=FileLoader(searchpath, encoding='UTF-8'),
            extensions=[CoreExtension()]
        )
Example #47
0
class HtmlFormatter (Formatter):
    def __init__(self, searchpath):
        Formatter.__init__(self)
        self._symbol_formatters = {
                FunctionSymbol: self._format_function,
                FunctionMacroSymbol: self._format_function_macro,
                CallbackSymbol: self._format_callback,
                ConstantSymbol: self._format_constant,
                ExportedVariableSymbol: self._format_constant,
                AliasSymbol: self._format_alias,
                StructSymbol: self._format_struct,
                EnumSymbol: self._format_enum,
                ClassSymbol: self._format_class,
                SectionSymbol: self._format_class,
                ParameterSymbol: self._format_parameter_symbol,
                ReturnValueSymbol : self._format_return_value_symbol,
                FieldSymbol: self._format_field_symbol,
                }

        self._summary_formatters = {
                FunctionSymbol: self._format_function_summary,
                FunctionMacroSymbol: self._format_function_macro_summary,
                CallbackSymbol: self._format_callback_summary,
                ConstantSymbol: self._format_constant_summary,
                ExportedVariableSymbol: self._format_exported_variable_summary,
                AliasSymbol: self._format_alias_summary,
                StructSymbol: self._format_struct_summary,
                EnumSymbol: self._format_enum_summary,
                }

        self._ordering = [FunctionSymbol, FunctionMacroSymbol,
                StructSymbol, EnumSymbol, ConstantSymbol, ExportedVariableSymbol,
                AliasSymbol, CallbackSymbol]

        module_path = os.path.dirname(__file__)
        searchpath.append (os.path.join(module_path, "templates"))
        self.engine = Engine(
            loader=FileLoader(searchpath, encoding='UTF-8'),
            extensions=[CoreExtension()]
        )

    def _get_extension (self):
        return "html"

    def _format_link (self, link, title):
        out = ''
        template = self.engine.get_template('link.html')
        out += '%s' % template.render ({'link': link,
                                         'link_title': title})
        return out

    def _format_type_tokens (self, type_tokens):
        out = ''
        link_before = False

        for tok in type_tokens:
            if isinstance (tok, Link):
                out += self._format_link (tok.get_link(), tok.title)
                link_before = True
            else:
                if link_before:
                    out += ' '
                out += tok
                link_before = False

        return out

    def _format_linked_symbol (self, symbol):
        out = ""

        if isinstance (symbol, QualifiedSymbol):
            out += self._format_type_tokens (symbol.type_tokens)

        elif hasattr (symbol, "link"):
            out += self._format_link (symbol.link.get_link(), symbol.link.title)

        if type (symbol) == ParameterSymbol:
            out += ' ' + symbol.argname

        if type (symbol) == FieldSymbol and symbol.member_name:
            template = self.engine.get_template('inline_code.html')
            member_name = template.render ({'code': symbol.member_name})
            if symbol.is_function_pointer:
                out = member_name
                out += "()"
            else:
                out += ' ' + member_name

        return out

    def _format_callable_prototype (self, return_value, function_name,
            parameters, is_pointer):
        template = self.engine.get_template('callable_prototype.html')
        param_offset = ' ' * (len (function_name) + 2)
        if is_pointer:
            param_offset += 3 * ' '
        callable_ = Callable (return_value, function_name, parameters)
        return template.render ({'callable': callable_,
                                 'param_offset': param_offset,
                                 'is_pointer': is_pointer,
                                })

    def __format_parameter_detail (self, name, detail):
        template = self.engine.get_template('parameter_detail.html')
        return template.render ({'name': name,
                                 'detail': detail,
                                })

    def _format_callable_summary (self, return_value, function_name,
            is_callable, is_pointer, flags):
        template = self.engine.get_template('callable_summary.html')

        return template.render({'return_value': return_value,
                                'function_name': function_name,
                                'is_callable': is_callable,
                                'is_pointer': is_pointer,
                                'flags': flags
                               })

    def _format_function_summary (self, func):
        return self._format_callable_summary (
                self._format_linked_symbol (func.return_value),
                self._format_linked_symbol (func),
                True,
                False,
                [])

    def _format_callback_summary (self, callback):
        return self._format_callable_summary (
                self._format_linked_symbol (callback.return_value),
                self._format_linked_symbol (callback),
                True,
                True,
                [])

    def _format_function_macro_summary (self, func):
        return self._format_callable_summary (
                "#define ",
                self._format_linked_symbol (func),
                True,
                False,
                [])

    def _format_constant_summary (self, constant):
        template = self.engine.get_template('constant_summary.html')
        constant_link = self._format_linked_symbol (constant)
        return template.render({'constant': constant_link})

    def _format_exported_variable_summary (self, extern):
        template = self.engine.get_template('exported_variable_summary.html')
        extern_link = self._format_linked_symbol (extern)
        return template.render({'extern': extern_link})

    def _format_alias_summary (self, alias):
        template = self.engine.get_template('alias_summary.html')
        alias_link = self._format_linked_symbol (alias)
        return template.render({'alias': alias_link})

    def _format_struct_summary (self, struct):
        template = self.engine.get_template('struct_summary.html')
        struct_link = self._format_linked_symbol (struct)
        return template.render({'struct': struct_link})

    def _format_enum_summary (self, enum):
        template = self.engine.get_template('enum_summary.html')
        enum_link = self._format_linked_symbol (enum)
        return template.render({'enum': enum_link})

    def _format_summary (self, summaries, summary_type):
        if not summaries:
            return None
        template = self.engine.get_template('summary.html')
        return template.render({'summary_type': summary_type,
                                'summaries': summaries
                            })

    def _format_symbols_toc_section (self, symbols_type, symbols_list):
        summary_formatter = self._summary_formatters.get(symbols_type)
        if not summary_formatter:
            return (None, None)

        toc_section_summaries = []
        detailed_descriptions = []
        
        for element in symbols_list.symbols:
            summary = summary_formatter(element)
            if summary:
                toc_section_summaries.append (summary)
            if element.detailed_description:
                detailed_descriptions.append (element.detailed_description)

        if not toc_section_summaries:
            return (None, None)

        summary = self._format_summary (toc_section_summaries,
                symbols_list.name)
        toc_section = TocSection (summary, symbols_list.name)

        symbol_descriptions = None
        if detailed_descriptions:
            symbol_descriptions = SymbolDescriptions (detailed_descriptions,
                    symbols_list.name)

        return (toc_section, symbol_descriptions)

    def _format_struct (self, struct):
        raw_code = self._format_raw_code (struct.raw_text)
        members_list = self._format_members_list (struct.members, 'Fields')

        template = self.engine.get_template ("struct.html")
        out = template.render ({"struct": struct,
                          "raw_code": raw_code,
                          "members_list": members_list})
        return (out, False)

    def _format_enum (self, enum):
        for member in enum.members:
            template = self.engine.get_template ("enum_member.html")
            member.detailed_description = template.render ({
                                    'link': member.link,
                                    'detail': member.formatted_doc,
                                    'value': str (member.enum_value)})

        members_list = self._format_members_list (enum.members, 'Members')
        template = self.engine.get_template ("enum.html")
        out = template.render ({"enum": enum,
                                "members_list": members_list})
        return (out, False)

    def _format_class(self, klass):
        if klass.parsed_page and not klass.symbols:
            klass.formatted_contents = doc_tool.page_parser.render_parsed_page(klass.parsed_page)

        toc_sections = []
        symbols_details = []

        for symbols_type in self._ordering:
            symbols_list = klass.typed_symbols.get(symbols_type)
            if not symbols_list:
                continue

            toc_section, symbols_descriptions = \
                    self._format_symbols_toc_section (symbols_type,
                            symbols_list)

            if toc_section:
                toc_sections.append(toc_section)
            if symbols_descriptions:
                symbols_details.append (symbols_descriptions) 

        hierarchy = None
        if hasattr (klass, 'hierarchy') and klass.hierarchy:
            hierarchy = []
            children = []
            for p in klass.hierarchy:
                hierarchy.append(self._format_linked_symbol (p))
            for c in klass.children.itervalues():
                children.append(self._format_linked_symbol (c))

            template = self.engine.get_template ("hierarchy.html")
            hierarchy = template.render ({'hierarchy': hierarchy,
                                          'children': children,
                                          'klass': klass})

        template = self.engine.get_template('class.html')

        out = template.render ({'klass': klass,
                                'hierarchy': hierarchy,
                                'toc_sections': toc_sections,
                                'stylesheet': self.__stylesheet,
                                'symbols_details': symbols_details})

        return (out, True)

    def _format_prototype (self, function, is_pointer, title):
        return_value = self._format_linked_symbol (function.return_value)
        parameters = []
        for param in function.parameters:
            parameters.append (self._format_linked_symbol(param))

        return self._format_callable_prototype (return_value,
                title, parameters, is_pointer)

    def _format_raw_code (self, code):
        template = self.engine.get_template('raw_code.html')
        return template.render ({'code': code})

    def _format_parameter_symbol (self, parameter):
        return (self.__format_parameter_detail (parameter.argname,
                parameter.formatted_doc), False)

    def _format_field_symbol (self, field):
        field_id = self._format_linked_symbol (field) 
        return (self.__format_parameter_detail (field_id,
            field.formatted_doc), False)

    def _format_return_value_symbol(self, return_value):
        if not return_value or not return_value.formatted_doc:
            return ('', False)
        template = self.engine.get_template('return_value.html')
        return (template.render ({'return_value': return_value}), False)

    def _format_callable(self, callable_, callable_type, title, is_pointer=False, flags=None):
        template = self.engine.get_template('callable.html')

        for p in callable_.parameters:
            p.do_format()

        parameters = [p.detailed_description for p in callable_.parameters if
                p.detailed_description is not None]

        prototype = self._format_prototype (callable_, is_pointer, title)

        return_value_detail = None
        if callable_.return_value:
            callable_.return_value.do_format()
            return_value_detail = callable_.return_value.detailed_description
        out = template.render ({'prototype': prototype,
                                'callable': callable_,
                                'return_value': return_value_detail,
                                'parameters': parameters,
                                'callable_type': callable_type,
                                'flags': flags})

        return (out, False)

    def _format_members_list(self, members, member_designation):
        template = self.engine.get_template('member_list.html')
        return template.render ({'members': members,
            'member_designation': member_designation})

    def _format_function(self, function):
        return self._format_callable (function, "method", function.link.title)

    def _format_callback (self, callback):
        return self._format_callable (callback, "callback",
                callback.link.title, is_pointer=True)

    def _format_function_macro(self, function_macro):
        template = self.engine.get_template('callable.html')
        prototype = self._format_raw_code (function_macro.original_text)

        for p in function_macro.parameters:
            p.do_format()

        parameters = [p.detailed_description for p in function_macro.parameters
                if p.detailed_description is not None]

        return_value_detail = None
        if function_macro.return_value:
            function_macro.return_value.do_format()
            return_value_detail = function_macro.return_value.detailed_description

        out = template.render ({'prototype': prototype,
                                'callable': function_macro,
                                'return_value': return_value_detail,
                                'parameters': parameters,
                                'callable_type': "function macro",
                                'flags': None})

        return (out, False)

    def _format_alias (self, alias):
        template = self.engine.get_template('alias.html')
        aliased_type = self._format_linked_symbol (alias.aliased_type)
        return (template.render ({'alias': alias, 'aliased_type':
                aliased_type}), False)

    def _format_constant(self, constant):
        template = self.engine.get_template('constant.html')
        definition = self._format_raw_code (constant.original_text)
        out = template.render ({'definition': definition,
                                'constant': constant})
        return (out, False)

    def _format_symbol (self, symbol):
        format_function = self._symbol_formatters.get(type(symbol))
        if format_function:
            return format_function (symbol)
        return (None, False)

    def _format_api_index (self, columns, rows):
        template = self.engine.get_template('API_index.html')
        rows.sort (key=lambda row: row[0].title)

        formatted_rows = []
        for row in rows:
            formatted_row = []
            for field in row:
                if isinstance(field, Link):
                    formatted_row.append (self._format_link(field.get_link(),
                        field.title))
                else:
                    formatted_row.append (field)
            formatted_rows.append (formatted_row)

        out = template.render ({'columns': columns,
                                'rows': formatted_rows,
                                'stylesheet': self.__stylesheet})

        return out

    def _format_class_hierarchy (self, dot_graph):
        f = tempfile.NamedTemporaryFile(suffix='.svg', delete=False)
        dot_graph.draw(f, prog='dot', format='svg', args="-Grankdir=LR")
        f.close()
        with open (f.name, 'r') as f:
            contents = f.read()
        os.unlink(f.name)

        template = self.engine.get_template('object_hierarchy.html')
        return template.render ({'graph': contents,
                                 'stylesheet': self.__stylesheet})

    def _get_style_sheet (self):
        return "style.css"

    def _get_extra_files (self):
        dir_ = os.path.dirname(__file__)
        return [os.path.join (dir_, self.__stylesheet),
                os.path.join (dir_, "API_index.js"),
                os.path.join (dir_, "home.png"),]

    def format (self):
        self.__stylesheet = self._get_style_sheet()
        Formatter.format(self)
Example #48
0
		""",
    },
    {
        "title": "These don't solve my problem",
        "body": """
			Please contact me. There are two ways to contact me for help. For both methods, describe your problem in as much detail as possible. The more I know about your issue right off the start, the less questions I have to ask you. Also, please provide information about your phone (model, Android version, etc.).

			<ol>
				<li>
					Open the app and select <i>Email Developer</i>. This will automatically add information about your device and your settings to the email.
				</li>
				<li>
					<a href="/contact">Fill out this form</a>.
				</li>
			</ol>
		""",
    },
]

from wheezy.template.engine import Engine
from wheezy.template.ext.core import CoreExtension
from wheezy.template.loader import FileLoader

searchpath = ["."]
engine = Engine(loader=FileLoader(searchpath), extensions=[CoreExtension()])
template = engine.get_template("template.html")

f = open("smsfix.html", "w")
f.write(template.render({"pagetitle": "SMS Time Fix Help", "topics": topics}))
f.close()
Example #49
0
			${PAYPAL}
		''',
	},
	{
		'title': "I have a feature request",
		'body': '''
			<a href="/contact">Contact me</a>
		''',
	},
	{
		'title': "These don't solve my problem",
		'body': '''
			<a href="/contact">Contact me</a>. Please describe your problem in as much detail as possible. The more I know about your issue right off the start, the less questions I have to ask you. Also, please provide information about your phone (model, Android version, etc.).
		''',
	},
]

from wheezy.template.engine import Engine
from wheezy.template.ext.core import CoreExtension
from wheezy.template.loader import FileLoader

searchpath = ['.']
engine = Engine(
    loader=FileLoader(searchpath),
    extensions=[CoreExtension()]
)
template = engine.get_template('template.html')

f = open('prioritysms.html', 'w')
f.write(template.render({'pagetitle': 'Priority SMS Help', 'topics': topics}))
f.close()
people = [Person(p.handle, p.name) for p in config.people]
problems = [Problem(config.week.contest_id, p.letter, p.name) for p in config.week.problems]

contest_ids = set(p.contest_id for p in problems)
assert len(contest_ids) == 1
contest_id = int(contest_ids.pop())

solves = dict()
for person in people:
    response = api.get_user_contest_submissions(person.handle, contest_id)
    solves[person] = set(s.problem.index for s in response if s.problem.contestId == contest_id and s.verdict == "OK")

people = sorted(people, key=lambda p: len(solves[p]), reverse=True)

template_input_path = config.template.input_path
engine = Engine(loader=FileLoader([template_input_path]), extensions=[CoreExtension()])

index_template = engine.get_template(config.template.index_local_path)
model = {"announcement": announcement, "people": people, "problems": problems, "solves": solves, "title": title}
index_html = index_template.render(model)

with open(os.path.join(config.template.output_path, "index.html"), "r") as f:
    existing_index_html = f.read()

updated_file = calculate_sha1(index_html) != calculate_sha1(existing_index_html)

if updated_file:
    with open(os.path.join(config.template.output_path, "index.html"), "w") as f:
        f.write(index_html)

    with open(os.path.join(config.template.output_path, "last_modified.json"), "w") as f:
Example #51
0
# region: wheezy.template

try:
    from wheezy.template.engine import Engine
    from wheezy.template.loader import DictLoader
    from wheezy.template.ext.core import CoreExtension
except ImportError:
    test_wheezy_template = None
else:
    engine = Engine(loader=DictLoader({'x': s("""\
@require(table)
<table>
    @for row in table:
    <tr>
        @for key, value in row.items():
        <td>@key!h</td><td>@value!s</td>
        @end
    </tr>
    @end
</table>
""")}), extensions=[CoreExtension()])
    engine.global_vars.update({'h': escape})
    wheezy_template = engine.get_template('x')

    def test_wheezy_template():
        return wheezy_template.render(ctx)


# region: Jinja2

try:
    call(['org-export','html','--infile',n['f'],'--outfile',n['export_to'],'--bootstrap' ])

# update again, see if everything exported
file_df = export_info(file_df)
need_update = file_df.query('export_date != export_date or export_date < mt')
if len(need_update) != 0:
    print("some files failed to update: %s!"%(",".join(need_update['title'])))

# export_to is relative to this script. should be relative to index.html
# remove '../'
file_df['uri'] = [ re.sub('^\.\./','',x) for x in file_df['export_to'] ]
# index template
from wheezy.template.engine import Engine
from wheezy.template.ext.core import CoreExtension
from wheezy.template.loader import FileLoader
engine = Engine(loader=FileLoader(['../src/']), extensions=[CoreExtension()])
template = engine.get_template('index.tmp')
# write it out
index_str = template.render({'file_df': file_df,'title': 'WF log'})
with open('../index.html','w') as indexf:
    indexf.write(index_str)


# ## Gopher
def html_to_goph(x):
    x = re.sub('(org|html)$', 'txt', x)
    x = re.sub('html/', '/gopher/', x)
    return(x)


for i, n in need_update.iterrows():
Example #53
0
class HtmlFormatter(Formatter):
    """
    Banana banana
    """

    theme_path = None
    add_anchors = False
    number_headings = False

    def __init__(self, searchpath):
        Formatter.__init__(self)

        self._symbol_formatters = {
            FunctionSymbol: self._format_function,
            FunctionMacroSymbol: self._format_function_macro,
            CallbackSymbol: self._format_callback,
            ConstantSymbol: self._format_constant,
            ExportedVariableSymbol: self._format_constant,
            AliasSymbol: self._format_alias,
            StructSymbol: self._format_struct,
            EnumSymbol: self._format_enum,
            ParameterSymbol: self._format_parameter_symbol,
            ReturnItemSymbol: self._format_return_item_symbol,
            FieldSymbol: self._format_field_symbol,
            SignalSymbol: self._format_signal_symbol,
            VFunctionSymbol: self._format_vfunction_symbol,
            PropertySymbol: self._format_property_symbol,
            ClassSymbol: self._format_class_symbol,
            InterfaceSymbol: self._format_interface_symbol,
        }

        self._ordering = [InterfaceSymbol, ClassSymbol, FunctionSymbol,
                          FunctionMacroSymbol, SignalSymbol,
                          PropertySymbol, StructSymbol,
                          VFunctionSymbol, EnumSymbol, ConstantSymbol,
                          ExportedVariableSymbol, AliasSymbol, CallbackSymbol]

        if HtmlFormatter.theme_path:
            theme_templates_path = os.path.join(
                HtmlFormatter.theme_path, 'templates')

            if os.path.exists(theme_templates_path):
                searchpath.insert(0, theme_templates_path)

        searchpath.append(os.path.join(HERE, "html_templates"))
        self.engine = Engine(
            loader=FileLoader(searchpath, encoding='UTF-8'),
            extensions=[CoreExtension(), CodeExtension()]
        )

        self.all_scripts = set()
        self.all_stylesheets = set()
        self._docstring_formatter = GtkDocStringFormatter()

    # pylint: disable=no-self-use
    def __init_section_numbers(self, root):
        if not HtmlFormatter.number_headings:
            return {}

        targets = []

        ctr = 0
        while len(targets) <= 1:
            ctr += 1
            if ctr > 5:
                return {}

            targets = root.xpath('.//*[self::h%s]' % ctr)

        section_numbers = {}
        for i in range(ctr, 6):
            section_numbers['h%d' % i] = 0

        section_numbers['first'] = ctr

        return section_numbers

    # pylint: disable=no-self-use
    def __update_section_number(self, target, section_numbers):
        if target.tag not in section_numbers:
            return None

        prev = section_numbers.get('prev')
        cur = int(target.tag[1])

        if cur < prev:
            for i in range(cur + 1, 6):
                section_numbers['h%d' % i] = 0

        section_numbers[target.tag] += 1
        section_numbers['prev'] = cur

        section_number = u''
        for i in range(section_numbers['first'], cur + 1):
            if section_number:
                section_number += '.'
            section_number += unicode(section_numbers['h%d' % i])

        return section_number

    # pylint: disable=too-many-locals
    def write_page(self, page, output):
        root = etree.HTML(unicode(page.detailed_description))
        id_nodes = {n.attrib['id']: "".join([x for x in n.itertext()])
                    for n in root.xpath('.//*[@id]')}

        section_numbers = self.__init_section_numbers(root)

        targets = root.xpath(
            './/*[self::h1 or self::h2 or self::h3 or '
            'self::h4 or self::h5 or self::img]')

        for target in targets:
            section_number = self.__update_section_number(
                target, section_numbers)

            if 'id' in target.attrib:
                continue

            if target.tag == 'img':
                text = target.attrib.get('alt')
            else:
                text = "".join([x for x in target.itertext()])

            if not text:
                continue

            id_ = id_from_text(text)
            ref_id = id_
            index = 1

            while id_ in id_nodes:
                id_ = '%s%s' % (ref_id, index)
                index += 1

            if section_number:
                target.text = '%s %s' % (section_number, target.text or '')

            target.attrib['id'] = id_
            id_nodes[id_] = text

        empty_links = root.xpath('.//a[not(text()) and not(*)]')
        for link in empty_links:
            href = link.attrib.get('href')
            if href and href.startswith('#'):
                title = id_nodes.get(href.strip('#'))
                if title:
                    link.text = title
                else:
                    warn('bad-local-link',
                         "Empty anchor link to %s in %s points nowhere" %
                         (href, page.source_file))
                    link.text = "FIXME broken link to %s" % href

        page.detailed_description = lxml.html.tostring(
            root, doctype="<!DOCTYPE html>", encoding='unicode',
            include_meta_content_type=True)
        return Formatter.write_page(self, page, output)

    # pylint: disable=no-self-use
    def _get_extension(self):
        return "html"

    def get_output_folder(self):
        return os.path.join(super(HtmlFormatter, self).get_output_folder(),
                            'html')

    def _format_link(self, link, title):
        out = ''
        if not link:
            assert link
            print "Issue here plz check", title
            return title

        template = self.engine.get_template('link.html')
        out += '%s' % template.render({'link': link,
                                       'link_title': title})
        return out

    def _format_type_tokens(self, type_tokens):
        out = ''
        link_before = False

        for tok in type_tokens:
            if isinstance(tok, Link):
                ref = tok.get_link()
                if ref:
                    out += self._format_link(ref, tok.title)
                    link_before = True
                else:
                    if link_before:
                        out += ' '
                    out += tok.title
                    link_before = False
            else:
                if link_before:
                    out += ' '
                out += tok
                link_before = False

        return out

    # pylint: disable=unidiomatic-typecheck
    def _format_linked_symbol(self, symbol):
        out = ""

        if isinstance(symbol, QualifiedSymbol):
            out += self._format_type_tokens(symbol.type_tokens)

        # FIXME : ugly
        elif hasattr(symbol, "link") and type(symbol) != FieldSymbol:
            out += self._format_link(symbol.link.get_link(), symbol.link.title)

        if type(symbol) == ParameterSymbol:
            out += ' ' + symbol.argname

        elif type(symbol) == FieldSymbol and symbol.member_name:
            out += self._format_type_tokens(symbol.qtype.type_tokens)
            template = self.engine.get_template('inline_code.html')
            member_name = template.render({'code': symbol.member_name})
            if symbol.is_function_pointer:
                out = member_name
                out += "()"
            else:
                out += ' ' + member_name

        return out

    def _format_callable_prototype(self, return_value, function_name,
                                   parameters, is_pointer):
        template = self.engine.get_template('callable_prototype.html')

        return template.render({'return_value': return_value,
                                'name': function_name,
                                'parameters': parameters,
                                'is_pointer': is_pointer})

    def __format_parameter_detail(self, name, detail, extra=None):
        extra = extra or {}
        template = self.engine.get_template('parameter_detail.html')
        return template.render({'name': name,
                                'detail': detail,
                                'extra': extra})

    def _format_symbol_descriptions(self, symbols_list):
        detailed_descriptions = []

        for element in symbols_list.symbols:
            if element.skip:
                continue
            if element.detailed_description:
                detailed_descriptions.append(element.detailed_description)

        symbol_type = symbols_list.name

        symbol_descriptions = None
        if detailed_descriptions:
            symbol_descriptions = SymbolDescriptions(detailed_descriptions,
                                                     symbol_type)

        return symbol_descriptions

    def _format_struct(self, struct):
        raw_code = None
        if struct.raw_text is not None:
            raw_code = self._format_raw_code(struct.raw_text)

        members_list = self._format_members_list(struct.members, 'Fields')

        template = self.engine.get_template("struct.html")
        out = template.render({"symbol": struct,
                               "struct": struct,
                               "raw_code": raw_code,
                               "members_list": members_list})
        return (out, False)

    def _format_enum(self, enum):
        for member in enum.members:
            template = self.engine.get_template("enum_member.html")
            member.detailed_description = template.render({
                'link': member.link,
                'detail': member.formatted_doc,
                'value': str(member.enum_value)})

        raw_code = None
        if enum.raw_text is not None:
            raw_code = self._format_raw_code(enum.raw_text)

        members_list = self._format_members_list(enum.members, 'Members')
        template = self.engine.get_template("enum.html")
        out = template.render({"symbol": enum,
                               "enum": enum,
                               "raw_code": raw_code,
                               "members_list": members_list})
        return (out, False)

    def prepare_page_attributes(self, page):
        """
        Banana banana
        """
        page.output_attrs['html']['scripts'] = OrderedSet()
        page.output_attrs['html']['stylesheets'] = OrderedSet()
        page.output_attrs['html']['extra_html'] = []
        page.output_attrs['html']['extra_footer_html'] = []
        if HtmlFormatter.add_anchors:
            page.output_attrs['html']['scripts'].add(
                os.path.join(HERE, 'html_assets', 'css.escape.js'))
        Formatter.prepare_page_attributes(self, page)

    def patch_page(self, page, symbol):
        raise NotImplementedError

    # pylint: disable=too-many-locals
    def _format_page(self, page):
        symbols_details = []

        for symbols_type in self._ordering:
            symbols_list = page.typed_symbols.get(symbols_type)
            if not symbols_list:
                continue

            symbols_descriptions = self._format_symbol_descriptions(
                symbols_list)

            if symbols_descriptions:
                symbols_details.append(symbols_descriptions)

        template = self.engine.get_template('page.html')

        scripts = page.output_attrs['html']['scripts']
        stylesheets = page.output_attrs['html']['stylesheets']
        scripts_basenames = [os.path.basename(script)
                             for script in scripts]
        stylesheets_basenames = [os.path.basename(stylesheet)
                                 for stylesheet in stylesheets]

        self.all_stylesheets.update(stylesheets)
        self.all_scripts.update(scripts)

        out = template.render(
            {'page': page,
             'source_file': os.path.basename(page.source_file),
             'scripts': scripts_basenames,
             'stylesheets': stylesheets_basenames,
             'assets_path': self._get_assets_path(),
             'extra_html': page.output_attrs['html']['extra_html'],
             'extra_footer_html':
             page.output_attrs['html']['extra_footer_html'],
             'symbols_details': symbols_details})

        return (out, True)

    def _format_prototype(self, function, is_pointer, title):
        if function.return_value:
            return_value = self._format_linked_symbol(function.return_value[0])
        else:
            return_value = None

        parameters = []
        for param in function.parameters:
            parameters.append(self._format_linked_symbol(param))

        return self._format_callable_prototype(return_value,
                                               title, parameters, is_pointer)

    def _format_raw_code(self, code):
        code = cgi.escape(code)
        template = self.engine.get_template('raw_code.html')
        return template.render({'code': code})

    def _format_parameter_symbol(self, parameter):
        return (self.__format_parameter_detail(
            parameter.argname,
            parameter.formatted_doc,
            extra=parameter.extension_contents),
                False)

    def _format_field_symbol(self, field):
        field_id = self._format_linked_symbol(field)
        template = self.engine.get_template('field_detail.html')
        return (template.render({'symbol': field,
                                 'name': field_id,
                                 'detail': field.formatted_doc}), False)

    def _format_return_item_symbol(self, return_item):
        template = self.engine.get_template('return_item.html')
        return_item.formatted_link = self._format_linked_symbol(return_item)
        return (template.render({'return_item': return_item}), False)

    def _format_return_value_symbol(self, return_value):
        template = self.engine.get_template('multi_return_value.html')
        if return_value[0] is None:
            return_value = return_value[1:]
        return template.render({'return_items': return_value})

    def _format_callable(self, callable_, callable_type, title,
                         is_pointer=False):
        template = self.engine.get_template('callable.html')

        parameters = [p.detailed_description for p in callable_.parameters if
                      p.detailed_description is not None]

        prototype = self._format_prototype(callable_, is_pointer, title)

        return_value_detail = self._format_return_value_symbol(
            callable_.return_value)

        tags = {}
        if callable_.comment:
            tags = dict(callable_.comment.tags)

        tags.pop('returns', None)
        tags.pop('topic', None)

        out = template.render({'prototype': prototype,
                               'symbol': callable_,
                               'return_value': return_value_detail,
                               'parameters': parameters,
                               'callable_type': callable_type,
                               'tags': tags,
                               'extra': callable_.extension_contents})

        return (out, False)

    def _format_signal_symbol(self, signal):
        title = "%s_callback" % re.sub('-', '_', signal.link.title)
        return self._format_callable(signal, "signal", title)

    def _format_vfunction_symbol(self, vmethod):
        return self._format_callable(vmethod, "virtual method",
                                     vmethod.link.title)

    def _format_property_symbol(self, prop):
        type_link = self._format_linked_symbol(prop.prop_type)
        template = self.engine.get_template('property_prototype.html')
        prototype = template.render({'property_name': prop.link.title,
                                     'property_type': type_link})
        template = self.engine.get_template('property.html')
        res = template.render({'symbol': prop,
                               'prototype': prototype,
                               'property': prop,
                               'extra': prop.extension_contents})
        return (res, False)

    def _format_hierarchy(self, klass):
        hierarchy = []
        children = []
        for _ in klass.hierarchy:
            hierarchy.append(self._format_linked_symbol(_))
        for _ in klass.children.itervalues():
            children.append(self._format_linked_symbol(_))

        if hierarchy or children:
            template = self.engine.get_template("hierarchy.html")
            hierarchy = template.render({'hierarchy': hierarchy,
                                         'children': children,
                                         'klass': klass})
        return hierarchy

    def _format_class_symbol(self, klass):
        hierarchy = self._format_hierarchy(klass)
        template = self.engine.get_template('class.html')
        return (template.render({'symbol': klass,
                                 'klass': klass,
                                 'hierarchy': hierarchy}),
                False)

    def _format_interface_symbol(self, interface):
        hierarchy = self._format_hierarchy(interface)
        template = self.engine.get_template('interface.html')
        return (template.render({'symbol': interface,
                                 'hierarchy': hierarchy}),
                False)

    def _format_members_list(self, members, member_designation):
        template = self.engine.get_template('member_list.html')
        return template.render({'members': members,
                                'member_designation': member_designation})

    def _format_function(self, function):
        return self._format_callable(function, "method", function.link.title)

    def _format_callback(self, callback):
        return self._format_callable(callback, "callback",
                                     callback.link.title, is_pointer=True)

    def _format_function_macro(self, function_macro):
        template = self.engine.get_template('callable.html')
        prototype = self._format_raw_code(function_macro.original_text)

        parameters = []
        for _ in function_macro.parameters:
            if not _.detailed_description:
                continue
            parameters.append(_.detailed_description)

        return_value_detail = self._format_return_value_symbol(
            function_macro.return_value)

        out = template.render({'prototype': prototype,
                               'symbol': function_macro,
                               'return_value': return_value_detail,
                               'parameters': parameters,
                               'callable_type': "function macro",
                               'flags': None,
                               'tags': {},
                               'extra': function_macro.extension_contents})

        return (out, False)

    def _format_alias(self, alias):
        template = self.engine.get_template('alias.html')
        aliased_type = self._format_linked_symbol(alias.aliased_type)
        return (template.render({'symbol': alias,
                                 'alias': alias,
                                 'aliased_type': aliased_type}), False)

    def _format_constant(self, constant):
        template = self.engine.get_template('constant.html')
        definition = self._format_raw_code(constant.original_text)
        out = template.render({'symbol': constant,
                               'definition': definition,
                               'constant': constant})
        return (out, False)

    def _format_symbol(self, symbol):
        format_function = self._symbol_formatters.get(type(symbol))
        if format_function:
            return format_function(symbol)
        return (None, False)

    def _format_object_hierarchy_symbol(self, symbol):
        dot_graph = _create_hierarchy_graph(symbol.hierarchy)
        tmp_file = tempfile.NamedTemporaryFile(suffix='.svg', delete=False)
        dot_graph.draw(tmp_file, prog='dot', format='svg', args="-Grankdir=LR")
        tmp_file.close()
        with open(tmp_file.name, 'r') as _:
            contents = _.read()
        os.unlink(_.name)

        pagename = 'object_hierarchy.html'
        template = self.engine.get_template(pagename)
        res = template.render({'graph': contents,
                               'assets_path': self._get_assets_path()})
        return (res, False)

    def _get_extra_files(self):
        res = []

        if HtmlFormatter.theme_path:
            theme_files = os.listdir(HtmlFormatter.theme_path)
            for file_ in theme_files:
                if file_ == 'templates':
                    pass
                src = os.path.join(HtmlFormatter.theme_path, file_)
                dest = os.path.basename(src)
                res.append((src, dest))

        for script_path in self.all_scripts:
            dest = os.path.join('js', os.path.basename(script_path))
            res.append((script_path, dest))

        for stylesheet_path in self.all_stylesheets:
            dest = os.path.join('css', os.path.basename(stylesheet_path))
            res.append((stylesheet_path, dest))

        return res

    @staticmethod
    def add_arguments(parser):
        """Banana banana
        """
        group = parser.add_argument_group(
            'Html formatter', 'html formatter options')
        group.add_argument("--html-theme", action="store",
                           dest="html_theme", help="html theme to use",
                           default='default')
        group.add_argument("--html-add-anchors", action="store_true",
                           dest="html_add_anchors",
                           help="Add anchors to html headers",
                           default='default')
        group.add_argument("--html-number-headings", action="store_true",
                           dest="html_number_headings",
                           help="Enable html headings numbering")

    @staticmethod
    def parse_config(doc_repo, config):
        """Banana banana
        """
        html_theme = config.get('html_theme', 'default')
        if html_theme == 'default':
            default_theme = os.path.join(HERE, '..',
                                         'default_theme-%s' % THEME_VERSION)
            html_theme = os.path.abspath(default_theme)
            info("Using default theme")
        else:
            html_theme = config.get_path('html_theme')
            info("Using theme located at %s" % html_theme)

        HtmlFormatter.theme_path = html_theme

        HtmlFormatter.add_anchors = bool(config.get("html_add_anchors"))
        HtmlFormatter.number_headings = bool(
            config.get("html_number_headings"))
Example #54
0
class MainWindow(QMainWindow):

    workspace_updated = pyqtSignal()

    def __init__(self):
        super(MainWindow, self).__init__()

        #self.app = app
        self.apps = []
        self.apps_dict = {}

        # Initiate logging
        self.logView = QTreeWidget()
        self.logView.setColumnCount(2)
        self.logView.expandAll()
        self.logView.itemClicked.connect(self.onLogItemClicked)
        self.logView.itemDoubleClicked.connect(self.onLogItemDoubleClicked)

        self.logView.setHeaderLabels(['ID', 'Message'])
        self.logView.setUniformRowHeights(True)
        self.logView.hideColumn(0)

        logHandler = Logger(self, self.logView)
        logging.getLogger().addHandler(logHandler)
        #sys.stdout = Logger( self.logView, sys.__stdout__)
        #sys.stderr = Logger( self.logView, sys.__stderr__, QColor(255,0,0) )
        logging.info('Welcome to Pathomx v%s' % (VERSION_STRING))

        # Central variable for storing application configuration (load/save from file?
        self.config = QSettings()
        if self.config.value('/Pathomx/Is_setup', False) != True:
            logging.info("Setting up initial configuration...")
            self.onResetConfig()
            logging.info('Done')

        # Do version upgrade availability check
        # FIXME: Do check here; if not done > 2 weeks
        if StrictVersion(self.config.value('/Pathomx/Latest_version', '0.0.0')) > StrictVersion(VERSION_STRING):
            # We've got an upgrade
            logging.warning('A new version (v%s) is available' % self.config.value('/Pathomx/Update/Latest_version', '0.0.0'))

        # Create database accessor
        self.db = db.databaseManager()
        self.data = None  # deprecated
        self.datasets = []  # List of instances of data.datasets() // No data loaded by default

        self.experiment = dict()
        self.layout = None  # No map by default

        #self.linestyles = styles.LineStyleHandler()

        # The following holds tabs & pathway objects for gpml imported pathways
        self.gpmlpathways = []
        self.tab_handlers = []
        self.url_handlers = defaultdict(list)
        self.app_launchers = {}
        self.app_launcher_categories = defaultdict(list)
        self.file_handlers = {}

        # Create templating engine
        self.templateEngine = Engine(
            loader=FileLoader([os.path.join(utils.scriptdir, 'html')]),
            extensions=[CoreExtension(), CodeExtension()]
        )
        self.templateEngine.global_vars.update({'tr': tr})

        self.update_view_callback_enabled = True

        self.printer = QPrinter()

        QNetworkProxyFactory.setUseSystemConfiguration(True)

        #  UI setup etc
        self.menuBars = {
            'file': self.menuBar().addMenu(tr('&File')),
            'plugins': self.menuBar().addMenu(tr('&Plugins')),
            'appearance': self.menuBar().addMenu(tr('&Appearance')),
            'resources': self.menuBar().addMenu(tr('&Resources')),
            'database': self.menuBar().addMenu(tr('&Database')),
            'help': self.menuBar().addMenu(tr('&Help')),
        }

        # FILE MENU
        aboutAction = QAction(QIcon.fromTheme("help-about"), 'About', self)
        aboutAction.setStatusTip(tr('About Pathomx'))
        aboutAction.triggered.connect(self.onAbout)
        self.menuBars['file'].addAction(aboutAction)

        newAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'document.png')), tr('&New Blank Workspace'), self)
        newAction.setShortcut('Ctrl+N')
        newAction.setStatusTip(tr('Create new blank workspace'))
        newAction.triggered.connect(self.onClearWorkspace)
        self.menuBars['file'].addAction(newAction)

        openAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'folder-open-document.png')), tr('&Open…'), self)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip(tr('Open previous analysis workspace'))
        openAction.triggered.connect(self.onOpenWorkspace)
        #self.menuBars['file'].addAction(openAction)

        openAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'folder-open-document.png')), tr('&Open Workflow…'), self)
        openAction.setStatusTip(tr('Open an analysis workflow'))
        openAction.triggered.connect(self.onOpenWorkflow)
        self.menuBars['file'].addAction(openAction)

        self.menuBars['file'].addSeparator()

        saveAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'disk.png')), tr('&Save'), self)
        saveAction.setShortcut('Ctrl+S')
        saveAction.setStatusTip(tr('Save current workspace for future use'))
        saveAction.triggered.connect(self.onSaveWorkspace)
        #self.menuBars['file'].addAction(saveAction)

        saveAsAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'disk--pencil.png')), tr('Save &As…'), self)
        saveAsAction.setShortcut('Ctrl+A')
        saveAsAction.setStatusTip(tr('Save current workspace for future use'))
        saveAsAction.triggered.connect(self.onSaveWorkspaceAs)
        #self.menuBars['file'].addAction(saveAsAction)

        saveAsAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'disk--pencil.png')), tr('Save Workflow As…'), self)
        saveAsAction.setStatusTip(tr('Save current workflow for future use'))
        saveAsAction.triggered.connect(self.onSaveWorkflowAs)
        self.menuBars['file'].addAction(saveAsAction)

        self.menuBars['file'].addSeparator()

        #printAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'printer.png')), tr('&Print…'), self)
        #printAction.setShortcut('Ctrl+P')
        #printAction.setStatusTip(tr('Print current figure'))
        #printAction.triggered.connect(self.onPrint)
        #self.menuBars['file'].addAction(printAction)

        self.menuBars['file'].addSeparator()

        # DATABASE MENU
        explore_dbAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'database-explore.png')), tr('&Explore database…'), self)
        explore_dbAction.setStatusTip('Explore database')
        explore_dbAction.triggered.connect(self.onDBExplore)
        self.menuBars['database'].addAction(explore_dbAction)

        load_identitiesAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'database-import.png')), tr('&Load database unification…'), self)
        load_identitiesAction.setStatusTip('Load additional unification mappings into database')
        load_identitiesAction.triggered.connect(self.onLoadIdentities)
        self.menuBars['database'].addAction(load_identitiesAction)

        self.menuBars['database'].addSeparator()

        reload_databaseAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'exclamation-red.png')), tr('&Reload database'), self)
        reload_databaseAction.setStatusTip('Reload pathway & metabolite database')
        reload_databaseAction.triggered.connect(self.onReloadDB)
        self.menuBars['database'].addAction(reload_databaseAction)
        # PLUGINS MENU

        change_pluginsAction = QAction(tr('&Manage plugins…'), self)
        change_pluginsAction.setStatusTip('Find, activate, deactivate and remove plugins')
        change_pluginsAction.triggered.connect(self.onChangePlugins)
        self.menuBars['plugins'].addAction(change_pluginsAction)

        check_pluginupdatesAction = QAction(tr('&Check for updated plugins'), self)
        check_pluginupdatesAction.setStatusTip('Check for updates to installed plugins')
        check_pluginupdatesAction.triggered.connect(self.onCheckPluginUpdates)
        #self.menuBars['plugins'].addAction(check_pluginupdatesAction)  FIXME: Add a plugin-update check

        linemarkerstyleAction = QAction('Line and marker styles…', self)
        linemarkerstyleAction.setStatusTip(tr('Set line and marker styles for data classes'))
        linemarkerstyleAction.triggered.connect(self.onLineMarkerStyles)
        self.menuBars['appearance'].addAction(linemarkerstyleAction)
        

        matlabpathAction = QAction('Edit MATLAB path…', self)
        matlabpathAction.setStatusTip(tr('Set MATLAB path'))
        matlabpathAction.triggered.connect(self.onMATLABPathEdit)
        self.menuBars['resources'].addAction(matlabpathAction)

        

        aboutAction = QAction(QIcon.fromTheme("help-about"), 'Introduction', self)
        aboutAction.setStatusTip(tr('About Pathomx'))
        aboutAction.triggered.connect(self.onAbout)
        self.menuBars['help'].addAction(aboutAction)

        self.menuBars['help'].addSeparator()

        goto_pathomx_websiteAction = QAction(tr('&Pathomx homepage'), self)
        goto_pathomx_websiteAction.setStatusTip('Go to the Pathomx website')
        goto_pathomx_websiteAction.triggered.connect(self.onGoToPathomxWeb)
        self.menuBars['help'].addAction(goto_pathomx_websiteAction)

        goto_pathomx_docsAction = QAction(tr('&Pathomx documentation'), self)
        goto_pathomx_docsAction.setStatusTip('Read latest Pathomx documentation')
        goto_pathomx_docsAction.triggered.connect(self.onGoToPathomxDocs)
        self.menuBars['help'].addAction(goto_pathomx_docsAction)

        goto_pathomx_demosAction = QAction(tr('&Pathomx demos'), self)
        goto_pathomx_demosAction.setStatusTip('Watch Pathomx demo videos')
        goto_pathomx_demosAction.triggered.connect(self.onGoToPathomxDemos)
        self.menuBars['help'].addAction(goto_pathomx_demosAction)

        self.menuBars['help'].addSeparator()

        do_registerAction = QAction(tr('&Register Pathomx'), self)
        do_registerAction.setStatusTip('Register Pathomx for release updates')
        do_registerAction.triggered.connect(self.onDoRegister)
        self.menuBars['help'].addAction(do_registerAction)

        # GLOBAL WEB SETTINGS
        QNetworkProxyFactory.setUseSystemConfiguration(True)

        QWebSettings.setMaximumPagesInCache(0)
        QWebSettings.setObjectCacheCapacities(0, 0, 0)
        QWebSettings.clearMemoryCaches()

        resources.matlab.set_exec_path( self.config.value('/Resources/MATLAB_path', 'matlab') )

        self.resources = {
            'MATLAB': resources.matlab,
            'R': resources.r,
        }

        self.plugins = {}  # Dict of plugin shortnames to data
        self.plugins_obj = {}  # Dict of plugin name references to objs (for load/save)
        self.pluginManager = PluginManagerSingleton.get()
        self.pluginManager.m = self

        self.plugin_places = []
        self.core_plugin_path = os.path.join(utils.scriptdir, 'plugins')
        self.plugin_places.append(self.core_plugin_path)

        user_application_data_paths = QStandardPaths.standardLocations(QStandardPaths.DataLocation)
        if user_application_data_paths:
            self.user_plugin_path = os.path.join(user_application_data_paths[0], 'plugins')
            utils.mkdir_p(self.user_plugin_path)
            self.plugin_places.append(self.user_plugin_path)

            self.application_data_path = os.path.join(user_application_data_paths[1])

        logging.info("Searching for plugins...")
        for place in self.plugin_places:
            logging.info(place)

        self.tools = defaultdict(list)
        
        self.pluginManager.setPluginPlaces(self.plugin_places)
        self.pluginManager.setPluginInfoExtension('pathomx-plugin')
        categories_filter = {
               "Import": plugins.ImportPlugin,
               "Processing": plugins.ProcessingPlugin,
               "Identification": plugins.IdentificationPlugin,
               "Analysis": plugins.AnalysisPlugin,
               "Visualisation": plugins.VisualisationPlugin,
               "Export": plugins.ExportPlugin,
               "Scripting": plugins.ScriptingPlugin,
               }
        self.pluginManager.setCategoriesFilter(categories_filter)
        self.pluginManager.collectPlugins()

        plugin_categories = ["Import", "Processing", "Identification", "Analysis", "Visualisation", "Export", "Scripting"]  # categories_filter.keys()
        apps = defaultdict(list)
        self.appBrowsers = {}
        self.plugin_names = dict()
        self.plugin_metadata = dict()


        # Loop round the plugins and print their names.
        for category in plugin_categories:
            for plugin in self.pluginManager.getPluginsOfCategory(category):

                plugin_image = os.path.join(os.path.dirname(plugin.path), 'icon.png')

                if not os.path.isfile(plugin_image):
                    plugin_image = None
                
                try:
                    resource_list = plugin.details.get('Documentation','Resources').split(',')
                except:
                    resource_list = []
                
                metadata = {
                    'id': plugin.plugin_object.__class__.__name__,  # __module__,
                    'image': plugin_image,
                    'image_forward_slashes': plugin_image.replace('\\', '/'),  # Slashes fix for CSS in windows
                    'name': plugin.name,
                    'version': plugin.version,
                    'description': plugin.description,
                    'author': plugin.author,
                    'resources': resource_list,
                    'info': plugin,
                    'path': os.path.dirname(plugin.path),
                    'module': os.path.basename(plugin.path),
                    'shortname': os.path.basename(plugin.path),
                    'is_core_plugin': plugin.path.startswith(self.core_plugin_path)
                }

                self.plugins[metadata['shortname']] = metadata
                self.plugin_names[id(plugin.plugin_object)] = plugin.name

                plugin.plugin_object.post_setup(path=os.path.dirname(plugin.path), name=plugin.name, metadata=metadata)

                apps[category].append(metadata)

        self.stack = QStackedWidget()

        self.threadpool = QThreadPool()
        logging.info("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())

        self.setCentralWidget(self.stack)
        self.stack.setCurrentIndex(0)

        self.workspace_count = 0  # Auto-increment
        self.workspace_parents = {}
        self.workspace_index = {}  # id -> obj

        self.workspace = QTreeWidget()
        self.workspace.setColumnCount(4)
        self.workspace.expandAll()

        self.workspace.setHeaderLabels(['', 'ID', ' ◎', ' ⚑'])  # ,'#'])
        self.workspace.setUniformRowHeights(True)
        self.workspace.hideColumn(1)

        self.editor = WorkspaceEditor(self)
        self.setCentralWidget(self.editor)

        app_category_icons = {
               "Import": QIcon(os.path.join(utils.scriptdir, 'icons', 'disk--arrow.png')),
               "Processing": QIcon(os.path.join(utils.scriptdir, 'icons', 'ruler-triangle.png')),
               "Identification": QIcon(os.path.join(utils.scriptdir, 'icons', 'target.png')),
               "Analysis": QIcon(os.path.join(utils.scriptdir, 'icons', 'calculator.png')),
               "Visualisation": QIcon(os.path.join(utils.scriptdir, 'icons', 'star.png')),
               "Export": QIcon(os.path.join(utils.scriptdir, 'icons', 'disk--pencil.png')),
               "Scripting": QIcon(os.path.join(utils.scriptdir, 'icons', 'script-text.png')),
               }

        template = self.templateEngine.get_template('apps.html')
        for category in plugin_categories:
            self.addWorkspaceItem(None, None, category, app_category_icons[category])

        self.workspace.setSelectionMode(QAbstractItemView.SingleSelection)
        self.workspace.currentItemChanged.connect(self.onWorkspaceStackChange)

        self.toolbox = QToolBox(self)
        for category in plugin_categories:
            panel = ToolPanel(self, tools=self.tools[category])
            self.toolbox.addItem(panel, app_category_icons[category], category)

        self.toolDock = QDockWidget(tr('Toolkit'))
        self.toolDock.setWidget(self.toolbox)

        self.workspaceDock = QDockWidget(tr('Workspace'))
        self.workspaceDock.setWidget(self.workspace)
        self.workspace.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.workspace.setColumnWidth(0, 298 - 25 * 2)
        self.workspace.setColumnWidth(2, 24)
        self.workspace.setColumnWidth(3, 24)
        self.workspaceDock.setMinimumWidth(300)
        self.workspaceDock.setMaximumWidth(300)

        self.dataView = QTreeView(self)
        self.dataModel = data.DataTreeModel(self.datasets)
        self.dataView.setModel(self.dataModel)

        self.dataView.hideColumn(0)

        self.dataDock = QDockWidget(tr('Data'))
        self.dataDock.setWidget(self.dataView)
        self.dataDock.setMinimumWidth(300)
        self.dataDock.setMaximumWidth(300)

        self.logDock = QDockWidget(tr('Log'))
        self.logDock.setWidget(self.logView)

        self.addDockWidget(Qt.LeftDockWidgetArea, self.logDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dataDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.workspaceDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.toolDock)

        self.tabifyDockWidget(self.toolDock, self.workspaceDock)
        self.tabifyDockWidget(self.workspaceDock, self.dataDock)
        self.tabifyDockWidget(self.dataDock, self.logDock)
        self.toolDock.raise_()

        self.dbtool = ui.DbApp(self)
        self.dbBrowser = self.dbtool.dbBrowser

        self.setWindowTitle(tr('Pathomx'))

        self.progressBar = QProgressBar(self.statusBar())
        self.progressBar.setMaximumSize(QSize(170, 19))
        self.progressBar.setRange(0, 100)
        self.statusBar().addPermanentWidget(self.progressBar)
        self.progressTracker = {}  # Dict storing values for each view/object

        logging.info('Ready.')
        self.statusBar().showMessage(tr('Ready'))
        self.showMaximized()

        # Do version upgrade check
        if StrictVersion(self.config.value('/Pathomx/Current_version', '0.0.0')) < StrictVersion(VERSION_STRING):
            # We've got an upgrade
            self.onAbout()
            self.config.setValue('/Pathomx/Current_version', VERSION_STRING)

        if self.config.value('/Pathomx/Offered_registration', False) != True:
            self.onDoRegister()
            self.config.setValue('/Pathomx/Offered_registration', True)

    def onLogItemClicked(self, item):
        # When an item in the log viewer is clicked, center on the associated Tool
        # this will fail if there is none (i.e. non-tool log item) so wrapped in an try, except.
        try:
            item.tool.editorItem.centerSelf()
        except:
            pass

    def onLogItemDoubleClicked(self, item):
        # When an item in the log viewer is clicked, center on the associated Tool
        # this will fail if there is none (i.e. non-tool log item) so wrapped in an try, except.
        try:
            item.tool.show()
        except:
            pass

    def onMATLABPathEdit(self):
    
        dialog = ui.MATLABPathDialog(self, path=self.config.value('/Resources/MATLAB_path', 'matlab'))
        if dialog.exec_():
            path = dialog.path.text()
            resources.matlab.set_exec_path( path )
            self.config.setValue('/Resources/MATLAB_path', path)


    def onChangePlugins(self):
        dialog = plugins.dialogPluginManagement(self)
        if dialog.exec_():
            pass

    def onCheckPluginUpdates(self):
        pass

    def onDBExplore(self):
        self.dbtool.show()

    # Init application configuration
    def onResetConfig(self):
        # Defaults not set, apply now and save complete config file
        self.config.setValue('Pathomx/Is_setup', True)
        self.config.setValue('Pathomx/Current_version', '0.0.0')
        self.config.setValue('Pathomx/Update/Latest_version', '0.0.0')
        self.config.setValue('Pathomx/Update/Last_checked', None)
        self.config.setValue('Pathomx/Offered_registration', False)

        self.config.setValue('Plugins/Active', [])
        self.config.setValue('Plugins/Disabled', [])
        self.config.setValue('Plugins/Available', [])
        self.config.setValue('Plugins/Paths', [])
        
        self.config.setValue('/Resources/MATLAB_path', 'matlab')
        
    # UI Events

    def onGoToPathomxWeb(self):
        QDesktopServices.openUrl(QUrl('http://pathomx.org'))

    def onGoToPathomxDemos(self):
        QDesktopServices.openUrl(QUrl('http://pathomx.org/demos'))

    def onGoToPathomxDocs(self):
        QDesktopServices.openUrl(QUrl('http://docs.pathomx.org/'))

    def onDoRegister(self):
        # Pop-up a registration window; take an email address and submit to
        # register for update-announce.
        dlg = ui.DialogRegister(self)
        if dlg.exec_():
            # Perform registration
            data = {
                'name': dlg.name.text(),
                'email': dlg.email.text(),
                'country': dlg.country.currentText(),
                'research': dlg.research.text(),
                'institution': dlg.institution.text(),
                'type': dlg.type.currentText(),
                'register': dlg.register.checked(),
            }
            # Send data to server;
            # http://register.pathomx.org POST

    def onLineMarkerStyles(self):
        dlg = ui.MatchLineStyleManagerDialog(self)
        if dlg.exec_():
            self.onRefreshAllViews()

    def onRefreshAllViews(self):
        for t in self.apps:
            t.views.style_updated.emit()


    def onBrowserNav(self, url):
        # Interpret internal URLs for message passing to display Compound, Reaction, Pathway data in the sidebar interface
        # then block the continued loading
        if url.isRelative() and url.hasFragment():
            # Local #url; pass to default handler
            pass

        if url.scheme() == 'pathomx':
            # Take string from pathomx:// onwards, split on /
            app = url.host()
            if app == 'app-manager':
                app, action = url.path().strip('/').split('/')
                if action == 'add':
                    a = self.app_launchers[app]()

                # Update workspace viewer
                self.workspace_updated.emit()  # Notify change to workspace layout        


            elif app == 'db':
                kind, id, action = url.path().strip('/').split('/')
                            # View an object
                if action == 'view':
                    if kind == 'pathway' and id in self.db.pathways:
                        pathway = self.db.pathways[id]
                        self.generatedbBrowserView(template='db/pathway.html', data={
                            'title': pathway.name,
                            'object': pathway,
                            })
                    elif kind == 'reaction' and id in self.db.reactions:
                        reaction = self.db.reactions[id]
                        self.generatedbBrowserView(template='db/reaction.html', data={
                            'title': reaction.name,
                            'object': reaction,
                            })
                    elif kind == 'compound' and id in self.db.compounds:
                        compound = self.db.compounds[id]
                        self.generatedbBrowserView(template='db/compound.html', data={
                            'title': compound.name,
                            'object': compound,
                            })
                    elif kind == 'protein' and id in self.db.proteins:
                        protein = self.db.proteins[id]
                        self.generatedbBrowserView(template='db/protein.html', data={
                            'title': protein.name,
                            'object': protein,
                            })
                    elif kind == 'gene' and id in self.db.genes:
                        gene = self.db.genes[id]
                        self.generatedbBrowserView(template='db/gene.html', data={
                            'title': gene.name,
                            'object': gene,
                            })

                    # Focus the database window
                    self.dbtool.raise_()

            #metaviz/compound/%s/view
            elif app in self.url_handlers:
                for handler in self.url_handlers[app]:
                    handler(url.path().strip('/'))

            # Store URL so we can reload the sidebar later
            self.dbBrowser_CurrentURL = url

        else:
            # It's an URL open in default browser
            QDesktopServices.openUrl(url)

    def onLoadIdentities(self):
        """ Open a data file"""
        filename, _ = QFileDialog.getOpenFileName(self, 'Load compound identities file', '')
        if filename:
            self.db.load_synonyms(filename)
            # Re-translate the datafile if there is one and refresh
            if self.data:
                self.data.translate(self.db)
                self.generateGraphView(regenerate_analysis=True)

    def onSaveAs(self):
        """ Save a copy of the graph as one of the supported formats"""
        # Note this will regenerate the graph with the current settings, with output type specified appropriately
        filename, _ = QFileDialog.getSaveFileName(self, 'Save current metabolic pathway map', '')
        if filename:
            fn, ext = os.path.splitext(filename)
            format = ext.replace('.', '')
            # Check format is supported
            if format in ['bmp', 'canon', 'dot', 'xdot', 'cmap', 'eps', 'fig', 'gd', 'gd2', 'gif', 'gtk', 'ico', 'imap', 'cmapx', 'imap_np', 'cmapx_np', 'ismap', 'jpg', 'jpeg', 'jpe', 'pdf', 'plain', 'plain-ext', 'png', 'ps', 'ps2', 'svg', 'svgz', 'tif', 'tiff', 'vml', 'vmlz', 'vrml', 'wbmp', 'webp', 'xlib']:
                self.generateGraph(filename, format)
            else:
                # Unsupported format error
                pass

    def onAbout(self):
        dlg = ui.DialogAbout(self)
        dlg.exec_()

    def onExit(self):
        self.Close(True)  # Close the frame.

    def onReloadDB(self):
        self.db = db.databaseManager()

    def onRefresh(self):
        self.generateGraphView()

    def generatedbBrowserView(self, template='base.html', data={'title': '', 'object': {}, 'data': {}}):
        metadata = {
            'htmlbase': os.path.join(utils.scriptdir, 'html'),
            # Current state data
            'current_pathways': [],  # self.config.value('/Pathways/Show').split(','),
            'data': self.data,
            # Color schemes
            # 'rdbu9':['b2182b', 'd6604d', 'f4a582', '33a02c', 'fddbc7', 'f7f7f7', 'd1e5f0', '92c5de', '4393c3', '2166ac']
        }

        template = self.templateEngine.get_template(template)
        self.dbBrowser.setHtml(template.render(dict(list(data.items()) + list(metadata.items()))), QUrl("~"))

    def onWorkspaceStackChange(self, item, previous):
        widget = self.workspace_index[item.text(1)]
        if widget:
            widget.show()
            widget.raise_()

    def addWorkspaceItem(self, widget, section, title, icon=None):

        tw = QTreeWidgetItem()
        wid = str(id(tw))
        tw.setText(0, tr(title))
        tw.setText(1, wid)

        if widget:
            widget._workspace_index = wid

        self.workspace_index[wid] = widget

        if icon:
            tw.setIcon(0, icon)

        if section:
            self.workspace_parents[section].addChild(tw)
            widget._workspace_section = self.workspace_parents[section]
            widget._workspace_tree_widget = tw
        else:
            self.workspace.addTopLevelItem(tw)
            self.workspace_parents[title] = tw
            tw.setExpanded(True)

        return tw

    def removeWorkspaceItem(self, widget):
        del self.workspace_index[widget._workspace_index]
        widget._workspace_section.removeChild(widget._workspace_tree_widget)

    def setWorkspaceStatus(self, workspace_item, status):
        status_icons = {
            'active': QIcon(os.path.join(utils.scriptdir, 'icons', 'flag-green.png')),
            'render': QIcon(os.path.join(utils.scriptdir, 'icons', 'flag-purple.png')),
            'waiting': QIcon(os.path.join(utils.scriptdir, 'icons', 'flag-yellow.png')),
            'error': QIcon(os.path.join(utils.scriptdir, 'icons', 'flag-red.png')),
            'paused': QIcon(os.path.join(utils.scriptdir, 'icons', 'flag-white.png')),
            'done': QIcon(os.path.join(utils.scriptdir, 'icons', 'flag-checker.png')),
            'clear': QIcon(None)
        }

        if status not in list(status_icons.keys()):
            status = 'clear'

        workspace_item.setIcon(3, status_icons[status])
        self.workspace.update(self.workspace.indexFromItem(workspace_item))

        # Keep things ticking
        QCoreApplication.processEvents()

        if status == 'active':  # Starting
            self.updateProgress(workspace_item, 0)

        elif status == 'clear' or status == 'error':
            self.updateProgress(workspace_item, None)

        elif status == 'done':  # Flash done then clear in a bit
            self.updateProgress(workspace_item, 1)
            statusclearCallback = functools.partial(self.setWorkspaceStatus, workspace_item, 'clear')
            workspace_item.status_timeout = QTimer.singleShot(1000, statusclearCallback)

    def clearWorkspaceStatus(self, workspace_item):
        self.setWorkspaceStatus(workspace_item, 'clear')

    def updateProgress(self, workspace_item, progress):

        if progress == None:
            if id(workspace_item) in self.progressTracker:
                del(self.progressTracker[id(workspace_item)])
            if len(self.progressTracker) == 0:
                self.progressBar.reset()
                return
        else:
            self.progressTracker[id(workspace_item)] = progress

        m = 100.0 / len(self.progressTracker)
        pt = sum([n * m for n in list(self.progressTracker.values())])

        if self.progressBar.value() < pt:  # Don't go backwards it's annoying FIXME: once hierarchical prediction; stack all things that 'will' start
            self.progressBar.setValue(pt)
        # Keep things ticking
        #QCoreApplication.processEvents()

    def register_url_handler(self, identifier, url_handler):
        self.url_handlers[identifier].append(url_handler)
    ### OPEN/SAVE WORKSPACE

    def onOpenWorkspace(self):
        self.openWorkspace('/Users/mxf793/Desktop/test.mpw')

    def openWorkspace(self, fn):
        pass

    def onSaveWorkspace(self):
        self.saveWorkspace('/Users/mxf793/Desktop/test.mpw')

    def onSaveWorkspaceAs(self):
        self.saveWorkspace('/Users/mxf793/Desktop/test.mpw')

    def saveWorkspace(self, fn):
        pass
    ### RESET WORKSPACE

    def onClearWorkspace(self):
        reply = QMessageBox.question(self, "Clear Workspace", "Are you sure you want to clear the workspace? Everything will be deleted.",
                            QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes:
            self.clearWorkspace()

    def clearWorkspace(self):
        for v in self.apps[:]:  # Copy as v.delete modifies the self.apps list
            v.delete()

        # Remove all workspace datasets
        del self.datasets[:]

        self.workspace_updated.emit()
    ### OPEN/SAVE WORKFLOWS

    def onSaveWorkflowAs(self):
        filename, _ = QFileDialog.getSaveFileName(self, 'Save current workflow', '', "Pathomx Workflow Format (*.mpf)")
        if filename:
            self.saveWorkflow(filename)

    def saveWorkflow(self, fn):

        root = et.Element("Workflow")
        root.set('xmlns:mpwfml', "http://pathomx.org/schema/Workflow/2013a")
        
        s = et.SubElement(root, "Styles")
        s = styles.linestyles.getXMLMatchDefinitionsLineStyles(s)

        # Build a JSONable object representing the entire current workspace and write it to file
        for v in self.apps:
            app = et.SubElement(root, "App")
            app.set("id", v.id)

            name = et.SubElement(app, "Name")
            name.text = v.name

            plugin = et.SubElement(app, "Plugin")
            plugin.set("version", '1.0')
            plugin.text = v.plugin.__class__.__name__

            plugin_class = et.SubElement(app, "Launcher")
            plugin_class.text = v.__class__.__name__

            position = et.SubElement(app, "EditorXY")
            position.set("x", str(v.editorItem.x()))
            position.set("y", str(v.editorItem.y()))

            config = et.SubElement(app, "Config")
            for ck, cv in list(v.config.config.items()):
                co = et.SubElement(config, "ConfigSetting")
                co.set("id", ck)
                t = type(cv).__name__
                co.set("type", type(cv).__name__)
                co = utils.CONVERT_TYPE_TO_XML[t](co, cv)

            datasources = et.SubElement(app, "DataInputs")
            # Build data inputs table (outputs are pre-specified by the object; this == links)
            for sk, si in list(v.data.i.items()):
                if si:  # Something on this interface
                    cs = et.SubElement(datasources, "Input")
                    cs.set("id", sk)
                    cs.set("manager", si.manager.id)
                    cs.set("interface", si.manager_interface)

        tree = et.ElementTree(root)
        tree.write(fn)  # , pretty_print=True)

    def onOpenWorkflow(self):
        """ Open a data file"""
        filename, _ = QFileDialog.getOpenFileName(self, 'Open new workflow', '', "Pathomx Workflow Format (*.mpf)")
        if filename:
            self.openWorkflow(filename)

    def openWorkflow(self, fn):
        logging.info("Loading workflow... %s" % fn)
        # Wipe existing workspace
        self.clearWorkspace()
        # Load from file
        tree = et.parse(fn)
        workflow = tree.getroot()

        s = workflow.find('Styles')
        styles.linestyles.setXMLMatchDefinitionsLineStyles(s)

        appref = {}
        logging.info("...Loading apps.")
        for xapp in workflow.findall('App'):
            # FIXME: This does not work with multiple launchers/plugin - define as plugin.class?
            # Check plugins loaded etc.
            logging.info(('- %s' % xapp.find('Name').text))
            app = self.app_launchers["%s.%s" % (xapp.find("Plugin").text, xapp.find("Launcher").text)](auto_consume_data=False, name=xapp.find('Name').text)
            editorxy = xapp.find('EditorXY')
            app.editorItem.setPos(QPointF(float(editorxy.get('x')), float(editorxy.get('y'))))
            #app = self.app_launchers[ item.find("launcher").text ]()
            #app.set_name(  )
            appref[xapp.get('id')] = app

            config = {}
            for xconfig in xapp.findall('Config/ConfigSetting'):
                #id="experiment_control" type="unicode" value="monocyte at intermediate differentiation stage (GDS2430_2)"/>
                if xconfig.get('type') in utils.CONVERT_TYPE_FROM_XML:
                    v = utils.CONVERT_TYPE_FROM_XML[xconfig.get('type')](xconfig)
                config[xconfig.get('id')] = v

            app.config.set_many(config, trigger_update=False)

        logging.info("...Linking objects.")
        # Now build the links between objects; we need to force these as data is not present
        for xapp in workflow.findall('App'):
            app = appref[xapp.get('id')]

            for idef in xapp.findall('DataInputs/Input'):
                app.data._consume_action(idef.get('id'), appref[idef.get('manager')].data.o[idef.get('interface')])

        logging.info("Load complete.")
        # Focus the home tab & refresh the view
        self.workspace_updated.emit()
Example #55
0
class MultiTemplateTestCase(unittest.TestCase):
    """ Test the ``CoreExtension`` compiled templates.
    """

    def setUp(self):
        from wheezy.template.engine import Engine
        from wheezy.template.ext.core import CoreExtension
        from wheezy.template.loader import DictLoader
        self.templates = {}
        self.engine = Engine(
            loader=DictLoader(templates=self.templates),
            extensions=[CoreExtension()])

    def render(self, name, ctx):
        template = self.engine.get_template(name)
        return template.render(ctx)

    def test_extends(self):
        self.templates.update({
            'master.html': """\
@def say_hi(name):
    Hello, @name!
@end
@say_hi('John')""",

            'tmpl.html': """\
@extends('master.html')
@def say_hi(name):
    Hi, @name!
@end
"""
        })
        assert '    Hi, John!\n' == self.render('tmpl.html', {})
        assert '    Hello, John!\n' == self.render('master.html', {})

    def test_super(self):
        self.templates.update({
            'master.html': """\
@def say_hi(name):
    Hello, @name!\
@end
@say_hi('John')""",

            'tmpl.html': """\
@extends('master.html')
@def say_hi(name):
    @super_defs['say_hi'](name)!!\
@end
"""
        })
        assert '        Hello, John!!!' == self.render('tmpl.html', {})

    def test_include(self):
        self.templates.update({
            'footer.html': """\
@require(name)
Thanks, @name""",

            'tmpl.html': """\
Welcome to my site.
@include('footer.html')
"""
        })
        ctx = {'name': 'John'}
        assert """\
Welcome to my site.
Thanks, John""" == self.render('tmpl.html', ctx)
        assert 'Thanks, John' == self.render('footer.html', ctx)

    def test_import(self):
        self.templates.update({
            'helpers.html': """\
@def say_hi(name):
Hi, @name\
@end""",

            'tmpl.html': """\
@import 'helpers.html' as helpers
@helpers.say_hi('John')"""
        })
        assert """\
Hi, John""" == self.render('tmpl.html', {})

    def test_import_dynamic(self):
        self.templates.update({
            'helpers.html': """\
@def say_hi(name):
Hi, @name\
@end""",

            'tmpl.html': """\
@require(helpers_impl)
@import helpers_impl as helpers
@helpers.say_hi('John')"""
        })
        assert """\
Hi, John""" == self.render('tmpl.html', {'helpers_impl': 'helpers.html'})

    def test_from_import(self):
        self.templates.update({
            'helpers.html': """\
@def say_hi(name):
Hi, @name\
@end""",

            'tmpl.html': """\
@from 'helpers.html' import say_hi
@say_hi('John')"""
        })
        assert """\
Hi, John""" == self.render('tmpl.html', {})

    def test_from_import_dynamic(self):
        self.templates.update({
            'helpers.html': """\
@def say_hi(name):
Hi, @name\
@end""",

            'tmpl.html': """\
@require(helpers_impl)
@from helpers_impl import say_hi
@say_hi('John')"""
        })
        assert """\
Hi, John""" == self.render('tmpl.html', {'helpers_impl': 'helpers.html'})

    def test_from_import_as(self):
        self.templates.update({
            'share/helpers.html': """\
@def say_hi(name):
Hi, @name\
@end""",

            'tmpl.html': """\
@from 'share/helpers.html' import say_hi as hi
@hi('John')"""
        })
        assert """\
Hi, John""" == self.render('tmpl.html', {})
Example #56
0
class TemplateTestCase(unittest.TestCase):
    """ Test the ``CoreExtension`` compiled templates.
    """

    def setUp(self):
        from wheezy.template.engine import Engine
        from wheezy.template.ext.core import CoreExtension
        from wheezy.template.loader import DictLoader
        self.templates = {}
        self.engine = Engine(
            loader=DictLoader(templates=self.templates),
            extensions=[CoreExtension()])

    def render(self, ctx, source):
        self.templates['test.html'] = source
        template = self.engine.get_template('test.html')
        return template.render(ctx)

    def test_markup(self):
        ctx = {}
        assert 'Hello' == self.render(ctx, 'Hello')

    def test_comment(self):
        assert 'Hello World' == self.render({}, """\
Hello\\
@# comment
 World""")

    def test_var(self):
        ctx = {
            'username': '******'
        }
        assert 'Welcome, John!' == self.render(ctx, """\
@require(username)
Welcome, @username!""")

    def test_if(self):
        template = """\
@require(n)
@if n > 0:
    Positive\\
@elif n == 0:
    Zero\\
@else:
    Negative\\
@end
"""
        assert '    Positive' == self.render({'n': 1}, template)
        assert '    Zero' == self.render({'n': 0}, template)
        assert '    Negative' == self.render({'n': -1}, template)

    def test_for(self):
        ctx = {
            'colors': ['red', 'yellow']
        }
        assert '    red\n    yellow\n' == self.render(ctx, """\
@require(colors)
@for color in colors:
    @color
@end
""")

    def test_def(self):
        assert 'Welcome, John!' == self.render({}, """\
@def welcome(name):
Welcome, @name!\\
@end
@welcome('John')""")

    def test_def_empty(self):
        assert '.' == self.render({}, """\
@def title():
@end
@title().""")

    def test_def_syntax_error_compound(self):
        self.assertRaises(SyntaxError, lambda: self.render({}, """\
@def welcome(name):
@if name:
Welcome, @name!\\
@end
@end
@welcome('John')"""))

    def test_def_no_syntax_error(self):
        assert 'Welcome, John!' == self.render({}, """\
@def welcome(name):
@#ignore
@if name:
Welcome, @name!\\
@end
@end
@welcome('John')""")
Example #57
0
    def __init__(self):
        super(MainWindow, self).__init__()

        #self.app = app
        self.apps = []
        self.apps_dict = {}

        # Initiate logging
        self.logView = QTreeWidget()
        self.logView.setColumnCount(2)
        self.logView.expandAll()
        self.logView.itemClicked.connect(self.onLogItemClicked)
        self.logView.itemDoubleClicked.connect(self.onLogItemDoubleClicked)

        self.logView.setHeaderLabels(['ID', 'Message'])
        self.logView.setUniformRowHeights(True)
        self.logView.hideColumn(0)

        logHandler = Logger(self, self.logView)
        logging.getLogger().addHandler(logHandler)
        #sys.stdout = Logger( self.logView, sys.__stdout__)
        #sys.stderr = Logger( self.logView, sys.__stderr__, QColor(255,0,0) )
        logging.info('Welcome to Pathomx v%s' % (VERSION_STRING))

        # Central variable for storing application configuration (load/save from file?
        self.config = QSettings()
        if self.config.value('/Pathomx/Is_setup', False) != True:
            logging.info("Setting up initial configuration...")
            self.onResetConfig()
            logging.info('Done')

        # Do version upgrade availability check
        # FIXME: Do check here; if not done > 2 weeks
        if StrictVersion(self.config.value('/Pathomx/Latest_version', '0.0.0')) > StrictVersion(VERSION_STRING):
            # We've got an upgrade
            logging.warning('A new version (v%s) is available' % self.config.value('/Pathomx/Update/Latest_version', '0.0.0'))

        # Create database accessor
        self.db = db.databaseManager()
        self.data = None  # deprecated
        self.datasets = []  # List of instances of data.datasets() // No data loaded by default

        self.experiment = dict()
        self.layout = None  # No map by default

        #self.linestyles = styles.LineStyleHandler()

        # The following holds tabs & pathway objects for gpml imported pathways
        self.gpmlpathways = []
        self.tab_handlers = []
        self.url_handlers = defaultdict(list)
        self.app_launchers = {}
        self.app_launcher_categories = defaultdict(list)
        self.file_handlers = {}

        # Create templating engine
        self.templateEngine = Engine(
            loader=FileLoader([os.path.join(utils.scriptdir, 'html')]),
            extensions=[CoreExtension(), CodeExtension()]
        )
        self.templateEngine.global_vars.update({'tr': tr})

        self.update_view_callback_enabled = True

        self.printer = QPrinter()

        QNetworkProxyFactory.setUseSystemConfiguration(True)

        #  UI setup etc
        self.menuBars = {
            'file': self.menuBar().addMenu(tr('&File')),
            'plugins': self.menuBar().addMenu(tr('&Plugins')),
            'appearance': self.menuBar().addMenu(tr('&Appearance')),
            'resources': self.menuBar().addMenu(tr('&Resources')),
            'database': self.menuBar().addMenu(tr('&Database')),
            'help': self.menuBar().addMenu(tr('&Help')),
        }

        # FILE MENU
        aboutAction = QAction(QIcon.fromTheme("help-about"), 'About', self)
        aboutAction.setStatusTip(tr('About Pathomx'))
        aboutAction.triggered.connect(self.onAbout)
        self.menuBars['file'].addAction(aboutAction)

        newAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'document.png')), tr('&New Blank Workspace'), self)
        newAction.setShortcut('Ctrl+N')
        newAction.setStatusTip(tr('Create new blank workspace'))
        newAction.triggered.connect(self.onClearWorkspace)
        self.menuBars['file'].addAction(newAction)

        openAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'folder-open-document.png')), tr('&Open…'), self)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip(tr('Open previous analysis workspace'))
        openAction.triggered.connect(self.onOpenWorkspace)
        #self.menuBars['file'].addAction(openAction)

        openAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'folder-open-document.png')), tr('&Open Workflow…'), self)
        openAction.setStatusTip(tr('Open an analysis workflow'))
        openAction.triggered.connect(self.onOpenWorkflow)
        self.menuBars['file'].addAction(openAction)

        self.menuBars['file'].addSeparator()

        saveAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'disk.png')), tr('&Save'), self)
        saveAction.setShortcut('Ctrl+S')
        saveAction.setStatusTip(tr('Save current workspace for future use'))
        saveAction.triggered.connect(self.onSaveWorkspace)
        #self.menuBars['file'].addAction(saveAction)

        saveAsAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'disk--pencil.png')), tr('Save &As…'), self)
        saveAsAction.setShortcut('Ctrl+A')
        saveAsAction.setStatusTip(tr('Save current workspace for future use'))
        saveAsAction.triggered.connect(self.onSaveWorkspaceAs)
        #self.menuBars['file'].addAction(saveAsAction)

        saveAsAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'disk--pencil.png')), tr('Save Workflow As…'), self)
        saveAsAction.setStatusTip(tr('Save current workflow for future use'))
        saveAsAction.triggered.connect(self.onSaveWorkflowAs)
        self.menuBars['file'].addAction(saveAsAction)

        self.menuBars['file'].addSeparator()

        #printAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'printer.png')), tr('&Print…'), self)
        #printAction.setShortcut('Ctrl+P')
        #printAction.setStatusTip(tr('Print current figure'))
        #printAction.triggered.connect(self.onPrint)
        #self.menuBars['file'].addAction(printAction)

        self.menuBars['file'].addSeparator()

        # DATABASE MENU
        explore_dbAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'database-explore.png')), tr('&Explore database…'), self)
        explore_dbAction.setStatusTip('Explore database')
        explore_dbAction.triggered.connect(self.onDBExplore)
        self.menuBars['database'].addAction(explore_dbAction)

        load_identitiesAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'database-import.png')), tr('&Load database unification…'), self)
        load_identitiesAction.setStatusTip('Load additional unification mappings into database')
        load_identitiesAction.triggered.connect(self.onLoadIdentities)
        self.menuBars['database'].addAction(load_identitiesAction)

        self.menuBars['database'].addSeparator()

        reload_databaseAction = QAction(QIcon(os.path.join(utils.scriptdir, 'icons', 'exclamation-red.png')), tr('&Reload database'), self)
        reload_databaseAction.setStatusTip('Reload pathway & metabolite database')
        reload_databaseAction.triggered.connect(self.onReloadDB)
        self.menuBars['database'].addAction(reload_databaseAction)
        # PLUGINS MENU

        change_pluginsAction = QAction(tr('&Manage plugins…'), self)
        change_pluginsAction.setStatusTip('Find, activate, deactivate and remove plugins')
        change_pluginsAction.triggered.connect(self.onChangePlugins)
        self.menuBars['plugins'].addAction(change_pluginsAction)

        check_pluginupdatesAction = QAction(tr('&Check for updated plugins'), self)
        check_pluginupdatesAction.setStatusTip('Check for updates to installed plugins')
        check_pluginupdatesAction.triggered.connect(self.onCheckPluginUpdates)
        #self.menuBars['plugins'].addAction(check_pluginupdatesAction)  FIXME: Add a plugin-update check

        linemarkerstyleAction = QAction('Line and marker styles…', self)
        linemarkerstyleAction.setStatusTip(tr('Set line and marker styles for data classes'))
        linemarkerstyleAction.triggered.connect(self.onLineMarkerStyles)
        self.menuBars['appearance'].addAction(linemarkerstyleAction)
        

        matlabpathAction = QAction('Edit MATLAB path…', self)
        matlabpathAction.setStatusTip(tr('Set MATLAB path'))
        matlabpathAction.triggered.connect(self.onMATLABPathEdit)
        self.menuBars['resources'].addAction(matlabpathAction)

        

        aboutAction = QAction(QIcon.fromTheme("help-about"), 'Introduction', self)
        aboutAction.setStatusTip(tr('About Pathomx'))
        aboutAction.triggered.connect(self.onAbout)
        self.menuBars['help'].addAction(aboutAction)

        self.menuBars['help'].addSeparator()

        goto_pathomx_websiteAction = QAction(tr('&Pathomx homepage'), self)
        goto_pathomx_websiteAction.setStatusTip('Go to the Pathomx website')
        goto_pathomx_websiteAction.triggered.connect(self.onGoToPathomxWeb)
        self.menuBars['help'].addAction(goto_pathomx_websiteAction)

        goto_pathomx_docsAction = QAction(tr('&Pathomx documentation'), self)
        goto_pathomx_docsAction.setStatusTip('Read latest Pathomx documentation')
        goto_pathomx_docsAction.triggered.connect(self.onGoToPathomxDocs)
        self.menuBars['help'].addAction(goto_pathomx_docsAction)

        goto_pathomx_demosAction = QAction(tr('&Pathomx demos'), self)
        goto_pathomx_demosAction.setStatusTip('Watch Pathomx demo videos')
        goto_pathomx_demosAction.triggered.connect(self.onGoToPathomxDemos)
        self.menuBars['help'].addAction(goto_pathomx_demosAction)

        self.menuBars['help'].addSeparator()

        do_registerAction = QAction(tr('&Register Pathomx'), self)
        do_registerAction.setStatusTip('Register Pathomx for release updates')
        do_registerAction.triggered.connect(self.onDoRegister)
        self.menuBars['help'].addAction(do_registerAction)

        # GLOBAL WEB SETTINGS
        QNetworkProxyFactory.setUseSystemConfiguration(True)

        QWebSettings.setMaximumPagesInCache(0)
        QWebSettings.setObjectCacheCapacities(0, 0, 0)
        QWebSettings.clearMemoryCaches()

        resources.matlab.set_exec_path( self.config.value('/Resources/MATLAB_path', 'matlab') )

        self.resources = {
            'MATLAB': resources.matlab,
            'R': resources.r,
        }

        self.plugins = {}  # Dict of plugin shortnames to data
        self.plugins_obj = {}  # Dict of plugin name references to objs (for load/save)
        self.pluginManager = PluginManagerSingleton.get()
        self.pluginManager.m = self

        self.plugin_places = []
        self.core_plugin_path = os.path.join(utils.scriptdir, 'plugins')
        self.plugin_places.append(self.core_plugin_path)

        user_application_data_paths = QStandardPaths.standardLocations(QStandardPaths.DataLocation)
        if user_application_data_paths:
            self.user_plugin_path = os.path.join(user_application_data_paths[0], 'plugins')
            utils.mkdir_p(self.user_plugin_path)
            self.plugin_places.append(self.user_plugin_path)

            self.application_data_path = os.path.join(user_application_data_paths[1])

        logging.info("Searching for plugins...")
        for place in self.plugin_places:
            logging.info(place)

        self.tools = defaultdict(list)
        
        self.pluginManager.setPluginPlaces(self.plugin_places)
        self.pluginManager.setPluginInfoExtension('pathomx-plugin')
        categories_filter = {
               "Import": plugins.ImportPlugin,
               "Processing": plugins.ProcessingPlugin,
               "Identification": plugins.IdentificationPlugin,
               "Analysis": plugins.AnalysisPlugin,
               "Visualisation": plugins.VisualisationPlugin,
               "Export": plugins.ExportPlugin,
               "Scripting": plugins.ScriptingPlugin,
               }
        self.pluginManager.setCategoriesFilter(categories_filter)
        self.pluginManager.collectPlugins()

        plugin_categories = ["Import", "Processing", "Identification", "Analysis", "Visualisation", "Export", "Scripting"]  # categories_filter.keys()
        apps = defaultdict(list)
        self.appBrowsers = {}
        self.plugin_names = dict()
        self.plugin_metadata = dict()


        # Loop round the plugins and print their names.
        for category in plugin_categories:
            for plugin in self.pluginManager.getPluginsOfCategory(category):

                plugin_image = os.path.join(os.path.dirname(plugin.path), 'icon.png')

                if not os.path.isfile(plugin_image):
                    plugin_image = None
                
                try:
                    resource_list = plugin.details.get('Documentation','Resources').split(',')
                except:
                    resource_list = []
                
                metadata = {
                    'id': plugin.plugin_object.__class__.__name__,  # __module__,
                    'image': plugin_image,
                    'image_forward_slashes': plugin_image.replace('\\', '/'),  # Slashes fix for CSS in windows
                    'name': plugin.name,
                    'version': plugin.version,
                    'description': plugin.description,
                    'author': plugin.author,
                    'resources': resource_list,
                    'info': plugin,
                    'path': os.path.dirname(plugin.path),
                    'module': os.path.basename(plugin.path),
                    'shortname': os.path.basename(plugin.path),
                    'is_core_plugin': plugin.path.startswith(self.core_plugin_path)
                }

                self.plugins[metadata['shortname']] = metadata
                self.plugin_names[id(plugin.plugin_object)] = plugin.name

                plugin.plugin_object.post_setup(path=os.path.dirname(plugin.path), name=plugin.name, metadata=metadata)

                apps[category].append(metadata)

        self.stack = QStackedWidget()

        self.threadpool = QThreadPool()
        logging.info("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())

        self.setCentralWidget(self.stack)
        self.stack.setCurrentIndex(0)

        self.workspace_count = 0  # Auto-increment
        self.workspace_parents = {}
        self.workspace_index = {}  # id -> obj

        self.workspace = QTreeWidget()
        self.workspace.setColumnCount(4)
        self.workspace.expandAll()

        self.workspace.setHeaderLabels(['', 'ID', ' ◎', ' ⚑'])  # ,'#'])
        self.workspace.setUniformRowHeights(True)
        self.workspace.hideColumn(1)

        self.editor = WorkspaceEditor(self)
        self.setCentralWidget(self.editor)

        app_category_icons = {
               "Import": QIcon(os.path.join(utils.scriptdir, 'icons', 'disk--arrow.png')),
               "Processing": QIcon(os.path.join(utils.scriptdir, 'icons', 'ruler-triangle.png')),
               "Identification": QIcon(os.path.join(utils.scriptdir, 'icons', 'target.png')),
               "Analysis": QIcon(os.path.join(utils.scriptdir, 'icons', 'calculator.png')),
               "Visualisation": QIcon(os.path.join(utils.scriptdir, 'icons', 'star.png')),
               "Export": QIcon(os.path.join(utils.scriptdir, 'icons', 'disk--pencil.png')),
               "Scripting": QIcon(os.path.join(utils.scriptdir, 'icons', 'script-text.png')),
               }

        template = self.templateEngine.get_template('apps.html')
        for category in plugin_categories:
            self.addWorkspaceItem(None, None, category, app_category_icons[category])

        self.workspace.setSelectionMode(QAbstractItemView.SingleSelection)
        self.workspace.currentItemChanged.connect(self.onWorkspaceStackChange)

        self.toolbox = QToolBox(self)
        for category in plugin_categories:
            panel = ToolPanel(self, tools=self.tools[category])
            self.toolbox.addItem(panel, app_category_icons[category], category)

        self.toolDock = QDockWidget(tr('Toolkit'))
        self.toolDock.setWidget(self.toolbox)

        self.workspaceDock = QDockWidget(tr('Workspace'))
        self.workspaceDock.setWidget(self.workspace)
        self.workspace.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.workspace.setColumnWidth(0, 298 - 25 * 2)
        self.workspace.setColumnWidth(2, 24)
        self.workspace.setColumnWidth(3, 24)
        self.workspaceDock.setMinimumWidth(300)
        self.workspaceDock.setMaximumWidth(300)

        self.dataView = QTreeView(self)
        self.dataModel = data.DataTreeModel(self.datasets)
        self.dataView.setModel(self.dataModel)

        self.dataView.hideColumn(0)

        self.dataDock = QDockWidget(tr('Data'))
        self.dataDock.setWidget(self.dataView)
        self.dataDock.setMinimumWidth(300)
        self.dataDock.setMaximumWidth(300)

        self.logDock = QDockWidget(tr('Log'))
        self.logDock.setWidget(self.logView)

        self.addDockWidget(Qt.LeftDockWidgetArea, self.logDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dataDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.workspaceDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.toolDock)

        self.tabifyDockWidget(self.toolDock, self.workspaceDock)
        self.tabifyDockWidget(self.workspaceDock, self.dataDock)
        self.tabifyDockWidget(self.dataDock, self.logDock)
        self.toolDock.raise_()

        self.dbtool = ui.DbApp(self)
        self.dbBrowser = self.dbtool.dbBrowser

        self.setWindowTitle(tr('Pathomx'))

        self.progressBar = QProgressBar(self.statusBar())
        self.progressBar.setMaximumSize(QSize(170, 19))
        self.progressBar.setRange(0, 100)
        self.statusBar().addPermanentWidget(self.progressBar)
        self.progressTracker = {}  # Dict storing values for each view/object

        logging.info('Ready.')
        self.statusBar().showMessage(tr('Ready'))
        self.showMaximized()

        # Do version upgrade check
        if StrictVersion(self.config.value('/Pathomx/Current_version', '0.0.0')) < StrictVersion(VERSION_STRING):
            # We've got an upgrade
            self.onAbout()
            self.config.setValue('/Pathomx/Current_version', VERSION_STRING)

        if self.config.value('/Pathomx/Offered_registration', False) != True:
            self.onDoRegister()
            self.config.setValue('/Pathomx/Offered_registration', True)