diff options
Diffstat (limited to 'lib/server')
-rw-r--r-- | lib/server/__init__.py | 2 | ||||
-rw-r--r-- | lib/server/_server.py | 20 | ||||
-rw-r--r-- | lib/server/config.py | 111 | ||||
-rw-r--r-- | lib/server/flask/__init__.py | 5 | ||||
-rw-r--r-- | lib/server/flask/_app.py | 57 |
5 files changed, 195 insertions, 0 deletions
diff --git a/lib/server/__init__.py b/lib/server/__init__.py new file mode 100644 index 0000000..a779594 --- /dev/null +++ b/lib/server/__init__.py @@ -0,0 +1,2 @@ +# server import +from server._server import Server diff --git a/lib/server/_server.py b/lib/server/_server.py new file mode 100644 index 0000000..eb7f94c --- /dev/null +++ b/lib/server/_server.py @@ -0,0 +1,20 @@ +# python import +import atexit, multiprocessing + +# server import +from server import config +from server.flask import app, run_app + +class Server(object): + + def __init__(self): + # start the server + self._server = multiprocessing.Process(target=run_app) + self._server.start() + # .. required to close properly + atexit.register(self.close) + + def close(self): + # stop web thread + self._server.terminate() + self._server.join() diff --git a/lib/server/config.py b/lib/server/config.py new file mode 100644 index 0000000..9180e54 --- /dev/null +++ b/lib/server/config.py @@ -0,0 +1,111 @@ + +# python import +import logging +from ConfigParser import SafeConfigParser + +# get application logger +logger = logging.getLogger('atoideweb') + + +class Config(object): + + class __Singleton: + """Our singleton object. + """ + + def __init__(self, config=None): + """Create the new singleton with the application config. + + :param config: SafeConfigParser object for all the application + :see: `ConfigParser.SafeConfigParser` + """ + # ensure config + if config is None: + # ... + self.__config = SafeConfigParser() + # ... + self.__config.read('config.ini') + # ... + else: + self.__config = config + + def set(self, path, value, type_=str): + # set value + self.set_value(*path.split(">"), value=value, type_=type_) + + def get(self, path, type_=str): + """A little jQuery like shortcut for the `get_value` method. + + :param path: something like "section>option" + :param type_: type of the expected value. Default: str + :return: expected value in the expected type or None + :rtype: `object` + """ + # get value + _value = self.get_value(*path.split(">"), type_=type_) + # check and return + return None if _value is None or _value == "" else _value + + def set_value(self, section, option, value=None, type_=str): + # check has config + if self.__config is None: + return + # ensure section + if self.__config.has_section(section): + pass + else: + self.__config.add_section(section) + # do set + self.__config.set(section, option, value) + + def get_value(self, section, option, type_=str): + """Simple config value getter to avoid exception risk when getting + a config value. If the section and option exist, returns the + corresponding value, None otherwise. + + The `type_` parameter specify the expected option type and + return. + + :param section: section name of the expected value + :param option: option name name of the expected value + :param type_: type of the expected value. Default: str + :return: expected value in the expected type or None + :rtype: `object` + """ + # check has config + if self.__config is None: + return None + # check value exist + elif self.__config.has_section(section) \ + and self.__config.has_option(section, option): + # check expected value type + if type_ is int: + return self.__config.getint(section, option) + elif type_ is bool: + return self.__config.getboolean(section, option) + elif type_ is str: + return self.__config.get(section, option) + elif type_ is list: + _v = self.__config.get(section, option) + return _v.split(' ') + # unexpected type ?? + else: + return None + # value does not exist + else: + # do nothing + return None + + # singleton instance + instance = None + + def __new__(c, config=None, force=False): + """Singleton new init. + """ + # if doesn't already initialized + if not Config.instance \ + or force is True: + # create a new instance + Config.instance = Config.__Singleton(config=config) + # return the manager object + return Config.instance diff --git a/lib/server/flask/__init__.py b/lib/server/flask/__init__.py new file mode 100644 index 0000000..7d75791 --- /dev/null +++ b/lib/server/flask/__init__.py @@ -0,0 +1,5 @@ +# flask import +from flask import request, jsonify + +# server import +from server.flask._app import logger, app, render, run_app diff --git a/lib/server/flask/_app.py b/lib/server/flask/_app.py new file mode 100644 index 0000000..cb2d4c3 --- /dev/null +++ b/lib/server/flask/_app.py @@ -0,0 +1,57 @@ +# python import +import os, logging + +# common gettext import +from gettext import gettext + +# server import +from server import config + +# get APP_NAME or default name +APP_NAME = config.Config().get('activity>name') +APP_NAME = 'my_activity' if APP_NAME is None else APP_NAME + +# get app config values +_debug = config.Config().get('server>debug') +_key = config.Config().get('server>secret_key') + +# our activity root directory relative to the current one +PROJET_ROOT = os.path.join(os.path.dirname(__file__), '..', '..', '..') + +# flask import +import flask + +# init app +app = flask.Flask(__name__) +app.debug = True if _debug is None else _debug +app.secret_key = 'NO_KEY_OOPS' if _key is None else _key +# override jinja template path +app.jinja_loader.searchpath = [os.path.join(PROJET_ROOT, 'templates')] + +# init static folder path +from werkzeug import SharedDataMiddleware +app.wsgi_app = SharedDataMiddleware(app.wsgi_app, + {'/static': os.path.join(PROJET_ROOT, 'static')}) + +# set basic logging out of sugar +try: + import sugar + # get sugar logger + logger = logging.getLogger(APP_NAME) + logger.setLevel(logging.DEBUG) +except Exception: + # .. or flask logger + logger = app.logger + + +def run_app(): + """run method to trigger at from python class. + """ + app.run() + + +def render(template, **context): + """Crappy hack for gettext issue in templates! + """ + context['_'] = gettext + return flask.render_template(template, **context) |