From 146de0f504a77c73b1756bb355bd3b86c4f0edfb Mon Sep 17 00:00:00 2001 From: thomaswoehlke <thomas.woehlke@gmail.com> Date: Sun, 25 Apr 2021 11:47:29 +0200 Subject: [PATCH] work --- data | 2 +- docs/BACKLOG.md | 2 +- src/__init__.py | 0 src/config.py | 3 + src/covid19/__init__.py | 12 ++- .../admin/templates/admin/admin_tasks.html | 6 ++ .../application/application_model.py | 5 ++ .../application/application_service.py | 33 ++++++++- .../application/application_services.py | 2 - .../application/application_views.py | 14 +--- .../application/application_workers.py | 18 ++--- .../user/templates/usr/user_info.html | 35 +-------- .../user/templates/usr/usr_table.html | 26 +++++++ src/covid19/blueprints/user/user_model.py | 6 +- src/covid19/blueprints/user/user_service.py | 14 ++++ src/covid19/blueprints/user/user_views.py | 10 ++- .../who/templates/who/who_tasks.html | 9 ++- src/covid19/blueprints/who/who_model.py | 27 ++++++- src/covid19/blueprints/who/who_views.py | 22 +++++- src/covid19/blueprints/who_test/__init__.py | 0 .../blueprints/who_test/who_test_service.py | 16 ++++ .../blueprints/who_test/who_test_views.py | 74 +++++++++++++++++++ 22 files changed, 258 insertions(+), 78 deletions(-) create mode 100644 src/__init__.py create mode 100644 src/covid19/blueprints/user/templates/usr/usr_table.html create mode 100644 src/covid19/blueprints/who_test/__init__.py create mode 100644 src/covid19/blueprints/who_test/who_test_service.py create mode 100644 src/covid19/blueprints/who_test/who_test_views.py diff --git a/data b/data index d77cd9f0..a56a0d7e 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit d77cd9f018d7587b57a1c7951d39eeddf92a6390 +Subproject commit a56a0d7e08039f512aad1c3f41aa7fd032b13438 diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index 137e369d..e84d6d74 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -297,7 +297,7 @@ * Issue #209 remove deprecated: database.ITEMS_PER_PAGE * ------------------------------------- * Issue #210 database.py: logging for Celery on Windows -*------------------------------------- +* ------------------------------------- * Issue #196 OwidImport.get_new_dates_reported_as_array() needs implementation * ------------------------------------- * Issue #212 implement OwidService.task_database_drop_create() diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/config.py b/src/config.py index 02a4c965..9fc4dff0 100644 --- a/src/config.py +++ b/src/config.py @@ -14,3 +14,6 @@ SQLALCHEMY_TRACK_MODIFICATIONS = True FLASK_ADMIN_SWATCH = 'superhero' FLASK_APP_DEBUGGER_ACTIVE = True PORT = 9090 +USER_ADMIN_LOGIN = 'admin@admin.de' +USER_ADMIN_USERNAME = 'admin' +USER_ADMIN_PASSWORD = 'pbkdf2:sha256:150000$O4SZaWF5$85ad348809215aa7fe0a16f79dc61228e7d0fb214c24df68b0745f1570ffc148' diff --git a/src/covid19/__init__.py b/src/covid19/__init__.py index a2b7f314..5549a515 100644 --- a/src/covid19/__init__.py +++ b/src/covid19/__init__.py @@ -1,13 +1,11 @@ -from database import app, run_run_with_debug, port +from database import app, run_run_with_debug, port, db import covid19.blueprints.application.application_views - +from covid19.blueprints.application.application_services import user_service +from covid19.blueprints.application.application_service import ApplicationService def run_web(): - app.logger.info(" ") - app.logger.info("#############################################################") - app.logger.info("# Covid19 Data - WEB #") - app.logger.info("#############################################################") - app.logger.info(" ") + application_service = ApplicationService(db, user_service) + application_service.prepare_run_web() app.run(debug=run_run_with_debug, port=port) diff --git a/src/covid19/blueprints/admin/templates/admin/admin_tasks.html b/src/covid19/blueprints/admin/templates/admin/admin_tasks.html index fccabeef..f4c149fe 100644 --- a/src/covid19/blueprints/admin/templates/admin/admin_tasks.html +++ b/src/covid19/blueprints/admin/templates/admin/admin_tasks.html @@ -33,6 +33,12 @@ href="{{ url_for( 'app_admin.url_admin_index') }}" role="button">Admin :: database :: Flask Admin</a> </div> + <p></p> + <div class="btn-group-vertical" role="group" aria-label="Views"> + <a class="btn btn-primary btn-lg btn-block text-left" + href="{{ url_for( 'who.url_who_mytest') }}" + role="button">WHO :: url_who_mytest</a> + </div> </div> <div class="col"> <div class="btn-group-vertical" role="group" aria-label="Views"> diff --git a/src/covid19/blueprints/application/application_model.py b/src/covid19/blueprints/application/application_model.py index 36b4451c..7fa4adfb 100644 --- a/src/covid19/blueprints/application/application_model.py +++ b/src/covid19/blueprints/application/application_model.py @@ -158,6 +158,11 @@ class ApplicationDateReported(db.Model): .filter(cls.year_week == year_week)\ .one_or_none() + @classmethod + def get_joungest_datum(cls): + return db.session.query(cls)\ + .order_by(cls.date_reported.desc())\ + .first() class ApplicationRegion(db.Model): __tablename__ = 'application_region' diff --git a/src/covid19/blueprints/application/application_service.py b/src/covid19/blueprints/application/application_service.py index 8ea7186e..b5b45577 100644 --- a/src/covid19/blueprints/application/application_service.py +++ b/src/covid19/blueprints/application/application_service.py @@ -1,11 +1,36 @@ from database import app - class ApplicationService: - def __init__(self, database): + def __init__(self, database, user_service): app.logger.debug("------------------------------------------------------------") - app.logger.debug(" Common Service [init]") + app.logger.debug(" Application Service [init]") app.logger.debug("------------------------------------------------------------") self.__database = database + self.__user_service = user_service app.logger.debug("------------------------------------------------------------") - app.logger.info(" Common Service [ready]") + app.logger.info(" Application Service [ready]") + + def prepare_run_web(self): + app.logger.info(" ") + app.logger.info("#############################################################") + app.logger.info("# Covid19 Data - WEB #") + app.logger.info("#############################################################") + app.logger.info(" ") + self.__user_service.prepare_default_user_login() + app.logger.info(" ") + + def prepare_run_mq(self): + app.logger.info(" ") + app.logger.info("#############################################################") + app.logger.info("# Covid19 Data - MQ (Celery WORKER) #") + app.logger.info("#############################################################") + app.logger.info(" ") + self.__user_service.prepare_default_user_login() + app.logger.info(" ") + + def prepare_start_redis(selfs): + my_app.logger.info("-------------------------------------------------------------") + my_app.logger.info("# start REDIS-Server #") + my_app.logger.info("-------------------------------------------------------------") + + diff --git a/src/covid19/blueprints/application/application_services.py b/src/covid19/blueprints/application/application_services.py index 276c3581..4c13000b 100644 --- a/src/covid19/blueprints/application/application_services.py +++ b/src/covid19/blueprints/application/application_services.py @@ -1,7 +1,6 @@ from database import db from covid19.blueprints.admin.admin_service import AdminService -from covid19.blueprints.application.application_service import ApplicationService from covid19.blueprints.ecdc.ecdc_service import EcdcService from covid19.blueprints.owid.owid_service import OwidService from covid19.blueprints.rki.rki_bundeslaender.rki_bundeslaender_service import RkiBundeslaenderService @@ -16,7 +15,6 @@ from covid19.blueprints.user.user_service import UserService # Services # admin_service = AdminService(db) -application_service = ApplicationService(db) ecdc_service = EcdcService(db) owid_service = OwidService(db) rki_service_bundeslaender = RkiBundeslaenderService(db) diff --git a/src/covid19/blueprints/application/application_views.py b/src/covid19/blueprints/application/application_views.py index c6c0cd78..7133a95a 100644 --- a/src/covid19/blueprints/application/application_views.py +++ b/src/covid19/blueprints/application/application_views.py @@ -1,17 +1,8 @@ from flask import render_template, redirect, url_for, Blueprint -from flask_admin.contrib.sqla import ModelView -from database import app, admin, db +from database import app from covid19.blueprints.application.application_model_transient import ApplicationPage -import covid19.blueprints.admin.admin_views -import covid19.blueprints.ecdc.ecdc_views -import covid19.blueprints.rki.rki_bundeslaender.rki_bundeslaender_views -import covid19.blueprints.rki.rki_landkreise.rki_landkreise_views -import covid19.blueprints.rki.rki_vaccination.rki_vaccination_views -import covid19.blueprints.who.who_views - - from covid19.blueprints.admin.admin_views import app_admin from covid19.blueprints.ecdc.ecdc_views import app_ecdc from covid19.blueprints.rki.rki_bundeslaender.rki_bundeslaender_views import app_rki_bundeslaender @@ -21,6 +12,8 @@ from covid19.blueprints.who.who_views import app_who from covid19.blueprints.owid.owid_views import app_owid from covid19.blueprints.user.user_views import app_user +from covid19.blueprints.who_test.who_test_views import app_who_test + app_application = Blueprint('application', __name__, template_folder='templates', url_prefix='/') app.register_blueprint(app_admin, url_prefix='/admin') @@ -33,6 +26,7 @@ app.register_blueprint(app_who, url_prefix='/who') app.register_blueprint(app_owid, url_prefix='/owid') app.register_blueprint(app_user, url_prefix='/usr') +app.register_blueprint(app_who_test, url_prefix='/who/test') ############################################################################################ # diff --git a/src/covid19/blueprints/application/application_workers.py b/src/covid19/blueprints/application/application_workers.py index 40e7c2a9..f6809d65 100644 --- a/src/covid19/blueprints/application/application_workers.py +++ b/src/covid19/blueprints/application/application_workers.py @@ -1,21 +1,17 @@ import sys import subprocess from covid19 import app -from database import create_celery, run_run_with_debug, port - +from database import create_celery, run_run_with_debug, port, db +from covid19.blueprints.application.application_services import user_service +from covid19.blueprints.application.application_service import ApplicationService def run_mq(my_app, my_celery): + application_service = ApplicationService(db, user_service) if sys.platform != 'linux': - my_app.logger.info("-------------------------------------------------------------") - my_app.logger.info("# start REDIS-Server #") - my_app.logger.info("-------------------------------------------------------------") + application_service.prepare_start_redis() redis_cmd = ['redis-server'] - subprocess.Popen(redis_cmd, shell=True) - my_app.logger.info(" ") - my_app.logger.info("#############################################################") - my_app.logger.info("# Covid19 Data - WORKER #") - my_app.logger.info("#############################################################") - my_app.logger.info(" ") + # subprocess.Popen(redis_cmd, shell=True) + application_service.prepare_run_mq() args = ['worker', '-l', 'INFO'] my_celery.start(args) diff --git a/src/covid19/blueprints/user/templates/usr/user_info.html b/src/covid19/blueprints/user/templates/usr/user_info.html index 911c629e..66af388f 100644 --- a/src/covid19/blueprints/user/templates/usr/user_info.html +++ b/src/covid19/blueprints/user/templates/usr/user_info.html @@ -7,38 +7,9 @@ <div class="container"> <div class="row"> <div class="col"> - <div class="card"> - <div class="card-body"> - <div class="card-title"> - User - </div> - <div class="card-text"> - Coronavirus Pandemic (COVID-19) - </div> - <div class="card-text"> - <a class="btn btn-primary" href="https://ourworldindata.org/coronavirus"> - https://ourworldindata.org/coronavirus - </a> - </div> - </div> - </div> - </div> - <div class="col"> - <div class="card"> - <div class="card-body"> - <div class="card-title"> - n.n - </div> - <div class="card-text"> - n.n - </div> - <div class="card-text"> - <a class="btn btn-primary" href="https://ourworldindata.org/coronavirus"> - n.n - </a> - </div> - </div> - </div> + {% if current_user.is_authenticated %} + {% include 'usr/usr_table.html' %} + {% endif %} </div> </div> </div> diff --git a/src/covid19/blueprints/user/templates/usr/usr_table.html b/src/covid19/blueprints/user/templates/usr/usr_table.html new file mode 100644 index 00000000..d926a5ae --- /dev/null +++ b/src/covid19/blueprints/user/templates/usr/usr_table.html @@ -0,0 +1,26 @@ + <table class="table table-hover table-striped table-dark"> + <thead class="table-secondary"> + <tr> + <th scope="col" class="text-right">Email</th> + <th scope="col" class="text-left">Name</th> + </tr> + </thead> + <tbody> + {% for usr in page_data.items %} + <tr> + <td class="text-right"> + {{ usr.email }} + </td> + <td class="text-left"> + {{ usr.name }} + </td> + </tr> + {% endfor %} + </tbody> + <tfoot class="table-secondary"> + <tr> + <th scope="col" class="text-right">Email</th> + <th scope="col" class="text-left">Name</th> + </tr> + </tfoot> + </table> \ No newline at end of file diff --git a/src/covid19/blueprints/user/user_model.py b/src/covid19/blueprints/user/user_model.py index 050fe148..9fbf6eb7 100644 --- a/src/covid19/blueprints/user/user_model.py +++ b/src/covid19/blueprints/user/user_model.py @@ -25,6 +25,10 @@ class User(UserMixin, db.Model): def check_password(self, password): return check_password_hash(self.password_hash, password) + @classmethod + def count(cls): + return db.session.query(cls).count() + @classmethod def remove_all(cls): for one in cls.get_all(): @@ -43,7 +47,7 @@ class User(UserMixin, db.Model): @classmethod def get_by_id(cls, other_id): my_other_id = int(other_id) - return db.session.query(cls).filter(cls.id == my_other_id).one() + return db.session.query(cls).filter(cls.id == my_other_id).one_or_none() class AnonymousUserValueObject(AnonymousUserMixin): diff --git a/src/covid19/blueprints/user/user_service.py b/src/covid19/blueprints/user/user_service.py index 72e33fe3..61ce8719 100644 --- a/src/covid19/blueprints/user/user_service.py +++ b/src/covid19/blueprints/user/user_service.py @@ -21,3 +21,17 @@ class UserService: user.password = form.password return user + def prepare_default_user_login(self): + app.logger.info(" UserService.prepare_default_user_login()") + if User.count() == 0: + app.logger.info("User.count() == 0") + login = app.config['USER_ADMIN_LOGIN'] + name = app.config['USER_ADMIN_USERNAME'] + pw = app.config['USER_ADMIN_PASSWORD'] + user = User(email=login, name=name, password_hash=pw) + self.__database.session.add(user) + self.__database.session.commit() + else: + app.logger.info("User.count() > 0") + + diff --git a/src/covid19/blueprints/user/user_views.py b/src/covid19/blueprints/user/user_views.py index fceb5e67..76eafe67 100644 --- a/src/covid19/blueprints/user/user_views.py +++ b/src/covid19/blueprints/user/user_views.py @@ -79,12 +79,18 @@ def unauthorized(): # Url Routes Frontend # --------------------------------------------------------------------------------------------------------------- - +@app_user.route('/info/page/<int:page>') @app_user.route('/info') -def url_user_info(): +def url_user_info(page=1): page_info = ApplicationPage('usr', "Info") + try: + page_data = User.get_all_as_page(page) + except OperationalError: + flash("No data in the database.") + page_data = None return render_template( 'usr/user_info.html', + page_data=page_data, page_info=page_info) diff --git a/src/covid19/blueprints/who/templates/who/who_tasks.html b/src/covid19/blueprints/who/templates/who/who_tasks.html index 580850ce..60fe85f0 100644 --- a/src/covid19/blueprints/who/templates/who/who_tasks.html +++ b/src/covid19/blueprints/who/templates/who/who_tasks.html @@ -17,8 +17,13 @@ </div> <div class="btn-group-vertical" role="group" aria-label="Views"> <a class="btn btn-primary btn-lg btn-block text-left" - href="{{ url_for( 'who.url_who_mytest') }}" - role="button">WHO :: url_who_mytest</a> + href="{{ url_for( 'who_test.url_who_test_who_import_get_new_dates_as_array') }}" + role="button">WHO :: url_who_test_who_import_get_new_dates_as_array</a> + </div> + <div class="btn-group-vertical" role="group" aria-label="Views"> + <a class="btn btn-primary btn-lg btn-block text-left" + href="{{ url_for( 'who_test.url_who_test_who_import_countries') }}" + role="button">WHO :: url_who_test_who_import_countries</a> </div> </div> <div class="col"> diff --git a/src/covid19/blueprints/who/who_model.py b/src/covid19/blueprints/who/who_model.py index 849b0d4c..158e1ca0 100644 --- a/src/covid19/blueprints/who/who_model.py +++ b/src/covid19/blueprints/who/who_model.py @@ -68,7 +68,7 @@ class WhoCountry(db.Model): region = db.relationship( 'WhoRegion', lazy='joined', - cascade='all, delete', + cascade='all', order_by='WhoRegion.region') def __str__(self): @@ -173,14 +173,14 @@ class WhoData(db.Model): date_reported = db.relationship( 'WhoDateReported', lazy='joined', - cascade='all, delete', + cascade='all', order_by='desc(WhoDateReported.date_reported)') country_id = db.Column(db.Integer, db.ForeignKey('who_country.id'), nullable=False) country = db.relationship( 'WhoCountry', lazy='joined', - cascade='all, delete', + cascade='all', order_by='asc(WhoCountry.country)') @classmethod @@ -234,6 +234,27 @@ class WhoData(db.Model): cls.cases_cumulative.desc() ).paginate(page, per_page=ITEMS_PER_PAGE) + @classmethod + def get_data_for_one_day(cls, date_reported): + return db.session.query(cls).filter( + cls.date_reported_id == date_reported.id + ).populate_existing().options( + joinedload(cls.country).joinedload(WhoCountry.region), + joinedload(cls.date_reported) + ).order_by( + cls.deaths_new.desc(), + cls.cases_new.desc(), + cls.deaths_cumulative.desc(), + cls.cases_cumulative.desc() + ).all() + + @classmethod + def delete_data_for_one_day(cls, date_reported): + for one_who_date in cls.get_data_for_one_day(date_reported): + db.session.delete(one_who_date) + db.session.commit() + return None + @classmethod def get_data_for_day_order_by_cases_new(cls, date_reported, page): return db.session.query(cls).filter( diff --git a/src/covid19/blueprints/who/who_views.py b/src/covid19/blueprints/who/who_views.py index ea1cd87c..5842d149 100644 --- a/src/covid19/blueprints/who/who_views.py +++ b/src/covid19/blueprints/who/who_views.py @@ -325,13 +325,31 @@ def url_who_germany(page: int = 1): @app_who.route('/mytest') def url_who_mytest(): - flash("url_who_mytest - Start") + flash("url_who_mytest - START: WhoImport.countries()") + app.logger.info("url_who_mytest - START: WhoImport.countries()") i = 0 for c in WhoImport.countries(): i += 1 line = " | " + str(i) + " | " + c.countries.country_code + " | " + c.countries.country + " | " + c.countries.who_region + " | " app.logger.info(line) - flash("url_who_mytest - Done") + flash("url_who_mytest - DONE: WhoImport.countries()") + app.logger.info("url_who_mytest - DONE: WhoImport.countries()") + flash("url_who_mytest - START: WhoImport.get_new_dates_as_array()") + app.logger.info("url_who_mytest - START: WhoImport.get_new_dates_as_array()") + i = 0 + for date_reported in WhoImport.get_new_dates_as_array(): + i += 1 + line = " | " + str(i) + " | " + date_reported + " | " + app.logger.info(line) + joungest_datum = WhoDateReported.get_joungest_datum() + app.logger.info(joungest_datum) + i = 0 + for who_data in WhoData.get_data_for_one_day(joungest_datum): + i += 1 + line = " | " + str(i) + " | " + str(who_data.date_reported) + " | " + who_data.country.country + " | " + app.logger.info(line) + flash("url_who_mytest - DONE: WhoImport.get_new_dates_as_array()") + app.logger.info("url_who_mytest - DONE: WhoImport.get_new_dates_as_array()") return redirect(url_for('who.url_who_tasks')) # ---------------------------------------------------------------------------------------------------------------- diff --git a/src/covid19/blueprints/who_test/__init__.py b/src/covid19/blueprints/who_test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/covid19/blueprints/who_test/who_test_service.py b/src/covid19/blueprints/who_test/who_test_service.py new file mode 100644 index 00000000..a406f658 --- /dev/null +++ b/src/covid19/blueprints/who_test/who_test_service.py @@ -0,0 +1,16 @@ +from flask import flash + +from database import app +from covid19.blueprints.application.application_service_config import ApplicationServiceConfig + +class WhoTestService: + def __init__(self, database): + app.logger.debug("------------------------------------------------------------") + app.logger.debug(" WHO Test Service [init]") + app.logger.debug("------------------------------------------------------------") + self.__database = database + self.cfg = ApplicationServiceConfig.create_config_for_who() + app.logger.debug("------------------------------------------------------------") + app.logger.info(" WHO Test Service [ready]") + + diff --git a/src/covid19/blueprints/who_test/who_test_views.py b/src/covid19/blueprints/who_test/who_test_views.py new file mode 100644 index 00000000..609a680d --- /dev/null +++ b/src/covid19/blueprints/who_test/who_test_views.py @@ -0,0 +1,74 @@ +from flask import render_template, redirect, url_for, flash, Blueprint +from sqlalchemy.exc import OperationalError +from celery import states +from celery.utils.log import get_task_logger +from flask_admin.contrib.sqla import ModelView +from flask_login import login_required + +from database import app, admin, db +from covid19.blueprints.application.application_services import who_service +from covid19.blueprints.application.application_workers import celery + +from covid19.blueprints.who.who_model_import import WhoImport +from covid19.blueprints.who.who_model import WhoRegion, WhoCountry, WhoDateReported, WhoData +from covid19.blueprints.application.application_model_transient import ApplicationPage + +from covid19.blueprints.who.who_views import app_who + +from covid19.blueprints.who_test.who_test_service import WhoTestService + +who_test_service = WhoTestService(db) + +app_who_test = Blueprint('who_test', __name__, template_folder='templates', url_prefix='/who/test') + +# --------------------------------------------------------------------------------------------------------------- +# Url Routes Frontend +# --------------------------------------------------------------------------------------------------------------- + + +@app_who_test.route('/who_import/countries') +@login_required +def url_who_test_who_import_countries(): + flash("url_who_mytest - START: WhoImport.countries()") + app.logger.info("url_who_mytest - START: WhoImport.countries()") + i = 0 + for c in WhoImport.countries(): + i += 1 + line = " | " + str(i) + " | " + c.countries.country_code + " | " + c.countries.country + " | " + c.countries.who_region + " | " + app.logger.info(line) + flash("url_who_mytest - DONE: WhoImport.countries()") + return redirect(url_for('who.url_who_tasks')) + + +@app_who_test.route('/mytest') +@login_required +def url_who_test_who_import_get_new_dates_as_array(): + app.logger.info("url_who_mytest - DONE: WhoImport.countries()") + flash("url_who_mytest - START: WhoImport.get_new_dates_as_array()") + app.logger.info("url_who_mytest - START: WhoImport.get_new_dates_as_array()") + app.logger.info("WhoImport.get_new_dates_as_array():") + i = 0 + for date_reported in WhoImport.get_new_dates_as_array(): + i += 1 + line = " | " + str(i) + " | " + date_reported + " | " + app.logger.info(line) + joungest_datum = WhoDateReported.get_joungest_datum() + app.logger.info("joungest_datum:") + app.logger.info(joungest_datum) + app.logger.info("WhoData.get_data_for_one_day(joungest_datum):") + i = 0 + for who_data in WhoData.get_data_for_one_day(joungest_datum): + i += 1 + line = " | " + str(i) + " | " + str(who_data.date_reported) + " | " + who_data.country.country + " | " + app.logger.info(line) + app.logger.info("WhoData.delete_data_for_one_day(joungest_datum)") + WhoData.delete_data_for_one_day(joungest_datum) + app.logger.info("WhoImport.get_new_dates_as_array():") + i = 0 + for date_reported in WhoImport.get_new_dates_as_array(): + i += 1 + line = " | " + str(i) + " | " + date_reported + " | " + app.logger.info(line) + flash("url_who_mytest - DONE: WhoImport.get_new_dates_as_array()") + app.logger.info("url_who_mytest - DONE: WhoImport.get_new_dates_as_array()") + return redirect(url_for('who.url_who_tasks')) -- GitLab