From b0f22f1af081ce5cb958548d2e2764afb1deccda Mon Sep 17 00:00:00 2001 From: Roland Haroutiounian Date: Wed, 3 May 2017 17:01:10 +0200 Subject: [PATCH] Added the Flask application implementation --- lodel/lodelsites/__init__.py | 0 lodel/lodelsites/lodelsite.py | 17 ++++++++++ lodel/lodelsites/utils.py | 20 ++++++++++++ lodel/utils/ini_files.py | 17 ++++++++++ lodel_app/__init__.py | 17 ++++++++++ lodel_app/config.ini | 2 ++ lodel_app/exceptions.py | 2 ++ lodel_app/views.py | 5 +++ lodeladmin.py | 9 ++++++ management/__init__.py | 2 ++ management/commands.py | 7 +++++ management/create_site.py | 58 +++++++++++++++++++++++++++++++++++ requirements.txt | 9 +++++- run.py | 5 +++ sites/__init__.py | 0 15 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 lodel/lodelsites/__init__.py create mode 100644 lodel/lodelsites/lodelsite.py create mode 100644 lodel/lodelsites/utils.py create mode 100644 lodel/utils/ini_files.py create mode 100644 lodel_app/__init__.py create mode 100644 lodel_app/config.ini create mode 100644 lodel_app/exceptions.py create mode 100644 lodel_app/views.py create mode 100644 lodeladmin.py create mode 100644 management/__init__.py create mode 100644 management/commands.py create mode 100644 management/create_site.py create mode 100644 run.py create mode 100644 sites/__init__.py diff --git a/lodel/lodelsites/__init__.py b/lodel/lodelsites/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lodel/lodelsites/lodelsite.py b/lodel/lodelsites/lodelsite.py new file mode 100644 index 0000000..c84d1d4 --- /dev/null +++ b/lodel/lodelsites/lodelsite.py @@ -0,0 +1,17 @@ +from lodel.utils.ini_files import ini_to_dict + +## @brief Represents a Lodel Site +# @note This class could inherit from Blueprint +class LodelSite(object): + + def __init__(self, settings_file): + self.settings_file = settings_file + + @property + def settings(self): + return ini_to_dict(self.settings_file) + + def config(self, state): + lodelsite_settings = self.settings + if lodelsite_settings: + state.app.config['sites'][lodelsite_settings['Description']['shortname']] = lodelsite_settings diff --git a/lodel/lodelsites/utils.py b/lodel/lodelsites/utils.py new file mode 100644 index 0000000..e05234f --- /dev/null +++ b/lodel/lodelsites/utils.py @@ -0,0 +1,20 @@ +import os + +## @brief Registers a lodelsite +# +# Each lodelsite is a Flask Blueprint. +# +# @param lodelapp Flask : application in which the lodelsite will be registered +# @param sitepath str +# @todo Use the main settings to get the lodelsites_main_module value +def register_lodelsites(lodelapp): + lodelsites_main_module = 'sites' + lodelsites_main_module_path = os.path.abspath(lodelsites_main_module) + + sitenames = os.listdir(lodelsites_main_module_path) + for sitename in sitenames: + # We check if the found item is a python package + if os.path.isfile('%s/%s/__init__.py' % (lodelsites_main_module_path, sitename)): + module = __import__('%s.%s' % (lodelsites_main_module, sitename), globals(), locals(), [sitename], 0) + bp = getattr(module, 'lodelsite_%s' % sitename) + lodelapp.register_blueprint(bp) diff --git a/lodel/utils/ini_files.py b/lodel/utils/ini_files.py new file mode 100644 index 0000000..b738772 --- /dev/null +++ b/lodel/utils/ini_files.py @@ -0,0 +1,17 @@ +from configparser import ConfigParser, MissingSectionHeaderError + +## @brief Returns a dictionary from an ini file content +# @param ini_file_path str +# @return dict +# @throw MissingSectionHeaderError +# @todo Implement a better way to deal with this exception +def ini_to_dict(ini_file_path): + result = {} + try: + config = ConfigParser() + config.read(ini_file_path) + result = config.__dict__['_sections'].copy() + except MissingSectionHeaderError as e: + pass + + return result diff --git a/lodel_app/__init__.py b/lodel_app/__init__.py new file mode 100644 index 0000000..7bbbe7d --- /dev/null +++ b/lodel_app/__init__.py @@ -0,0 +1,17 @@ +from flask import Flask +import os + +from lodel.lodelsites.utils import register_lodelsites +from lodel.utils.ini_files import ini_to_dict + + +lodel_app = Flask(__name__) +lodel_app.config['DEBUG'] = True +lodel_app.config['sites'] = {} +lodel_app.config.update(ini_to_dict(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.ini'))) + +# Lodelsites +register_lodelsites(lodel_app) + +# Main views +from .views import * diff --git a/lodel_app/config.ini b/lodel_app/config.ini new file mode 100644 index 0000000..e6d41a3 --- /dev/null +++ b/lodel_app/config.ini @@ -0,0 +1,2 @@ +[lodel] +sitename = Lodel2 \ No newline at end of file diff --git a/lodel_app/exceptions.py b/lodel_app/exceptions.py new file mode 100644 index 0000000..398c74d --- /dev/null +++ b/lodel_app/exceptions.py @@ -0,0 +1,2 @@ +class LodelFatalError(Exception): + pass diff --git a/lodel_app/views.py b/lodel_app/views.py new file mode 100644 index 0000000..f6429a5 --- /dev/null +++ b/lodel_app/views.py @@ -0,0 +1,5 @@ +from . import lodel_app + +@lodel_app.route("/") +def hello_world(): + return "Hello World" \ No newline at end of file diff --git a/lodeladmin.py b/lodeladmin.py new file mode 100644 index 0000000..ba015df --- /dev/null +++ b/lodeladmin.py @@ -0,0 +1,9 @@ +from flask_script import Manager +from lodel_app import lodel_app + +manager = Manager(lodel_app) + +from management import * + +if __name__ == "__main__": + manager.run() \ No newline at end of file diff --git a/management/__init__.py b/management/__init__.py new file mode 100644 index 0000000..371e215 --- /dev/null +++ b/management/__init__.py @@ -0,0 +1,2 @@ +from .commands import * +from .create_site import create_site diff --git a/management/commands.py b/management/commands.py new file mode 100644 index 0000000..f332bbd --- /dev/null +++ b/management/commands.py @@ -0,0 +1,7 @@ +# CLI Commands called by the lodeladmin module + +from lodeladmin import manager + +@manager.command +def hello(): + print("Hello, World!") diff --git a/management/create_site.py b/management/create_site.py new file mode 100644 index 0000000..1da6c10 --- /dev/null +++ b/management/create_site.py @@ -0,0 +1,58 @@ +import os + +from lodeladmin import manager +from flask.templating import render_template_string +from jinja2.exceptions import TemplateNotFound + + +## @brief Create a new Lodel site +# @param name str +# @todo dynamically define the lodelsites folder +@manager.command +def create_site(name, long_name=None): + os.mkdir("sites/%s" % name) + os.mkdir("sites/%s/templates" % name) + os.mkdir("sites/%s/templates/%s" % (name, name)) + + with open("sites/%s/__init__.py" % name, 'w') as init_file: + init_file.write(render_template_string("""from flask import Blueprint +from lodel.lodelsites.lodelsite import LodelSite + +import os + +settings_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "settings.ini") + +lodelsite = LodelSite(settings_file) +lodelsite_{{shortname}} = Blueprint( + lodelsite.settings['Description']['shortname'], + __name__, + template_folder=lodelsite.settings['Description']['templates_folder'], + url_prefix="/{{ shortname }}") +lodelsite_{{shortname}}.record_once(lodelsite.config) + +from .views import *""", **{'shortname':name})) + + with open("sites/%s/views.py" % name, "w") as views_file: + views_file.write(render_template_string("""from flask import render_template, abort, current_app +from jinja2 import TemplateNotFound + +from . import lodelsite_{{shortname}} + +@lodelsite_{{shortname}}.route('/', defaults={'page':'index'}) +@lodelsite_{{shortname}}.route('/{{ "" | safe }}') +def show(page): + try: + return render_template("{{ shortname }}/%s.html" % page, **{'settings': current_app.config['sites']['{{shortname}}']}) + except TemplateNotFound: + abort(404)""", **{'shortname':name})) + + with open("sites/%s/templates/%s/index.html" % (name, name), "w") as index_tpl: + index_tpl.write("{{ settings['Description']['name'] }}") + + with open("sites/%s/settings.ini" % name, "w") as settings_file: + settings_file.write(render_template_string("""[Description] +name={{ name }} +shortname={{ shortname }} +templates_folder=templates""", **{'name': name, 'shortname': name})) + + print("site %s created successfully" % name) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 0a961aa..84aedd4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,20 @@ +appdirs==1.4.3 astroid==1.4.4 +click==6.7 +Flask==0.12.1 +Flask-Script==2.0.5 itsdangerous==0.24 Jinja2==2.7.3 lazy-object-proxy==1.2.1 logilab-common==1.2.0 +lxml==3.6.0 MarkupSafe==0.23 +packaging==16.8 pep8==1.6.2 +pkg-resources==0.0.0 pylint==1.4.4 pymongo==2.7.2 +pyparsing==2.2.0 six==1.10.0 Werkzeug==0.9.6 wrapt==1.10.6 -lxml==3.6.0 diff --git a/run.py b/run.py new file mode 100644 index 0000000..ef4ac22 --- /dev/null +++ b/run.py @@ -0,0 +1,5 @@ +from lodel_app import lodel_app + + +if __name__ == "__main__": + lodel_app.run() \ No newline at end of file diff --git a/sites/__init__.py b/sites/__init__.py new file mode 100644 index 0000000..e69de29