object-oriented and DI
This commit is contained in:
parent
ab54ab981a
commit
962e0d2e41
7 changed files with 110 additions and 100 deletions
|
@ -2,9 +2,9 @@
|
||||||
; Default configuration
|
; Default configuration
|
||||||
[main]
|
[main]
|
||||||
lang = fr
|
lang = fr
|
||||||
db_url = sqlite:///db.sqlite
|
db_url = db.sqlite
|
||||||
|
db_backup_json_file = db.json
|
||||||
newcomment_polling = 60
|
newcomment_polling = 60
|
||||||
db_file = db.json
|
|
||||||
|
|
||||||
[site]
|
[site]
|
||||||
name = "My blog"
|
name = "My blog"
|
||||||
|
|
67
run.py
67
run.py
|
@ -4,12 +4,16 @@
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask_apscheduler import APScheduler
|
from flask_apscheduler import APScheduler
|
||||||
|
|
||||||
from stacosys.conf import config
|
import stacosys.conf.config as config
|
||||||
|
from stacosys.core import database
|
||||||
|
from stacosys.core import rss
|
||||||
|
#from stacosys.interface import api
|
||||||
|
#from stacosys.interface import form
|
||||||
|
|
||||||
# configure logging
|
# configure logging
|
||||||
def configure_logging(level):
|
def configure_logging(level):
|
||||||
|
@ -18,7 +22,7 @@ def configure_logging(level):
|
||||||
ch = logging.StreamHandler()
|
ch = logging.StreamHandler()
|
||||||
ch.setLevel(level)
|
ch.setLevel(level)
|
||||||
# create formatter
|
# create formatter
|
||||||
formatter = logging.Formatter('[%(asctime)s] %(name)s %(levelname)s %(message)s')
|
formatter = logging.Formatter("[%(asctime)s] %(name)s %(levelname)s %(message)s")
|
||||||
# add formatter to ch
|
# add formatter to ch
|
||||||
ch.setFormatter(formatter)
|
ch.setFormatter(formatter)
|
||||||
# add ch to logger
|
# add ch to logger
|
||||||
|
@ -29,21 +33,21 @@ class JobConfig(object):
|
||||||
|
|
||||||
JOBS = []
|
JOBS = []
|
||||||
|
|
||||||
SCHEDULER_EXECUTORS = {'default': {'type': 'threadpool', 'max_workers': 4}}
|
SCHEDULER_EXECUTORS = {"default": {"type": "threadpool", "max_workers": 4}}
|
||||||
|
|
||||||
def __init__(self, imap_polling_seconds, new_comment_polling_seconds):
|
def __init__(self, imap_polling_seconds, new_comment_polling_seconds):
|
||||||
self.JOBS = [
|
self.JOBS = [
|
||||||
{
|
{
|
||||||
'id': 'fetch_mail',
|
"id": "fetch_mail",
|
||||||
'func': 'stacosys.core.cron:fetch_mail_answers',
|
"func": "stacosys.core.cron:fetch_mail_answers",
|
||||||
'trigger': 'interval',
|
"trigger": "interval",
|
||||||
'seconds': imap_polling_seconds,
|
"seconds": imap_polling_seconds,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id': 'submit_new_comment',
|
"id": "submit_new_comment",
|
||||||
'func': 'stacosys.core.cron:submit_new_comment',
|
"func": "stacosys.core.cron:submit_new_comment",
|
||||||
'trigger': 'interval',
|
"trigger": "interval",
|
||||||
'seconds': new_comment_polling_seconds,
|
"seconds": new_comment_polling_seconds,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -51,56 +55,49 @@ class JobConfig(object):
|
||||||
def stacosys_server(config_pathname):
|
def stacosys_server(config_pathname):
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
config.initialize(config_pathname, app)
|
|
||||||
|
conf = config.Config.load(config_pathname)
|
||||||
|
|
||||||
# configure logging
|
# configure logging
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
configure_logging(logging.INFO)
|
configure_logging(logging.INFO)
|
||||||
logging.getLogger('werkzeug').level = logging.WARNING
|
logging.getLogger("werkzeug").level = logging.WARNING
|
||||||
logging.getLogger('apscheduler.executors').level = logging.WARNING
|
logging.getLogger("apscheduler.executors").level = logging.WARNING
|
||||||
|
|
||||||
# initialize database
|
# initialize database
|
||||||
from stacosys.core import database
|
db = database.Database()
|
||||||
|
db.setup(conf.get(config.DB_URL))
|
||||||
|
|
||||||
database.setup()
|
|
||||||
database.dump_db()
|
|
||||||
|
|
||||||
# cron email fetcher
|
# cron email fetcher
|
||||||
app.config.from_object(
|
app.config.from_object(
|
||||||
JobConfig(
|
JobConfig(
|
||||||
config.get_int(config.IMAP_POLLING), config.get_int(config.COMMENT_POLLING)
|
conf.get_int(config.IMAP_POLLING), conf.get_int(config.COMMENT_POLLING)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
scheduler = APScheduler()
|
scheduler = APScheduler()
|
||||||
scheduler.init_app(app)
|
scheduler.init_app(app)
|
||||||
scheduler.start()
|
scheduler.start()
|
||||||
|
|
||||||
logger.info('Start Stacosys application')
|
logger.info("Start Stacosys application")
|
||||||
|
|
||||||
# generate RSS for all sites
|
# generate RSS for all sites
|
||||||
from stacosys.core import rss
|
rss_manager = rss.Rss(conf.get(config.LANG), conf.get(config.RSS_FILE), conf.get(config.RSS_PROTO))
|
||||||
|
rss_manager.generate_all()
|
||||||
rss.generate_all()
|
|
||||||
|
|
||||||
# start Flask
|
# start Flask
|
||||||
from stacosys.interface import api
|
#logger.info("Load interface %s" % api)
|
||||||
|
#logger.info("Load interface %s" % form)
|
||||||
logger.info('Load interface %s' % api)
|
|
||||||
|
|
||||||
from stacosys.interface import form
|
|
||||||
|
|
||||||
logger.info('Load interface %s' % form)
|
|
||||||
|
|
||||||
app.run(
|
app.run(
|
||||||
host=config.get(config.HTTP_HOST),
|
host=conf.get(config.HTTP_HOST),
|
||||||
port=config.get(config.HTTP_PORT),
|
port=conf.get(config.HTTP_PORT),
|
||||||
debug=False,
|
debug=False,
|
||||||
use_reloader=False,
|
use_reloader=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('config', help='config path name')
|
parser.add_argument("config", help="config path name")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
stacosys_server(args.config)
|
stacosys_server(args.config)
|
||||||
|
|
|
@ -2,23 +2,37 @@
|
||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
import json
|
import json
|
||||||
from playhouse.db_url import connect
|
from peewee import DatabaseProxy, Model
|
||||||
|
from playhouse.db_url import connect, SqliteDatabase
|
||||||
from playhouse.shortcuts import model_to_dict
|
from playhouse.shortcuts import model_to_dict
|
||||||
from tinydb import TinyDB
|
from tinydb import TinyDB
|
||||||
from stacosys.conf import config
|
from stacosys.conf import config
|
||||||
|
|
||||||
|
db = SqliteDatabase(None)
|
||||||
def get_db():
|
|
||||||
return connect(config.get(config.DB_URL))
|
|
||||||
|
|
||||||
|
|
||||||
def setup():
|
class BaseModel(Model):
|
||||||
from stacosys.model.site import Site
|
class Meta:
|
||||||
from stacosys.model.comment import Comment
|
database = db
|
||||||
|
|
||||||
get_db().create_tables([Site, Comment], safe=True)
|
|
||||||
if config.exists(config.DB_BACKUP_JSON_FILE):
|
class Database:
|
||||||
_backup_db(config.DB_BACKUP_JSON_FILE, Comment)
|
def get_db(self):
|
||||||
|
return db
|
||||||
|
|
||||||
|
def setup(self, db_url):
|
||||||
|
|
||||||
|
db.init(db_url)
|
||||||
|
db.connect()
|
||||||
|
|
||||||
|
from stacosys.model.site import Site
|
||||||
|
from stacosys.model.comment import Comment
|
||||||
|
|
||||||
|
db.create_tables([Site, Comment], safe=True)
|
||||||
|
|
||||||
|
|
||||||
|
# if config.exists(config.DB_BACKUP_JSON_FILE):
|
||||||
|
# _backup_db(config.DB_BACKUP_JSON_FILE, Comment)
|
||||||
|
|
||||||
|
|
||||||
def _tojson_model(comment):
|
def _tojson_model(comment):
|
||||||
|
@ -35,3 +49,4 @@ def _backup_db(db_file, Comment):
|
||||||
for comment in Comment.select():
|
for comment in Comment.select():
|
||||||
cc = _tojson_model(comment)
|
cc = _tojson_model(comment)
|
||||||
table.insert(cc)
|
table.insert(cc)
|
||||||
|
|
||||||
|
|
|
@ -6,49 +6,54 @@ from datetime import datetime
|
||||||
import markdown
|
import markdown
|
||||||
import PyRSS2Gen
|
import PyRSS2Gen
|
||||||
|
|
||||||
from stacosys.conf import config
|
import stacosys.conf.config as config
|
||||||
from stacosys.core.templater import get_template
|
from stacosys.core.templater import get_template
|
||||||
from stacosys.model.comment import Comment
|
from stacosys.model.comment import Comment
|
||||||
from stacosys.model.site import Site
|
from stacosys.model.site import Site
|
||||||
|
|
||||||
|
|
||||||
def generate_all():
|
class Rss:
|
||||||
|
def __init__(self, lang, rss_file, rss_proto):
|
||||||
|
self._lang = lang
|
||||||
|
self._rss_file = rss_file
|
||||||
|
self._rss_proto = rss_proto
|
||||||
|
|
||||||
for site in Site.select():
|
def generate_all(self):
|
||||||
generate_site(site.token)
|
|
||||||
|
|
||||||
|
for site in Site.select():
|
||||||
|
self._generate_site(site.token)
|
||||||
|
|
||||||
def generate_site(token):
|
def _generate_site(self, token):
|
||||||
|
|
||||||
site = Site.select().where(Site.token == token).get()
|
site = Site.select().where(Site.token == token).get()
|
||||||
rss_title = get_template('rss_title_message').render(site=site.name)
|
rss_title = get_template(self._lang, "rss_title_message").render(site=site.name)
|
||||||
md = markdown.Markdown()
|
md = markdown.Markdown()
|
||||||
|
|
||||||
items = []
|
items = []
|
||||||
for row in (
|
for row in (
|
||||||
Comment.select()
|
Comment.select()
|
||||||
.join(Site)
|
.join(Site)
|
||||||
.where(Site.token == token, Comment.published)
|
.where(Site.token == token, Comment.published)
|
||||||
.order_by(-Comment.published)
|
.order_by(-Comment.published)
|
||||||
.limit(10)
|
.limit(10)
|
||||||
):
|
):
|
||||||
item_link = '%s://%s%s' % (config.get(config.RSS_PROTO), site.url, row.url)
|
item_link = "%s://%s%s" % (self._rss_proto, site.url, row.url)
|
||||||
items.append(
|
items.append(
|
||||||
PyRSS2Gen.RSSItem(
|
PyRSS2Gen.RSSItem(
|
||||||
title='%s - %s://%s%s'
|
title="%s - %s://%s%s"
|
||||||
% (config.get(config.RSS_PROTO), row.author_name, site.url, row.url),
|
% (self._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)),
|
||||||
pubDate=row.published,
|
pubDate=row.published,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
rss = PyRSS2Gen.RSS2(
|
rss = PyRSS2Gen.RSS2(
|
||||||
title=rss_title,
|
title=rss_title,
|
||||||
link='%s://%s' % (config.get(config.RSS_PROTO), site.url),
|
link="%s://%s" % (self._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.get(config.RSS_FILE), 'w'), encoding='utf-8')
|
rss.write_xml(open(self._rss_file, "w"), encoding="utf-8")
|
||||||
|
|
|
@ -8,9 +8,9 @@ from jinja2 import Environment, FileSystemLoader
|
||||||
from stacosys.conf import config
|
from stacosys.conf import config
|
||||||
|
|
||||||
current_path = os.path.dirname(__file__)
|
current_path = os.path.dirname(__file__)
|
||||||
template_path = os.path.abspath(os.path.join(current_path, '../templates'))
|
template_path = os.path.abspath(os.path.join(current_path, "../templates"))
|
||||||
env = Environment(loader=FileSystemLoader(template_path))
|
env = Environment(loader=FileSystemLoader(template_path))
|
||||||
|
|
||||||
|
|
||||||
def get_template(name):
|
def get_template(lang, name):
|
||||||
return env.get_template(config.get(config.LANG) + '/' + name + '.tpl')
|
return env.get_template(lang + "/" + name + ".tpl")
|
||||||
|
|
|
@ -7,28 +7,24 @@ from peewee import TextField
|
||||||
from peewee import DateTimeField
|
from peewee import DateTimeField
|
||||||
from peewee import ForeignKeyField
|
from peewee import ForeignKeyField
|
||||||
from stacosys.model.site import Site
|
from stacosys.model.site import Site
|
||||||
from stacosys.core.database import get_db
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from stacosys.core.database import BaseModel
|
||||||
|
|
||||||
|
class Comment(BaseModel):
|
||||||
class Comment(Model):
|
|
||||||
url = CharField()
|
url = CharField()
|
||||||
created = DateTimeField()
|
created = DateTimeField()
|
||||||
notified = DateTimeField(null=True, default=None)
|
notified = DateTimeField(null=True, default=None)
|
||||||
published = DateTimeField(null=True, default=None)
|
published = DateTimeField(null=True, default=None)
|
||||||
author_name = CharField()
|
author_name = CharField()
|
||||||
author_site = CharField(default='')
|
author_site = CharField(default="")
|
||||||
author_gravatar = CharField(default='')
|
author_gravatar = CharField(default="")
|
||||||
content = TextField()
|
content = TextField()
|
||||||
site = ForeignKeyField(Site, related_name='site')
|
site = ForeignKeyField(Site, related_name="site")
|
||||||
|
|
||||||
class Meta:
|
|
||||||
database = get_db()
|
|
||||||
|
|
||||||
def notify_site_admin(self):
|
def notify_site_admin(self):
|
||||||
self.notified = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
self.notified = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def publish(self):
|
def publish(self):
|
||||||
self.published = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
self.published = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
self.save()
|
self.save()
|
||||||
|
|
|
@ -3,14 +3,11 @@
|
||||||
|
|
||||||
from peewee import Model
|
from peewee import Model
|
||||||
from peewee import CharField
|
from peewee import CharField
|
||||||
from stacosys.core.database import get_db
|
from stacosys.core.database import BaseModel
|
||||||
|
|
||||||
|
|
||||||
class Site(Model):
|
class Site(BaseModel):
|
||||||
name = CharField(unique=True)
|
name = CharField(unique=True)
|
||||||
url = CharField()
|
url = CharField()
|
||||||
token = CharField()
|
token = CharField()
|
||||||
admin_email = CharField()
|
admin_email = CharField()
|
||||||
|
|
||||||
class Meta:
|
|
||||||
database = get_db()
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue