import sys import os from typing import Dict, List from importlib import import_module from flask import Flask, request, session from .sams_app import SAMSApp from .exceptions import ( ManifestDefaultLanguageMissing, DefaultLanguageDictMissing, AppNotExist, FunctionNotExists ) def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) class SAMSHub: def __init__(self, name: str, config: dict): self._config = config; if not self._config.get('default_language'): raise TypeError( 'Parameter config musst contain a value for "default_language"') self._apps = {} self._appList = [] self._flaskApp = Flask(name) self._flaskApp.context_processor(self._context_processor) self._flaskApp.secret_key = os.urandom(24) def addApp(self, app: SAMSApp = None, alias = None): if not isinstance(app, SAMSApp): raise TypeError('Argument app has to be a SAMSApp.') appDict = {'app': app, 'urlPrefix': (alias or app.name)} self._apps[app.name] = appDict self._appList.append(appDict) if app.name == self._config.get('main_app'): self._flaskApp.register_blueprint(app.blueprint) self._flaskApp.register_blueprint( app.blueprint, url_prefix = '/' + appDict['urlPrefix']) @property def appKeys(self): return self._apps.keys() @property def flaskApp(self): return self._flaskApp def app(self, name): try: return self._apps[name]['app'] except: raise AppNotExist def __add_urls(self, module): for view in self.__manifests[module].get('views', []): pathElements = [module] if view['url']: pathElements.append(view['url']) rule = '/' + '/'.join(pathElements) endpoint = '_'.join(view['function'].split('.')) view_func = self.__get_attr(self.__modules[module], view['function']) self.__blueprints[module].add_url_rule(rule = rule, endpoint = endpoint , view_func = view_func) def _context_processor(self): return { 'app_lang': self.app(request.blueprint).lang( session.get('language', self._config['default_language']) ), 'menu': self.menu( session.get('language', self._config['default_language'])) } def menu(self, langCode): menu = [] for appDict in self._appList: if self._config.get('main_app') == appDict['app'].name: menu.extend(appDict['app'].menu(langCode = langCode)) else: menu.extend(appDict['app'].menu(langCode = langCode, urlPrefix = appDict['urlPrefix'])) return menu @staticmethod def _get_module_rule(module, path): pathElements = [module] if path: pathElements.append(path) return '/' + '/'.join(pathElements) @staticmethod def _get_attr(object, attrString): attr = None try: return getattr(object, attrString) except AttributeError: pass attrList = attrString.split('.') if len(attrList) <= 1: raise FunctionNotExists('The function ' + attrString + ' does not exist') return( SAMSHub._get_attr(getattr(object, attrList[0]), '.'.join(attrList[1:])) )