From c6e136be5c9a63d49182840420a5e2158703e4d5 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Mon, 30 Jan 2023 11:49:18 +0000 Subject: [PATCH 01/77] add custom filter to check whether the date is in the past, use it in toc.html --- portality/app.py | 7 ++++++- portality/templates/doaj/toc.html | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/portality/app.py b/portality/app.py index 9e890ed970..9f3a674a55 100644 --- a/portality/app.py +++ b/portality/app.py @@ -17,7 +17,7 @@ from flask import request, abort, render_template, redirect, send_file, url_for, jsonify, send_from_directory from flask_login import login_user, current_user -from datetime import datetime +from datetime import datetime, date import portality.models as models from portality.core import app, es_connection, initialise_index @@ -279,6 +279,11 @@ def form_diff_table_subject_expand(val): return ", ".join(results) +@app.template_filter("is_in_the_past") +def is_in_the_past(dttm): + date = datetime.strptime(dttm, "%Y-%m-%d").date() + return date <= date.today() + ####################################################### diff --git a/portality/templates/doaj/toc.html b/portality/templates/doaj/toc.html index 5c12d2dc58..27b71c7581 100644 --- a/portality/templates/doaj/toc.html +++ b/portality/templates/doaj/toc.html @@ -84,7 +84,7 @@

- {% if bibjson.discontinued_date %} + {% if bibjson.discontinued_date | is_in_the_past %}

Ceased publication on {{ bibjson.discontinued_datestamp.strftime("%d %B %Y") }}

{% endif %} From 8e200bedd13a89a89134d68ebe8add80bd1bc4e6 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Tue, 31 Jan 2023 14:20:42 +0000 Subject: [PATCH 02/77] add background job --- portality/settings.py | 2 + portality/tasks/find_discontinued_soon.py | 113 ++++++++++++++++++ .../templates/email/discontinue_soon.jinja2 | 7 ++ 3 files changed, 122 insertions(+) create mode 100644 portality/tasks/find_discontinued_soon.py create mode 100644 portality/templates/email/discontinue_soon.jinja2 diff --git a/portality/settings.py b/portality/settings.py index 76bd18fbaa..7896d33ac3 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -1354,3 +1354,5 @@ } } +# report journals that discontinue in ... days (eg. 1 = tomorrow) +DISCONTINUED_DATE_DELTA = 1 \ No newline at end of file diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py new file mode 100644 index 0000000000..7ff598d79a --- /dev/null +++ b/portality/tasks/find_discontinued_soon.py @@ -0,0 +1,113 @@ +import datetime +import csv +import json + +from portality.core import app +from portality import models,app_email + +from portality.background import BackgroundTask + + +def _date(): + return (datetime.datetime.today() + datetime.timedelta(days=app.config.get('DISCONTINUED_DATE_DELTA', 1))).strftime( + '%Y-%m-%d') +class DiscontinuedSoonQuery: + @classmethod + def query(cls): + return { + "query": { + "bool": { + "filter": { + "bool" : { + "must": [ + {"term" : {"bibjson.discontinued_date": _date()}} + ] + } + } + } + } + } + +# ~~FindDiscontinuedSoonBackgroundTask:Task~~ + +class FindDiscontinuedSoonBackgroundTask(BackgroundTask): + __action__ = "find_discontinued_soon" + + def run(self): + jdata = [] + + for journal in models.Journal.iterate(q=DiscontinuedSoonQuery.query(), keepalive='5m', wrap=True): + bibjson = journal.bibjson() + owner = journal.owner + account = models.Account.pull(owner) + + jdata.append({"id": journal.id, + "title":bibjson.title, + "eissn": bibjson.get_one_identifier(bibjson.E_ISSN), + "pissn": bibjson.get_one_identifier(bibjson.P_ISSN), + "account_email": account.email if account else "Not Found", + "publisher": bibjson.publisher}) + + try: + # send warning email about the service tag in article metadata detected + to = app.config.get('SCRIPT_TAG_DETECTED_EMAIL_RECIPIENTS') + fro = app.config.get("SYSTEM_EMAIL_FROM", "helpdesk@doaj.org") + subject = app.config.get("SERVICE_NAME", "") + " - script tag detected in application metadata" + es_type = "application" + app_email.send_mail(to=to, + fro=fro, + subject=subject, + template_name="email/discontinue_soon.jinja2", + es_type=es_type, + days=app.config.get('DISCONTINUED_DATE_DELTA',1), + data=json.dumps({"data": jdata}, indent=4, separators=(',', ': '))) + except app_email.EmailException: + app.logger.exception('Error sending email with journals discountinuing soon - ' + jdata) + + def cleanup(self): + """ + Cleanup after a successful OR failed run of the task + :return: + """ + pass + + @classmethod + def prepare(cls, username, **kwargs): + """ + Take an arbitrary set of keyword arguments and return an instance of a BackgroundJob, + or fail with a suitable exception + + :param kwargs: arbitrary keyword arguments pertaining to this task type + :return: a BackgroundJob instance representing this task + """ + + # first prepare a job record + job = background_helper.create_job(username, cls.__action__, + queue_id=huey_helper.queue_id, ) + return job + + @classmethod + def submit(cls, background_job): + """ + Submit the specified BackgroundJob to the background queue + + :param background_job: the BackgroundJob instance + :return: + """ + background_job.save() + request_es_backup.schedule(args=(background_job.id,), delay=1) + +huey_helper = RequestESBackupBackgroundTask.create_huey_helper(main_queue) + +@huey_helper.register_schedule +def scheduled_request_es_backup(): + user = app.config.get("SYSTEM_USERNAME") + job = FindDiscontinuedSoonBackgroundTask.prepare(user) + FindDiscontinuedSoonBackgroundTask.submit(job) + + +@huey_helper.register_execute(is_load_config=False) +def request_es_backup(job_id): + job = models.BackgroundJob.pull(job_id) + task = FindDiscontinuedSoonBackgroundTask(job) + BackgroundApi.execute(task) diff --git a/portality/templates/email/discontinue_soon.jinja2 b/portality/templates/email/discontinue_soon.jinja2 new file mode 100644 index 0000000000..25debb60a8 --- /dev/null +++ b/portality/templates/email/discontinue_soon.jinja2 @@ -0,0 +1,7 @@ +{# +~~FindDiscontinuedSoonBackgroundTask:Email~~ +#} + +Following journals will discontinue in {{ days }} days. + +{{ data }} \ No newline at end of file From d5e1608f69437b57cf2808ea8c2fd66e6c9ed8a6 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Tue, 31 Jan 2023 14:23:05 +0000 Subject: [PATCH 03/77] copy-paste mistakes fixed --- portality/tasks/find_discontinued_soon.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index 7ff598d79a..c691b0c54f 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -95,19 +95,19 @@ def submit(cls, background_job): :return: """ background_job.save() - request_es_backup.schedule(args=(background_job.id,), delay=1) + find_discontinued_soon.schedule(args=(background_job.id,), delay=1) huey_helper = RequestESBackupBackgroundTask.create_huey_helper(main_queue) @huey_helper.register_schedule -def scheduled_request_es_backup(): +def scheduled_find_discontinued_soon(): user = app.config.get("SYSTEM_USERNAME") job = FindDiscontinuedSoonBackgroundTask.prepare(user) FindDiscontinuedSoonBackgroundTask.submit(job) @huey_helper.register_execute(is_load_config=False) -def request_es_backup(job_id): +def find_discontinued_soon(job_id): job = models.BackgroundJob.pull(job_id) task = FindDiscontinuedSoonBackgroundTask(job) BackgroundApi.execute(task) From 8c173c3df942ee1abb118a28afd00b48ba3f0302 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Tue, 31 Jan 2023 14:25:21 +0000 Subject: [PATCH 04/77] change delay to seconds --- portality/tasks/request_es_backup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portality/tasks/request_es_backup.py b/portality/tasks/request_es_backup.py index 57a077a1fd..438d437490 100644 --- a/portality/tasks/request_es_backup.py +++ b/portality/tasks/request_es_backup.py @@ -73,7 +73,7 @@ def submit(cls, background_job): :return: """ background_job.save() - request_es_backup.schedule(args=(background_job.id,), delay=10) + request_es_backup.schedule(args=(background_job.id,), delay=86400) huey_helper = RequestESBackupBackgroundTask.create_huey_helper(main_queue) From 7edc4c20133e93138a3c4421171f2b5048fc1d79 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Tue, 31 Jan 2023 14:26:07 +0000 Subject: [PATCH 05/77] wrong file edited! --- portality/tasks/find_discontinued_soon.py | 2 +- portality/tasks/request_es_backup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index c691b0c54f..c6c1e24a99 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -95,7 +95,7 @@ def submit(cls, background_job): :return: """ background_job.save() - find_discontinued_soon.schedule(args=(background_job.id,), delay=1) + find_discontinued_soon.schedule(args=(background_job.id,), delay=86400) huey_helper = RequestESBackupBackgroundTask.create_huey_helper(main_queue) diff --git a/portality/tasks/request_es_backup.py b/portality/tasks/request_es_backup.py index 438d437490..57a077a1fd 100644 --- a/portality/tasks/request_es_backup.py +++ b/portality/tasks/request_es_backup.py @@ -73,7 +73,7 @@ def submit(cls, background_job): :return: """ background_job.save() - request_es_backup.schedule(args=(background_job.id,), delay=86400) + request_es_backup.schedule(args=(background_job.id,), delay=10) huey_helper = RequestESBackupBackgroundTask.create_huey_helper(main_queue) From c88549b1f028a0d24b32995604dc25ef2deb3176 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Wed, 1 Feb 2023 13:17:21 +0000 Subject: [PATCH 06/77] add UT and fix code --- doajtest/unit/test_task_discontinued_soon.py | 65 ++++++++++++++++++++ portality/settings.py | 1 + portality/tasks/find_discontinued_soon.py | 48 +++++++++------ 3 files changed, 95 insertions(+), 19 deletions(-) create mode 100644 doajtest/unit/test_task_discontinued_soon.py diff --git a/doajtest/unit/test_task_discontinued_soon.py b/doajtest/unit/test_task_discontinued_soon.py new file mode 100644 index 0000000000..77e9c558c5 --- /dev/null +++ b/doajtest/unit/test_task_discontinued_soon.py @@ -0,0 +1,65 @@ +import unittest +import datetime + +from doajtest.helpers import DoajTestCase + +from portality.core import app +from portality import models +from portality.tasks import find_discontinued_soon +from doajtest.fixtures import JournalFixtureFactory + +class TestDiscontinuedSoon(DoajTestCase): + + def _date_tomorrow(self): + return (datetime.datetime.today() + datetime.timedelta(days=1)).strftime('%Y-%m-%d') + + def _date_in_2_days(self): + return (datetime.datetime.today() + datetime.timedelta(days=2)).strftime('%Y-%m-%d') + + def test_discontinued_soon_found(self): + + journal_discontinued_tommorow_1 = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) + journal_discontinued_tommorow_1.set_id("1") + jbib = journal_discontinued_tommorow_1.bibjson() + jbib.title = "Discontinued Tomorrow 1" + jbib.discontinued_date = self._date_tomorrow() + journal_discontinued_tommorow_1.save(blocking=True) + + journal_discontinued_tommorow_2 = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) + journal_discontinued_tommorow_2.set_id("2") + jbib = journal_discontinued_tommorow_2.bibjson() + jbib.title = "Discontinued Tomorrow 2" + jbib.discontinued_date = self._date_tomorrow() + journal_discontinued_tommorow_2.save(blocking=True) + + journal_discontinued_in_2_days = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) + journal_discontinued_in_2_days.set_id("3") + jbib = journal_discontinued_in_2_days.bibjson() + jbib.title = "Discontinued In 2 days" + jbib.discontinued_date = self._date_in_2_days() + journal_discontinued_in_2_days.save(blocking=True) + + job = find_discontinued_soon.FindDiscontinuedSoonBackgroundTask.prepare("system") + task = find_discontinued_soon.FindDiscontinuedSoonBackgroundTask(job) + task.run() + + assert len(job.audit) == 3 + assert job.audit[0]["message"] == "Journal discontinuing soon found: 1" + assert job.audit[1]["message"] == "Journal discontinuing soon found: 2" + assert job.audit[2]["message"] == "Email with journals discontinuing soon sent" + + def test_discontinued_soon_not_found(self): + + journal_discontinued_in_2_days = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) + journal_discontinued_in_2_days.set_id("3") + jbib = journal_discontinued_in_2_days.bibjson() + jbib.title = "Discontinued In 2 days" + jbib.discontinued_date = self._date_in_2_days() + journal_discontinued_in_2_days.save(blocking=True) + + job = find_discontinued_soon.FindDiscontinuedSoonBackgroundTask.prepare("system") + task = find_discontinued_soon.FindDiscontinuedSoonBackgroundTask(job) + task.run() + + assert len(job.audit) == 1 + assert job.audit[0]["message"] == "No journals discontinuing soon found" diff --git a/portality/settings.py b/portality/settings.py index 7896d33ac3..64a734a0d0 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -417,6 +417,7 @@ "anon_export": {"month": "*", "day": "10", "day_of_week": "*", "hour": "6", "minute": "30"}, "old_data_cleanup": {"month": "*", "day": "12", "day_of_week": "*", "hour": "6", "minute": "30"}, "monitor_bgjobs": {"month": "*", "day": "*/6", "day_of_week": "*", "hour": "10", "minute": "0"}, + "find_discontinued_soon": {"month": "*", "day": "*", "day_of_week": "*", "hour": "7", "minute": "0"}, } HUEY_TASKS = { diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index c6c1e24a99..3212559636 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -5,7 +5,10 @@ from portality.core import app from portality import models,app_email -from portality.background import BackgroundTask +from portality.tasks.redis_huey import main_queue + +from portality.background import BackgroundTask, BackgroundSummary +from portality.tasks.helpers import background_helper def _date(): @@ -34,6 +37,7 @@ class FindDiscontinuedSoonBackgroundTask(BackgroundTask): __action__ = "find_discontinued_soon" def run(self): + job = self.background_job jdata = [] for journal in models.Journal.iterate(q=DiscontinuedSoonQuery.query(), keepalive='5m', wrap=True): @@ -47,22 +51,28 @@ def run(self): "pissn": bibjson.get_one_identifier(bibjson.P_ISSN), "account_email": account.email if account else "Not Found", "publisher": bibjson.publisher}) - - try: - # send warning email about the service tag in article metadata detected - to = app.config.get('SCRIPT_TAG_DETECTED_EMAIL_RECIPIENTS') - fro = app.config.get("SYSTEM_EMAIL_FROM", "helpdesk@doaj.org") - subject = app.config.get("SERVICE_NAME", "") + " - script tag detected in application metadata" - es_type = "application" - app_email.send_mail(to=to, - fro=fro, - subject=subject, - template_name="email/discontinue_soon.jinja2", - es_type=es_type, - days=app.config.get('DISCONTINUED_DATE_DELTA',1), - data=json.dumps({"data": jdata}, indent=4, separators=(',', ': '))) - except app_email.EmailException: - app.logger.exception('Error sending email with journals discountinuing soon - ' + jdata) + job.add_audit_message("Journal discontinuing soon found: " + journal.id) + + if len(jdata): + try: + # send warning email about the service tag in article metadata detected + to = app.config.get('SCRIPT_TAG_DETECTED_EMAIL_RECIPIENTS') + fro = app.config.get("SYSTEM_EMAIL_FROM", "helpdesk@doaj.org") + subject = app.config.get("SERVICE_NAME", "") + " - script tag detected in application metadata" + es_type = "application" + app_email.send_mail(to=to, + fro=fro, + subject=subject, + template_name="email/discontinue_soon.jinja2", + es_type=es_type, + days=app.config.get('DISCONTINUED_DATE_DELTA',1), + data=json.dumps({"data": jdata}, indent=4, separators=(',', ': '))) + except app_email.EmailException: + app.logger.exception('Error sending email with journals discountinuing soon - ' + jdata) + + job.add_audit_message("Email with journals discontinuing soon sent") + else: + job.add_audit_message("No journals discontinuing soon found") def cleanup(self): """ @@ -95,9 +105,9 @@ def submit(cls, background_job): :return: """ background_job.save() - find_discontinued_soon.schedule(args=(background_job.id,), delay=86400) + find_discontinued_soon.schedule(args=(background_job.id,), delay=10) -huey_helper = RequestESBackupBackgroundTask.create_huey_helper(main_queue) +huey_helper = FindDiscontinuedSoonBackgroundTask.create_huey_helper(main_queue) @huey_helper.register_schedule def scheduled_find_discontinued_soon(): From 1c7e0e10927d276fd8676622bfba50a6827e5ba1 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Wed, 1 Feb 2023 13:49:19 +0000 Subject: [PATCH 07/77] refactoring --- doajtest/unit/test_task_discontinued_soon.py | 9 +-- portality/settings.py | 1 + portality/tasks/find_discontinued_soon.py | 58 +++++++++++--------- portality/ui/messages.py | 6 ++ 4 files changed, 45 insertions(+), 29 deletions(-) diff --git a/doajtest/unit/test_task_discontinued_soon.py b/doajtest/unit/test_task_discontinued_soon.py index 77e9c558c5..00c3183dce 100644 --- a/doajtest/unit/test_task_discontinued_soon.py +++ b/doajtest/unit/test_task_discontinued_soon.py @@ -6,6 +6,7 @@ from portality.core import app from portality import models from portality.tasks import find_discontinued_soon +from portality.ui.messages import Messages from doajtest.fixtures import JournalFixtureFactory class TestDiscontinuedSoon(DoajTestCase): @@ -44,9 +45,9 @@ def test_discontinued_soon_found(self): task.run() assert len(job.audit) == 3 - assert job.audit[0]["message"] == "Journal discontinuing soon found: 1" - assert job.audit[1]["message"] == "Journal discontinuing soon found: 2" - assert job.audit[2]["message"] == "Email with journals discontinuing soon sent" + assert job.audit[0]["message"] == Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id="1") + assert job.audit[1]["message"] == Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id="2") + assert job.audit[2]["message"] == Messages.DISCONTINUED_JOURNALS_FOUND_EMAIL_SENT_LOG def test_discontinued_soon_not_found(self): @@ -62,4 +63,4 @@ def test_discontinued_soon_not_found(self): task.run() assert len(job.audit) == 1 - assert job.audit[0]["message"] == "No journals discontinuing soon found" + assert job.audit[0]["message"] == Messages.NO_DISCONTINUED_JOURNALS_FOUND_LOG diff --git a/portality/settings.py b/portality/settings.py index 64a734a0d0..ab044207d6 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -341,6 +341,7 @@ MANAGING_EDITOR_EMAIL = "managing-editors@doaj.org" CONTACT_FORM_ADDRESS = "feedback+contactform@doaj.org" SCRIPT_TAG_DETECTED_EMAIL_RECIPIENTS = ["helpdesk@doaj.org"] +DISCONTINUED_JOURNALS_FOUND_RECEIPIENTS = ["dom@doaj.org"] SYSTEM_EMAIL_FROM = 'helpdesk@doaj.org' CC_ALL_EMAILS_TO = SYSTEM_EMAIL_FROM # DOAJ may get a dedicated inbox in the future diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index 3212559636..f322cd1e74 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -9,6 +9,7 @@ from portality.background import BackgroundTask, BackgroundSummary from portality.tasks.helpers import background_helper +from portality.ui.messages import Messages def _date(): @@ -36,8 +37,7 @@ def query(cls): class FindDiscontinuedSoonBackgroundTask(BackgroundTask): __action__ = "find_discontinued_soon" - def run(self): - job = self.background_job + def find_journals_discontinuing_soon(self, job): jdata = [] for journal in models.Journal.iterate(q=DiscontinuedSoonQuery.query(), keepalive='5m', wrap=True): @@ -50,29 +50,37 @@ def run(self): "eissn": bibjson.get_one_identifier(bibjson.E_ISSN), "pissn": bibjson.get_one_identifier(bibjson.P_ISSN), "account_email": account.email if account else "Not Found", - "publisher": bibjson.publisher}) - job.add_audit_message("Journal discontinuing soon found: " + journal.id) - - if len(jdata): - try: - # send warning email about the service tag in article metadata detected - to = app.config.get('SCRIPT_TAG_DETECTED_EMAIL_RECIPIENTS') - fro = app.config.get("SYSTEM_EMAIL_FROM", "helpdesk@doaj.org") - subject = app.config.get("SERVICE_NAME", "") + " - script tag detected in application metadata" - es_type = "application" - app_email.send_mail(to=to, - fro=fro, - subject=subject, - template_name="email/discontinue_soon.jinja2", - es_type=es_type, - days=app.config.get('DISCONTINUED_DATE_DELTA',1), - data=json.dumps({"data": jdata}, indent=4, separators=(',', ': '))) - except app_email.EmailException: - app.logger.exception('Error sending email with journals discountinuing soon - ' + jdata) - - job.add_audit_message("Email with journals discontinuing soon sent") + "publisher": bibjson.publisher, + "discontinued date": bibjson.discontinued_date}) + job.add_audit_message(Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id=journal.id)) + + return jdata + + + def send_email(self, data, job): + try: + # send warning email about the service tag in article metadata detected + to = app.config.get('DISCONTINUED_JOURNALS_FOUND_RECEIPIENTS') + fro = app.config.get("SYSTEM_EMAIL_FROM", "helpdesk@doaj.org") + subject = app.config.get("SERVICE_NAME", "") + " - journals discontinuing soon found" + app_email.send_mail(to=to, + fro=fro, + subject=subject, + template_name="email/discontinue_soon.jinja2", + days=app.config.get('DISCONTINUED_DATE_DELTA',1), + data=json.dumps({"data": data}, indent=4, separators=(',', ': '))) + except app_email.EmailException: + app.logger.exception(Messages.DISCONTINUED_JOURNALS_FOUND_EMAIL_ERROR_LOG) + + job.add_audit_message(Messages.DISCONTINUED_JOURNALS_FOUND_EMAIL_SENT_LOG) + + def run(self): + job = self.background_job + journals = self.find_journals_discontinuing_soon(job=job) + if len(journals): + self.send_email(job=job, data=journals) else: - job.add_audit_message("No journals discontinuing soon found") + job.add_audit_message(Messages.NO_DISCONTINUED_JOURNALS_FOUND_LOG) def cleanup(self): """ @@ -120,4 +128,4 @@ def scheduled_find_discontinued_soon(): def find_discontinued_soon(job_id): job = models.BackgroundJob.pull(job_id) task = FindDiscontinuedSoonBackgroundTask(job) - BackgroundApi.execute(task) + BackgroundApi.execute(task) \ No newline at end of file diff --git a/portality/ui/messages.py b/portality/ui/messages.py index 82667e36e9..1c5af3a6da 100644 --- a/portality/ui/messages.py +++ b/portality/ui/messages.py @@ -109,6 +109,12 @@ class Messages(object): NOTIFY__DEFAULT_SHORT_NOTIFICATION = "You have a new notification" + DISCONTINUED_JOURNAL_FOUND_LOG = "Journal discontinuing soon found: {id}" + DISCONTINUED_JOURNALS_FOUND_EMAIL_SENT_LOG = "Email with journals discontinuing soon sent" + DISCONTINUED_JOURNALS_FOUND_EMAIL_ERROR_LOG = "Error sending email with journals discountinuing soon." + NO_DISCONTINUED_JOURNALS_FOUND_LOG = "No journals discontinuing soon found" + + @classmethod def flash(cls, tup): if isinstance(tup, tuple): From 6357e7f581696da8fc2082187ca2b46a7a536d6b Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Wed, 1 Feb 2023 13:53:17 +0000 Subject: [PATCH 08/77] add FeatureMap annotations --- portality/tasks/find_discontinued_soon.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index f322cd1e74..eec4b8a20f 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -41,6 +41,7 @@ def find_journals_discontinuing_soon(self, job): jdata = [] for journal in models.Journal.iterate(q=DiscontinuedSoonQuery.query(), keepalive='5m', wrap=True): + # ~~->Journal:Model~~ bibjson = journal.bibjson() owner = journal.owner account = models.Account.pull(owner) @@ -58,6 +59,7 @@ def find_journals_discontinuing_soon(self, job): def send_email(self, data, job): + # ~~->Email:ExternalService~~ try: # send warning email about the service tag in article metadata detected to = app.config.get('DISCONTINUED_JOURNALS_FOUND_RECEIPIENTS') From 91ad6eb3583fdd0774133b5b9ca80318ec97fa94 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Wed, 1 Feb 2023 14:10:39 +0000 Subject: [PATCH 09/77] add functional test --- doajtest/testbook/public_site/ToC.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 doajtest/testbook/public_site/ToC.yml diff --git a/doajtest/testbook/public_site/ToC.yml b/doajtest/testbook/public_site/ToC.yml new file mode 100644 index 0000000000..b481085cf9 --- /dev/null +++ b/doajtest/testbook/public_site/ToC.yml @@ -0,0 +1,15 @@ +suite: Public Site +testset: ToC +tests: +- title: Test Correctly Displayed Discontinued Date + context: + role: anonymous + steps: + - step: To prepare to do this test make sure there are 3 journals publically available in DOAJ + one with discontinued date in the past + one with discontinued date in the future + one with discontinued date today + - step: Search for every journal from the list above + results: + - On the ToC of the journal with discontinued date in the past or today - the discontinued date is displayed + - On the ToC of the journal with discontinued date in the future - the discontinued date is not displayed From a037fd54eb453ddda40d4aaf707fa90365607ff1 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Tue, 7 Feb 2023 14:09:13 +0000 Subject: [PATCH 10/77] implement notification --- .../journal_discontinuing_soon_notify.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 portality/events/consumers/journal_discontinuing_soon_notify.py diff --git a/portality/events/consumers/journal_discontinuing_soon_notify.py b/portality/events/consumers/journal_discontinuing_soon_notify.py new file mode 100644 index 0000000000..dbfc7cd236 --- /dev/null +++ b/portality/events/consumers/journal_discontinuing_soon_notify.py @@ -0,0 +1,45 @@ +# ~~JournalDiscontinuingSoonNotify:Consumer~~ +from portality.util import url_for + +from portality.events.consumer import EventConsumer +from portality import constants +from portality import models +from portality.bll import DOAJ +from portality.bll import exceptions + + +class JournalDiscontinuingSoon(EventConsumer): + ID = "journal:assed:discontinuing_soon:notify" + + @classmethod + def consumes(cls, event): + return event.id == constants.EVENT_JOURNAL_DISCONTINUING_SOON and \ + event.context.get("journal") is not None + + @classmethod + def consume(cls, event): + j_source = event.context.get("journal") + + try: + journal = models.Journal(**j_source) + except Exception as e: + raise exceptions.NoSuchObjectException("Unable to construct Journal from supplied source - data structure validation error, {x}".format(x=e)) + + if not journal.editor: + raise exceptions.NoSuchPropertyException("Journal {x} does not have property `editor`".format(x=journal.id)) + + # ~~-> Notifications:Service ~~ + svc = DOAJ.notificationsService() + + notification = models.Notification() + notification.who = journal.editor + notification.created_by = cls.ID + notification.classification = constants.NOTIFICATION_CLASSIFICATION_ASSIGN + notification.long = svc.long_notification(cls.ID).format( + journal_name=journal.bibjson().title, + group_name=journal.editor_group + ) + notification.short = svc.short_notification(cls.ID) + notification.action = url_for("editor.journal_page", journal_id=journal.id) + + svc.notify(notification) From b2557c160799e2e06100851138fa6c351dbe916b Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Tue, 7 Feb 2023 14:10:25 +0000 Subject: [PATCH 11/77] implement notification --- cms/data/notifications.yml | 8 +++ portality/bll/services/events.py | 4 +- portality/constants.py | 2 + .../journal_discontinuing_soon_notify.py | 53 ++++++++++-------- portality/tasks/find_discontinued_soon.py | 55 +++++++++++-------- 5 files changed, 75 insertions(+), 47 deletions(-) diff --git a/cms/data/notifications.yml b/cms/data/notifications.yml index 6aca840e49..a33ae53b5c 100644 --- a/cms/data/notifications.yml +++ b/cms/data/notifications.yml @@ -142,3 +142,11 @@ update_request:publisher:rejected:notify: short: Your update request was rejected +journal:assed:discontinuing_soon:notify: + long: | + Following journals will discontinue in {days} days. + + {data} + short: + Journals discontinuing soon found + diff --git a/portality/bll/services/events.py b/portality/bll/services/events.py index 2b27b85beb..3c5e96473c 100644 --- a/portality/bll/services/events.py +++ b/portality/bll/services/events.py @@ -21,6 +21,7 @@ from portality.events.consumers.journal_editor_group_assigned_notify import JournalEditorGroupAssignedNotify from portality.events.consumers.application_publisher_inprogress_notify import ApplicationPublisherInprogressNotify from portality.events.consumers.update_request_publisher_rejected_notify import UpdateRequestPublisherRejectedNotify +from portality.events.consumers.journal_discontinuing_soon_notify import JournalDiscontinuingSoonNotify class EventsService(object): @@ -44,7 +45,8 @@ class EventsService(object): JournalEditorGroupAssignedNotify, UpdateRequestPublisherAcceptedNotify, UpdateRequestPublisherAssignedNotify, - UpdateRequestPublisherRejectedNotify + UpdateRequestPublisherRejectedNotify, + JournalDiscontinuingSoonNotify ] def __init__(self): diff --git a/portality/constants.py b/portality/constants.py index e9ff3e86f0..9224eda606 100644 --- a/portality/constants.py +++ b/portality/constants.py @@ -53,7 +53,9 @@ EVENT_APPLICATION_EDITOR_GROUP_ASSIGNED = "application:editor_group:assigned" EVENT_JOURNAL_ASSED_ASSIGNED = "journal:assed:assigned" EVENT_JOURNAL_EDITOR_GROUP_ASSIGNED = "journal:editor_group:assigned" +EVENT_JOURNAL_DISCONTINUING_SOON = "journal:discontinuing_soon" +NOTIFICATION_CLASSIFICATION_STATUS = "status" NOTIFICATION_CLASSIFICATION_STATUS_CHANGE = "status_change" NOTIFICATION_CLASSIFICATION_ASSIGN = "assign" NOTIFICATION_CLASSIFICATION_CREATE = "create" diff --git a/portality/events/consumers/journal_discontinuing_soon_notify.py b/portality/events/consumers/journal_discontinuing_soon_notify.py index dbfc7cd236..d2c8e10778 100644 --- a/portality/events/consumers/journal_discontinuing_soon_notify.py +++ b/portality/events/consumers/journal_discontinuing_soon_notify.py @@ -2,44 +2,49 @@ from portality.util import url_for from portality.events.consumer import EventConsumer +from portality.core import app from portality import constants from portality import models from portality.bll import DOAJ from portality.bll import exceptions -class JournalDiscontinuingSoon(EventConsumer): +class JournalDiscontinuingSoonNotify(EventConsumer): ID = "journal:assed:discontinuing_soon:notify" @classmethod def consumes(cls, event): return event.id == constants.EVENT_JOURNAL_DISCONTINUING_SOON and \ - event.context.get("journal") is not None + event.context.get("job") is not None @classmethod def consume(cls, event): - j_source = event.context.get("journal") + source = event.context.get("job") try: - journal = models.Journal(**j_source) + job = models.BackgroundJob(**source) except Exception as e: - raise exceptions.NoSuchObjectException("Unable to construct Journal from supplied source - data structure validation error, {x}".format(x=e)) - - if not journal.editor: - raise exceptions.NoSuchPropertyException("Journal {x} does not have property `editor`".format(x=journal.id)) - - # ~~-> Notifications:Service ~~ - svc = DOAJ.notificationsService() - - notification = models.Notification() - notification.who = journal.editor - notification.created_by = cls.ID - notification.classification = constants.NOTIFICATION_CLASSIFICATION_ASSIGN - notification.long = svc.long_notification(cls.ID).format( - journal_name=journal.bibjson().title, - group_name=journal.editor_group - ) - notification.short = svc.short_notification(cls.ID) - notification.action = url_for("editor.journal_page", journal_id=journal.id) - - svc.notify(notification) + raise exceptions.NoSuchObjectException( + "Unable to construct a BackgroundJob object from the data supplied {x}".format(x=e)) + + if job.user is None: + return + + acc = models.Account.pull(job.user) + if acc is None or not acc.has_role("admin"): + return + + # ~~-> Notifications:Service ~~ + svc = DOAJ.notificationsService() + + notification = models.Notification() + notification.who = acc.id + notification.created_by = cls.ID + notification.classification = constants.NOTIFICATION_CLASSIFICATION_ASSIGN + notification.long = svc.long_notification(cls.ID).format( + days=app.config.get('DISCONTINUED_DATE_DELTA',1), + data=event.context.get("data") + ) + notification.short = svc.short_notification(cls.ID) + + svc.notify(notification) diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index eec4b8a20f..fa3e4e09a8 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -3,6 +3,7 @@ import json from portality.core import app +from portality.bll import DOAJ from portality import models,app_email from portality.tasks.redis_huey import main_queue @@ -10,6 +11,7 @@ from portality.background import BackgroundTask, BackgroundSummary from portality.tasks.helpers import background_helper from portality.ui.messages import Messages +from portality import constants def _date(): @@ -37,7 +39,7 @@ def query(cls): class FindDiscontinuedSoonBackgroundTask(BackgroundTask): __action__ = "find_discontinued_soon" - def find_journals_discontinuing_soon(self, job): + def find_journals_discontinuing_soon(self): jdata = [] for journal in models.Journal.iterate(q=DiscontinuedSoonQuery.query(), keepalive='5m', wrap=True): @@ -57,30 +59,19 @@ def find_journals_discontinuing_soon(self, job): return jdata - - def send_email(self, data, job): - # ~~->Email:ExternalService~~ - try: - # send warning email about the service tag in article metadata detected - to = app.config.get('DISCONTINUED_JOURNALS_FOUND_RECEIPIENTS') - fro = app.config.get("SYSTEM_EMAIL_FROM", "helpdesk@doaj.org") - subject = app.config.get("SERVICE_NAME", "") + " - journals discontinuing soon found" - app_email.send_mail(to=to, - fro=fro, - subject=subject, - template_name="email/discontinue_soon.jinja2", - days=app.config.get('DISCONTINUED_DATE_DELTA',1), - data=json.dumps({"data": data}, indent=4, separators=(',', ': '))) - except app_email.EmailException: - app.logger.exception(Messages.DISCONTINUED_JOURNALS_FOUND_EMAIL_ERROR_LOG) - - job.add_audit_message(Messages.DISCONTINUED_JOURNALS_FOUND_EMAIL_SENT_LOG) - def run(self): job = self.background_job journals = self.find_journals_discontinuing_soon(job=job) + journals = find_journals_discontinuing_soon() if len(journals): - self.send_email(job=job, data=journals) + DOAJ.eventsService().trigger(models.Event( + constants.EVENT_JOURNAL_DISCONTINUING_SOON, + "system", + { + "context": "job", + "data": jdata, + "job": job + })) else: job.add_audit_message(Messages.NO_DISCONTINUED_JOURNALS_FOUND_LOG) @@ -130,4 +121,24 @@ def scheduled_find_discontinued_soon(): def find_discontinued_soon(job_id): job = models.BackgroundJob.pull(job_id) task = FindDiscontinuedSoonBackgroundTask(job) - BackgroundApi.execute(task) \ No newline at end of file + BackgroundApi.execute(task) + +def find_journals_discontinuing_soon(): + jdata = [] + + for journal in models.Journal.iterate(q=DiscontinuedSoonQuery.query(), keepalive='5m', wrap=True): + # ~~->Journal:Model~~ + bibjson = journal.bibjson() + owner = journal.owner + account = models.Account.pull(owner) + + jdata.append({"id": journal.id, + "title":bibjson.title, + "eissn": bibjson.get_one_identifier(bibjson.E_ISSN), + "pissn": bibjson.get_one_identifier(bibjson.P_ISSN), + "account_email": account.email if account else "Not Found", + "publisher": bibjson.publisher, + "discontinued date": bibjson.discontinued_date}) + print(Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id=journal.id)) + + return jdata \ No newline at end of file From 255bce208d9db383be96ae607467392f9d36179c Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Tue, 7 Feb 2023 14:32:08 +0000 Subject: [PATCH 12/77] add notif action and remove test code --- .../consumers/journal_discontinuing_soon_notify.py | 12 ++++++++++-- portality/tasks/find_discontinued_soon.py | 5 ++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/portality/events/consumers/journal_discontinuing_soon_notify.py b/portality/events/consumers/journal_discontinuing_soon_notify.py index d2c8e10778..216a857df5 100644 --- a/portality/events/consumers/journal_discontinuing_soon_notify.py +++ b/portality/events/consumers/journal_discontinuing_soon_notify.py @@ -1,4 +1,5 @@ # ~~JournalDiscontinuingSoonNotify:Consumer~~ +import json from portality.util import url_for from portality.events.consumer import EventConsumer @@ -15,7 +16,8 @@ class JournalDiscontinuingSoonNotify(EventConsumer): @classmethod def consumes(cls, event): return event.id == constants.EVENT_JOURNAL_DISCONTINUING_SOON and \ - event.context.get("job") is not None + event.context.get("job") is not None and \ + event.context.get("data") is not None @classmethod def consume(cls, event): @@ -34,6 +36,11 @@ def consume(cls, event): if acc is None or not acc.has_role("admin"): return + + journals = [] + for j in data: + journals.append(j["id"]) + # ~~-> Notifications:Service ~~ svc = DOAJ.notificationsService() @@ -43,8 +50,9 @@ def consume(cls, event): notification.classification = constants.NOTIFICATION_CLASSIFICATION_ASSIGN notification.long = svc.long_notification(cls.ID).format( days=app.config.get('DISCONTINUED_DATE_DELTA',1), - data=event.context.get("data") + data=json.dumps({"data": data}, indent=4, separators=(',', ': ')) ) notification.short = svc.short_notification(cls.ID) + notification.action = url_for("dashboard.notifications") svc.notify(notification) diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index fa3e4e09a8..2102d4723d 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -62,14 +62,13 @@ def find_journals_discontinuing_soon(self): def run(self): job = self.background_job journals = self.find_journals_discontinuing_soon(job=job) - journals = find_journals_discontinuing_soon() if len(journals): DOAJ.eventsService().trigger(models.Event( constants.EVENT_JOURNAL_DISCONTINUING_SOON, "system", { "context": "job", - "data": jdata, + "data": journals, "job": job })) else: @@ -139,6 +138,6 @@ def find_journals_discontinuing_soon(): "account_email": account.email if account else "Not Found", "publisher": bibjson.publisher, "discontinued date": bibjson.discontinued_date}) - print(Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id=journal.id)) + job.add_audit_message(Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id=journal.id)) return jdata \ No newline at end of file From e8edabb43c2c4e8d5383248443f2ef593a649e30 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Wed, 8 Feb 2023 11:48:17 +0000 Subject: [PATCH 13/77] change notification classification --- portality/events/consumers/journal_discontinuing_soon_notify.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portality/events/consumers/journal_discontinuing_soon_notify.py b/portality/events/consumers/journal_discontinuing_soon_notify.py index 216a857df5..ed00f6151e 100644 --- a/portality/events/consumers/journal_discontinuing_soon_notify.py +++ b/portality/events/consumers/journal_discontinuing_soon_notify.py @@ -47,7 +47,7 @@ def consume(cls, event): notification = models.Notification() notification.who = acc.id notification.created_by = cls.ID - notification.classification = constants.NOTIFICATION_CLASSIFICATION_ASSIGN + notification.classification = constants.NOTIFICATION_CLASSIFICATION_STATUS notification.long = svc.long_notification(cls.ID).format( days=app.config.get('DISCONTINUED_DATE_DELTA',1), data=json.dumps({"data": data}, indent=4, separators=(',', ': ')) From f23b55bc009c5013e47874a7065920f6fcc679f3 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Wed, 8 Feb 2023 12:59:16 +0000 Subject: [PATCH 14/77] revert accidental deletion --- .../event_consumers/test_journal_discontinuing_soon_notify.py | 0 portality/events/consumers/journal_discontinuing_soon_notify.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py diff --git a/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py b/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/portality/events/consumers/journal_discontinuing_soon_notify.py b/portality/events/consumers/journal_discontinuing_soon_notify.py index ed00f6151e..f61c035014 100644 --- a/portality/events/consumers/journal_discontinuing_soon_notify.py +++ b/portality/events/consumers/journal_discontinuing_soon_notify.py @@ -21,7 +21,7 @@ def consumes(cls, event): @classmethod def consume(cls, event): - + data = event.context.get("data") source = event.context.get("job") try: job = models.BackgroundJob(**source) From 8cbc1465ab025f97d1c89bf04430734dd092026c Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Wed, 8 Feb 2023 13:02:56 +0000 Subject: [PATCH 15/77] new even notif unit tests --- .../test_journal_discontinuing_soon_notify.py | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py b/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py index e69de29bb2..ab62fa433f 100644 --- a/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py +++ b/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py @@ -0,0 +1,68 @@ +from portality import models +from portality import constants +from portality.bll import exceptions +from doajtest.helpers import DoajTestCase +from doajtest.fixtures import JournalFixtureFactory +from portality.events.consumers.journal_discontinuing_soon_notify import JournalDiscontinuingSoonNotify +from doajtest.fixtures import BackgroundFixtureFactory +import time + + +class TestJournalDiscontinuingSoonNotify(DoajTestCase): + def setUp(self): + super(TestJournalDiscontinuingSoonNotify, self).setUp() + + def tearDown(self): + super(TestJournalDiscontinuingSoonNotify, self).tearDown() + + def test_consumes(self): + event = models.Event(constants.EVENT_JOURNAL_DISCONTINUING_SOON, context={"job" : {}}) + assert not JournalDiscontinuingSoonNotify.consumes(event) + + event = models.Event("test:event", context={"data" : {"1234"}}) + assert not JournalDiscontinuingSoonNotify.consumes(event) + + event = models.Event("test:event", context={"data": {}}) + assert not JournalDiscontinuingSoonNotify.consumes(event) + + event = models.Event(constants.EVENT_JOURNAL_DISCONTINUING_SOON) + assert not JournalDiscontinuingSoonNotify.consumes(event) + + event = models.Event(constants.EVENT_JOURNAL_DISCONTINUING_SOON, context = {"data": {"1234"}, "job": {"1234"}}) + assert JournalDiscontinuingSoonNotify.consumes(event) + + def test_consume_success(self): + self._make_and_push_test_context("/") + + source = BackgroundFixtureFactory.example() + bj = models.BackgroundJob(**source) + # bj.save(blocking=True) + + acc = models.Account() + acc.set_id('testuser') + acc.set_email("test@example.com") + acc.add_role('admin') + acc.save(blocking=True) + + + + event = models.Event(constants.BACKGROUND_JOB_FINISHED, context={"job" : bj.data, "data" : JournalFixtureFactory.make_many_journal_sources(2)}) + JournalDiscontinuingSoonNotify.consume(event) + + time.sleep(2) + ns = models.Notification.all() + assert len(ns) == 1 + + n = ns[0] + assert n.who == acc.id + assert n.created_by == JournalDiscontinuingSoonNotify.ID + assert n.classification == constants.NOTIFICATION_CLASSIFICATION_STATUS + assert n.long is not None + assert n.short is not None + assert n.action is not None + assert not n.is_seen() + + def test_consume_fail(self): + event = models.Event(constants.NOTIFICATION_CLASSIFICATION_STATUS, context={"job": "abcd"}) + with self.assertRaises(exceptions.NoSuchObjectException): + JournalDiscontinuingSoonNotify.consume(event) From f72e7218501792b7466778c3262d8935644dafe5 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Wed, 8 Feb 2023 13:15:31 +0000 Subject: [PATCH 16/77] make sure only journals in doaj are found and fix unit tests --- doajtest/unit/test_task_discontinued_soon.py | 15 ++++++++++++--- portality/tasks/find_discontinued_soon.py | 5 +++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/doajtest/unit/test_task_discontinued_soon.py b/doajtest/unit/test_task_discontinued_soon.py index 00c3183dce..f6a4be9483 100644 --- a/doajtest/unit/test_task_discontinued_soon.py +++ b/doajtest/unit/test_task_discontinued_soon.py @@ -19,6 +19,7 @@ def _date_in_2_days(self): def test_discontinued_soon_found(self): + # Both these should be found journal_discontinued_tommorow_1 = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) journal_discontinued_tommorow_1.set_id("1") jbib = journal_discontinued_tommorow_1.bibjson() @@ -33,6 +34,7 @@ def test_discontinued_soon_found(self): jbib.discontinued_date = self._date_tomorrow() journal_discontinued_tommorow_2.save(blocking=True) + # that shouldn't be found journal_discontinued_in_2_days = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) journal_discontinued_in_2_days.set_id("3") jbib = journal_discontinued_in_2_days.bibjson() @@ -44,20 +46,27 @@ def test_discontinued_soon_found(self): task = find_discontinued_soon.FindDiscontinuedSoonBackgroundTask(job) task.run() - assert len(job.audit) == 3 + assert len(job.audit) == 2 assert job.audit[0]["message"] == Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id="1") assert job.audit[1]["message"] == Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id="2") - assert job.audit[2]["message"] == Messages.DISCONTINUED_JOURNALS_FOUND_EMAIL_SENT_LOG def test_discontinued_soon_not_found(self): + # None of these should be found - this one discontinues in 2 days journal_discontinued_in_2_days = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) - journal_discontinued_in_2_days.set_id("3") + journal_discontinued_in_2_days.set_id("1") jbib = journal_discontinued_in_2_days.bibjson() jbib.title = "Discontinued In 2 days" jbib.discontinued_date = self._date_in_2_days() journal_discontinued_in_2_days.save(blocking=True) + # this one is not in doaj + journal_not_in_doaj = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=False)) + journal_not_in_doaj.set_id("2") + jbib = journal_not_in_doaj.bibjson() + jbib.discontinued_date = self._date_tomorrow() + journal_not_in_doaj.save(blocking=True) + job = find_discontinued_soon.FindDiscontinuedSoonBackgroundTask.prepare("system") task = find_discontinued_soon.FindDiscontinuedSoonBackgroundTask(job) task.run() diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index 2102d4723d..6762a5b315 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -26,7 +26,8 @@ def query(cls): "filter": { "bool" : { "must": [ - {"term" : {"bibjson.discontinued_date": _date()}} + {"term" : {"bibjson.discontinued_date": _date()}}, + {"term" : {"admin.in_doaj":True}} ] } } @@ -39,7 +40,7 @@ def query(cls): class FindDiscontinuedSoonBackgroundTask(BackgroundTask): __action__ = "find_discontinued_soon" - def find_journals_discontinuing_soon(self): + def find_journals_discontinuing_soon(self, job): jdata = [] for journal in models.Journal.iterate(q=DiscontinuedSoonQuery.query(), keepalive='5m', wrap=True): From b394331a448007d320d4d6e057b4c0be5c316514 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Wed, 8 Feb 2023 16:50:34 +0000 Subject: [PATCH 17/77] add link to notification --- .../test_journal_discontinuing_soon_notify.py | 2 +- .../journal_discontinuing_soon_notify.py | 17 ++++++++++---- portality/models/v2/journal.py | 23 ++++++++++++++++++- portality/tasks/find_discontinued_soon.py | 3 ++- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py b/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py index ab62fa433f..e6e3b397e7 100644 --- a/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py +++ b/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py @@ -28,7 +28,7 @@ def test_consumes(self): event = models.Event(constants.EVENT_JOURNAL_DISCONTINUING_SOON) assert not JournalDiscontinuingSoonNotify.consumes(event) - event = models.Event(constants.EVENT_JOURNAL_DISCONTINUING_SOON, context = {"data": {"1234"}, "job": {"1234"}}) + event = models.Event(constants.EVENT_JOURNAL_DISCONTINUING_SOON, context = {"data": {"1234"}, "job": {"1234"}, "discontinue_date": "2002-22-02"}) assert JournalDiscontinuingSoonNotify.consumes(event) def test_consume_success(self): diff --git a/portality/events/consumers/journal_discontinuing_soon_notify.py b/portality/events/consumers/journal_discontinuing_soon_notify.py index f61c035014..c7945bafbe 100644 --- a/portality/events/consumers/journal_discontinuing_soon_notify.py +++ b/portality/events/consumers/journal_discontinuing_soon_notify.py @@ -1,14 +1,18 @@ # ~~JournalDiscontinuingSoonNotify:Consumer~~ import json -from portality.util import url_for +import urllib.parse +from portality.util import url_for from portality.events.consumer import EventConsumer from portality.core import app from portality import constants from portality import models -from portality.bll import DOAJ -from portality.bll import exceptions +from portality.bll import DOAJ, exceptions +from portality.lib import edges +from portality import dao + +from portality.models.v2.journal import JournalDiscontinuedDateQuery class JournalDiscontinuingSoonNotify(EventConsumer): ID = "journal:assed:discontinuing_soon:notify" @@ -17,12 +21,14 @@ class JournalDiscontinuingSoonNotify(EventConsumer): def consumes(cls, event): return event.id == constants.EVENT_JOURNAL_DISCONTINUING_SOON and \ event.context.get("job") is not None and \ - event.context.get("data") is not None + event.context.get("data") is not None and \ + event.context.get("discontinue_date") is not None @classmethod def consume(cls, event): data = event.context.get("data") source = event.context.get("job") + discontinued_date = event.context.get("discontinue_date") try: job = models.BackgroundJob(**source) except Exception as e: @@ -53,6 +59,7 @@ def consume(cls, event): data=json.dumps({"data": data}, indent=4, separators=(',', ': ')) ) notification.short = svc.short_notification(cls.ID) - notification.action = url_for("dashboard.notifications") + q = JournalDiscontinuedDateQuery(discontinued_date=discontinued_date).query() + notification.action = url_for('admin.index') + '?ref=toc&source=' + dao.Facetview2.url_encode_query(q) svc.notify(notification) diff --git a/portality/models/v2/journal.py b/portality/models/v2/journal.py index 03ef069b70..fb9246be1f 100644 --- a/portality/models/v2/journal.py +++ b/portality/models/v2/journal.py @@ -1121,4 +1121,25 @@ def query(self): "sort" : [ {"created_date" : {"order" : "desc"}} ] - } \ No newline at end of file + } + +class JournalDiscontinuedDateQuery(object): + base_query = { + "track_total_hits": True, + "query": { + "bool": { + "must": [ + {"terms": {"bibjson.discontinued_date": ""}} + ] + } + }, + "size": 10000 + } + + def __init__(self, discontinued_date): + self.discontinued_date = discontinued_date + + def query(self): + q = deepcopy(self.base_query) + q["query"]["bool"]["must"][0]["terms"]["bibjson.discontinued_date"] = [self.discontinued_date] + return q \ No newline at end of file diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index 6762a5b315..a0bc15f261 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -70,7 +70,8 @@ def run(self): { "context": "job", "data": journals, - "job": job + "job": job, + "discontinue_date": _date() })) else: job.add_audit_message(Messages.NO_DISCONTINUED_JOURNALS_FOUND_LOG) From 555e1a6231b368d1703980222c5838c5d1759353 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Wed, 15 Feb 2023 16:27:42 +0000 Subject: [PATCH 18/77] send separate notifications to appropriate managing editors --- cms/data/notifications.yml | 7 +- .../journal_discontinuing_soon_notify.py | 37 +++++----- portality/settings.py | 2 +- portality/tasks/find_discontinued_soon.py | 70 ++++++++----------- 4 files changed, 52 insertions(+), 64 deletions(-) diff --git a/cms/data/notifications.yml b/cms/data/notifications.yml index a33ae53b5c..d06d287d0d 100644 --- a/cms/data/notifications.yml +++ b/cms/data/notifications.yml @@ -144,9 +144,6 @@ update_request:publisher:rejected:notify: journal:assed:discontinuing_soon:notify: long: | - Following journals will discontinue in {days} days. - - {data} + Journal "{title}" (id: {id}) will discontinue in {days} days. short: - Journals discontinuing soon found - + Journals discontinuing soon found \ No newline at end of file diff --git a/portality/events/consumers/journal_discontinuing_soon_notify.py b/portality/events/consumers/journal_discontinuing_soon_notify.py index c7945bafbe..09e3f1cb70 100644 --- a/portality/events/consumers/journal_discontinuing_soon_notify.py +++ b/portality/events/consumers/journal_discontinuing_soon_notify.py @@ -20,46 +20,45 @@ class JournalDiscontinuingSoonNotify(EventConsumer): @classmethod def consumes(cls, event): return event.id == constants.EVENT_JOURNAL_DISCONTINUING_SOON and \ - event.context.get("job") is not None and \ - event.context.get("data") is not None and \ + event.context.get("journal") is not None and \ event.context.get("discontinue_date") is not None @classmethod def consume(cls, event): - data = event.context.get("data") - source = event.context.get("job") + journal_id = event.context.get("journal") discontinued_date = event.context.get("discontinue_date") - try: - job = models.BackgroundJob(**source) - except Exception as e: - raise exceptions.NoSuchObjectException( - "Unable to construct a BackgroundJob object from the data supplied {x}".format(x=e)) - if job.user is None: + journal = models.Journal.pull(journal_id) + if journal is None: return - acc = models.Account.pull(job.user) - if acc is None or not acc.has_role("admin"): + app_id = journal.latest_related_application_id() + if app_id is None: return + else: + application = models.Application.pull(app_id) + if not application.editor_group: + return - journals = [] - for j in data: - journals.append(j["id"]) + eg = models.EditorGroup.pull_by_key("name", application.editor_group) + managing_editor = eg.maned + if not managing_editor: + return # ~~-> Notifications:Service ~~ svc = DOAJ.notificationsService() notification = models.Notification() - notification.who = acc.id + notification.who = managing_editor notification.created_by = cls.ID notification.classification = constants.NOTIFICATION_CLASSIFICATION_STATUS notification.long = svc.long_notification(cls.ID).format( days=app.config.get('DISCONTINUED_DATE_DELTA',1), - data=json.dumps({"data": data}, indent=4, separators=(',', ': ')) + title=journal.bibjson().title, + id=journal.id ) notification.short = svc.short_notification(cls.ID) - q = JournalDiscontinuedDateQuery(discontinued_date=discontinued_date).query() - notification.action = url_for('admin.index') + '?ref=toc&source=' + dao.Facetview2.url_encode_query(q) + notification.action = url_for("admin.journal_page", journal_id=journal.id) svc.notify(notification) diff --git a/portality/settings.py b/portality/settings.py index ab044207d6..6711a70bbd 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -1357,4 +1357,4 @@ } # report journals that discontinue in ... days (eg. 1 = tomorrow) -DISCONTINUED_DATE_DELTA = 1 \ No newline at end of file +DISCONTINUED_DATE_DELTA = 0 \ No newline at end of file diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index a0bc15f261..0562f09297 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -45,17 +45,7 @@ def find_journals_discontinuing_soon(self, job): for journal in models.Journal.iterate(q=DiscontinuedSoonQuery.query(), keepalive='5m', wrap=True): # ~~->Journal:Model~~ - bibjson = journal.bibjson() - owner = journal.owner - account = models.Account.pull(owner) - - jdata.append({"id": journal.id, - "title":bibjson.title, - "eissn": bibjson.get_one_identifier(bibjson.E_ISSN), - "pissn": bibjson.get_one_identifier(bibjson.P_ISSN), - "account_email": account.email if account else "Not Found", - "publisher": bibjson.publisher, - "discontinued date": bibjson.discontinued_date}) + jdata.append(journal.id) job.add_audit_message(Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id=journal.id)) return jdata @@ -64,15 +54,14 @@ def run(self): job = self.background_job journals = self.find_journals_discontinuing_soon(job=job) if len(journals): - DOAJ.eventsService().trigger(models.Event( - constants.EVENT_JOURNAL_DISCONTINUING_SOON, - "system", - { - "context": "job", - "data": journals, - "job": job, - "discontinue_date": _date() - })) + for j in journals: + DOAJ.eventsService().trigger(models.Event( + constants.EVENT_JOURNAL_DISCONTINUING_SOON, + "system", + { + "journal": j, + "discontinue_date": _date() + })) else: job.add_audit_message(Messages.NO_DISCONTINUED_JOURNALS_FOUND_LOG) @@ -124,22 +113,25 @@ def find_discontinued_soon(job_id): task = FindDiscontinuedSoonBackgroundTask(job) BackgroundApi.execute(task) -def find_journals_discontinuing_soon(): - jdata = [] - - for journal in models.Journal.iterate(q=DiscontinuedSoonQuery.query(), keepalive='5m', wrap=True): - # ~~->Journal:Model~~ - bibjson = journal.bibjson() - owner = journal.owner - account = models.Account.pull(owner) - - jdata.append({"id": journal.id, - "title":bibjson.title, - "eissn": bibjson.get_one_identifier(bibjson.E_ISSN), - "pissn": bibjson.get_one_identifier(bibjson.P_ISSN), - "account_email": account.email if account else "Not Found", - "publisher": bibjson.publisher, - "discontinued date": bibjson.discontinued_date}) - job.add_audit_message(Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id=journal.id)) - - return jdata \ No newline at end of file + +# Test code - please do not clean up until after the tests +# def find_journals_discontinuing_soon(): +# jdata = [] +# +# for journal in models.Journal.iterate(q=DiscontinuedSoonQuery.query(), keepalive='5m', wrap=True): +# # ~~->Journal:Model~~ +# jdata.append(journal.id) +# +# return jdata +# +# if __name__ == "__main__": +# journals = find_journals_discontinuing_soon() +# if len(journals): +# for j in journals: +# DOAJ.eventsService().trigger(models.Event( +# constants.EVENT_JOURNAL_DISCONTINUING_SOON, +# "system", +# { +# "journal": j, +# "discontinue_date": _date() +# })) \ No newline at end of file From b9e984fad203b726438fe84802adc60ba14b2fbf Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Wed, 15 Feb 2023 16:35:07 +0000 Subject: [PATCH 19/77] check for current application --- .../consumers/journal_discontinuing_soon_notify.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/portality/events/consumers/journal_discontinuing_soon_notify.py b/portality/events/consumers/journal_discontinuing_soon_notify.py index 09e3f1cb70..5502ebddae 100644 --- a/portality/events/consumers/journal_discontinuing_soon_notify.py +++ b/portality/events/consumers/journal_discontinuing_soon_notify.py @@ -32,11 +32,13 @@ def consume(cls, event): if journal is None: return - app_id = journal.latest_related_application_id() + app_id = journal.current_application if app_id is None: - return - else: - application = models.Application.pull(app_id) + app_id = journal.latest_related_application_id() + if app_id is None: + return + + application = models.Application.pull(app_id) if not application.editor_group: return From ae807e82231ff5b3efa6f7f1aecedde375c15e11 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Wed, 15 Feb 2023 16:42:50 +0000 Subject: [PATCH 20/77] remove unnecessary setting --- portality/settings.py | 1 - 1 file changed, 1 deletion(-) diff --git a/portality/settings.py b/portality/settings.py index 6711a70bbd..878619ea91 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -341,7 +341,6 @@ MANAGING_EDITOR_EMAIL = "managing-editors@doaj.org" CONTACT_FORM_ADDRESS = "feedback+contactform@doaj.org" SCRIPT_TAG_DETECTED_EMAIL_RECIPIENTS = ["helpdesk@doaj.org"] -DISCONTINUED_JOURNALS_FOUND_RECEIPIENTS = ["dom@doaj.org"] SYSTEM_EMAIL_FROM = 'helpdesk@doaj.org' CC_ALL_EMAILS_TO = SYSTEM_EMAIL_FROM # DOAJ may get a dedicated inbox in the future From 24214f7c8ded9c5aa48e1d36bb7549e2a7a9b1d8 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Fri, 17 Feb 2023 12:34:57 +0000 Subject: [PATCH 21/77] fix imports and tests --- .../test_journal_discontinuing_soon_notify.py | 40 ++++++++++++++----- portality/app.py | 2 +- portality/tasks/find_discontinued_soon.py | 2 +- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py b/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py index e6e3b397e7..f4f70f2f78 100644 --- a/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py +++ b/doajtest/unit/event_consumers/test_journal_discontinuing_soon_notify.py @@ -2,22 +2,43 @@ from portality import constants from portality.bll import exceptions from doajtest.helpers import DoajTestCase -from doajtest.fixtures import JournalFixtureFactory +from doajtest.fixtures import JournalFixtureFactory, ApplicationFixtureFactory from portality.events.consumers.journal_discontinuing_soon_notify import JournalDiscontinuingSoonNotify from doajtest.fixtures import BackgroundFixtureFactory import time +# Mock required to make application lookup work +@classmethod +def pull_application(cls, id): + app = models.Application(**ApplicationFixtureFactory.make_application_source()) + return app + +@classmethod +def pull_by_key(cls, key, value): + ed = models.EditorGroup() + acc = models.Account() + acc.set_id('testuser') + acc.set_email("test@example.com") + acc.save(blocking=True) + ed.set_maned(acc.id) + ed.save(blocking=True) + + return ed class TestJournalDiscontinuingSoonNotify(DoajTestCase): def setUp(self): super(TestJournalDiscontinuingSoonNotify, self).setUp() + self.pull_application = models.Application.pull + models.Application.pull = pull_application + self.pull_by_key = models.EditorGroup.pull_by_key + models.EditorGroup.pull_by_key = pull_by_key def tearDown(self): super(TestJournalDiscontinuingSoonNotify, self).tearDown() + models.Application.pull = self.pull_application + models.EditorGroup.pull_by_key = self.pull_by_key def test_consumes(self): - event = models.Event(constants.EVENT_JOURNAL_DISCONTINUING_SOON, context={"job" : {}}) - assert not JournalDiscontinuingSoonNotify.consumes(event) event = models.Event("test:event", context={"data" : {"1234"}}) assert not JournalDiscontinuingSoonNotify.consumes(event) @@ -28,7 +49,7 @@ def test_consumes(self): event = models.Event(constants.EVENT_JOURNAL_DISCONTINUING_SOON) assert not JournalDiscontinuingSoonNotify.consumes(event) - event = models.Event(constants.EVENT_JOURNAL_DISCONTINUING_SOON, context = {"data": {"1234"}, "job": {"1234"}, "discontinue_date": "2002-22-02"}) + event = models.Event(constants.EVENT_JOURNAL_DISCONTINUING_SOON, context = {"journal": {"1234"}, "discontinue_date": "2002-22-02"}) assert JournalDiscontinuingSoonNotify.consumes(event) def test_consume_success(self): @@ -44,9 +65,11 @@ def test_consume_success(self): acc.add_role('admin') acc.save(blocking=True) + source = JournalFixtureFactory.make_journal_source() + journal = models.Journal(**source) + journal.save(blocking=True) - - event = models.Event(constants.BACKGROUND_JOB_FINISHED, context={"job" : bj.data, "data" : JournalFixtureFactory.make_many_journal_sources(2)}) + event = models.Event(constants.BACKGROUND_JOB_FINISHED, context={"job" : bj.data, "journal" : journal.id}) JournalDiscontinuingSoonNotify.consume(event) time.sleep(2) @@ -61,8 +84,3 @@ def test_consume_success(self): assert n.short is not None assert n.action is not None assert not n.is_seen() - - def test_consume_fail(self): - event = models.Event(constants.NOTIFICATION_CLASSIFICATION_STATUS, context={"job": "abcd"}) - with self.assertRaises(exceptions.NoSuchObjectException): - JournalDiscontinuingSoonNotify.consume(event) diff --git a/portality/app.py b/portality/app.py index 9f3a674a55..a11a928959 100644 --- a/portality/app.py +++ b/portality/app.py @@ -17,7 +17,7 @@ from flask import request, abort, render_template, redirect, send_file, url_for, jsonify, send_from_directory from flask_login import login_user, current_user -from datetime import datetime, date +from datetime import datetime import portality.models as models from portality.core import app, es_connection, initialise_index diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index 0562f09297..2214a6e560 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -8,7 +8,7 @@ from portality.tasks.redis_huey import main_queue -from portality.background import BackgroundTask, BackgroundSummary +from portality.background import BackgroundTask, BackgroundSummary, BackgroundApi from portality.tasks.helpers import background_helper from portality.ui.messages import Messages from portality import constants From f54af1c0f2e17efd8cdd7a8081a6d147ded17a59 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Fri, 17 Feb 2023 12:40:48 +0000 Subject: [PATCH 22/77] fix task test --- doajtest/unit/test_task_discontinued_soon.py | 52 ++++++++++---------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/doajtest/unit/test_task_discontinued_soon.py b/doajtest/unit/test_task_discontinued_soon.py index f6a4be9483..3c9e4bcd1d 100644 --- a/doajtest/unit/test_task_discontinued_soon.py +++ b/doajtest/unit/test_task_discontinued_soon.py @@ -9,38 +9,40 @@ from portality.ui.messages import Messages from doajtest.fixtures import JournalFixtureFactory +DELTA = app.config.get('DISCONTINUED_DATE_DELTA',1) + class TestDiscontinuedSoon(DoajTestCase): - def _date_tomorrow(self): - return (datetime.datetime.today() + datetime.timedelta(days=1)).strftime('%Y-%m-%d') + def _date_to_found(self): + return (datetime.datetime.today() + datetime.timedelta(days=DELTA)).strftime('%Y-%m-%d') - def _date_in_2_days(self): - return (datetime.datetime.today() + datetime.timedelta(days=2)).strftime('%Y-%m-%d') + def _date_too_late(self): + return (datetime.datetime.today() + datetime.timedelta(days=DELTA+1)).strftime('%Y-%m-%d') def test_discontinued_soon_found(self): # Both these should be found - journal_discontinued_tommorow_1 = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) - journal_discontinued_tommorow_1.set_id("1") - jbib = journal_discontinued_tommorow_1.bibjson() + journal_discontinued_to_found_1 = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) + journal_discontinued_to_found_1.set_id("1") + jbib = journal_discontinued_to_found_1.bibjson() jbib.title = "Discontinued Tomorrow 1" - jbib.discontinued_date = self._date_tomorrow() - journal_discontinued_tommorow_1.save(blocking=True) + jbib.discontinued_date = self._date_to_found() + journal_discontinued_to_found_1.save(blocking=True) - journal_discontinued_tommorow_2 = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) - journal_discontinued_tommorow_2.set_id("2") - jbib = journal_discontinued_tommorow_2.bibjson() + journal_discontinued_to_found_2 = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) + journal_discontinued_to_found_2.set_id("2") + jbib = journal_discontinued_to_found_2.bibjson() jbib.title = "Discontinued Tomorrow 2" - jbib.discontinued_date = self._date_tomorrow() - journal_discontinued_tommorow_2.save(blocking=True) + jbib.discontinued_date = self._date_to_found() + journal_discontinued_to_found_2.save(blocking=True) # that shouldn't be found - journal_discontinued_in_2_days = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) - journal_discontinued_in_2_days.set_id("3") - jbib = journal_discontinued_in_2_days.bibjson() + journal_discontinued_too_late = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) + journal_discontinued_too_late.set_id("3") + jbib = journal_discontinued_too_late.bibjson() jbib.title = "Discontinued In 2 days" - jbib.discontinued_date = self._date_in_2_days() - journal_discontinued_in_2_days.save(blocking=True) + jbib.discontinued_date = self._date_too_late() + journal_discontinued_too_late.save(blocking=True) job = find_discontinued_soon.FindDiscontinuedSoonBackgroundTask.prepare("system") task = find_discontinued_soon.FindDiscontinuedSoonBackgroundTask(job) @@ -53,18 +55,18 @@ def test_discontinued_soon_found(self): def test_discontinued_soon_not_found(self): # None of these should be found - this one discontinues in 2 days - journal_discontinued_in_2_days = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) - journal_discontinued_in_2_days.set_id("1") - jbib = journal_discontinued_in_2_days.bibjson() + journal_discontinued_too_late = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) + journal_discontinued_too_late.set_id("1") + jbib = journal_discontinued_too_late.bibjson() jbib.title = "Discontinued In 2 days" - jbib.discontinued_date = self._date_in_2_days() - journal_discontinued_in_2_days.save(blocking=True) + jbib.discontinued_date = self._date_too_late() + journal_discontinued_too_late.save(blocking=True) # this one is not in doaj journal_not_in_doaj = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=False)) journal_not_in_doaj.set_id("2") jbib = journal_not_in_doaj.bibjson() - jbib.discontinued_date = self._date_tomorrow() + jbib.discontinued_date = self._date_to_found() journal_not_in_doaj.save(blocking=True) job = find_discontinued_soon.FindDiscontinuedSoonBackgroundTask.prepare("system") From 82b206a972ea41fb26fa8bb56f633e0e0fb3c008 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Tue, 7 Mar 2023 14:16:49 +0000 Subject: [PATCH 23/77] fix the filter --- portality/templates/doaj/toc.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portality/templates/doaj/toc.html b/portality/templates/doaj/toc.html index 27b71c7581..de5c99a52a 100644 --- a/portality/templates/doaj/toc.html +++ b/portality/templates/doaj/toc.html @@ -84,7 +84,7 @@

- {% if bibjson.discontinued_date | is_in_the_past %} + {% if bibjson.discontinued_date is not none and bibjson.discontinued_date | is_in_the_past %}

Ceased publication on {{ bibjson.discontinued_datestamp.strftime("%d %B %Y") }}

{% endif %} From ffd151dc0b45c737064493e7f9a08640538c5a0d Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Mon, 20 Mar 2023 12:47:14 +0000 Subject: [PATCH 24/77] remove unused method --- portality/models/v2/journal.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/portality/models/v2/journal.py b/portality/models/v2/journal.py index fb9246be1f..edd2d5b397 100644 --- a/portality/models/v2/journal.py +++ b/portality/models/v2/journal.py @@ -1122,24 +1122,3 @@ def query(self): {"created_date" : {"order" : "desc"}} ] } - -class JournalDiscontinuedDateQuery(object): - base_query = { - "track_total_hits": True, - "query": { - "bool": { - "must": [ - {"terms": {"bibjson.discontinued_date": ""}} - ] - } - }, - "size": 10000 - } - - def __init__(self, discontinued_date): - self.discontinued_date = discontinued_date - - def query(self): - q = deepcopy(self.base_query) - q["query"]["bool"]["must"][0]["terms"]["bibjson.discontinued_date"] = [self.discontinued_date] - return q \ No newline at end of file From b35475182fa88ecf95e58928e1c388238f61a39e Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Mon, 20 Mar 2023 12:48:59 +0000 Subject: [PATCH 25/77] default discontinued date delta to 0 --- portality/events/consumers/journal_discontinuing_soon_notify.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portality/events/consumers/journal_discontinuing_soon_notify.py b/portality/events/consumers/journal_discontinuing_soon_notify.py index 5502ebddae..79f1349a24 100644 --- a/portality/events/consumers/journal_discontinuing_soon_notify.py +++ b/portality/events/consumers/journal_discontinuing_soon_notify.py @@ -56,7 +56,7 @@ def consume(cls, event): notification.created_by = cls.ID notification.classification = constants.NOTIFICATION_CLASSIFICATION_STATUS notification.long = svc.long_notification(cls.ID).format( - days=app.config.get('DISCONTINUED_DATE_DELTA',1), + days=app.config.get('DISCONTINUED_DATE_DELTA',0), title=journal.bibjson().title, id=journal.id ) From ccf94f1c2528275cf660627d455f0dbd556d6d8a Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Mon, 20 Mar 2023 13:03:14 +0000 Subject: [PATCH 26/77] add functionality to dates lib --- portality/lib/dates.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/portality/lib/dates.py b/portality/lib/dates.py index 7c81618cf8..c061f5af7d 100644 --- a/portality/lib/dates.py +++ b/portality/lib/dates.py @@ -71,9 +71,18 @@ def before_now(seconds: int): return before(datetime.utcnow(), seconds) -def after(timestamp, seconds): +def seconds_after(timestamp, seconds): return timestamp + timedelta(seconds=seconds) +def seconds_after_now(timestamp, seconds): + return after(datetime.utcnow(), seconds) + +def days_after(timestamp, days): + return timestamp + timedelta(days=days) + +def days_after_now(timestamp, days): + return days_after(datetime.utcnow(), days) + def eta(since, sofar, total): now = datetime.utcnow() @@ -116,3 +125,13 @@ def day_ranges(fro, to): def human_date(stamp, string_format="%d %B %Y"): return reformat(stamp, out_format=string_format) + +def is_before(mydate, comparison=None): + if comparison is None: + comparison = datetime.utcnow() + if isinstance(mydate, str): + mydate = parse(mydate) + if isinstance(comparison, str): + comparison = parse(comparison) + return mydate < comparison + From d30fbd2fd1db435ea77842cfa57bf3777abb73f6 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Mon, 20 Mar 2023 13:03:29 +0000 Subject: [PATCH 27/77] refactor DiscontinuedSoonQuery --- portality/tasks/find_discontinued_soon.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index 2214a6e560..9e0e4b82db 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -4,6 +4,7 @@ from portality.core import app from portality.bll import DOAJ +from portality.lib import dates from portality import models,app_email from portality.tasks.redis_huey import main_queue @@ -18,6 +19,9 @@ def _date(): return (datetime.datetime.today() + datetime.timedelta(days=app.config.get('DISCONTINUED_DATE_DELTA', 1))).strftime( '%Y-%m-%d') class DiscontinuedSoonQuery: + def __init__(self, time_delta=None): + self._delta = time_delta if time_delta is not None else app.config.get('DISCONTINUED_DATE_DELTA', 1); + self._date = days_after_now(days=time_delta) @classmethod def query(cls): return { @@ -26,7 +30,7 @@ def query(cls): "filter": { "bool" : { "must": [ - {"term" : {"bibjson.discontinued_date": _date()}}, + {"term" : {"bibjson.discontinued_date": self._date}}, {"term" : {"admin.in_doaj":True}} ] } From ef0510a06e3472b1183756584831ba8009eb3316 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Mon, 20 Mar 2023 13:11:00 +0000 Subject: [PATCH 28/77] use dates lib in jinja filter --- portality/app.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/portality/app.py b/portality/app.py index a11a928959..218fd4e793 100644 --- a/portality/app.py +++ b/portality/app.py @@ -281,8 +281,7 @@ def form_diff_table_subject_expand(val): @app.template_filter("is_in_the_past") def is_in_the_past(dttm): - date = datetime.strptime(dttm, "%Y-%m-%d").date() - return date <= date.today() + return dates.is_before(dates.today()) ####################################################### From a3d869491755c62708f15b9b153bb4cb3d756a08 Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Mon, 20 Mar 2023 13:26:46 +0000 Subject: [PATCH 29/77] fix errors --- .../consumers/journal_discontinuing_soon_notify.py | 3 --- portality/lib/dates.py | 4 ++-- portality/tasks/find_discontinued_soon.py | 14 +++++++------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/portality/events/consumers/journal_discontinuing_soon_notify.py b/portality/events/consumers/journal_discontinuing_soon_notify.py index 79f1349a24..7f41dd8ba7 100644 --- a/portality/events/consumers/journal_discontinuing_soon_notify.py +++ b/portality/events/consumers/journal_discontinuing_soon_notify.py @@ -11,9 +11,6 @@ from portality.lib import edges from portality import dao - -from portality.models.v2.journal import JournalDiscontinuedDateQuery - class JournalDiscontinuingSoonNotify(EventConsumer): ID = "journal:assed:discontinuing_soon:notify" diff --git a/portality/lib/dates.py b/portality/lib/dates.py index c061f5af7d..7d394f0559 100644 --- a/portality/lib/dates.py +++ b/portality/lib/dates.py @@ -74,13 +74,13 @@ def before_now(seconds: int): def seconds_after(timestamp, seconds): return timestamp + timedelta(seconds=seconds) -def seconds_after_now(timestamp, seconds): +def seconds_after_now(seconds: int): return after(datetime.utcnow(), seconds) def days_after(timestamp, days): return timestamp + timedelta(days=days) -def days_after_now(timestamp, days): +def days_after_now(days: int): return days_after(datetime.utcnow(), days) diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index 9e0e4b82db..5111a4af51 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -20,17 +20,16 @@ def _date(): '%Y-%m-%d') class DiscontinuedSoonQuery: def __init__(self, time_delta=None): - self._delta = time_delta if time_delta is not None else app.config.get('DISCONTINUED_DATE_DELTA', 1); - self._date = days_after_now(days=time_delta) - @classmethod - def query(cls): + self._delta = time_delta if time_delta is not None else app.config.get('DISCONTINUED_DATE_DELTA', 0); + self._date = dates.days_after_now(days=self._delta) + def query(self): return { "query": { "bool": { "filter": { "bool" : { "must": [ - {"term" : {"bibjson.discontinued_date": self._date}}, + {"term" : {"bibjson.discontinued_date": dates.format(self._date, format="%Y-%m-%d")}}, {"term" : {"admin.in_doaj":True}} ] } @@ -47,7 +46,7 @@ class FindDiscontinuedSoonBackgroundTask(BackgroundTask): def find_journals_discontinuing_soon(self, job): jdata = [] - for journal in models.Journal.iterate(q=DiscontinuedSoonQuery.query(), keepalive='5m', wrap=True): + for journal in models.Journal.iterate(q=DiscontinuedSoonQuery().query(), keepalive='5m', wrap=True): # ~~->Journal:Model~~ jdata.append(journal.id) job.add_audit_message(Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id=journal.id)) @@ -122,7 +121,8 @@ def find_discontinued_soon(job_id): # def find_journals_discontinuing_soon(): # jdata = [] # -# for journal in models.Journal.iterate(q=DiscontinuedSoonQuery.query(), keepalive='5m', wrap=True): +# q = DiscontinuedSoonQuery() +# for journal in models.Journal.iterate(q=q.query(), keepalive='5m', wrap=True): # # ~~->Journal:Model~~ # jdata.append(journal.id) # From 427ad2bb8b229422857740ee52f82bb640a3c23c Mon Sep 17 00:00:00 2001 From: Aga Domanska Date: Mon, 27 Mar 2023 12:00:03 +0100 Subject: [PATCH 30/77] new full new notification type - alert --- portality/constants.py | 2 +- .../static/js/edges/notifications.edge.js | 5 ++ portality/tasks/find_discontinued_soon.py | 52 +++++++++---------- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/portality/constants.py b/portality/constants.py index 2600c65173..cfd7346711 100644 --- a/portality/constants.py +++ b/portality/constants.py @@ -55,7 +55,7 @@ EVENT_JOURNAL_EDITOR_GROUP_ASSIGNED = "journal:editor_group:assigned" EVENT_JOURNAL_DISCONTINUING_SOON = "journal:discontinuing_soon" -NOTIFICATION_CLASSIFICATION_STATUS = "status" +NOTIFICATION_CLASSIFICATION_STATUS = "alert" NOTIFICATION_CLASSIFICATION_STATUS_CHANGE = "status_change" NOTIFICATION_CLASSIFICATION_ASSIGN = "assign" NOTIFICATION_CLASSIFICATION_CREATE = "create" diff --git a/portality/static/js/edges/notifications.edge.js b/portality/static/js/edges/notifications.edge.js index 65788540ad..4b8c00e083 100644 --- a/portality/static/js/edges/notifications.edge.js +++ b/portality/static/js/edges/notifications.edge.js @@ -10,6 +10,10 @@ $.extend(true, doaj, { seen_url: "/dashboard/notifications/{notification_id}/seen", icons: { + alert: ` + + + `, finished: ` @@ -34,6 +38,7 @@ $.extend(true, doaj, { }, classifications: { + alert: "Requires attention", finished: "Task has completed", status_change: "Application status change", assign: "Assigned to user" diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index 5111a4af51..16786480d2 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -14,10 +14,6 @@ from portality.ui.messages import Messages from portality import constants - -def _date(): - return (datetime.datetime.today() + datetime.timedelta(days=app.config.get('DISCONTINUED_DATE_DELTA', 1))).strftime( - '%Y-%m-%d') class DiscontinuedSoonQuery: def __init__(self, time_delta=None): self._delta = time_delta if time_delta is not None else app.config.get('DISCONTINUED_DATE_DELTA', 0); @@ -43,6 +39,10 @@ def query(self): class FindDiscontinuedSoonBackgroundTask(BackgroundTask): __action__ = "find_discontinued_soon" + def __init__(self, time_delta=None): + self._delta = time_delta if time_delta is not None else app.config.get('DISCONTINUED_DATE_DELTA', 0); + self._date = dates.days_after_now(days=self._delta) + def find_journals_discontinuing_soon(self, job): jdata = [] @@ -63,7 +63,7 @@ def run(self): "system", { "journal": j, - "discontinue_date": _date() + "discontinue_date": self._date() })) else: job.add_audit_message(Messages.NO_DISCONTINUED_JOURNALS_FOUND_LOG) @@ -118,24 +118,24 @@ def find_discontinued_soon(job_id): # Test code - please do not clean up until after the tests -# def find_journals_discontinuing_soon(): -# jdata = [] -# -# q = DiscontinuedSoonQuery() -# for journal in models.Journal.iterate(q=q.query(), keepalive='5m', wrap=True): -# # ~~->Journal:Model~~ -# jdata.append(journal.id) -# -# return jdata -# -# if __name__ == "__main__": -# journals = find_journals_discontinuing_soon() -# if len(journals): -# for j in journals: -# DOAJ.eventsService().trigger(models.Event( -# constants.EVENT_JOURNAL_DISCONTINUING_SOON, -# "system", -# { -# "journal": j, -# "discontinue_date": _date() -# })) \ No newline at end of file +def find_journals_discontinuing_soon(): + jdata = [] + + q = DiscontinuedSoonQuery() + for journal in models.Journal.iterate(q=q.query(), keepalive='5m', wrap=True): + # ~~->Journal:Model~~ + jdata.append(journal.id) + + return jdata + +if __name__ == "__main__": + journals = find_journals_discontinuing_soon() + if len(journals): + for j in journals: + DOAJ.eventsService().trigger(models.Event( + constants.EVENT_JOURNAL_DISCONTINUING_SOON, + "system", + { + "journal": j, + "discontinue_date": dates.days_after_now(days=0) + })) \ No newline at end of file From 890f2263acba70f9512986c17ee761b160249622 Mon Sep 17 00:00:00 2001 From: Aga Date: Fri, 14 Apr 2023 10:05:18 +0100 Subject: [PATCH 31/77] fix is_before usage --- portality/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portality/app.py b/portality/app.py index 218fd4e793..1083899d85 100644 --- a/portality/app.py +++ b/portality/app.py @@ -281,7 +281,7 @@ def form_diff_table_subject_expand(val): @app.template_filter("is_in_the_past") def is_in_the_past(dttm): - return dates.is_before(dates.today()) + return dates.is_before(dttm, dates.today()) ####################################################### From 6139624309485ee1f391e943b3f5c0a66eb756dc Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 17 Apr 2023 13:28:48 +0100 Subject: [PATCH 32/77] clean up --- portality/tasks/find_discontinued_soon.py | 26 +---------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index 16786480d2..d9c281abb2 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -114,28 +114,4 @@ def scheduled_find_discontinued_soon(): def find_discontinued_soon(job_id): job = models.BackgroundJob.pull(job_id) task = FindDiscontinuedSoonBackgroundTask(job) - BackgroundApi.execute(task) - - -# Test code - please do not clean up until after the tests -def find_journals_discontinuing_soon(): - jdata = [] - - q = DiscontinuedSoonQuery() - for journal in models.Journal.iterate(q=q.query(), keepalive='5m', wrap=True): - # ~~->Journal:Model~~ - jdata.append(journal.id) - - return jdata - -if __name__ == "__main__": - journals = find_journals_discontinuing_soon() - if len(journals): - for j in journals: - DOAJ.eventsService().trigger(models.Event( - constants.EVENT_JOURNAL_DISCONTINUING_SOON, - "system", - { - "journal": j, - "discontinue_date": dates.days_after_now(days=0) - })) \ No newline at end of file + BackgroundApi.execute(task) \ No newline at end of file From 73416774d544d29013f7796fb8b8b1e81687f8fd Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Tue, 18 Apr 2023 12:48:16 +0100 Subject: [PATCH 33/77] Update the cron schedule for discontinued task --- portality/settings.py | 2 +- test.cfg | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/portality/settings.py b/portality/settings.py index 645ae5da18..30c9ddc85f 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -434,7 +434,7 @@ "anon_export": {"month": "*", "day": "10", "day_of_week": "*", "hour": "6", "minute": "30"}, "old_data_cleanup": {"month": "*", "day": "12", "day_of_week": "*", "hour": "6", "minute": "30"}, "monitor_bgjobs": {"month": "*", "day": "*/6", "day_of_week": "*", "hour": "10", "minute": "0"}, - "find_discontinued_soon": {"month": "*", "day": "*", "day_of_week": "*", "hour": "7", "minute": "0"}, + "find_discontinued_soon": {"month": "*", "day": "*", "day_of_week": "*", "hour": "0", "minute": "3"} } HUEY_TASKS = { diff --git a/test.cfg b/test.cfg index 37eea9ca92..907b59bb7b 100644 --- a/test.cfg +++ b/test.cfg @@ -55,7 +55,8 @@ HUEY_SCHEDULE = { "harvest": {"month": "*", "day": "*", "day_of_week": "*", "hour": "5", "minute": "30"}, "anon_export": CRON_NEVER, "old_data_cleanup": {"month": "*", "day": "*", "day_of_week": "3", "hour": "12", "minute": "0"}, - "monitor_bgjobs": {"month": "*", "day": "*/6", "day_of_week": "*", "hour": "10", "minute": "0"} + "monitor_bgjobs": {"month": "*", "day": "*/6", "day_of_week": "*", "hour": "10", "minute": "0"}, + "find_discontinued_soon": {"month": "*", "day": "*", "day_of_week": "*", "hour": "0", "minute": "3"} } # ======================= From ea294dc4e1419cad8c692c12c60645cf5be48de4 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Tue, 2 May 2023 17:52:57 +0100 Subject: [PATCH 34/77] Add missing import for new background job --- portality/tasks/consumer_long_running.py | 2 +- portality/tasks/consumer_main_queue.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/portality/tasks/consumer_long_running.py b/portality/tasks/consumer_long_running.py index bf0aa61b61..ff8763e148 100644 --- a/portality/tasks/consumer_long_running.py +++ b/portality/tasks/consumer_long_running.py @@ -16,4 +16,4 @@ from portality.tasks.harvester import scheduled_harvest # noqa from portality.tasks.anon_export import scheduled_anon_export, anon_export # noqa from portality.tasks.old_data_cleanup import scheduled_old_data_cleanup, execute_old_data_cleanup # noqa -from portality.tasks.monitor_bgjobs import scheduled_monitor_bgjobs, execute_monitor_bgjobs +from portality.tasks.monitor_bgjobs import scheduled_monitor_bgjobs, execute_monitor_bgjobs # noqa diff --git a/portality/tasks/consumer_main_queue.py b/portality/tasks/consumer_main_queue.py index 2eda75d8da..ea3774d560 100644 --- a/portality/tasks/consumer_main_queue.py +++ b/portality/tasks/consumer_main_queue.py @@ -26,3 +26,4 @@ from portality.tasks.async_workflow_notifications import async_workflow_notifications # noqa from portality.tasks.check_latest_es_backup import scheduled_check_latest_es_backup, check_latest_es_backup # noqa from portality.tasks.request_es_backup import scheduled_request_es_backup, request_es_backup # noqa +from portality.tasks.find_discontinued_soon import scheduled_find_discontinued_soon, find_discontinued_soon # noqa From 80ddf82fa228c0baab3d848c4f5a5c81845aa09f Mon Sep 17 00:00:00 2001 From: Aga Date: Thu, 4 May 2023 14:30:11 +0100 Subject: [PATCH 35/77] add super init to the bg job --- portality/tasks/find_discontinued_soon.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index d9c281abb2..1edac3b390 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -39,23 +39,23 @@ def query(self): class FindDiscontinuedSoonBackgroundTask(BackgroundTask): __action__ = "find_discontinued_soon" - def __init__(self, time_delta=None): + def __init__(self, job, time_delta=None): + super(FindDiscontinuedSoonBackgroundTask,self).__init__(job) self._delta = time_delta if time_delta is not None else app.config.get('DISCONTINUED_DATE_DELTA', 0); self._date = dates.days_after_now(days=self._delta) - def find_journals_discontinuing_soon(self, job): + def find_journals_discontinuing_soon(self): jdata = [] for journal in models.Journal.iterate(q=DiscontinuedSoonQuery().query(), keepalive='5m', wrap=True): # ~~->Journal:Model~~ jdata.append(journal.id) - job.add_audit_message(Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id=journal.id)) + self.background_job.add_audit_message(Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id=journal.id)) return jdata def run(self): - job = self.background_job - journals = self.find_journals_discontinuing_soon(job=job) + journals = self.find_journals_discontinuing_soon() if len(journals): for j in journals: DOAJ.eventsService().trigger(models.Event( @@ -63,10 +63,10 @@ def run(self): "system", { "journal": j, - "discontinue_date": self._date() + "discontinue_date": self._date })) else: - job.add_audit_message(Messages.NO_DISCONTINUED_JOURNALS_FOUND_LOG) + self.background_job.add_audit_message(Messages.NO_DISCONTINUED_JOURNALS_FOUND_LOG) def cleanup(self): """ From 1fdb9661551dc7f448a05fcd0827eb3dafd3ba12 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Thu, 18 May 2023 12:15:39 +0100 Subject: [PATCH 36/77] Propagate refactor of dates.after to dates.seconds_after --- doajtest/unit/api_tests/test_apiv3_discovery.py | 4 ++-- .../sync_journals_applications.py | 2 +- portality/tasks/article_duplicate_report.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doajtest/unit/api_tests/test_apiv3_discovery.py b/doajtest/unit/api_tests/test_apiv3_discovery.py index b847c48b5b..ffc94feacc 100644 --- a/doajtest/unit/api_tests/test_apiv3_discovery.py +++ b/doajtest/unit/api_tests/test_apiv3_discovery.py @@ -241,7 +241,7 @@ def test_03_applications(self): for i in range(5): a = models.Suggestion() a.set_owner("owner") - a.set_created(dates.format(dates.after(now, i))) + a.set_created(dates.format(dates.seconds_after(now, i))) bj = a.bibjson() bj.title = "Test Suggestion {x}".format(x=i) bj.add_identifier(bj.P_ISSN, "{x}000-0000".format(x=i)) @@ -256,7 +256,7 @@ def test_03_applications(self): for i in range(5): a = models.Suggestion() a.set_owner("stranger") - a.set_created(dates.format(dates.after(now, i + 5))) + a.set_created(dates.format(dates.seconds_after(now, i + 5))) bj = a.bibjson() bj.title = "Test Suggestion {x}".format(x=i) bj.add_identifier(bj.P_ISSN, "{x}000-0000".format(x=i)) diff --git a/portality/migrate/20180106_1463_ongoing_updates/sync_journals_applications.py b/portality/migrate/20180106_1463_ongoing_updates/sync_journals_applications.py index adb85410aa..4315618d51 100644 --- a/portality/migrate/20180106_1463_ongoing_updates/sync_journals_applications.py +++ b/portality/migrate/20180106_1463_ongoing_updates/sync_journals_applications.py @@ -52,7 +52,7 @@ app_created = application.created_timestamp for journal in related_journals: almu = application.last_manual_update_timestamp - almu_adjusted = dates.after(almu, 3600) + almu_adjusted = dates.seconds_after(almu, 3600) # do a load of reporting prep jc_ac_diff = int((journal.created_timestamp - app_created).total_seconds()) diff --git a/portality/tasks/article_duplicate_report.py b/portality/tasks/article_duplicate_report.py index b92616d837..04419674e6 100644 --- a/portality/tasks/article_duplicate_report.py +++ b/portality/tasks/article_duplicate_report.py @@ -72,7 +72,7 @@ def run(self): n = dates.now() diff = (n - start).total_seconds() expected_total = ((diff / a_count) * total) - estimated_finish = dates.format(dates.after(start, expected_total)) + estimated_finish = dates.format(dates.seconds_after(start, expected_total)) a_count += 1 article = models.Article(_source={'id': a[0], 'created_date': a[1], 'bibjson': {'identifier': json.loads(a[2]), 'link': json.loads(a[3]), 'title': a[4]}, 'admin': {'in_doaj': json.loads(a[5])}}) From f70586e7f4c3e0356ae95532a7ee01cc368ed3b3 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Thu, 18 May 2023 16:24:31 +0100 Subject: [PATCH 37/77] A few minor fixes to journals discontinuing task --- portality/tasks/find_discontinued_soon.py | 32 ++++++++++++----------- portality/ui/messages.py | 4 +-- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index 1edac3b390..8ca7a2524a 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -1,32 +1,30 @@ -import datetime -import csv -import json - from portality.core import app from portality.bll import DOAJ from portality.lib import dates -from portality import models,app_email +from portality import models from portality.tasks.redis_huey import main_queue -from portality.background import BackgroundTask, BackgroundSummary, BackgroundApi +from portality.background import BackgroundTask, BackgroundApi from portality.tasks.helpers import background_helper from portality.ui.messages import Messages from portality import constants + class DiscontinuedSoonQuery: def __init__(self, time_delta=None): - self._delta = time_delta if time_delta is not None else app.config.get('DISCONTINUED_DATE_DELTA', 0); + self._delta = time_delta if time_delta is not None else app.config.get('DISCONTINUED_DATE_DELTA', 0) self._date = dates.days_after_now(days=self._delta) + def query(self): return { "query": { "bool": { "filter": { - "bool" : { + "bool": { "must": [ - {"term" : {"bibjson.discontinued_date": dates.format(self._date, format="%Y-%m-%d")}}, - {"term" : {"admin.in_doaj":True}} + {"term": {"bibjson.discontinued_date": dates.format(self._date, format="%Y-%m-%d")}}, + {"term": {"admin.in_doaj": True}} ] } } @@ -34,14 +32,14 @@ def query(self): } } -# ~~FindDiscontinuedSoonBackgroundTask:Task~~ +# ~~FindDiscontinuedSoonBackgroundTask:Task~~ class FindDiscontinuedSoonBackgroundTask(BackgroundTask): __action__ = "find_discontinued_soon" def __init__(self, job, time_delta=None): - super(FindDiscontinuedSoonBackgroundTask,self).__init__(job) - self._delta = time_delta if time_delta is not None else app.config.get('DISCONTINUED_DATE_DELTA', 0); + super(FindDiscontinuedSoonBackgroundTask, self).__init__(job) + self._delta = time_delta if time_delta is not None else app.config.get('DISCONTINUED_DATE_DELTA', 0) self._date = dates.days_after_now(days=self._delta) def find_journals_discontinuing_soon(self): @@ -60,11 +58,12 @@ def run(self): for j in journals: DOAJ.eventsService().trigger(models.Event( constants.EVENT_JOURNAL_DISCONTINUING_SOON, - "system", + self.background_job.user, { "journal": j, "discontinue_date": self._date })) + self.background_job.add_audit_message(Messages.DISCONTINUED_JOURNALS_FOUND_NOTIFICATION_SENT_LOG) else: self.background_job.add_audit_message(Messages.NO_DISCONTINUED_JOURNALS_FOUND_LOG) @@ -81,6 +80,7 @@ def prepare(cls, username, **kwargs): Take an arbitrary set of keyword arguments and return an instance of a BackgroundJob, or fail with a suitable exception + :param username: User account for this task to complete as :param kwargs: arbitrary keyword arguments pertaining to this task type :return: a BackgroundJob instance representing this task """ @@ -101,8 +101,10 @@ def submit(cls, background_job): background_job.save() find_discontinued_soon.schedule(args=(background_job.id,), delay=10) + huey_helper = FindDiscontinuedSoonBackgroundTask.create_huey_helper(main_queue) + @huey_helper.register_schedule def scheduled_find_discontinued_soon(): user = app.config.get("SYSTEM_USERNAME") @@ -114,4 +116,4 @@ def scheduled_find_discontinued_soon(): def find_discontinued_soon(job_id): job = models.BackgroundJob.pull(job_id) task = FindDiscontinuedSoonBackgroundTask(job) - BackgroundApi.execute(task) \ No newline at end of file + BackgroundApi.execute(task) diff --git a/portality/ui/messages.py b/portality/ui/messages.py index aedd06ffdd..ac7f9163bc 100644 --- a/portality/ui/messages.py +++ b/portality/ui/messages.py @@ -111,8 +111,8 @@ class Messages(object): NOTIFY__DEFAULT_SHORT_NOTIFICATION = "You have a new notification" DISCONTINUED_JOURNAL_FOUND_LOG = "Journal discontinuing soon found: {id}" - DISCONTINUED_JOURNALS_FOUND_EMAIL_SENT_LOG = "Email with journals discontinuing soon sent" - DISCONTINUED_JOURNALS_FOUND_EMAIL_ERROR_LOG = "Error sending email with journals discountinuing soon." + DISCONTINUED_JOURNALS_FOUND_NOTIFICATION_SENT_LOG = "Notification with journals discontinuing soon sent." + DISCONTINUED_JOURNALS_FOUND_NOTIFICATION_ERROR_LOG = "Error sending notification with journals discontinuing soon." NO_DISCONTINUED_JOURNALS_FOUND_LOG = "No journals discontinuing soon found" From 43633cc189c00fa4ea33ba550507372209e6c641 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Fri, 19 May 2023 16:25:45 +0100 Subject: [PATCH 38/77] Remove delta arg for find discontinued soon --- portality/tasks/find_discontinued_soon.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/portality/tasks/find_discontinued_soon.py b/portality/tasks/find_discontinued_soon.py index 8ca7a2524a..379618dc0a 100644 --- a/portality/tasks/find_discontinued_soon.py +++ b/portality/tasks/find_discontinued_soon.py @@ -12,8 +12,8 @@ class DiscontinuedSoonQuery: - def __init__(self, time_delta=None): - self._delta = time_delta if time_delta is not None else app.config.get('DISCONTINUED_DATE_DELTA', 0) + def __init__(self): + self._delta = app.config.get('DISCONTINUED_DATE_DELTA', 0) self._date = dates.days_after_now(days=self._delta) def query(self): @@ -37,9 +37,9 @@ def query(self): class FindDiscontinuedSoonBackgroundTask(BackgroundTask): __action__ = "find_discontinued_soon" - def __init__(self, job, time_delta=None): + def __init__(self, job): super(FindDiscontinuedSoonBackgroundTask, self).__init__(job) - self._delta = time_delta if time_delta is not None else app.config.get('DISCONTINUED_DATE_DELTA', 0) + self._delta = app.config.get('DISCONTINUED_DATE_DELTA', 0) self._date = dates.days_after_now(days=self._delta) def find_journals_discontinuing_soon(self): From c691831569c47a579103bb97e5b52e07ae6b0364 Mon Sep 17 00:00:00 2001 From: Aga Date: Wed, 7 Jun 2023 12:41:24 +0100 Subject: [PATCH 39/77] change person notified to journal editor --- .../consumers/journal_discontinuing_soon_notify.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/portality/events/consumers/journal_discontinuing_soon_notify.py b/portality/events/consumers/journal_discontinuing_soon_notify.py index 7f41dd8ba7..11da31bb96 100644 --- a/portality/events/consumers/journal_discontinuing_soon_notify.py +++ b/portality/events/consumers/journal_discontinuing_soon_notify.py @@ -29,18 +29,10 @@ def consume(cls, event): if journal is None: return - app_id = journal.current_application - if app_id is None: - app_id = journal.latest_related_application_id() - if app_id is None: - return - - application = models.Application.pull(app_id) - - if not application.editor_group: + if not journal.editor_group: return - eg = models.EditorGroup.pull_by_key("name", application.editor_group) + eg = models.EditorGroup.pull_by_key("name", journal.editor_group) managing_editor = eg.maned if not managing_editor: return From 2fbcf73c9122ece6148d095efb9767e7d7158bf8 Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 12 Jun 2023 13:25:32 +0100 Subject: [PATCH 40/77] make expandable facets better optimised for screen readers --- cms/sass/components/_accordion.scss | 3 +++ cms/sass/components/_buttons.scss | 7 +++++++ cms/sass/main.scss | 1 + portality/static/js/doaj.fieldrender.edges.js | 18 +++++++++--------- 4 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 cms/sass/components/_accordion.scss diff --git a/cms/sass/components/_accordion.scss b/cms/sass/components/_accordion.scss new file mode 100644 index 0000000000..e066ee02f6 --- /dev/null +++ b/cms/sass/components/_accordion.scss @@ -0,0 +1,3 @@ +.accordion:focus-within { + border: $grapefruit solid; +} \ No newline at end of file diff --git a/cms/sass/components/_buttons.scss b/cms/sass/components/_buttons.scss index 1e71d3aceb..061c75c454 100644 --- a/cms/sass/components/_buttons.scss +++ b/cms/sass/components/_buttons.scss @@ -117,3 +117,10 @@ button[type="submit"].button--secondary { color: currentColor; } } + +button.aria-button { + all: inherit; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} diff --git a/cms/sass/main.scss b/cms/sass/main.scss index cdd22133b8..9b30911f48 100644 --- a/cms/sass/main.scss +++ b/cms/sass/main.scss @@ -28,6 +28,7 @@ "layout/sidenav", "components/alert", + "components/accordion", "components/back-to-top", "components/buttons", "components/card", diff --git a/portality/static/js/doaj.fieldrender.edges.js b/portality/static/js/doaj.fieldrender.edges.js index 01f5589f2f..d2afa72b07 100644 --- a/portality/static/js/doaj.fieldrender.edges.js +++ b/portality/static/js/doaj.fieldrender.edges.js @@ -645,13 +645,13 @@ $.extend(true, doaj, { toggle = ''; } var placeholder = 'Search ' + this.component.nodeCount + ' subjects'; - var frag = '

' + this.title + toggle + '

\ - '; // substitute in the component parts frag = frag.replace(/{{FILTERS}}/g, treeFrag); @@ -1833,10 +1833,10 @@ $.extend(true, doaj, { if (this.togglable) { toggle = ''; } - var frag = '

' + this.component.display + toggle + '

\ - '; // substitute in the component parts frag = frag.replace(/{{FILTERS}}/g, filterFrag + results); @@ -2084,10 +2084,10 @@ $.extend(true, doaj, { if (this.togglable) { toggle = ''; } - var frag = '

' + this.component.display + toggle + '

\ - '; // substitute in the component parts frag = frag.replace(/{{FILTERS}}/g, filterFrag + results); From 24e4c14c3a2ffb6c7afacfe349c1bb0509a741b4 Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 12 Jun 2023 14:10:58 +0100 Subject: [PATCH 41/77] add functional test --- doajtest/testbook/public_site/public_search.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doajtest/testbook/public_site/public_search.yml b/doajtest/testbook/public_site/public_search.yml index 1bce101f8c..bc72ad24f9 100644 --- a/doajtest/testbook/public_site/public_search.yml +++ b/doajtest/testbook/public_site/public_search.yml @@ -166,3 +166,16 @@ tests: results: - You are taken to the full text of this article on the Web. It opens in a new tab +- title: 'Test Public Search Results Display: Accessibility' + context: + role: anonymous + steps: + - step: Go to the DOAJ search page at /search/articles + - step: Turn on a screen reader + results: + - Extendable facets are focusable and focus is marked with an orange solid border + - The screenreader gives the header role ("button") + - The screenreader gives the state of the facet ("extended" or "folded") + - step: click spacebar to fold/unfold the facet + resuts: + - screenreader gives correct state of the facet ("extended" or "folded") From 26ea10d3f4e8cc4acf715781b429d2e95139bd5c Mon Sep 17 00:00:00 2001 From: Ramakrishna Date: Fri, 7 Jul 2023 15:48:09 +0530 Subject: [PATCH 42/77] new script generate report for number of applications per year depending on status --- .../scripts/application_status_report.py | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 portality/scripts/application_status_report.py diff --git a/portality/scripts/application_status_report.py b/portality/scripts/application_status_report.py new file mode 100644 index 0000000000..e94192c471 --- /dev/null +++ b/portality/scripts/application_status_report.py @@ -0,0 +1,85 @@ +from portality import models +import csv + +"""This script generates a report of the status of applications in the DOAJ. The output is a CSV file with number + of applications in each status(new, accepted, rejected) for each year.""" + + +def date_applied_query(date_year): + return { + "query": { + "bool": { + "must": [ + { + "term": { + "admin.application_type.exact": "new_application" + } + }, + { + "range": { + "admin.date_applied": { + "gte": str(date_year) + "-01-01", + "lte": str(date_year) + "-12-31" + } + } + } + ] + } + } + } + + +def status_query(date_year, status): + return { + "query": { + "bool": { + "must": [ + { + "term": { + "action": "status:" + status + } + }, + { + "range": { + "created_date": { + "gte": str(date_year) + "-01-01", + "lte": str(date_year) + "-12-31" + } + } + } + ] + } + } + } + + +if __name__ == "__main__": + + import argparse + + parser = argparse.ArgumentParser() + parser.add_argument("-o", "--out", help="output file path") + parser.add_argument("-y", "--year", help="year to filter by") + args = parser.parse_args() + + if not args.out: + print("Please specify an output file path with the -o option") + parser.print_help() + exit() + + if not args.year: + print("Please specify a year to filter the applications with the -y option") + parser.print_help() + exit() + + with open(args.out, "w", encoding="utf-8") as f: + writer = csv.writer(f) + + res = models.Application.query(q=date_applied_query(args.year), size=0) + writer.writerow(["Submitted", res.get("hits", {}).get("total", {}).get("value", 0)]) + + res = models.Provenance.query(q=status_query(args.year, "accepted"), size=0) + writer.writerow(["Accepted", res.get("hits", {}).get("total", {}).get("value", 0)]) + + res = models.Provenance.query(q=status_query(args.year, "rejected"), size=0) + writer.writerow(["Rejected", res.get("hits", {}).get("total", {}).get("value", 0)]) From d4f4eb236610af7c8df2db9f20b0d25260e4ef3f Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 10 Jul 2023 13:02:14 +0100 Subject: [PATCH 43/77] make custom checkboxes accessible via keyboard and outlined on focus --- cms/sass/base/_general.scss | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cms/sass/base/_general.scss b/cms/sass/base/_general.scss index 29d2445e24..c9034a400a 100644 --- a/cms/sass/base/_general.scss +++ b/cms/sass/base/_general.scss @@ -261,7 +261,19 @@ select { input[type="checkbox"], input[type="radio"] { - display: none; + opacity: 0; + height: 40px; + width: 40px; + + &:focus + label { + outline: dashed 2px lightgrey; + outline-offset: 5px; + } + + &:focus:not(:focus-visible){ + outline: none; + } + + label { margin: 0 0 $spacing-03 0; From 71c4c0ba6489aeea0d2dca004fc3c39fb992a81d Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 10 Jul 2023 13:31:48 +0100 Subject: [PATCH 44/77] Set default checkbox with opacity 0 and move outside the div Add border for focus Set overflow-y to visible to show border even if outside the div --- cms/sass/base/_general.scss | 7 ++++--- cms/sass/components/_filters.scss | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cms/sass/base/_general.scss b/cms/sass/base/_general.scss index c9034a400a..dc4454d977 100644 --- a/cms/sass/base/_general.scss +++ b/cms/sass/base/_general.scss @@ -262,12 +262,13 @@ select { input[type="checkbox"], input[type="radio"] { opacity: 0; - height: 40px; - width: 40px; + width: 0.8em; + height: 0.8em; + margin-left: -0.8rem; &:focus + label { outline: dashed 2px lightgrey; - outline-offset: 5px; + outline-offset: 1px; } &:focus:not(:focus-visible){ diff --git a/cms/sass/components/_filters.scss b/cms/sass/components/_filters.scss index e82883841b..eeb7b09f32 100644 --- a/cms/sass/components/_filters.scss +++ b/cms/sass/components/_filters.scss @@ -49,7 +49,7 @@ .filter__choices { max-height: $spacing-07; height: auto; - overflow-y: auto; + overflow-y: visible; @include unstyled-list; li { From 9395f76c7efe209b67badfe2c6d72b5647f039e7 Mon Sep 17 00:00:00 2001 From: Aga Date: Tue, 11 Jul 2023 12:58:35 +0100 Subject: [PATCH 45/77] add functional test --- doajtest/testbook/public_site/public_search.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doajtest/testbook/public_site/public_search.yml b/doajtest/testbook/public_site/public_search.yml index bc72ad24f9..6b47834e85 100644 --- a/doajtest/testbook/public_site/public_search.yml +++ b/doajtest/testbook/public_site/public_search.yml @@ -179,3 +179,12 @@ tests: - step: click spacebar to fold/unfold the facet resuts: - screenreader gives correct state of the facet ("extended" or "folded") + - step: click tab + results: + - focus is on the list of checkboxes + results: + - focus is clearly marked by the outline + - step: click spacebar to check the filter + results: + - filter is applied + From 8a80c7dd29e7d7729bafc7a23fb735eaa846d0e9 Mon Sep 17 00:00:00 2001 From: Aga Date: Tue, 11 Jul 2023 14:03:27 +0100 Subject: [PATCH 46/77] remove change of overflow --- cms/sass/components/_filters.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/sass/components/_filters.scss b/cms/sass/components/_filters.scss index eeb7b09f32..e82883841b 100644 --- a/cms/sass/components/_filters.scss +++ b/cms/sass/components/_filters.scss @@ -49,7 +49,7 @@ .filter__choices { max-height: $spacing-07; height: auto; - overflow-y: visible; + overflow-y: auto; @include unstyled-list; li { From cfdb01d34a52c6e3fdf957745173f55e0ea10c3a Mon Sep 17 00:00:00 2001 From: Aga Date: Tue, 11 Jul 2023 14:10:31 +0100 Subject: [PATCH 47/77] add minimal top padding to filter choises to ensure visible focus outline --- cms/sass/components/_filters.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cms/sass/components/_filters.scss b/cms/sass/components/_filters.scss index e82883841b..ceabae488b 100644 --- a/cms/sass/components/_filters.scss +++ b/cms/sass/components/_filters.scss @@ -50,6 +50,8 @@ max-height: $spacing-07; height: auto; overflow-y: auto; + //add minimal padding to ensure visible outline + padding-top: .2rem; @include unstyled-list; li { From 186e2c3fc7989cd05f0911619fcd0055e1e12387 Mon Sep 17 00:00:00 2001 From: Sophy Date: Mon, 17 Jul 2023 13:59:18 +0100 Subject: [PATCH 48/77] Use SASS variables See https://github.com/DOAJ/doaj/pull/2271 --- cms/sass/components/_filters.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/sass/components/_filters.scss b/cms/sass/components/_filters.scss index ceabae488b..026403d67d 100644 --- a/cms/sass/components/_filters.scss +++ b/cms/sass/components/_filters.scss @@ -51,7 +51,7 @@ height: auto; overflow-y: auto; //add minimal padding to ensure visible outline - padding-top: .2rem; + padding-top: $spacing-01; @include unstyled-list; li { From e2d6ce1c8ec1486d8d193772b5f50871cb09e518 Mon Sep 17 00:00:00 2001 From: Zhan4i <122616204+Zhan4i@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:05:01 +0200 Subject: [PATCH 49/77] change the city of Kadri --- cms/data/volunteers.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cms/data/volunteers.yml b/cms/data/volunteers.yml index 01dbfe24a1..9e09159ad7 100644 --- a/cms/data/volunteers.yml +++ b/cms/data/volunteers.yml @@ -467,8 +467,8 @@ ass_ed: - name: Kadri Kıran area: Systematic Entomology year_since: - city: Tekirdag - country: Turkey + city: Edirne + country: Türkiye language: English, Turkish, German photo: "Kadri Kiran.jpg" From dc99a55586ac2783b594f54597e2cc87bf4b54d9 Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 31 Jul 2023 10:02:30 +0100 Subject: [PATCH 50/77] change text of notification --- cms/data/notifications.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/data/notifications.yml b/cms/data/notifications.yml index d06d287d0d..1a67c6c7c2 100644 --- a/cms/data/notifications.yml +++ b/cms/data/notifications.yml @@ -146,4 +146,4 @@ journal:assed:discontinuing_soon:notify: long: | Journal "{title}" (id: {id}) will discontinue in {days} days. short: - Journals discontinuing soon found \ No newline at end of file + Journal discontinuing \ No newline at end of file From 6f87cb30f2d024b269ecb9a1305119096cc1b430 Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 31 Jul 2023 10:49:24 +0100 Subject: [PATCH 51/77] Set field Search when it is changed even if text field is empty. --- portality/static/js/doaj.fieldrender.edges.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/portality/static/js/doaj.fieldrender.edges.js b/portality/static/js/doaj.fieldrender.edges.js index 01f5589f2f..08a2aa35bf 100644 --- a/portality/static/js/doaj.fieldrender.edges.js +++ b/portality/static/js/doaj.fieldrender.edges.js @@ -1551,13 +1551,12 @@ $.extend(true, doaj, { var textIdSelector = edges.css_id_selector(this.namespace, "text", this); var text = this.component.jq(textIdSelector).val(); - if (text === "") { - return; - } - // if there is search text, then proceed to run the search var val = this.component.jq(element).val(); this.component.setSearchField(val, false); + if (text === "") { + return; + } this.component.setSearchText(text); }; From 18ef44ab1d1b08e6be73345c42e46690458319a1 Mon Sep 17 00:00:00 2001 From: Aga Date: Thu, 3 Aug 2023 12:37:03 +0100 Subject: [PATCH 52/77] modify url regex --- doajtest/fixtures/urls.py | 5 ++++- portality/regex.py | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/doajtest/fixtures/urls.py b/doajtest/fixtures/urls.py index 0e44633849..82eb73fc39 100644 --- a/doajtest/fixtures/urls.py +++ b/doajtest/fixtures/urls.py @@ -9,5 +9,8 @@ INVALID_URL_LISTS = [ "ht:www", "nonexistent.com", - "https://www.doaj.org and https://www.reddit.com" + "https://www.doaj.org and https://www.reddit.com", + "http://www.doaj.org and www.doaj.org", +"http://www.doaj.org, www.doaj.org", +"http://www.doaj.org, https://www.doaj.org" ] \ No newline at end of file diff --git a/portality/regex.py b/portality/regex.py index 7c5773855d..195ce1013f 100644 --- a/portality/regex.py +++ b/portality/regex.py @@ -17,8 +17,14 @@ BIG_END_DATE_COMPILED = re.compile(BIG_END_DATE) #~~URL:Regex~~ -HTTP_URL = r'^https?://([^/:]+\.[a-z]{2,63}|([0-9]{1,3}\.){3}[0-9]{1,3})(:[0-9]+)?(\/.*)?(#.*)?$' -HTTP_URL_COMPILED = re.compile(HTTP_URL, re.IGNORECASE) +# HTTP_URL = r'^https?://([^/:]+\.[a-z]{2,63}|([0-9]{1,3}\.){3}[0-9]{1,3})(:[0-9]+)?(\/.*)?(#.*)?$' +HTTP_URL_COMPILED = re.compile(r'^(?:https?|ftp):\/\/' # Scheme: http(s) or ftp + r'(?:[\w-]+\.)*[\w-]+' # Domain name (optional subdomains) + r'(?:\.[a-z]{2,})' # Top-level domain (e.g., .com, .org) + r'(?:\/[^\/\s]*)*' # Path (optional) + r'(?:\?[^\/\s]*)?' # Query string (optional) + r'(?:#[^\/\s]*)?$' # Fragment (optional), re.IGNORECASE) + ) def is_match(pattern, string, *args, **kwargs): From 9ef9bedcb1424872a01f85ac79e5def61ec1949b Mon Sep 17 00:00:00 2001 From: Aga Date: Thu, 3 Aug 2023 12:39:08 +0100 Subject: [PATCH 53/77] define regex string as multiline string --- portality/regex.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/portality/regex.py b/portality/regex.py index 195ce1013f..6435c85f3a 100644 --- a/portality/regex.py +++ b/portality/regex.py @@ -17,14 +17,16 @@ BIG_END_DATE_COMPILED = re.compile(BIG_END_DATE) #~~URL:Regex~~ -# HTTP_URL = r'^https?://([^/:]+\.[a-z]{2,63}|([0-9]{1,3}\.){3}[0-9]{1,3})(:[0-9]+)?(\/.*)?(#.*)?$' -HTTP_URL_COMPILED = re.compile(r'^(?:https?|ftp):\/\/' # Scheme: http(s) or ftp - r'(?:[\w-]+\.)*[\w-]+' # Domain name (optional subdomains) - r'(?:\.[a-z]{2,})' # Top-level domain (e.g., .com, .org) - r'(?:\/[^\/\s]*)*' # Path (optional) - r'(?:\?[^\/\s]*)?' # Query string (optional) - r'(?:#[^\/\s]*)?$' # Fragment (optional), re.IGNORECASE) - ) +HTTP_URL = ( + r'^(?:https?|ftp)://' # Scheme: http(s) or ftp + r'(?:[\w-]+\.)*[\w-]+' # Domain name (optional subdomains) + r'(?:\.[a-z]{2,})' # Top-level domain (e.g., .com, .org) + r'(?:\/[^\/\s]*)*' # Path (optional) + r'(?:\?[^\/\s]*)?' # Query string (optional) + r'(?:#[^\/\s]*)?$' # Fragment (optional) +) + +HTTP_URL_COMPILED = re.compile(HTTP_URL, re.IGNORECASE) def is_match(pattern, string, *args, **kwargs): From 7d0b139fc1547573eaa915da7d1c2177ea5dbb0b Mon Sep 17 00:00:00 2001 From: Aga Date: Thu, 3 Aug 2023 12:41:23 +0100 Subject: [PATCH 54/77] do not accept ftp --- portality/regex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portality/regex.py b/portality/regex.py index 6435c85f3a..a298a4731f 100644 --- a/portality/regex.py +++ b/portality/regex.py @@ -18,7 +18,7 @@ #~~URL:Regex~~ HTTP_URL = ( - r'^(?:https?|ftp)://' # Scheme: http(s) or ftp + r'^(?:https?)://' # Scheme: http(s) or ftp r'(?:[\w-]+\.)*[\w-]+' # Domain name (optional subdomains) r'(?:\.[a-z]{2,})' # Top-level domain (e.g., .com, .org) r'(?:\/[^\/\s]*)*' # Path (optional) From c5206ff9c8931da7a3a434d108f8512bf2fb3773 Mon Sep 17 00:00:00 2001 From: Aga Date: Thu, 3 Aug 2023 12:42:37 +0100 Subject: [PATCH 55/77] add use case test --- doajtest/fixtures/urls.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doajtest/fixtures/urls.py b/doajtest/fixtures/urls.py index 82eb73fc39..0fa1f98302 100644 --- a/doajtest/fixtures/urls.py +++ b/doajtest/fixtures/urls.py @@ -3,7 +3,8 @@ "http://www.moonlight.com", "https://www.cosmos.com#galaxy", "https://www.cosmos.com/galaxy", - "https://www.cosmos.com/galaxy#peanut" + "https://www.cosmos.com/galaxy#peanut", + "http://ftp.example.com/file%20name.txt" ] INVALID_URL_LISTS = [ @@ -12,5 +13,6 @@ "https://www.doaj.org and https://www.reddit.com", "http://www.doaj.org and www.doaj.org", "http://www.doaj.org, www.doaj.org", -"http://www.doaj.org, https://www.doaj.org" +"http://www.doaj.org, https://www.doaj.org", +"http://ftp.example.com/file name.txt" ] \ No newline at end of file From 00175598d0f91398c56ac484da9a8aeb76224d0b Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Mon, 7 Aug 2023 12:02:39 +0100 Subject: [PATCH 56/77] Version bump for future discontinued release --- portality/settings.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/portality/settings.py b/portality/settings.py index f44c28f9a6..168f20498a 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -9,7 +9,7 @@ # Application Version information # ~~->API:Feature~~ -DOAJ_VERSION = "6.3.10" +DOAJ_VERSION = "6.3.11" API_VERSION = "3.0.1" ###################################### diff --git a/setup.py b/setup.py index 571b37f957..04a9736d53 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='doaj', - version='6.3.10', + version='6.3.11', packages=find_packages(), install_requires=[ "awscli==1.20.50", From def73f7db1660e9136674fde2beb0277946715b8 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 7 Aug 2023 15:48:09 +0200 Subject: [PATCH 57/77] Updated l. 209-222 --- .../static/js/edges/admin.applications.edge.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/portality/static/js/edges/admin.applications.edge.js b/portality/static/js/edges/admin.applications.edge.js index 4fc1a2aeeb..3fcdbc3ab7 100644 --- a/portality/static/js/edges/admin.applications.edge.js +++ b/portality/static/js/edges/admin.applications.edge.js @@ -206,20 +206,20 @@ $.extend(true, doaj, { } ], fieldDisplays: { - 'admin.application_status.exact': 'Application status', + 'admin.application_status.exact': 'Status', 'index.application_type.exact' : 'Application', - 'index.has_editor_group.exact' : 'Has editor group?', - 'index.has_editor.exact' : 'Has Associate Editor?', + 'index.has_editor_group.exact' : 'Editor group', + 'index.has_editor.exact' : 'Associate Editor', 'admin.editor_group.exact' : 'Editor group', 'admin.editor.exact' : 'Editor', 'index.classification.exact' : 'Classification', - 'index.language.exact' : 'Journal language', - 'index.country.exact' : 'Country of publisher', + 'index.language.exact' : 'Language', + 'index.country.exact' : 'Country', 'index.subject.exact' : 'Subject', 'bibjson.publisher.name.exact' : 'Publisher', 'bibjson.provider.exact' : 'Platform, Host, Aggregator', - "index.has_apc.exact" : "Publication charges?", - 'index.license.exact' : 'Journal license' + "index.has_apc.exact" : "Charges?", + 'index.license.exact' : 'License' }, valueMaps : { "index.application_type.exact" : { From 3613a52e34a8661086c6f68c2c07b2df1850c3cc Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 7 Aug 2023 15:49:09 +0200 Subject: [PATCH 58/77] Updated 1. 516-526 --- portality/static/js/edges/admin.journalarticle.edge.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/portality/static/js/edges/admin.journalarticle.edge.js b/portality/static/js/edges/admin.journalarticle.edge.js index af19af1789..0508530334 100644 --- a/portality/static/js/edges/admin.journalarticle.edge.js +++ b/portality/static/js/edges/admin.journalarticle.edge.js @@ -515,15 +515,15 @@ $.extend(true, doaj, { fieldDisplays: { "es_type.exact": "Showing", "admin.in_doaj" : "In DOAJ?", - "index.language.exact" : "Journal language", + "index.language.exact" : "Language", "bibjson.publisher.name.exact" : "Publisher", "index.classification.exact" : "Classification", "index.subject.exact" : "Subject", - "index.country.exact" : "Country of publisher", - "index.license.exact" : "Journal license", + "index.country.exact" : "Country", + "index.license.exact" : "License", "bibjson.year.exact" : "Year of publication", - "bibjson.journal.title.exact" : "Journal title", - "index.has_apc.exact" : "Publication charges?" + "bibjson.journal.title.exact" : "Title", + "index.has_apc.exact" : "Charges?" }, valueMaps : { "es_type.exact" : { From 239bb0cc8d4ed74d7f6c83a1afd29c7af587236e Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 7 Aug 2023 17:18:22 +0200 Subject: [PATCH 59/77] Updated l-471-486 --- portality/static/js/edges/admin.journals.edge.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/portality/static/js/edges/admin.journals.edge.js b/portality/static/js/edges/admin.journals.edge.js index f08d570ac5..f6d6aef096 100644 --- a/portality/static/js/edges/admin.journals.edge.js +++ b/portality/static/js/edges/admin.journals.edge.js @@ -469,21 +469,21 @@ $.extend(true, doaj, { category: "selected-filters", fieldDisplays: { "admin.in_doaj" : "In DOAJ?", - "index.has_seal.exact" : "DOAJ Seal", + "index.has_seal.exact" : "Seal?", "admin.owner.exact" : "Owner", - "index.has_editor_group.exact" : "Has editor group?", - "index.has_editor.exact" : "Has Associate Editor?", + "index.has_editor_group.exact" : "Editor group?", + "index.has_editor.exact" : "Associate Editor?", "admin.editor_group.exact" : "Editor group", "admin.editor.exact" : "Associate Editor", - "index.license.exact" : "Journal license", + "index.license.exact" : "License", "bibjson.publisher.name.exact" : "Publisher", "index.classification.exact" : "Classification", "index.subject.exact" : "Subject", - "index.language.exact" : "Journal language", - "index.country.exact" : "Country of publisher", + "index.language.exact" : "Language", + "index.country.exact" : "Country", "index.continued.exact" : "Continued", "bibjson.discontinued_date" : "Discontinued Year", - "index.has_apc.exact" : "Publication charges?" + "index.has_apc.exact" : "Charges?" }, valueMaps : { "admin.in_doaj" : { From c40cedc2e59bb17031fcf7f5485750610bb64298 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 7 Aug 2023 17:19:45 +0200 Subject: [PATCH 60/77] Updated 1. 210-223 --- .../static/js/edges/admin.update_requests.edge.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/portality/static/js/edges/admin.update_requests.edge.js b/portality/static/js/edges/admin.update_requests.edge.js index 38ea75566f..22cc532911 100644 --- a/portality/static/js/edges/admin.update_requests.edge.js +++ b/portality/static/js/edges/admin.update_requests.edge.js @@ -207,20 +207,20 @@ $.extend(true, doaj, { id: "selected-filters", category: "selected-filters", fieldDisplays: { - 'admin.application_status.exact': 'Application Status', + 'admin.application_status.exact': 'Status', 'index.application_type.exact' : 'Update Request', - 'index.has_editor_group.exact' : 'Has Editor Group?', - 'index.has_editor.exact' : 'Has Associate Editor?', + 'index.has_editor_group.exact' : 'Editor Group?', + 'index.has_editor.exact' : 'Associate Editor?', 'admin.editor_group.exact' : 'Editor Group', 'admin.editor.exact' : 'Editor', 'index.classification.exact' : 'Classification', - 'index.language.exact' : 'Journal language', - 'index.country.exact' : 'Country of publisher', + 'index.language.exact' : 'Language', + 'index.country.exact' : 'Country', 'index.subject.exact' : 'Subject', 'bibjson.publisher.name.exact' : 'Publisher', 'bibjson.provider.exact' : 'Platform, Host, Aggregator', - "index.has_apc.exact" : "Publication charges?", - 'index.license.exact' : 'Journal license' + "index.has_apc.exact" : "Charges?", + 'index.license.exact' : 'License' }, valueMaps : { "index.application_type.exact" : { From 5161c44356a810041575a482a80b7acc8e689d48 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 7 Aug 2023 17:20:36 +0200 Subject: [PATCH 61/77] Updated 1.303-310 --- .../static/js/edges/associate.applications.edge.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/portality/static/js/edges/associate.applications.edge.js b/portality/static/js/edges/associate.applications.edge.js index 7ff2a1b444..e963095a6e 100644 --- a/portality/static/js/edges/associate.applications.edge.js +++ b/portality/static/js/edges/associate.applications.edge.js @@ -300,14 +300,14 @@ $.extend(true, doaj, { id: "selected-filters", category: "selected-filters", fieldDisplays: { - 'admin.application_status.exact': 'Application Status', + 'admin.application_status.exact': 'Status', 'index.classification.exact' : 'Classification', - 'index.language.exact' : 'Journal language', - 'index.country.exact' : 'Country of publisher', + 'index.language.exact' : 'Language', + 'index.country.exact' : 'Country', 'index.subject.exact' : 'Subject', 'bibjson.publisher.name.exact' : 'Publisher', - 'index.license.exact' : 'Journal license', - "index.has_apc.exact" : "Publication charges?" + 'index.license.exact' : 'License', + "index.has_apc.exact" : "Charges?" } }) ]; From be07a606a3a96c94f2bf3fa8073211f44fcae3e6 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 7 Aug 2023 17:21:26 +0200 Subject: [PATCH 62/77] Updated l. 311-320 --- portality/static/js/edges/associate.journals.edge.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/portality/static/js/edges/associate.journals.edge.js b/portality/static/js/edges/associate.journals.edge.js index 6077ce0cf6..e10c2efa15 100644 --- a/portality/static/js/edges/associate.journals.edge.js +++ b/portality/static/js/edges/associate.journals.edge.js @@ -310,14 +310,14 @@ $.extend(true, doaj, { fieldDisplays: { "admin.in_doaj" : "In DOAJ?", "admin.owner.exact" : "Owner", - "index.license.exact" : "Journal license", + "index.license.exact" : "License", "bibjson.publisher.name.exact" : "Publisher", "index.classification.exact" : "Classification", "index.subject.exact" : "Subject", - "index.language.exact" : "Journal language", - "index.country.exact" : "Country of publisher", - "index.title.exact" : "Journal title", - "index.has_apc.exact" : "Publication charges?" + "index.language.exact" : "Language", + "index.country.exact" : "Country", + "index.title.exact" : "Title", + "index.has_apc.exact" : "Charges?" }, valueMaps : { "admin.in_doaj" : { From efd0a171dc7913a175bd3941c670ab302d428a03 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 7 Aug 2023 17:22:44 +0200 Subject: [PATCH 63/77] Updated l. 365-377 --- .../static/js/edges/editor.groupjournals.edge.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/portality/static/js/edges/editor.groupjournals.edge.js b/portality/static/js/edges/editor.groupjournals.edge.js index 632d04ca9c..9c145ba018 100644 --- a/portality/static/js/edges/editor.groupjournals.edge.js +++ b/portality/static/js/edges/editor.groupjournals.edge.js @@ -364,17 +364,17 @@ $.extend(true, doaj, { fieldDisplays: { "admin.in_doaj" : "In DOAJ?", "admin.owner.exact" : "Owner", - "index.has_editor.exact" : "Has Associate Editor?", + "index.has_editor.exact" : "Associate Editor?", "admin.editor_group.exact" : "Editor group", "admin.editor.exact" : "Associate Editor", - "index.license.exact" : "Journal license", + "index.license.exact" : "License", "bibjson.publisher.name.exact" : "Publisher", "index.classification.exact" : "Classification", "index.subject.exact" : "Subject", - "index.language.exact" : "Journal language", - "index.country.exact" : "Country of publisher", - "index.title.exact" : "Journal title", - "index.has_apc.exact" : "Publication charges?" + "index.language.exact" : "Language", + "index.country.exact" : "Country", + "index.title.exact" : "Title", + "index.has_apc.exact" : "Charges?" }, valueMaps : { "admin.in_doaj" : { From fb33c36ecb51d26bee11d3f6add2b8c1901cb66d Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Tue, 8 Aug 2023 17:42:18 +0100 Subject: [PATCH 64/77] Fixes for tests relating to discontinued date --- doajtest/unit/test_task_discontinued_soon.py | 34 ++++++++++++++------ 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/doajtest/unit/test_task_discontinued_soon.py b/doajtest/unit/test_task_discontinued_soon.py index 3c9e4bcd1d..3716151294 100644 --- a/doajtest/unit/test_task_discontinued_soon.py +++ b/doajtest/unit/test_task_discontinued_soon.py @@ -1,22 +1,37 @@ import unittest import datetime -from doajtest.helpers import DoajTestCase +from doajtest.helpers import DoajTestCase, patch_config -from portality.core import app from portality import models from portality.tasks import find_discontinued_soon from portality.ui.messages import Messages from doajtest.fixtures import JournalFixtureFactory -DELTA = app.config.get('DISCONTINUED_DATE_DELTA',1) +# Expect a notification for journals discontinuing in 1 days time (tomorrow) +DELTA = 1 + class TestDiscontinuedSoon(DoajTestCase): - def _date_to_found(self): + @classmethod + def setUpClass(cls) -> None: + super().setUpClass() + cls.orig_config = patch_config(cls.app_test, { + 'DISCONTINUED_DATE_DELTA': DELTA + }) + + @classmethod + def tearDownClass(cls) -> None: + super().tearDownClass() + patch_config(cls.app_test, cls.orig_config) + + @staticmethod + def _date_to_find(): return (datetime.datetime.today() + datetime.timedelta(days=DELTA)).strftime('%Y-%m-%d') - def _date_too_late(self): + @staticmethod + def _date_too_late(): return (datetime.datetime.today() + datetime.timedelta(days=DELTA+1)).strftime('%Y-%m-%d') def test_discontinued_soon_found(self): @@ -26,14 +41,14 @@ def test_discontinued_soon_found(self): journal_discontinued_to_found_1.set_id("1") jbib = journal_discontinued_to_found_1.bibjson() jbib.title = "Discontinued Tomorrow 1" - jbib.discontinued_date = self._date_to_found() + jbib.discontinued_date = self._date_to_find() journal_discontinued_to_found_1.save(blocking=True) journal_discontinued_to_found_2 = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) journal_discontinued_to_found_2.set_id("2") jbib = journal_discontinued_to_found_2.bibjson() jbib.title = "Discontinued Tomorrow 2" - jbib.discontinued_date = self._date_to_found() + jbib.discontinued_date = self._date_to_find() journal_discontinued_to_found_2.save(blocking=True) # that shouldn't be found @@ -48,9 +63,10 @@ def test_discontinued_soon_found(self): task = find_discontinued_soon.FindDiscontinuedSoonBackgroundTask(job) task.run() - assert len(job.audit) == 2 + assert len(job.audit) == 3 # Journals 1 & 2, and a message to say notification is sent assert job.audit[0]["message"] == Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id="1") assert job.audit[1]["message"] == Messages.DISCONTINUED_JOURNAL_FOUND_LOG.format(id="2") + assert job.audit[2]["message"] == Messages.DISCONTINUED_JOURNALS_FOUND_NOTIFICATION_SENT_LOG def test_discontinued_soon_not_found(self): @@ -66,7 +82,7 @@ def test_discontinued_soon_not_found(self): journal_not_in_doaj = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=False)) journal_not_in_doaj.set_id("2") jbib = journal_not_in_doaj.bibjson() - jbib.discontinued_date = self._date_to_found() + jbib.discontinued_date = self._date_to_find() journal_not_in_doaj.save(blocking=True) job = find_discontinued_soon.FindDiscontinuedSoonBackgroundTask.prepare("system") From 45b3332d662333c0331c81c1895921afd71b2cdb Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Wed, 9 Aug 2023 09:31:40 +0100 Subject: [PATCH 65/77] Version bump --- portality/settings.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/portality/settings.py b/portality/settings.py index 168f20498a..b50039200f 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -9,7 +9,7 @@ # Application Version information # ~~->API:Feature~~ -DOAJ_VERSION = "6.3.11" +DOAJ_VERSION = "6.3.12" API_VERSION = "3.0.1" ###################################### diff --git a/setup.py b/setup.py index 04a9736d53..0a0bd52783 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='doaj', - version='6.3.11', + version='6.3.12', packages=find_packages(), install_requires=[ "awscli==1.20.50", From f45ed82a0d994898d0db5fee52258efb4d3accfa Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Thu, 10 Aug 2023 09:29:16 +0100 Subject: [PATCH 66/77] Version bump for JS / CSS --- portality/settings.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/portality/settings.py b/portality/settings.py index b50039200f..c01aa845ba 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -9,7 +9,7 @@ # Application Version information # ~~->API:Feature~~ -DOAJ_VERSION = "6.3.12" +DOAJ_VERSION = "6.3.13" API_VERSION = "3.0.1" ###################################### diff --git a/setup.py b/setup.py index 0a0bd52783..520bd1325a 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='doaj', - version='6.3.12', + version='6.3.13', packages=find_packages(), install_requires=[ "awscli==1.20.50", From 102b302635b4193b95dc12704258ccf9274c8263 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Thu, 10 Aug 2023 12:10:47 +0200 Subject: [PATCH 67/77] Updated line 34 with details --- cms/pages/about/at-20.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/pages/about/at-20.md b/cms/pages/about/at-20.md index e3dde2fd1f..b4b02854bf 100644 --- a/cms/pages/about/at-20.md +++ b/cms/pages/about/at-20.md @@ -31,7 +31,7 @@ Further down the page is a historical timeline to give you a full overview of DO - {% include "includes/svg/at-20/theme_global.svg" %} - Name: _DOAJ at 20: Global_ - Date: _28th September 2023_ - - Event Time: to be confirmed + - Event Time: 13:00 UTC ([Check the event time](https://www.timeanddate.com/worldclock/fixedtime.html?iso=20230615T13&ah=1&am=30) where you are.) - Duration: 90 mins - {% include "includes/svg/at-20/theme_trusted.svg" %} - Name: _DOAJ at 20: Trusted_ From f65c6848436196e7f6b9215e15fec857278ce855 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Thu, 10 Aug 2023 12:20:22 +0200 Subject: [PATCH 68/77] Removed Ilaria and Louise --- cms/data/team.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/cms/data/team.yml b/cms/data/team.yml index 3fb9f40049..ce175c0667 100644 --- a/cms/data/team.yml +++ b/cms/data/team.yml @@ -55,17 +55,6 @@ 2020: https://drive.google.com/file/d/1-4wTgvwCu_tvDv5NIoJhZi0QpQl-fpdB/view?usp=sharing 2022: https://drive.google.com/file/d/1xEUUxhqSE0OnKd_x8z1oLLRRrJrKAwXA/view?usp=sharing -- name: Ilaria Fava - role: Managing Editor - photo: Ilaria.jpg - bio: 'Ilaria is a librarian with several years of experience within the Open Access community in her home country of Italy, where she has dealt with Open Access issues at both national and international level. She also serves the Göttingen State and University Library working on Open Science projects. -Based in Rome and Göttingen, Ilaria loves baking cakes; she speaks Italian, English, some Spanish and a little German.' - coi: - 2016: https://drive.google.com/file/d/0ByRf6PVViI-mY2dRZTR5eTFjQkk/view?usp=sharing&resourcekey=0-fPa6ce_HjfoVQqKGqWxLNw - 2018: https://drive.google.com/file/d/1AMi0uIWHgEiaqmJLM7f_SFsiLEJENfjF/view?usp=sharing - 2020: https://drive.google.com/file/d/1jWZKc6xjp3yfo6qjQWp6Yp3y-71ZHLth/view?usp=sharing - 2022: https://drive.google.com/file/d/1_au6llN2ALPnkNTgUrzLrSTw8gundldJ/view?usp=sharing - - name: Joanna Ball role: Managing Director photo: joba.jpg @@ -120,14 +109,6 @@ Based in Rome and Göttingen, Ilaria loves baking cakes; she speaks Italian, Eng 2020: https://drive.google.com/file/d/1zU-lLB5W54E_QUm5uto5tqB6cZl83TAJ/view?usp=sharing 2022: https://drive.google.com/file/d/19rw-naMJqHkI5T7aDIDPUkwPutBdDpDm/view?usp=sharing -- name: Louise Stoddard - role: Communications Manager - photo: louise.jpg - bio: "Louise has over 15 years experience in communications and public relations for non-profit and international organisations. She holds a Masters in Journalism and a Bachelor of Science and Economics in International Development from The University of Wales, Swansea. Louise has worked for the United Nations for 8 years, also with academic and non-profit organisations promoting access to knowledge and information. In 2021 Louise joined DOAJ as the focal point for public relations and communications. Outside of work Louise can usually be found in her vegetable garden." - coi: - 2021: https://drive.google.com/file/d/1DmDsIkv-orjF7QGEVwqFDAl0EQx3qRXg/view?usp=sharing - 2022: https://drive.google.com/file/d/1wOeX97BZGEX50orKo6TwlWmGsdbLFfBD/view?usp=sharing - - name: Luis Montilla role: Managing Editor photo: luis.jpeg From 16d8252603ffc1743d219ed43c35cf051b7979e1 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Thu, 10 Aug 2023 11:26:22 +0100 Subject: [PATCH 69/77] update priorities calculation settings --- portality/scripts/priorities.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/portality/scripts/priorities.csv b/portality/scripts/priorities.csv index 08e56c10b5..75c95cf037 100644 --- a/portality/scripts/priorities.csv +++ b/portality/scripts/priorities.csv @@ -1,6 +1,7 @@ id,labels,columns HP/DaR,"Priority: High, Type: Data at Risk", HP/bug,"Priority: High, bug", +Deadline,Priority: Deadline, HP/PfL,"Prioroty: High, Workflow: Pending for Live",Review HP/sup,"Priority: High, Origin: Support", Test1,Workflow: On Test,Review From 1b598f596699fd7d78b292a581fd745eea6b64b0 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Thu, 10 Aug 2023 12:27:28 +0200 Subject: [PATCH 70/77] Added l.11 --- cms/pages/about/team.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/pages/about/team.md b/cms/pages/about/team.md index 1a5c81ee40..07a0a19795 100644 --- a/cms/pages/about/team.md +++ b/cms/pages/about/team.md @@ -8,4 +8,4 @@ featuremap: ~~Team:Fragment->TeamData:Template~~ --- - +## Past team members From da0e49df0a0bba26158cf711f46a2c2cb21ac6eb Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Thu, 10 Aug 2023 12:28:35 +0200 Subject: [PATCH 71/77] Update team.md --- cms/pages/about/team.md | 1 - 1 file changed, 1 deletion(-) diff --git a/cms/pages/about/team.md b/cms/pages/about/team.md index 07a0a19795..68a3200a48 100644 --- a/cms/pages/about/team.md +++ b/cms/pages/about/team.md @@ -8,4 +8,3 @@ featuremap: ~~Team:Fragment->TeamData:Template~~ --- -## Past team members From 80c02fbd4645a0ac5902efaa273e750a89a57074 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Thu, 10 Aug 2023 12:30:44 +0200 Subject: [PATCH 72/77] Removed Rikard --- cms/data/team.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/cms/data/team.yml b/cms/data/team.yml index ce175c0667..8bf5675a36 100644 --- a/cms/data/team.yml +++ b/cms/data/team.yml @@ -146,16 +146,6 @@ coi: 2023: https://drive.google.com/file/d/1Mipqt2uTdv968VajWjEkIo5S9rTHSKCT/view?usp=sharing -- name: Rikard Zeylon - role: Managing Editor - photo: Rikard.jpg - bio: 'Rikard has a Bachelor of Arts degree with a Major in Cultural Sciences and a specialization in publishing. He enjoys reading about philosophy and religion.' - coi: - 2016: https://drive.google.com/file/d/0ByRf6PVViI-mdnJPdldOM0hUMFU/view?usp=sharing&resourcekey=0-8dJAtvm2n7vXV9NhqZYckw - 2018: https://drive.google.com/file/d/1tOnW8L6TwolyLpIXwMKTITf9wGh_ukLb/view?usp=sharing - 2020: https://drive.google.com/file/d/14c0RgpyD2Slzyh5s8LGvj5OwWbL4H8NX/view?usp=sharing - 2023: https://drive.google.com/file/d/1HQIh1DlfhEutTWniXDGLYFVa9VxJ4OT9/view?usp=share_link - - name: Sonja Brage role: Managing Editor photo: sonja.jpg From f731f4a4cccf3425e4971782603b3c6e96770e6d Mon Sep 17 00:00:00 2001 From: katrinesund <141714527+katrinesund@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:52:48 +0200 Subject: [PATCH 73/77] Changed outdated info about Open event and added new information about Global event --- cms/pages/about/at-20.md | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/cms/pages/about/at-20.md b/cms/pages/about/at-20.md index b4b02854bf..c384036920 100644 --- a/cms/pages/about/at-20.md +++ b/cms/pages/about/at-20.md @@ -23,16 +23,17 @@ Further down the page is a historical timeline to give you a full overview of DO [//]: # (NB. adding whitespace around the titles will break styling) {.events .unstyled-list} - {% include "includes/svg/at-20/theme_open.svg" %} - - **[Registration is open](https://us02web.zoom.us/webinar/register/WN_-b000to3RZKexuFsJGJw1g#/registration)** + - **[Recording is available](https://www.youtube.com/watch?v=qnpSdX3eusk)** - Name: _DOAJ at 20: Open_ - Date: 15th June 2023 - - Event Time: 13:00 UTC ([Check the event time](https://www.timeanddate.com/worldclock/fixedtime.html?iso=20230615T13&ah=1&am=30) where you are.) + - Event Time: 13:00 UTC - Duration: 90 mins - {% include "includes/svg/at-20/theme_global.svg" %} + - **[Registration is open](https://us02web.zoom.us/webinar/register/WN_fu42oi59S7GZ366rjyAUGg#/registration)** - Name: _DOAJ at 20: Global_ - Date: _28th September 2023_ - Event Time: 13:00 UTC ([Check the event time](https://www.timeanddate.com/worldclock/fixedtime.html?iso=20230615T13&ah=1&am=30) where you are.) - - Duration: 90 mins + - Duration: 2 hours - {% include "includes/svg/at-20/theme_trusted.svg" %} - Name: _DOAJ at 20: Trusted_ - Date: _7th December 2023_ @@ -41,27 +42,15 @@ Further down the page is a historical timeline to give you a full overview of DO ## Open -Join us for the first of three events marking our 20th anniversary as a key open infrastructure. 'DOAJ at 20: Open' is free and open to researchers, librarians, research support staff, publishers, and anyone interested in open access! - -The event will build around the theme ‘open’, where our moderator (Abeni Wickham) will be chatting with our three guests: Lars Bjørnshauge, Mikael Laakso, and Nadine Buckland. The discussion will focus on their thoughts and aspirations on open scholarship. They will also explore the obstacles and challenges in adopting immediate open access. - -The event will last 90 minutes. - -**Abeni Wickham** - -Abeni was born in Guyana, South America and holds a PhD in Molecular Physics from Linkoping University. She left academia in 2018 to create SciFree, a software company with a mission to make research open to the public for free. SciFree currently serves 45 University Library customers in Sweden, Denmark, the United Kingdom and the USA. Besides building new tech platforms for university infrastructure, Abeni volunteers on the NASIG Digital Preservation committee, helps PhDs transition in their careers and enjoys surfing both actual waves and the Open Access wave worldwide. - -**Lars Bjørnshauge** - -Lars Bjørnshauge is the Director of Infrastructure Services for Open Access C.I.C (www.is4oa.org). A true open access champion, Lars is DOAJ’s founder and worked as the Managing Director until 2022. Previously, he has been the Deputy Director and Acting Director for the Technical Information Center of Denmark at the Technical University of Denmark. Lars has also been the Director of Libraries at Lund University in Sweden, and the Director of SPARC Europe. In addition to founding DOAJ, he has also co-founded OpenDOAR (the Directory of Open Access Repositories, DOAB (Directory of Open Access Books), and Think.Check.Submit. Lars was on the OASPA Board from 2012-2019. +Our first of three events marking our 20th anniversary took place on the 15th June 2023. The event was built around the theme ‘open’, where our moderator (Abeni Wickham) had a coversation with our three guests: Lars Bjørnshauge, Mikael Laakso, and Nadine Buckland. The discussion focused on development and changes over the last 20 years, with reflections from all speakers on what the next years will bring. A recording of the event is [available on YouTube](https://www.youtube.com/watch?v=qnpSdX3eusk). -**Mikael Laakso** +## Global -Mikael Laakso is an Associate Professor in Information Systems Science at Hanken School of Economics in Helsinki. He has been researching the changing landscape towards openness in scholarly publishing by studying combinations of bibliometrics, web metrics, business models, science policy, and author behaviour. Since the start of his research in this domain around 2009, DOAJ data has been instrumental to most of his research projects. In addition to research, Mikael has also been active in national and international working groups furthering various dimensions of open science. +Our second event will be around the theme Global, where we will have eight lighting talks from speakers from around the world. Our moderator and DOAJ Ambassador, Ivonne Lujano, will introduce speakers and manage two Q&As, where the audience can ask our speakers questions. More information about the event and all the speakers can be found on the [registration page](https://us02web.zoom.us/webinar/register/WN_fu42oi59S7GZ366rjyAUGg#/registration). -**Nadine D. Tulloch-Buckland** +## Trusted -Nadine D. Tulloch-Buckland is the former General Manager of the UWI Press, Senior Lecturer of the University of the West Indies and Director of Spoizer Content Agency Limited. She has over twenty years’ experience in scholarly publishing with specific emphasis on finance and business model development geared towards sustainability in scholarly publishing in the Caribbean. Nadine is the current Treasurer of ALPSP and former Treasurer/Director of AUPresses. She is an advocate for Sustainable Open Access Publishing. +Our third and last DOAJ at 20 event will be around the theme Trusted. More information about this event will be available later in the year. ## Timeline From 558a7cb668836d2d831ed5551591cb02e8946fd9 Mon Sep 17 00:00:00 2001 From: katrinesund <141714527+katrinesund@users.noreply.github.com> Date: Thu, 10 Aug 2023 13:24:05 +0200 Subject: [PATCH 74/77] Updated check time link - line 34 --- cms/pages/about/at-20.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/pages/about/at-20.md b/cms/pages/about/at-20.md index c384036920..b364aa00da 100644 --- a/cms/pages/about/at-20.md +++ b/cms/pages/about/at-20.md @@ -32,7 +32,7 @@ Further down the page is a historical timeline to give you a full overview of DO - **[Registration is open](https://us02web.zoom.us/webinar/register/WN_fu42oi59S7GZ366rjyAUGg#/registration)** - Name: _DOAJ at 20: Global_ - Date: _28th September 2023_ - - Event Time: 13:00 UTC ([Check the event time](https://www.timeanddate.com/worldclock/fixedtime.html?iso=20230615T13&ah=1&am=30) where you are.) + - Event Time: 13:00 UTC ([Check the event time](https://www.timeanddate.com/worldclock/fixedtime.html?iso=20230928T13&ah=1&am=30) where you are.) - Duration: 2 hours - {% include "includes/svg/at-20/theme_trusted.svg" %} - Name: _DOAJ at 20: Trusted_ From 05cd57e6577cb499865b503832ff58828ef38dc5 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Thu, 10 Aug 2023 13:31:47 +0200 Subject: [PATCH 75/77] Reinstated Rikard --- cms/data/team.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cms/data/team.yml b/cms/data/team.yml index 8bf5675a36..ce175c0667 100644 --- a/cms/data/team.yml +++ b/cms/data/team.yml @@ -146,6 +146,16 @@ coi: 2023: https://drive.google.com/file/d/1Mipqt2uTdv968VajWjEkIo5S9rTHSKCT/view?usp=sharing +- name: Rikard Zeylon + role: Managing Editor + photo: Rikard.jpg + bio: 'Rikard has a Bachelor of Arts degree with a Major in Cultural Sciences and a specialization in publishing. He enjoys reading about philosophy and religion.' + coi: + 2016: https://drive.google.com/file/d/0ByRf6PVViI-mdnJPdldOM0hUMFU/view?usp=sharing&resourcekey=0-8dJAtvm2n7vXV9NhqZYckw + 2018: https://drive.google.com/file/d/1tOnW8L6TwolyLpIXwMKTITf9wGh_ukLb/view?usp=sharing + 2020: https://drive.google.com/file/d/14c0RgpyD2Slzyh5s8LGvj5OwWbL4H8NX/view?usp=sharing + 2023: https://drive.google.com/file/d/1HQIh1DlfhEutTWniXDGLYFVa9VxJ4OT9/view?usp=share_link + - name: Sonja Brage role: Managing Editor photo: sonja.jpg From 7347a80d1fedfa662d81e34a362ffb1e9b123a35 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Thu, 10 Aug 2023 15:33:32 +0100 Subject: [PATCH 76/77] Revert "Merge branch 'release/2023-08-10_3400_3402_facets_accessibility'" This reverts commit 80ca25af1abc6746786d0d63883040c7a009f58b, reversing changes made to 4f9dbd2fc0a299194b6d716a9ef294f9dd4dbc75. --- cms/sass/base/_general.scss | 15 +------------ cms/sass/components/_accordion.scss | 3 --- cms/sass/components/_buttons.scss | 7 ------ cms/sass/components/_filters.scss | 2 -- cms/sass/main.scss | 1 - .../testbook/public_site/public_search.yml | 22 ------------------- portality/settings.py | 2 +- portality/static/js/doaj.fieldrender.edges.js | 18 +++++++-------- setup.py | 2 +- 9 files changed, 12 insertions(+), 60 deletions(-) delete mode 100644 cms/sass/components/_accordion.scss diff --git a/cms/sass/base/_general.scss b/cms/sass/base/_general.scss index dc4454d977..29d2445e24 100644 --- a/cms/sass/base/_general.scss +++ b/cms/sass/base/_general.scss @@ -261,20 +261,7 @@ select { input[type="checkbox"], input[type="radio"] { - opacity: 0; - width: 0.8em; - height: 0.8em; - margin-left: -0.8rem; - - &:focus + label { - outline: dashed 2px lightgrey; - outline-offset: 1px; - } - - &:focus:not(:focus-visible){ - outline: none; - } - + display: none; + label { margin: 0 0 $spacing-03 0; diff --git a/cms/sass/components/_accordion.scss b/cms/sass/components/_accordion.scss deleted file mode 100644 index e066ee02f6..0000000000 --- a/cms/sass/components/_accordion.scss +++ /dev/null @@ -1,3 +0,0 @@ -.accordion:focus-within { - border: $grapefruit solid; -} \ No newline at end of file diff --git a/cms/sass/components/_buttons.scss b/cms/sass/components/_buttons.scss index 061c75c454..1e71d3aceb 100644 --- a/cms/sass/components/_buttons.scss +++ b/cms/sass/components/_buttons.scss @@ -117,10 +117,3 @@ button[type="submit"].button--secondary { color: currentColor; } } - -button.aria-button { - all: inherit; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -} diff --git a/cms/sass/components/_filters.scss b/cms/sass/components/_filters.scss index 026403d67d..e82883841b 100644 --- a/cms/sass/components/_filters.scss +++ b/cms/sass/components/_filters.scss @@ -50,8 +50,6 @@ max-height: $spacing-07; height: auto; overflow-y: auto; - //add minimal padding to ensure visible outline - padding-top: $spacing-01; @include unstyled-list; li { diff --git a/cms/sass/main.scss b/cms/sass/main.scss index 9b30911f48..cdd22133b8 100644 --- a/cms/sass/main.scss +++ b/cms/sass/main.scss @@ -28,7 +28,6 @@ "layout/sidenav", "components/alert", - "components/accordion", "components/back-to-top", "components/buttons", "components/card", diff --git a/doajtest/testbook/public_site/public_search.yml b/doajtest/testbook/public_site/public_search.yml index 6b47834e85..1bce101f8c 100644 --- a/doajtest/testbook/public_site/public_search.yml +++ b/doajtest/testbook/public_site/public_search.yml @@ -166,25 +166,3 @@ tests: results: - You are taken to the full text of this article on the Web. It opens in a new tab -- title: 'Test Public Search Results Display: Accessibility' - context: - role: anonymous - steps: - - step: Go to the DOAJ search page at /search/articles - - step: Turn on a screen reader - results: - - Extendable facets are focusable and focus is marked with an orange solid border - - The screenreader gives the header role ("button") - - The screenreader gives the state of the facet ("extended" or "folded") - - step: click spacebar to fold/unfold the facet - resuts: - - screenreader gives correct state of the facet ("extended" or "folded") - - step: click tab - results: - - focus is on the list of checkboxes - results: - - focus is clearly marked by the outline - - step: click spacebar to check the filter - results: - - filter is applied - diff --git a/portality/settings.py b/portality/settings.py index c01aa845ba..b50039200f 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -9,7 +9,7 @@ # Application Version information # ~~->API:Feature~~ -DOAJ_VERSION = "6.3.13" +DOAJ_VERSION = "6.3.12" API_VERSION = "3.0.1" ###################################### diff --git a/portality/static/js/doaj.fieldrender.edges.js b/portality/static/js/doaj.fieldrender.edges.js index f920b009e1..08a2aa35bf 100644 --- a/portality/static/js/doaj.fieldrender.edges.js +++ b/portality/static/js/doaj.fieldrender.edges.js @@ -645,13 +645,13 @@ $.extend(true, doaj, { toggle = ''; } var placeholder = 'Search ' + this.component.nodeCount + ' subjects'; - var frag = '

\ -
\ + var frag = '

' + this.title + toggle + '

\ +
'; +
'; // substitute in the component parts frag = frag.replace(/{{FILTERS}}/g, treeFrag); @@ -1832,10 +1832,10 @@ $.extend(true, doaj, { if (this.togglable) { toggle = ''; } - var frag = '

\ -
\ + var frag = '

' + this.component.display + toggle + '

\ +
'; +
'; // substitute in the component parts frag = frag.replace(/{{FILTERS}}/g, filterFrag + results); @@ -2083,10 +2083,10 @@ $.extend(true, doaj, { if (this.togglable) { toggle = ''; } - var frag = '

\ -
\ + var frag = '

' + this.component.display + toggle + '

\ +
'; +
'; // substitute in the component parts frag = frag.replace(/{{FILTERS}}/g, filterFrag + results); diff --git a/setup.py b/setup.py index 520bd1325a..0a0bd52783 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='doaj', - version='6.3.13', + version='6.3.12', packages=find_packages(), install_requires=[ "awscli==1.20.50", From eba538632452fc787ebd6c0472ebb084de69317d Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Tue, 15 Aug 2023 14:12:26 +0100 Subject: [PATCH 77/77] update PR template with css question --- .github/PULL_REQUEST_TEMPLATE.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7b677ba74a..3a3600a653 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -72,6 +72,11 @@ Instructions for reviewers: - [ ] Developer - [ ] Reviewer +- Have CSS/style changes been implemented? If they are of a global scope (e.g. on base HTML elements) have the downstream impacts of the change in other areas of the system been considered? + - [ ] N/A + - [ ] Developer + - [ ] Reviewer + ### Documentation - FeatureMap annotations have been added