From 8ff21c615dbb8d3d9f4d97f31094cd4f587cb6a8 Mon Sep 17 00:00:00 2001 From: Lephe Date: Wed, 15 Jun 2022 11:23:58 +0100 Subject: [PATCH] program: add infrastructure for the progrank job (#114) * Add an automatic job every day at 4 AM to recompute the progrank of every program. Currently everyone gets progrank 0. [MIGRATION] This commit contains a new version of the schema. [SETUP] * Install flask-crontab (with pip) * Run `flask crontab add` to register the jobs --- REQUIREMENTS.md | 7 ++++- app/__init__.py | 5 ++++ app/jobs/__init__.py | 1 + app/jobs/update_progrank.py | 11 +++++++ app/models/program.py | 4 +++ app/templates/programs/index.html | 3 +- app/utils/filters/date.py | 3 ++ ..._program_add_progrank_score_and_update_.py | 30 +++++++++++++++++++ 8 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 app/jobs/__init__.py create mode 100644 app/jobs/update_progrank.py create mode 100644 migrations/versions/daa5d5913ef8_program_add_progrank_score_and_update_.py diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md index 6289a1f..6d4cec8 100644 --- a/REQUIREMENTS.md +++ b/REQUIREMENTS.md @@ -25,7 +25,12 @@ python-pyyaml python-slugify ``` +Non disponibles sur l'AUR, mais disponibles sur pip : +``` +flask-crontab (0.1.2) +``` + Optionnel: ``` -python-flask-debugtoolbar +python-flask-debugtoolbar (out-of-date sur l'AUR : bien installer la 0.13) ``` diff --git a/app/__init__.py b/app/__init__.py index e6b64da..2f960d7 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -4,6 +4,7 @@ from flask_migrate import Migrate from flask_login import LoginManager from flask_mail import Mail from flask_wtf.csrf import CSRFProtect +from flask_crontab import Crontab from config import FlaskApplicationSettings, V5Config app = Flask(__name__) @@ -17,6 +18,7 @@ db = SQLAlchemy(app) migrate = Migrate(app, db) mail = Mail(app) csrf = CSRFProtect(app) +crontab = Crontab(app) login = LoginManager(app) login.login_view = 'login' @@ -38,6 +40,9 @@ from app.utils import filters # Register processors from app import processors +# Register scheduled jobs +from app import jobs + # Enable flask-debug-toolbar if requested if V5Config.ENABLE_FLASK_DEBUG_TOOLBAR: from flask_debugtoolbar import DebugToolbarExtension diff --git a/app/jobs/__init__.py b/app/jobs/__init__.py new file mode 100644 index 0000000..9a77601 --- /dev/null +++ b/app/jobs/__init__.py @@ -0,0 +1 @@ +from app.jobs.update_progrank import update_progrank diff --git a/app/jobs/update_progrank.py b/app/jobs/update_progrank.py new file mode 100644 index 0000000..e475599 --- /dev/null +++ b/app/jobs/update_progrank.py @@ -0,0 +1,11 @@ +from app import db, crontab +from app.models.program import Program +from datetime import datetime + +@crontab.job(minute="0", hour="4") +def update_progrank(): + for p in Program.query.all(): + p.progrank = 0 + p.progrank_date = datetime.now() + db.session.merge(p) + db.session.commit() diff --git a/app/models/program.py b/app/models/program.py index ba291ad..46aef41 100644 --- a/app/models/program.py +++ b/app/models/program.py @@ -20,6 +20,10 @@ class Program(Post): thread = db.relationship('Thread', foreign_keys=thread_id, back_populates='owner_program') + # Progrank, and last date of progrank update + progrank = db.Column(db.Integer) + progrank_date = db.Column(db.DateTime) + # Implicit attributes: # * tags (inherited from Post) # * attachements (available at thread.top_comment.attachments) diff --git a/app/templates/programs/index.html b/app/templates/programs/index.html index 26fdc86..29ec171 100644 --- a/app/templates/programs/index.html +++ b/app/templates/programs/index.html @@ -17,12 +17,13 @@

Tous les programmes

- + {% for p in programs %} +
IDNomAuteurPublié leTags
IDNomAuteurPublié leProgrankTags
{{ p.id }} {{ p.name }} {{ p.author.name }} {{ p.date_created | dyndate }}{{ p.progrank }} {%- for tag in p.tags %} {{ tag.tag.pretty }} diff --git a/app/utils/filters/date.py b/app/utils/filters/date.py index a8155cc..93a2566 100644 --- a/app/utils/filters/date.py +++ b/app/utils/filters/date.py @@ -7,6 +7,9 @@ def filter_date(date, format="%Y-%m-%d à %H:%M"): Print a date in a human-readable format. """ + if date is None: + return "None" + if format == "dynamic": d = "1er" if date.day == 1 else int(date.day) m = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", diff --git a/migrations/versions/daa5d5913ef8_program_add_progrank_score_and_update_.py b/migrations/versions/daa5d5913ef8_program_add_progrank_score_and_update_.py new file mode 100644 index 0000000..7077a9b --- /dev/null +++ b/migrations/versions/daa5d5913ef8_program_add_progrank_score_and_update_.py @@ -0,0 +1,30 @@ +"""program: add progrank score and update date fields + +Revision ID: daa5d5913ef8 +Revises: 189bbc0e1543 +Create Date: 2022-06-15 11:14:30.745287 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'daa5d5913ef8' +down_revision = '189bbc0e1543' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('program', sa.Column('progrank', sa.Integer(), nullable=True)) + op.add_column('program', sa.Column('progrank_date', sa.DateTime(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('program', 'progrank_date') + op.drop_column('program', 'progrank') + # ### end Alembic commands ###