mirror of https://github.com/kianby/stacosys
WIP
parent
637b00261a
commit
3c4a25e5ad
@ -1,3 +0,0 @@
|
||||
from flask import Flask
|
||||
|
||||
app = Flask(__name__)
|
@ -1,3 +1,48 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import profig
|
||||
|
||||
# constants
|
||||
FLASK_APP = "flask.app"
|
||||
|
||||
DB_URL = "main.db_url"
|
||||
|
||||
HTTP_HOST = "http.host"
|
||||
HTTP_PORT = "http.port"
|
||||
|
||||
SECURITY_SALT = "security.salt"
|
||||
SECURITY_SECRET = "security.secret"
|
||||
|
||||
MAIL_POLLING = "polling.newmail"
|
||||
COMMENT_POLLING = "polling.newcomment"
|
||||
|
||||
# variable
|
||||
params = dict()
|
||||
|
||||
|
||||
def initialize(config_pathname, flask_app):
|
||||
cfg = profig.Config(config_pathname)
|
||||
cfg.sync()
|
||||
params.update(cfg)
|
||||
params.update({FLASK_APP: flask_app})
|
||||
|
||||
|
||||
def get(key):
|
||||
return params[key]
|
||||
|
||||
|
||||
def getInt(key):
|
||||
return int(params[key])
|
||||
|
||||
|
||||
def _str2bool(v):
|
||||
return v.lower() in ("yes", "true", "t", "1")
|
||||
|
||||
|
||||
def getBool(key):
|
||||
return _str2bool(params[key])
|
||||
|
||||
|
||||
def flaskapp():
|
||||
return params[FLASK_APP]
|
||||
|
@ -1,115 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Created with https://app.quicktype.io
|
||||
# name: stacosys
|
||||
|
||||
json_schema = """
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-06/schema#",
|
||||
"$ref": "#/definitions/Welcome",
|
||||
"definitions": {
|
||||
"Welcome": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"general": {
|
||||
"$ref": "#/definitions/General"
|
||||
},
|
||||
"http": {
|
||||
"$ref": "#/definitions/HTTP"
|
||||
},
|
||||
"security": {
|
||||
"$ref": "#/definitions/Security"
|
||||
},
|
||||
"rss": {
|
||||
"$ref": "#/definitions/RSS"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"general",
|
||||
"http",
|
||||
"rss",
|
||||
"security"
|
||||
],
|
||||
"title": "Welcome"
|
||||
},
|
||||
"General": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"debug": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"lang": {
|
||||
"type": "string"
|
||||
},
|
||||
"db_url": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"db_url",
|
||||
"debug",
|
||||
"lang"
|
||||
],
|
||||
"title": "General"
|
||||
},
|
||||
"HTTP": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"root_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"host": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"host",
|
||||
"port",
|
||||
"root_url"
|
||||
],
|
||||
"title": "HTTP"
|
||||
},
|
||||
"RSS": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"proto": {
|
||||
"type": "string"
|
||||
},
|
||||
"file": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"file",
|
||||
"proto"
|
||||
],
|
||||
"title": "RSS"
|
||||
},
|
||||
"Security": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"salt": {
|
||||
"type": "string"
|
||||
},
|
||||
"secret": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"salt",
|
||||
"secret"
|
||||
],
|
||||
"title": "Security"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
@ -1,84 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
from flask import Flask
|
||||
from conf import config
|
||||
from jsonschema import validate
|
||||
from flask_apscheduler import APScheduler
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# add current path and parent path to syspath
|
||||
current_path = os.path.dirname(__file__)
|
||||
parent_path = os.path.abspath(os.path.join(current_path, os.path.pardir))
|
||||
paths = [current_path, parent_path]
|
||||
for path in paths:
|
||||
if path not in sys.path:
|
||||
sys.path.insert(0, path)
|
||||
|
||||
# more imports
|
||||
import database
|
||||
import processor
|
||||
from interface import api
|
||||
from interface import form
|
||||
|
||||
# configure logging
|
||||
def configure_logging(level):
|
||||
root_logger = logging.getLogger()
|
||||
root_logger.setLevel(level)
|
||||
ch = logging.StreamHandler()
|
||||
ch.setLevel(level)
|
||||
# create formatter
|
||||
formatter = logging.Formatter(
|
||||
'[%(asctime)s] %(name)s %(levelname)s %(message)s')
|
||||
# add formatter to ch
|
||||
ch.setFormatter(formatter)
|
||||
# add ch to logger
|
||||
root_logger.addHandler(ch)
|
||||
|
||||
logging_level = (20, 10)[config.general['debug']]
|
||||
configure_logging(logging_level)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Config(object):
|
||||
JOBS = [
|
||||
{
|
||||
'id': 'fetch_mail',
|
||||
'func': 'core.cron:fetch_mail_answers',
|
||||
'trigger': 'interval',
|
||||
'seconds': 120
|
||||
},
|
||||
{
|
||||
'id': 'submit_new_comment',
|
||||
'func': 'core.cron:submit_new_comment',
|
||||
'trigger': 'interval',
|
||||
'seconds': 60
|
||||
},
|
||||
]
|
||||
|
||||
# initialize database
|
||||
database.setup()
|
||||
|
||||
# start processor
|
||||
template_path = os.path.abspath(os.path.join(current_path, '../templates'))
|
||||
processor.start(template_path)
|
||||
|
||||
# cron
|
||||
app.config.from_object(Config())
|
||||
scheduler = APScheduler()
|
||||
scheduler.init_app(app)
|
||||
scheduler.start()
|
||||
|
||||
# tune logging level
|
||||
if not config.general['debug']:
|
||||
logging.getLogger('werkzeug').level = logging.WARNING
|
||||
|
||||
logger.info("Start Stacosys application")
|
||||
|
||||
app.run(host=config.http['host'],
|
||||
port=config.http['port'],
|
||||
debug=config.general['debug'], use_reloader=False)
|
@ -0,0 +1,16 @@
|
||||
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
from jinja2 import Environment
|
||||
from jinja2 import FileSystemLoader
|
||||
from conf import config
|
||||
|
||||
current_path = os.path.dirname(__file__)
|
||||
template_path = os.path.abspath(os.path.join(current_path, "../templates"))
|
||||
env = Environment(loader=FileSystemLoader(template_path))
|
||||
|
||||
|
||||
def get_template(name):
|
||||
return env.get_template(config.general["lang"] + "/" + name + ".tpl")
|
@ -1,36 +1,90 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
import os
|
||||
import logging
|
||||
import json
|
||||
from clize import Clize, run
|
||||
from jsonschema import validate
|
||||
from conf import config, schema
|
||||
from flask import Flask
|
||||
from flask_apscheduler import APScheduler
|
||||
from conf import config
|
||||
|
||||
# configure logging
|
||||
def configure_logging(level):
|
||||
root_logger = logging.getLogger()
|
||||
root_logger.setLevel(level)
|
||||
ch = logging.StreamHandler()
|
||||
ch.setLevel(level)
|
||||
# create formatter
|
||||
formatter = logging.Formatter("[%(asctime)s] %(name)s %(levelname)s %(message)s")
|
||||
# add formatter to ch
|
||||
ch.setFormatter(formatter)
|
||||
# add ch to logger
|
||||
root_logger.addHandler(ch)
|
||||
|
||||
def load_json(filename):
|
||||
jsondoc = None
|
||||
with open(filename, 'rt') as json_file:
|
||||
jsondoc = json.loads(json_file.read())
|
||||
return jsondoc
|
||||
|
||||
class JobConfig(object):
|
||||
|
||||
JOBS = []
|
||||
|
||||
def __init__(self, mail_polling_seconds, new_comment_polling_seconds):
|
||||
self.JOBS = [
|
||||
{
|
||||
"id": "fetch_mail",
|
||||
"func": "core.cron:fetch_mail_answers",
|
||||
"trigger": "interval",
|
||||
"seconds": mail_polling_seconds,
|
||||
},
|
||||
{
|
||||
"id": "submit_new_comment",
|
||||
"func": "core.cron:submit_new_comment",
|
||||
"trigger": "interval",
|
||||
"seconds": new_comment_polling_seconds,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@Clize
|
||||
def stacosys_server(config_pathname):
|
||||
|
||||
# load and validate startup config
|
||||
conf = load_json(config_pathname)
|
||||
json_schema = json.loads(schema.json_schema)
|
||||
validate(conf, json_schema)
|
||||
app = Flask(__name__)
|
||||
config.initialize(config_pathname, app)
|
||||
|
||||
# configure logging
|
||||
logger = logging.getLogger(__name__)
|
||||
configure_logging(logging.INFO)
|
||||
logging.getLogger("werkzeug").level = logging.WARNING
|
||||
|
||||
# initialize database
|
||||
from core import database
|
||||
|
||||
database.setup()
|
||||
|
||||
# start processor
|
||||
from core import processor
|
||||
|
||||
# cron email fetcher
|
||||
app.config.from_object(
|
||||
JobConfig(
|
||||
config.getInt(config.MAIL_POLLING), config.getInt(config.COMMENT_POLLING)
|
||||
)
|
||||
)
|
||||
scheduler = APScheduler()
|
||||
scheduler.init_app(app)
|
||||
scheduler.start()
|
||||
|
||||
logger.info("Start Stacosys application")
|
||||
|
||||
# start Flask
|
||||
from interface import api
|
||||
from interface import form
|
||||
|
||||
# set configuration
|
||||
config.general = conf['general']
|
||||
config.http = conf['http']
|
||||
config.security = conf['security']
|
||||
config.rss = conf['rss']
|
||||
app.run(
|
||||
host=config.get(config.HTTP_HOST),
|
||||
port=config.get(config.HTTP_PORT),
|
||||
debug=False,
|
||||
use_reloader=False,
|
||||
)
|
||||
|
||||
# start application
|
||||
from core import app
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
run(stacosys_server)
|
||||
|
@ -0,0 +1,21 @@
|
||||
; Default configuration
|
||||
[main]
|
||||
lang = fr
|
||||
db_url = sqlite:///db.sqlite
|
||||
|
||||
[http]
|
||||
root_url = http://localhost:8100
|
||||
host = 0.0.0.0
|
||||
port = 8100
|
||||
|
||||
[security]
|
||||
salt = BRRJRqXgGpXWrgTidBPcixIThHpDuKc0
|
||||
secret = Uqca5Kc8xuU6THz9
|
||||
|
||||
[rss]
|
||||
proto = http
|
||||
file = comments.xml
|
||||
|
||||
[polling]
|
||||
newmail = 15
|
||||
newcomment = 60
|
Loading…
Reference in New Issue