Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/lib/server
diff options
context:
space:
mode:
Diffstat (limited to 'lib/server')
-rw-r--r--lib/server/__init__.py2
-rw-r--r--lib/server/_server.py20
-rw-r--r--lib/server/config.py111
-rw-r--r--lib/server/flask/__init__.py5
-rw-r--r--lib/server/flask/_app.py57
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)