Configuration moved to JSON and validated by JSON Schema
This commit is contained in:
parent
47bda266a4
commit
8ebed3cda6
21 changed files with 300 additions and 103 deletions
147
app/conf/schema.py
Normal file
147
app/conf/schema.py
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Created with https://app.quicktype.io
|
||||||
|
# name: stacosys
|
||||||
|
|
||||||
|
json_schema = """
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/Stacosys",
|
||||||
|
"definitions": {
|
||||||
|
"Stacosys": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"general": {
|
||||||
|
"$ref": "#/definitions/General"
|
||||||
|
},
|
||||||
|
"http": {
|
||||||
|
"$ref": "#/definitions/HTTP"
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"$ref": "#/definitions/Security"
|
||||||
|
},
|
||||||
|
"rss": {
|
||||||
|
"$ref": "#/definitions/RSS"
|
||||||
|
},
|
||||||
|
"zmq": {
|
||||||
|
"$ref": "#/definitions/Zmq"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"general",
|
||||||
|
"http",
|
||||||
|
"rss",
|
||||||
|
"security",
|
||||||
|
"zmq"
|
||||||
|
],
|
||||||
|
"title": "stacosys"
|
||||||
|
},
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"private": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"private",
|
||||||
|
"salt",
|
||||||
|
"secret"
|
||||||
|
],
|
||||||
|
"title": "security"
|
||||||
|
},
|
||||||
|
"Zmq": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"active": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"host": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"pub_port": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"sub_port": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"active",
|
||||||
|
"host",
|
||||||
|
"pub_port",
|
||||||
|
"sub_port"
|
||||||
|
],
|
||||||
|
"title": "zmq"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
|
@ -4,7 +4,12 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
from flask import Flask
|
||||||
from flask.ext.cors import CORS
|
from flask.ext.cors import CORS
|
||||||
|
from conf import config
|
||||||
|
from jsonschema import validate
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
# add current path and parent path to syspath
|
# add current path and parent path to syspath
|
||||||
current_path = os.path.dirname(__file__)
|
current_path = os.path.dirname(__file__)
|
||||||
|
@ -15,16 +20,12 @@ for path in paths:
|
||||||
sys.path.insert(0, path)
|
sys.path.insert(0, path)
|
||||||
|
|
||||||
# more imports
|
# more imports
|
||||||
import config
|
import database
|
||||||
from app.services import database
|
import processor
|
||||||
from app.services import processor
|
from interface import api
|
||||||
from app.interface import api
|
from interface import form
|
||||||
from app.interface import form
|
from interface import report
|
||||||
from app.interface import report
|
from interface import zclient
|
||||||
#from app.controllers import mail
|
|
||||||
from app.interface import zclient
|
|
||||||
from app import app
|
|
||||||
|
|
||||||
|
|
||||||
# configure logging
|
# configure logging
|
||||||
def configure_logging(level):
|
def configure_logging(level):
|
||||||
|
@ -40,7 +41,7 @@ def configure_logging(level):
|
||||||
# add ch to logger
|
# add ch to logger
|
||||||
root_logger.addHandler(ch)
|
root_logger.addHandler(ch)
|
||||||
|
|
||||||
logging_level = (20, 10)[config.DEBUG]
|
logging_level = (20, 10)[config.general['debug']]
|
||||||
configure_logging(logging_level)
|
configure_logging(logging_level)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -52,25 +53,23 @@ database.setup()
|
||||||
zclient.start()
|
zclient.start()
|
||||||
|
|
||||||
# start processor
|
# start processor
|
||||||
template_path = os.path.abspath(os.path.join(current_path, 'templates'))
|
template_path = os.path.abspath(os.path.join(current_path, '../templates'))
|
||||||
processor.start(template_path)
|
processor.start(template_path)
|
||||||
|
|
||||||
# less feature in private mode
|
# less feature in private mode
|
||||||
if not config.PRIVATE:
|
if not config.security['private']:
|
||||||
# enable CORS
|
# enable CORS
|
||||||
cors = CORS(app, resources={r"/comments/*": {"origins": "*"}})
|
cors = CORS(app, resources={r"/comments/*": {"origins": "*"}})
|
||||||
from app.controllers import reader
|
from app.controllers import reader
|
||||||
logger.debug('imported: %s ' % reader.__name__)
|
logger.debug('imported: %s ' % reader.__name__)
|
||||||
|
|
||||||
# tune logging level
|
# tune logging level
|
||||||
if not config.DEBUG:
|
if not config.general['debug']:
|
||||||
logging.getLogger('app.cors').level = logging.WARNING
|
logging.getLogger('app.cors').level = logging.WARNING
|
||||||
logging.getLogger('werkzeug').level = logging.WARNING
|
logging.getLogger('werkzeug').level = logging.WARNING
|
||||||
|
|
||||||
logger.info("Start Stacosys application")
|
logger.info("Start Stacosys application")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
app.run(host=config.http['host'],
|
||||||
|
port=config.http['port'],
|
||||||
app.run(host=config.HTTP_ADDRESS,
|
debug=config.general['debug'], use_reloader=False)
|
||||||
port=config.HTTP_PORT,
|
|
||||||
debug=config.DEBUG, use_reloader=False)
|
|
|
@ -1,13 +1,13 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
import config
|
from conf import config
|
||||||
import functools
|
import functools
|
||||||
from playhouse.db_url import connect
|
from playhouse.db_url import connect
|
||||||
|
|
||||||
|
|
||||||
def get_db():
|
def get_db():
|
||||||
return connect(config.DB_URL)
|
return connect(config.general['db_url'])
|
||||||
|
|
||||||
|
|
||||||
def provide_db(func):
|
def provide_db(func):
|
||||||
|
@ -21,9 +21,9 @@ def provide_db(func):
|
||||||
|
|
||||||
@provide_db
|
@provide_db
|
||||||
def setup(db):
|
def setup(db):
|
||||||
from app.models.site import Site
|
from models.site import Site
|
||||||
from app.models.comment import Comment
|
from models.comment import Comment
|
||||||
from app.models.reader import Reader
|
from models.reader import Reader
|
||||||
from app.models.report import Report
|
from models.report import Report
|
||||||
|
|
||||||
db.create_tables([Site, Comment, Reader, Report], safe=True)
|
db.create_tables([Site, Comment, Reader, Report], safe=True)
|
|
@ -9,21 +9,27 @@ from threading import Thread
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
from jinja2 import Environment
|
from jinja2 import Environment
|
||||||
from jinja2 import FileSystemLoader
|
from jinja2 import FileSystemLoader
|
||||||
from app.models.site import Site
|
from models.site import Site
|
||||||
from app.models.reader import Reader
|
from models.reader import Reader
|
||||||
from app.models.report import Report
|
from models.report import Report
|
||||||
from app.models.comment import Comment
|
from models.comment import Comment
|
||||||
from app.helpers.hashing import md5
|
from helpers.hashing import md5
|
||||||
import json
|
import json
|
||||||
import config
|
from conf import config
|
||||||
import PyRSS2Gen
|
import PyRSS2Gen
|
||||||
import markdown
|
import markdown
|
||||||
|
import zmq
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
proc = None
|
proc = None
|
||||||
env = None
|
env = None
|
||||||
|
|
||||||
|
if config.zmq['active']:
|
||||||
|
context = zmq.Context()
|
||||||
|
zpub = context.socket(zmq.PUB)
|
||||||
|
zpub.connect('tcp://127.0.0.1:{}'.format(config.zmq['sub_port']))
|
||||||
|
|
||||||
|
|
||||||
class Processor(Thread):
|
class Processor(Thread):
|
||||||
|
|
||||||
|
@ -69,7 +75,7 @@ def new_comment(data):
|
||||||
subscribe = data.get('subscribe', '')
|
subscribe = data.get('subscribe', '')
|
||||||
|
|
||||||
# private mode: email contains gravar md5 hash
|
# private mode: email contains gravar md5 hash
|
||||||
if config.PRIVATE:
|
if config.security['private']:
|
||||||
author_gravatar = author_email
|
author_gravatar = author_email
|
||||||
author_email = ''
|
author_email = ''
|
||||||
else:
|
else:
|
||||||
|
@ -112,7 +118,7 @@ def new_comment(data):
|
||||||
mail(site.admin_email, subject, email_body)
|
mail(site.admin_email, subject, email_body)
|
||||||
|
|
||||||
# Reader subscribes to further comments
|
# Reader subscribes to further comments
|
||||||
if not config.PRIVATE and subscribe and author_email:
|
if not config.security['private'] and subscribe and author_email:
|
||||||
subscribe_reader(author_email, token, url)
|
subscribe_reader(author_email, token, url)
|
||||||
|
|
||||||
logger.debug("new comment processed ")
|
logger.debug("new comment processed ")
|
||||||
|
@ -171,7 +177,7 @@ def reply_comment_email(data):
|
||||||
mail(from_email, 'Re: ' + subject, email_body)
|
mail(from_email, 'Re: ' + subject, email_body)
|
||||||
|
|
||||||
# notify reader once comment is published
|
# notify reader once comment is published
|
||||||
if not config.PRIVATE:
|
if not config.security['private']:
|
||||||
reader_email = get_email_metadata(message)
|
reader_email = get_email_metadata(message)
|
||||||
if reader_email:
|
if reader_email:
|
||||||
notify_reader(from_email, reader_email, comment.site.token,
|
notify_reader(from_email, reader_email, comment.site.token,
|
||||||
|
@ -258,7 +264,7 @@ def notify_subscribed_readers(token, site_url, url):
|
||||||
to_email = reader.email
|
to_email = reader.email
|
||||||
logger.info('notify reader %s' % to_email)
|
logger.info('notify reader %s' % to_email)
|
||||||
unsubscribe_url = '%s/unsubscribe?email=%s&token=%s&url=%s' % (
|
unsubscribe_url = '%s/unsubscribe?email=%s&token=%s&url=%s' % (
|
||||||
config.ROOT_URL, to_email, token, reader.url)
|
config.http['root_url'], to_email, token, reader.url)
|
||||||
email_body = get_template(
|
email_body = get_template(
|
||||||
'notify_subscriber').render(article_url=article_url,
|
'notify_subscriber').render(article_url=article_url,
|
||||||
unsubscribe_url=unsubscribe_url)
|
unsubscribe_url=unsubscribe_url)
|
||||||
|
@ -337,8 +343,8 @@ def report(token):
|
||||||
unsubscribed.append({'url': "http://" + site.url + row.url,
|
unsubscribed.append({'url': "http://" + site.url + row.url,
|
||||||
'name': row.name, 'email': row.email})
|
'name': row.name, 'email': row.email})
|
||||||
|
|
||||||
email_body = get_template('report').render(secret=config.SECRET,
|
email_body = get_template('report').render(secret=config.security['secret'],
|
||||||
root_url=config.ROOT_URL,
|
root_url=config.http['root_url'],
|
||||||
standbys=standbys,
|
standbys=standbys,
|
||||||
published=published,
|
published=published,
|
||||||
rejected=rejected,
|
rejected=rejected,
|
||||||
|
@ -354,7 +360,7 @@ def report(token):
|
||||||
|
|
||||||
def rss(token, onstart=False):
|
def rss(token, onstart=False):
|
||||||
|
|
||||||
if onstart and os.path.isfile(config.RSS_FILE):
|
if onstart and os.path.isfile(config.rss['file']):
|
||||||
return
|
return
|
||||||
|
|
||||||
site = Site.select().where(Site.token == token).get()
|
site = Site.select().where(Site.token == token).get()
|
||||||
|
@ -365,9 +371,9 @@ def rss(token, onstart=False):
|
||||||
for row in Comment.select().join(Site).where(
|
for row in Comment.select().join(Site).where(
|
||||||
Site.token == token, Comment.published).order_by(
|
Site.token == token, Comment.published).order_by(
|
||||||
-Comment.published).limit(10):
|
-Comment.published).limit(10):
|
||||||
item_link = "%s://%s%s" % (config.RSS_URL_PROTO, site.url, row.url)
|
item_link = "%s://%s%s" % (config.rss['proto'], site.url, row.url)
|
||||||
items.append(PyRSS2Gen.RSSItem(
|
items.append(PyRSS2Gen.RSSItem(
|
||||||
title='%s - %s://%s%s' % (config.RSS_URL_PROTO, row.author_name, site.url, row.url),
|
title='%s - %s://%s%s' % (config.rss['proto'], row.author_name, site.url, row.url),
|
||||||
link=item_link,
|
link=item_link,
|
||||||
description=md.convert(row.content),
|
description=md.convert(row.content),
|
||||||
guid=PyRSS2Gen.Guid('%s/%d' % (item_link, row.id)),
|
guid=PyRSS2Gen.Guid('%s/%d' % (item_link, row.id)),
|
||||||
|
@ -376,11 +382,11 @@ def rss(token, onstart=False):
|
||||||
|
|
||||||
rss = PyRSS2Gen.RSS2(
|
rss = PyRSS2Gen.RSS2(
|
||||||
title=rss_title,
|
title=rss_title,
|
||||||
link='%s://%s' % (config.RSS_URL_PROTO, site.url),
|
link='%s://%s' % (config.rss['proto'], site.url),
|
||||||
description="Commentaires du site '%s'" % site.name,
|
description="Commentaires du site '%s'" % site.name,
|
||||||
lastBuildDate=datetime.now(),
|
lastBuildDate=datetime.now(),
|
||||||
items=items)
|
items=items)
|
||||||
rss.write_xml(open(config.RSS_FILE, "w"), encoding="utf-8")
|
rss.write_xml(open(config.rss['file'], 'w'), encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
def mail(to_email, subject, message):
|
def mail(to_email, subject, message):
|
||||||
|
@ -400,7 +406,7 @@ def mail(to_email, subject, message):
|
||||||
|
|
||||||
|
|
||||||
def get_template(name):
|
def get_template(name):
|
||||||
return env.get_template(config.LANG + '/' + name + '.tpl')
|
return env.get_template(config.general['lang'] + '/' + name + '.tpl')
|
||||||
|
|
||||||
|
|
||||||
def enqueue(something):
|
def enqueue(something):
|
|
@ -2,11 +2,11 @@
|
||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import config
|
from conf import config
|
||||||
|
|
||||||
|
|
||||||
def salt(value):
|
def salt(value):
|
||||||
string = '%s%s' % (value, config.SALT)
|
string = '%s%s' % (value, config.security['salt'])
|
||||||
dk = hashlib.sha256(string.encode())
|
dk = hashlib.sha256(string.encode())
|
||||||
return dk.hexdigest()
|
return dk.hexdigest()
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,11 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import config
|
|
||||||
from flask import request, jsonify, abort
|
from flask import request, jsonify, abort
|
||||||
from app import app
|
from core import app
|
||||||
from app.models.site import Site
|
from models.site import Site
|
||||||
from app.models.comment import Comment
|
from models.comment import Comment
|
||||||
from app.services import processor
|
from core import processor
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,12 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import config
|
|
||||||
from flask import request, jsonify, abort, redirect
|
from flask import request, jsonify, abort, redirect
|
||||||
from app import app
|
from core import app
|
||||||
from app.models.site import Site
|
from models.site import Site
|
||||||
from app.models.comment import Comment
|
from models.comment import Comment
|
||||||
from app.helpers.hashing import md5
|
from helpers.hashing import md5
|
||||||
from app.services import processor
|
from core import processor
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from flask import request, abort
|
from flask import request, abort
|
||||||
from app import app
|
from core import app
|
||||||
from app.services import processor
|
from core import processor
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from flask import request, abort
|
from flask import request, abort
|
||||||
from app import app
|
from core import app
|
||||||
from app.services import processor
|
from core import processor
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import config
|
from conf import config
|
||||||
from flask import request, jsonify, abort
|
from flask import request, jsonify, abort
|
||||||
from app import app
|
from core import app
|
||||||
from app.models.site import Site
|
from models.site import Site
|
||||||
from app.models.comment import Comment
|
from models.comment import Comment
|
||||||
from app.helpers.hashing import md5
|
from helpers.hashing import md5
|
||||||
from app.services import processor
|
from core import processor
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ def report():
|
||||||
token = request.args.get('token', '')
|
token = request.args.get('token', '')
|
||||||
secret = request.args.get('secret', '')
|
secret = request.args.get('secret', '')
|
||||||
|
|
||||||
if secret != config.SECRET:
|
if secret != config.security['secret']:
|
||||||
logger.warn('Unauthorized request')
|
logger.warn('Unauthorized request')
|
||||||
abort(401)
|
abort(401)
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ def accept_comment():
|
||||||
id = request.args.get('comment', '')
|
id = request.args.get('comment', '')
|
||||||
secret = request.args.get('secret', '')
|
secret = request.args.get('secret', '')
|
||||||
|
|
||||||
if secret != config.SECRET:
|
if secret != config.security['secret']:
|
||||||
logger.warn('Unauthorized request')
|
logger.warn('Unauthorized request')
|
||||||
abort(401)
|
abort(401)
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ def reject_comment():
|
||||||
id = request.args.get('comment', '')
|
id = request.args.get('comment', '')
|
||||||
secret = request.args.get('secret', '')
|
secret = request.args.get('secret', '')
|
||||||
|
|
||||||
if secret != config.SECRET:
|
if secret != config.security['secret']:
|
||||||
logger.warn('Unauthorized request')
|
logger.warn('Unauthorized request')
|
||||||
abort(401)
|
abort(401)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ from conf import config
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
from app.services import processor
|
from core import processor
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ from peewee import CharField
|
||||||
from peewee import TextField
|
from peewee import TextField
|
||||||
from peewee import DateTimeField
|
from peewee import DateTimeField
|
||||||
from peewee import ForeignKeyField
|
from peewee import ForeignKeyField
|
||||||
from app.models.site import Site
|
from models.site import Site
|
||||||
from app.services.database import get_db
|
from core.database import get_db
|
||||||
|
|
||||||
|
|
||||||
class Comment(Model):
|
class Comment(Model):
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
from peewee import Model
|
from peewee import Model
|
||||||
from peewee import CharField
|
from peewee import CharField
|
||||||
from peewee import ForeignKeyField
|
from peewee import ForeignKeyField
|
||||||
from app.services.database import get_db
|
from core.database import get_db
|
||||||
from app.models.site import Site
|
from models.site import Site
|
||||||
|
|
||||||
|
|
||||||
class Reader(Model):
|
class Reader(Model):
|
||||||
|
|
|
@ -5,8 +5,8 @@ from peewee import Model
|
||||||
from peewee import CharField
|
from peewee import CharField
|
||||||
from peewee import BooleanField
|
from peewee import BooleanField
|
||||||
from peewee import ForeignKeyField
|
from peewee import ForeignKeyField
|
||||||
from app.services.database import get_db
|
from core.database import get_db
|
||||||
from app.models.site import Site
|
from models.site import Site
|
||||||
|
|
||||||
class Report(Model):
|
class Report(Model):
|
||||||
name = CharField()
|
name = CharField()
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
from peewee import Model
|
from peewee import Model
|
||||||
from peewee import CharField
|
from peewee import CharField
|
||||||
from app.services.database import get_db
|
from core.database import get_db
|
||||||
|
|
||||||
|
|
||||||
class Site(Model):
|
class Site(Model):
|
||||||
|
|
37
app/stacosys.py
Normal file
37
app/stacosys.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import json
|
||||||
|
from clize import clize, run
|
||||||
|
from jsonschema import validate
|
||||||
|
from conf import config, schema
|
||||||
|
|
||||||
|
def load_json(filename):
|
||||||
|
jsondoc = None
|
||||||
|
with open(filename, 'rt') as json_file:
|
||||||
|
jsondoc = json.loads(json_file.read())
|
||||||
|
return jsondoc
|
||||||
|
|
||||||
|
|
||||||
|
@clize
|
||||||
|
def stacosys_server(config_pathname):
|
||||||
|
|
||||||
|
# load and validate startup config
|
||||||
|
conf = load_json(config_pathname)
|
||||||
|
json_schema = json.loads(schema.json_schema)
|
||||||
|
v = validate(conf, json_schema)
|
||||||
|
print('validation: {}'.format(v))
|
||||||
|
|
||||||
|
# set configuration
|
||||||
|
config.general = conf['general']
|
||||||
|
config.http = conf['http']
|
||||||
|
config.security = conf['security']
|
||||||
|
config.rss = conf['rss']
|
||||||
|
config.zmq = conf['zmq']
|
||||||
|
|
||||||
|
# start application
|
||||||
|
from core import app
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
run(stacosys_server)
|
27
config.json
Normal file
27
config.json
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"general" : {
|
||||||
|
"debug": true,
|
||||||
|
"lang": "fr",
|
||||||
|
"db_url": "sqlite:///db.sqlite"
|
||||||
|
},
|
||||||
|
"http": {
|
||||||
|
"root_url": "http://localhost:8100",
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"port": 8100
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"salt": "BRRJRqXgGpXWrgTidBPcixIThHpDuKc0",
|
||||||
|
"secret": "Uqca5Kc8xuU6THz9",
|
||||||
|
"private": true
|
||||||
|
},
|
||||||
|
"rss": {
|
||||||
|
"proto": "http",
|
||||||
|
"file": "comments.xml"
|
||||||
|
},
|
||||||
|
"zmq": {
|
||||||
|
"active": true,
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"pub_port": 7701,
|
||||||
|
"sub_port": 7702
|
||||||
|
}
|
||||||
|
}
|
25
config.py
25
config.py
|
@ -1,25 +0,0 @@
|
||||||
# Configuration file
|
|
||||||
|
|
||||||
DEBUG = True
|
|
||||||
|
|
||||||
LANG = "fr"
|
|
||||||
|
|
||||||
# DB_URL = "mysql://stacosys_user:stacosys_password@localhost:3306/stacosys"
|
|
||||||
DB_URL = "sqlite:///db.sqlite"
|
|
||||||
|
|
||||||
MAIL_URL = "http://localhost:8025/mbox"
|
|
||||||
|
|
||||||
HTTP_ADDRESS = "127.0.0.1"
|
|
||||||
HTTP_PORT = 8100
|
|
||||||
HTTP_WORKERS = 1
|
|
||||||
|
|
||||||
SALT = "BRRJRqXgGpXWrgTidBPcixIThHpDuKc0"
|
|
||||||
|
|
||||||
SECRET = "Uqca5Kc8xuU6THz9"
|
|
||||||
|
|
||||||
ROOT_URL = 'http://localhost:8100'
|
|
||||||
|
|
||||||
RSS_URL_PROTO = 'http'
|
|
||||||
RSS_FILE = 'comments.xml'
|
|
||||||
|
|
||||||
PRIVATE = True
|
|
|
@ -1,11 +1,19 @@
|
||||||
|
attrs==17.4.0
|
||||||
chardet==3.0.4
|
chardet==3.0.4
|
||||||
click==6.7
|
click==6.7
|
||||||
|
clize==4.0.3
|
||||||
|
docutils==0.14
|
||||||
Flask==0.12.2
|
Flask==0.12.2
|
||||||
|
Flask-Cors==3.0.3
|
||||||
itsdangerous==0.24
|
itsdangerous==0.24
|
||||||
Jinja2==2.10
|
Jinja2==2.10
|
||||||
|
jsonschema==2.6.0
|
||||||
Markdown==2.6.11
|
Markdown==2.6.11
|
||||||
MarkupSafe==1.0
|
MarkupSafe==1.0
|
||||||
|
od==1.0
|
||||||
peewee==2.10.2
|
peewee==2.10.2
|
||||||
PyRSS2Gen==1.1
|
PyRSS2Gen==1.1
|
||||||
pyzmq==16.0.3
|
pyzmq==16.0.3
|
||||||
|
sigtools==2.0.1
|
||||||
|
six==1.11.0
|
||||||
Werkzeug==0.14.1
|
Werkzeug==0.14.1
|
||||||
|
|
2
run.sh
2
run.sh
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
python app/run.py "$@"
|
python app/stacosys.py "$@"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue