remove cron tasks
This commit is contained in:
parent
185641e6d0
commit
5f28274706
10 changed files with 50 additions and 148 deletions
|
@ -3,7 +3,6 @@
|
||||||
[main]
|
[main]
|
||||||
lang = fr
|
lang = fr
|
||||||
db_sqlite_file = db.sqlite
|
db_sqlite_file = db.sqlite
|
||||||
newcomment_polling = 60
|
|
||||||
|
|
||||||
[site]
|
[site]
|
||||||
name = "My blog"
|
name = "My blog"
|
||||||
|
|
|
@ -6,9 +6,6 @@ import sqlite3
|
||||||
connection = sqlite3.connect("db.sqlite")
|
connection = sqlite3.connect("db.sqlite")
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
|
|
||||||
# What script performs:
|
|
||||||
# - first, remove site table: crash here if table doesn't exist (compatibility test without effort)
|
|
||||||
# - remove site_id colum from comment table
|
|
||||||
script = """
|
script = """
|
||||||
CREATE TABLE comment (
|
CREATE TABLE comment (
|
||||||
id INTEGER NOT NULL PRIMARY KEY,
|
id INTEGER NOT NULL PRIMARY KEY,
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
|
|
||||||
import sqlite3
|
|
||||||
import datetime
|
|
||||||
from ulid import ULID
|
|
||||||
|
|
||||||
# add column ulid
|
|
||||||
connection = sqlite3.connect("db.sqlite")
|
|
||||||
cursor = connection.cursor()
|
|
||||||
script = """
|
|
||||||
PRAGMA foreign_keys = OFF;
|
|
||||||
BEGIN TRANSACTION;
|
|
||||||
ALTER TABLE comment ADD ulid INTEGER;
|
|
||||||
COMMIT;
|
|
||||||
PRAGMA foreign_keys = ON;
|
|
||||||
"""
|
|
||||||
cursor.executescript(script)
|
|
||||||
connection.close()
|
|
||||||
|
|
||||||
# fill in ulid column
|
|
||||||
connection = sqlite3.connect("db.sqlite")
|
|
||||||
cursor = connection.cursor()
|
|
||||||
updates = []
|
|
||||||
for row in cursor.execute('SELECT * FROM comment'):
|
|
||||||
row_id = row[0]
|
|
||||||
string_created = row[2]
|
|
||||||
date_created = datetime.datetime.strptime(string_created, "%Y-%m-%d %H:%M:%S")
|
|
||||||
ulid = ULID.from_datetime(date_created)
|
|
||||||
update = "UPDATE comment SET ulid = " + str(int(ulid)) + " WHERE id = " + str(row_id)
|
|
||||||
print(update)
|
|
||||||
updates.append(update)
|
|
||||||
|
|
||||||
for update in updates:
|
|
||||||
pass
|
|
||||||
connection.execute(update)
|
|
||||||
connection.commit()
|
|
||||||
connection.close()
|
|
26
poetry.lock
generated
26
poetry.lock
generated
|
@ -54,6 +54,14 @@ docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
|
||||||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
|
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
|
||||||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"]
|
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "background"
|
||||||
|
version = "0.2.1"
|
||||||
|
description = "It does what it says it does."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backports.zoneinfo"
|
name = "backports.zoneinfo"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
@ -495,14 +503,6 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
six = ">=1.5"
|
six = ">=1.5"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "python-ulid"
|
|
||||||
version = "1.0.3"
|
|
||||||
description = "Universally Unique Lexicographically Sortable Identifier"
|
|
||||||
category = "main"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytz"
|
name = "pytz"
|
||||||
version = "2021.3"
|
version = "2021.3"
|
||||||
|
@ -696,7 +696,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.8"
|
python-versions = "^3.8"
|
||||||
content-hash = "24b77862cfbece0c68447f4d026bed51431e3a655a92dde2697368e758bfac89"
|
content-hash = "1062100a70ba0ca6a9f5db6470d0a980784af1d9b96d0bb681e1b65bacc204cf"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
appdirs = [
|
appdirs = [
|
||||||
|
@ -715,6 +715,10 @@ attrs = [
|
||||||
{file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
|
{file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
|
||||||
{file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
|
{file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
|
||||||
]
|
]
|
||||||
|
background = [
|
||||||
|
{file = "background-0.2.1-py3-none-any.whl", hash = "sha256:c230e2813c773f93ecae54281ce6b1b425c895c24599cc203b7f137e4d7c4802"},
|
||||||
|
{file = "background-0.2.1.tar.gz", hash = "sha256:4a5ed40b4a2a9f3340b1402862725d35016dc2490f95d89a2de47c3ddf215b91"},
|
||||||
|
]
|
||||||
"backports.zoneinfo" = [
|
"backports.zoneinfo" = [
|
||||||
{file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"},
|
{file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"},
|
||||||
{file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"},
|
{file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"},
|
||||||
|
@ -1008,10 +1012,6 @@ python-dateutil = [
|
||||||
{file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
|
{file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
|
||||||
{file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
|
{file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
|
||||||
]
|
]
|
||||||
python-ulid = [
|
|
||||||
{file = "python-ulid-1.0.3.tar.gz", hash = "sha256:5dd8b969312a40e2212cec9c1ad63f25d4b6eafd92ee3195883e0287b6e9d19e"},
|
|
||||||
{file = "python_ulid-1.0.3-py3-none-any.whl", hash = "sha256:8704dc20f547f531fe3a41d4369842d737a0f275403b909d0872e7ea0fe8d6f2"},
|
|
||||||
]
|
|
||||||
pytz = [
|
pytz = [
|
||||||
{file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"},
|
{file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"},
|
||||||
{file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"},
|
{file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"},
|
||||||
|
|
|
@ -18,7 +18,7 @@ requests = "^2.25.1"
|
||||||
coverage = "^5.5"
|
coverage = "^5.5"
|
||||||
peewee = "^3.14.8"
|
peewee = "^3.14.8"
|
||||||
tox = "^3.24.5"
|
tox = "^3.24.5"
|
||||||
python-ulid = "^1.0.3"
|
background = "^0.2.1"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
rope = "^0.16.0"
|
rope = "^0.16.0"
|
||||||
|
|
12
run.py
12
run.py
|
@ -2,7 +2,6 @@
|
||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import hashlib
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -14,7 +13,6 @@ from stacosys.db import database
|
||||||
from stacosys.interface import api
|
from stacosys.interface import api
|
||||||
from stacosys.interface import app
|
from stacosys.interface import app
|
||||||
from stacosys.interface import form
|
from stacosys.interface import form
|
||||||
from stacosys.interface import scheduler
|
|
||||||
from stacosys.interface.web import admin
|
from stacosys.interface.web import admin
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,20 +77,14 @@ def stacosys_server(config_pathname):
|
||||||
conf.get(ConfigParameter.SITE_ADMIN_EMAIL)
|
conf.get(ConfigParameter.SITE_ADMIN_EMAIL)
|
||||||
)
|
)
|
||||||
|
|
||||||
# configure scheduler
|
|
||||||
conf.put(ConfigParameter.SITE_TOKEN, hashlib.sha1(conf.get(ConfigParameter.SITE_NAME).encode('utf-8')).hexdigest())
|
|
||||||
scheduler.configure(
|
|
||||||
conf.get_int(ConfigParameter.COMMENT_POLLING),
|
|
||||||
conf.get(ConfigParameter.SITE_NAME),
|
|
||||||
mailer,
|
|
||||||
)
|
|
||||||
|
|
||||||
# inject config parameters into flask
|
# inject config parameters into flask
|
||||||
app.config.update(LANG=conf.get(ConfigParameter.LANG))
|
app.config.update(LANG=conf.get(ConfigParameter.LANG))
|
||||||
|
app.config.update(SITE_NAME=conf.get(ConfigParameter.SITE_NAME))
|
||||||
app.config.update(SITE_URL=conf.get(ConfigParameter.SITE_URL))
|
app.config.update(SITE_URL=conf.get(ConfigParameter.SITE_URL))
|
||||||
app.config.update(SITE_REDIRECT=conf.get(ConfigParameter.SITE_REDIRECT))
|
app.config.update(SITE_REDIRECT=conf.get(ConfigParameter.SITE_REDIRECT))
|
||||||
app.config.update(WEB_USERNAME=conf.get(ConfigParameter.WEB_USERNAME))
|
app.config.update(WEB_USERNAME=conf.get(ConfigParameter.WEB_USERNAME))
|
||||||
app.config.update(WEB_PASSWORD=conf.get(ConfigParameter.WEB_PASSWORD))
|
app.config.update(WEB_PASSWORD=conf.get(ConfigParameter.WEB_PASSWORD))
|
||||||
|
app.config.update(MAILER=mailer)
|
||||||
logger.info(f"start interfaces {api} {form} {admin}")
|
logger.info(f"start interfaces {api} {form} {admin}")
|
||||||
|
|
||||||
# start Flask
|
# start Flask
|
||||||
|
|
|
@ -9,7 +9,6 @@ import profig
|
||||||
class ConfigParameter(Enum):
|
class ConfigParameter(Enum):
|
||||||
DB_SQLITE_FILE = "main.db_sqlite_file"
|
DB_SQLITE_FILE = "main.db_sqlite_file"
|
||||||
LANG = "main.lang"
|
LANG = "main.lang"
|
||||||
COMMENT_POLLING = "main.newcomment_polling"
|
|
||||||
|
|
||||||
HTTP_HOST = "http.host"
|
HTTP_HOST = "http.host"
|
||||||
HTTP_PORT = "http.port"
|
HTTP_PORT = "http.port"
|
||||||
|
@ -24,7 +23,6 @@ class ConfigParameter(Enum):
|
||||||
|
|
||||||
SITE_NAME = "site.name"
|
SITE_NAME = "site.name"
|
||||||
SITE_URL = "site.url"
|
SITE_URL = "site.url"
|
||||||
SITE_TOKEN = "site.token"
|
|
||||||
SITE_ADMIN_EMAIL = "site.admin_email"
|
SITE_ADMIN_EMAIL = "site.admin_email"
|
||||||
SITE_REDIRECT = "site.redirect"
|
SITE_REDIRECT = "site.redirect"
|
||||||
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from stacosys.db import dao
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def submit_new_comment(site_name, mailer):
|
|
||||||
for comment in dao.find_not_notified_comments():
|
|
||||||
comment_list = (
|
|
||||||
"author: %s" % comment.author_name,
|
|
||||||
"site: %s" % comment.author_site,
|
|
||||||
"date: %s" % comment.created,
|
|
||||||
"url: %s" % comment.url,
|
|
||||||
"",
|
|
||||||
"%s" % comment.content,
|
|
||||||
"",
|
|
||||||
)
|
|
||||||
email_body = "\n".join(comment_list)
|
|
||||||
|
|
||||||
# send email to notify admin
|
|
||||||
subject = "STACOSYS %s" % site_name
|
|
||||||
if mailer.send(subject, email_body):
|
|
||||||
logger.debug("new comment processed ")
|
|
||||||
|
|
||||||
# save notification datetime
|
|
||||||
dao.notify_comment(comment)
|
|
||||||
else:
|
|
||||||
logger.warning("rescheduled. send mail failure " + subject)
|
|
|
@ -1,8 +1,8 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
import background
|
||||||
from flask import abort, redirect, request
|
from flask import abort, redirect, request
|
||||||
|
|
||||||
from stacosys.db import dao
|
from stacosys.db import dao
|
||||||
|
@ -13,7 +13,6 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@app.route("/newcomment", methods=["POST"])
|
@app.route("/newcomment", methods=["POST"])
|
||||||
def new_form_comment():
|
def new_form_comment():
|
||||||
|
|
||||||
data = request.form
|
data = request.form
|
||||||
logger.info("form data " + str(data))
|
logger.info("form data " + str(data))
|
||||||
|
|
||||||
|
@ -40,7 +39,10 @@ def new_form_comment():
|
||||||
abort(400)
|
abort(400)
|
||||||
|
|
||||||
# add a row to Comment table
|
# add a row to Comment table
|
||||||
dao.create_comment(url, author_name, author_site, author_gravatar, message)
|
comment = dao.create_comment(url, author_name, author_site, author_gravatar, message)
|
||||||
|
|
||||||
|
# send notification e-mail asynchronously
|
||||||
|
submit_new_comment(comment)
|
||||||
|
|
||||||
return redirect(app.config.get("SITE_REDIRECT"), code=302)
|
return redirect(app.config.get("SITE_REDIRECT"), code=302)
|
||||||
|
|
||||||
|
@ -51,3 +53,32 @@ def check_form_data(d):
|
||||||
return not filtered
|
return not filtered
|
||||||
|
|
||||||
|
|
||||||
|
@background.task
|
||||||
|
def submit_new_comment(comment):
|
||||||
|
comment_list = (
|
||||||
|
"Web admin interface: %s/web/admin" % app.config.get("SITE_URL"),
|
||||||
|
"",
|
||||||
|
"author: %s" % comment.author_name,
|
||||||
|
"site: %s" % comment.author_site,
|
||||||
|
"date: %s" % comment.created,
|
||||||
|
"url: %s" % comment.url,
|
||||||
|
"",
|
||||||
|
"%s" % comment.content,
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
email_body = "\n".join(comment_list)
|
||||||
|
|
||||||
|
# send email to notify admin
|
||||||
|
subject = "STACOSYS " + app.config.get("SITE_NAME")
|
||||||
|
if app.config.get("MAILER").send(subject, email_body):
|
||||||
|
logger.debug("new comment processed")
|
||||||
|
|
||||||
|
# save notification datetime
|
||||||
|
dao.notify_comment(comment)
|
||||||
|
else:
|
||||||
|
logger.warning("rescheduled. send mail failure " + subject)
|
||||||
|
|
||||||
|
|
||||||
|
@background.callback
|
||||||
|
def submit_new_comment_callback(future):
|
||||||
|
pass
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from flask_apscheduler import APScheduler
|
|
||||||
from stacosys.interface import app
|
|
||||||
|
|
||||||
|
|
||||||
class JobConfig(object):
|
|
||||||
|
|
||||||
JOBS: list = []
|
|
||||||
|
|
||||||
SCHEDULER_EXECUTORS = {"default": {"type": "threadpool", "max_workers": 1}}
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
new_comment_polling_seconds,
|
|
||||||
site_name,
|
|
||||||
mailer,
|
|
||||||
):
|
|
||||||
self.JOBS = [
|
|
||||||
{
|
|
||||||
"id": "submit_new_comment",
|
|
||||||
"func": "stacosys.core.cron:submit_new_comment",
|
|
||||||
"args": [site_name, mailer],
|
|
||||||
"trigger": "interval",
|
|
||||||
"seconds": new_comment_polling_seconds,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def configure(
|
|
||||||
comment_polling,
|
|
||||||
site_name,
|
|
||||||
mailer,
|
|
||||||
):
|
|
||||||
app.config.from_object(
|
|
||||||
JobConfig(
|
|
||||||
comment_polling,
|
|
||||||
site_name,
|
|
||||||
mailer,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
scheduler = APScheduler()
|
|
||||||
scheduler.init_app(app)
|
|
||||||
scheduler.start()
|
|
Loading…
Add table
Reference in a new issue