From b5de043ed2c357967c4ca52ca978a2f04d7e113a Mon Sep 17 00:00:00 2001 From: Ramakrishna Date: Thu, 2 Feb 2023 16:25:40 +0530 Subject: [PATCH 01/79] Upload the journals as individual packages --- portality/models/preservation.py | 4 ++ portality/tasks/preservation.py | 62 +++++++++++++------ .../templates/publisher/preservation.html | 4 ++ 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/portality/models/preservation.py b/portality/models/preservation.py index c8042e1465..60c19e6e04 100644 --- a/portality/models/preservation.py +++ b/portality/models/preservation.py @@ -98,6 +98,10 @@ def no_files_articles(self, articles_list): if articles_list is not None and len(articles_list) > 0: self.data["articles_info"]["no_files_articles"] = ", ".join(articles_list) + def uploaded_journals(self, uploaded_journals): + if uploaded_journals is not None and len(uploaded_journals) > 0: + self.data["articles_info"]["uploaded_journals"] = ", ".join(uploaded_journals) + @classmethod def by_owner(cls, owner, size=10): q = OwnerFileQuery(owner) diff --git a/portality/tasks/preservation.py b/portality/tasks/preservation.py index 727adc5ac7..00f9c644a6 100644 --- a/portality/tasks/preservation.py +++ b/portality/tasks/preservation.py @@ -126,11 +126,15 @@ def __init__(self): self.__unbagged_articles = [] self.__not_found_articles = [] self.__no_files_articles = [] + self.__uploaded_journals = [] self.has_errors = False def add_successful_article(self, article: ArticlePackage): self.__successful_articles.append(os.path.basename(article.article_dir)) + def add_uploaded_journal(self, journal_package): + self.__uploaded_journals.append(journal_package) + def add_unowned_articles(self, article: ArticlePackage): self.has_errors = True self.__unowned_articles.append(os.path.basename(article.article_dir)) @@ -168,6 +172,9 @@ def not_found_articles(self): def no_files_articles(self): return self.__no_files_articles + def uploaded_journals(self): + return self.__uploaded_journals + def get_count(self): return len(self.__successful_articles) + \ len(self.__unowned_articles) + \ @@ -243,24 +250,39 @@ def run(self): job.add_audit_message("Create Package structure") articles_list = preserv.create_package_structure() - self.save_articles_list(articles_list, preserve_model) + app.logger.debug("Created package structure") if len(articles_list.successful_articles()) > 0: - package = PreservationPackage(preserv.preservation_dir, job.user) - job.add_audit_message("Create preservation package") - tar_file = package.create_package() - app.logger.debug(f"Created tar file {tar_file}") - - job.add_audit_message("Create shasum") - sha256 = package.sha256() - - job.add_audit_message("Upload package") - response = package.upload_package(sha256) - app.logger.debug(f"Uploaded. Response{response.text}") + # Each subdirectory is a jornal and the directory name is ISSN of the journal + # iterate through the directories and upload each journal as an individual package + dirs = os.listdir(preserv.preservation_dir) + upload_failed = False + for sub_dir in dirs: + tar_file = os.path.join(preserv.preservation_dir, sub_dir) + package = PreservationPackage(tar_file, job.user) + job.add_audit_message("Create preservation package") + tar_file = package.create_package() + app.logger.debug(f"Created tar file {tar_file}") + + job.add_audit_message("Create shasum") + sha256 = package.sha256() + + job.add_audit_message("Upload package") + response = package.upload_package(sha256) + app.logger.debug(f"Uploaded. Response{response.text}") + + job.add_audit_message("Validate response") + self.validate_response(response, tar_file, sha256, preserve_model) + + if preserve_model.status == 'failed': + upload_failed = True + break + else: + articles_list.add_uploaded_journal(package.tar_file_name) - job.add_audit_message("Validate response") - self.validate_response(response, tar_file, sha256, preserve_model) + if not upload_failed: + preserve_model.uploaded_to_ia() # Check if the only few articles are successful if articles_list.is_partial_success(): @@ -278,6 +300,8 @@ def run(self): preserve_model.failed(FailedReasons.no_valid_article_available) preserve_model.save() + self.save_articles_list(articles_list, preserve_model) + except (PreservationException, Exception) as exp: # ~~-> PreservationException:Exception~~ preserve_model.failed(str(exp)) @@ -305,6 +329,8 @@ def save_articles_list(self, articles_list: ArticlesList, model: PreservationSta model.unbagged_articles(articles_list.unbagged_articles()) if len(articles_list.no_files_articles()) > 0: model.no_files_articles(articles_list.no_files_articles()) + if len(articles_list.uploaded_journals()) > 0: + model.uploaded_journals(articles_list.uploaded_journals()) model.save() def cleanup(self): @@ -345,8 +371,7 @@ def validate_response(self, response, tar_file, sha256, model): if res_filename and res_filename == tar_file: if res_shasum and res_shasum == sha256: - app.logger.info("successfully uploaded") - model.uploaded_to_ia() + app.logger.info("successfully uploaded " + tar_file) else: model.failed(FailedReasons.checksum_doesnot_match) else: @@ -379,7 +404,7 @@ def validate_response(self, response, tar_file, sha256, model): model.save() else: - app.logger.error(f"Upload failed {response.text}") + app.logger.error(f"Upload failed for {tar_file}. Reason - {response.text}") model.failed(response.text) model.save() @@ -680,7 +705,8 @@ class PreservationPackage: def __init__(self, directory, owner): self.package_dir = directory - self.tar_file = self.package_dir + ".tar.gz" + created_time = dates.format(datetime.utcnow(), "%Y-%m-%d-%H-%M-%S") + self.tar_file = directory + "_" + created_time + ".tar.gz" self.tar_file_name = os.path.basename(self.tar_file) self.__owner = owner diff --git a/portality/templates/publisher/preservation.html b/portality/templates/publisher/preservation.html index b99c8e6c91..081f716f2a 100644 --- a/portality/templates/publisher/preservation.html +++ b/portality/templates/publisher/preservation.html @@ -144,6 +144,10 @@

History of uploads (showing last {{previous|length}})

{% endif %} {% if file.status == "uploaded" or file.status == "partial" and file.articles_info %} - - -
-

- Added {{journal.created_timestamp.strftime("%e %B %Y")}} - {% if journal.last_manual_update_timestamp and - dates.format(journal.last_manual_update_timestamp) != dates.DEFAULT_TIMESTAMP_VAL - %} - • Updated {{journal.last_manual_update_timestamp.strftime("%e %B %Y")}} + {% else %} + {{ policy }} + {% endif %} + + {% endfor %} + + + {% endif %} -

-
- - - {% include "includes/_hotjar.html" %} - -{% endblock %} -{% block extra_js_bottom %} + {% if bibjson.pid_scheme %} +
+ +
+

Permanent article identifier:

+
    + {% for identifier in bibjson.pid_scheme %} +
  • {{ identifier }}
  • + {% endfor %} +
+
+
+ {% endif %} + + +
+

Journal metadata

+ +
+ +
+ {% if bibjson.publisher_name %} +
Publisher
+
+ {% set source = search_query_source(terms=[{"bibjson.publisher.name.exact": [bibjson.publisher_name]}]) %} + {{ bibjson.publisher_name }} + {% if bibjson.publisher_country %}, {{ bibjson.publisher_country_name() }}{% endif %} +
+ {% endif %} - + {% if bibjson.language %} +
Manuscripts accepted in
+
{{ bibjson.language_name()|join(", ") }}
+ {% endif %} +
+
+ +
+ +
+ {% for path, code in bibjson.lcc_paths_and_codes() %} + {% if loop.index0 == 0 %} +
LCC subjects + + Look up the Library of Congress Classification Outline + +
{% endif %} +
+ {% set source = search_query_source(terms=[{"index.schema_codes_tree.exact": [code]}]) %} + + {{ path }} + +
+ {% endfor %} + + {% if bibjson.keywords %} +
Keywords
+
+ {% for keyword in bibjson.keywords %} + {% set source = search_query_source(query_string=keyword) %} + {{ keyword }} + {% endfor %} +
+ {% endif %} +
+
+
+ + - {% include "_edges_common_js.html" %} - +{% endblock %} -{% endblock extra_js_bottom %} diff --git a/portality/templates/doaj/toc_articles.html b/portality/templates/doaj/toc_articles.html new file mode 100644 index 0000000000..2446a355df --- /dev/null +++ b/portality/templates/doaj/toc_articles.html @@ -0,0 +1,44 @@ +{% extends "layouts/toc_base.html" %} + +{% block toc_content %} + +
+
+
+
+
+ +{% endblock %} + +{% block extra_js_bottom %} + + + + {% include "_edges_common_js.html" %} + + +{% endblock extra_js_bottom %} diff --git a/portality/templates/layouts/toc_base.html b/portality/templates/layouts/toc_base.html new file mode 100644 index 0000000000..0c27ac504d --- /dev/null +++ b/portality/templates/layouts/toc_base.html @@ -0,0 +1,147 @@ +{% extends "layouts/public_base.html" %} + +{% block body_class %} + journal-details +{% endblock %} + +{% block page_title %}{% include "doaj/includes/_journal_meta_title.html" %}{% endblock %} +{% block meta_og_title %}{% include "doaj/includes/_journal_meta_title.html" %}{% endblock %} +{% block meta_twitter_title %}{% include "doaj/includes/_journal_meta_title.html" %}{% endblock %} +{%- block meta_description -%}{% include "doaj/includes/_journal_meta_description.html" %}{%- endblock -%} +{%- block meta_og_description -%}{% include "doaj/includes/_journal_meta_description.html" %}{%- endblock -%} +{%- block meta_twitter_description -%}{% include "doaj/includes/_journal_meta_description.html" %}{%- endblock -%} + +{% block content %} + + +
+
+ {% if journal.last_manually_updated_since(days=30) %} + + + Updated recently + + {% endif %} +

+ + {{ bibjson.title }} + {% if bibjson.alternative_title %} + + {% endif %} + + {%- set seal = journal.has_seal() -%} + {%- if seal -%} + + {%- endif %} +

+

+ + + {# this next bit has to be all on one line so that the spacing is correct #} + {% if bibjson.pissn %}{{bibjson.pissn}} (Print){% endif %}{% if bibjson.eissn %}{% if bibjson.pissn %} / {% endif %}{{bibjson.eissn}} (Online){% endif %} + +

+ + {% if bibjson.discontinued_date %} +

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

+ {% endif %} + + {% set past = journal.get_past_continuations() %} + {% if past %} +

Continues + {% for p in past %} + {% set bibjson = p.bibjson() %} + {% if bibjson.issns()|length > 0 %} + {% if p.is_in_doaj() %} + {{ bibjson.title }} + {% else %} + {{ bibjson.title }}, ISSN: {{ bibjson.get_preferred_issn() }} (not available in DOAJ) + {% endif %} + {% endif %} + {% if not loop.last %}; {% endif %} + {% endfor %} +

+ {% endif %} + + {% set future = journal.get_future_continuations() %} + {% if future %} +

Continued by + {% for f in future %} + {% set bibjson = f.bibjson() %} + {% if bibjson.issns()|length > 0 %} + {% if f.is_in_doaj() %} + {{ bibjson.title }} + {% else %} + {{ bibjson.title }}, ISSN: {{ bibjson.get_preferred_issn() }} (not available in DOAJ) + {% endif %} + {% endif %} + {% if not loop.last %}; {% endif %} + {% endfor %} +

+ {% endif %} + + +
+ +
+ + +
+ {% block toc_content %} {% endblock %} +
+
+ +
+

+ Added {{journal.created_timestamp.strftime("%e %B %Y")}} + {% if journal.last_manual_update_timestamp and + dates.format(journal.last_manual_update_timestamp) != dates.DEFAULT_TIMESTAMP_VAL + %} + • Updated {{journal.last_manual_update_timestamp.strftime("%e %B %Y")}} + {% endif %} +

+
+ +
+ {% include "includes/_hotjar.html" %} + +{% endblock %} diff --git a/portality/view/doaj.py b/portality/view/doaj.py index 5ac2f67f69..80ff0b2195 100644 --- a/portality/view/doaj.py +++ b/portality/view/doaj.py @@ -249,16 +249,7 @@ def autocomplete(doc_type, field_name): # http://flask.pocoo.org/docs/security/#json-security -@blueprint.route("/toc/") -@blueprint.route("/toc//") -@blueprint.route("/toc///") -def toc(identifier=None, volume=None, issue=None): - """ Table of Contents page for a journal. identifier may be the journal id or an issn """ - # If this route is changed, update JOURNAL_TOC_URL_FRAG in settings.py (partial ToC page link for journal CSV) - - journal = None - issn_ref = False - +def find_toc_journal_by_identifier(identifier): if identifier is None: abort(404) @@ -274,44 +265,40 @@ def toc(identifier=None, volume=None, issue=None): if journal is None: abort(400) - issn_ref = True # just a flag so we can check if we were requested via issn + return journal + elif len(identifier) == 32: js = models.Journal.pull(identifier) # Returns None on fail if js is None or not js.is_in_doaj(): abort(404) - journal = js - else: - abort(400) + return js + + abort(400) - # get the bibjson record that we're going to render - bibjson = journal.bibjson() - # The issn we are using to build the TOC - issn = bibjson.get_preferred_issn() +def is_issn_by_identifier(identifier): + return len(identifier) == 9 - # now redirect to the canonical E-ISSN if one is available +def find_correct_redirect_identifier(identifier, bibjson) -> str: + """ + return None if identifier is correct and no redirect is needed - if issn_ref: # the journal is referred to by an ISSN + :param identifier: + :param bibjson: + :return: + """ + if is_issn_by_identifier(identifier): # the journal is referred to by an ISSN # if there is an E-ISSN (and it's not the one in the request), redirect to it eissn = bibjson.get_one_identifier(bibjson.E_ISSN) if eissn and identifier != eissn: - return redirect(url_for('doaj.toc', identifier=eissn, volume=volume, issue=issue), 301) + return eissn # if there's no E-ISSN, but there is a P-ISSN (and it's not the one in the request), redirect to the P-ISSN if not eissn: pissn = bibjson.get_one_identifier(bibjson.P_ISSN) if pissn and identifier != pissn: - return redirect(url_for('doaj.toc', identifier=pissn, volume=volume, issue=issue), 301) - - # Add the volume and issue to query if present in path - if volume: - filters = [dao.Facetview2.make_term_filter('bibjson.journal.volume.exact', volume)] - if issue: - filters += [dao.Facetview2.make_term_filter('bibjson.journal.number.exact', issue)] - q = dao.Facetview2.make_query(filters=filters) - - return redirect(url_for('doaj.toc', identifier=issn) + '?source=' + dao.Facetview2.url_encode_query(q)) + return pissn # The journal has neither a PISSN or an EISSN. Yet somehow # issn_ref is True, the request was referring to the journal @@ -328,22 +315,52 @@ def toc(identifier=None, volume=None, issue=None): if not issn: issn = bibjson.get_one_identifier(bibjson.P_ISSN) if issn: - return redirect(url_for('doaj.toc', identifier=issn, volume=volume, issue=issue), 301) + return issn # let it continue loading if we only have the hex UUID for the journal (no ISSNs) # and the user is referring to the toc page via that ID - # get the continuations for this journal, future and past - future_journals = journal.get_future_continuations() - past_journals = journal.get_past_continuations() +@blueprint.route("/toc/") +def toc(identifier=None): + """ Table of Contents page for a journal. identifier may be the journal id or an issn """ + # If this route is changed, update JOURNAL_TOC_URL_FRAG in settings.py (partial ToC page link for journal CSV) + + journal = find_toc_journal_by_identifier(identifier) + bibjson = journal.bibjson() + real_identifier = find_correct_redirect_identifier(identifier, bibjson) + if real_identifier: + return redirect(url_for('doaj.toc', identifier=real_identifier), 301) + else: + # now render all that information + return render_template('doaj/toc.html', journal=journal, bibjson=bibjson ) + + +@blueprint.route("/toc/articles/") +@blueprint.route("/toc/articles//") +@blueprint.route("/toc/articles///") +def toc_articles(identifier=None, volume=None, issue=None): + journal = find_toc_journal_by_identifier(identifier) + bibjson = journal.bibjson() + real_identifier = find_correct_redirect_identifier(identifier, bibjson) + if real_identifier: + return redirect(url_for('doaj.toc_articles', identifier=real_identifier, + volume=volume, issue=issue), 301) + else: + + if is_issn_by_identifier(identifier) and volume: + filters = [dao.Facetview2.make_term_filter('bibjson.journal.volume.exact', volume)] + if issue: + filters += [dao.Facetview2.make_term_filter('bibjson.journal.number.exact', issue)] + q = dao.Facetview2.make_query(filters=filters) + + # The issn we are using to build the TOC + issn = bibjson.get_preferred_issn() + return redirect(url_for('doaj.toc', identifier=issn) + + '?source=' + dao.Facetview2.url_encode_query(q)) - # extract the bibjson, which is what the template is after, and whether the record is in doaj - #future = [j.bibjson() j for j in future_journals] - #past = [j.bibjson() for j in past_journals] + # now render all that information + return render_template('doaj/toc_articles.html', journal=journal, bibjson=bibjson ) - # now render all that information - return render_template('doaj/toc.html', journal=journal, bibjson=bibjson, future=future_journals, past=past_journals, - toc_issns=journal.bibjson().issns()) #~~->Article:Page~~ From 5f2c9f91009c44842e1c200fd9333d431e586605 Mon Sep 17 00:00:00 2001 From: philip Date: Wed, 2 Aug 2023 14:54:12 +0100 Subject: [PATCH 12/79] rename share toc test cases --- doajtest/unit/test_toc.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doajtest/unit/test_toc.py b/doajtest/unit/test_toc.py index b58b20445f..dafe64ac31 100644 --- a/doajtest/unit/test_toc.py +++ b/doajtest/unit/test_toc.py @@ -5,7 +5,7 @@ from portality.util import url_for -def test_toc_uses_both_issns_when_available(app_test, url_name): +def _test_toc_uses_both_issns_when_available(app_test, url_name): j = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) pissn = j.bibjson().first_pissn eissn = j.bibjson().first_eissn @@ -20,7 +20,7 @@ def test_toc_uses_both_issns_when_available(app_test, url_name): assert eissn in response.data.decode() -def toc_correctly_uses_pissn(app_test, url_name): +def _test_toc_correctly_uses_pissn(app_test, url_name): j = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) pissn = j.bibjson().first_pissn # remove eissn @@ -35,7 +35,7 @@ def toc_correctly_uses_pissn(app_test, url_name): assert pissn in response.data.decode() -def toc_correctly_uses_eissn(app_test, url_name): +def _test_toc_correctly_uses_eissn(app_test, url_name): j = models.Journal(**JournalFixtureFactory.make_journal_source(in_doaj=True)) eissn = j.bibjson().first_eissn # remove pissn @@ -131,21 +131,21 @@ def test_02_toc_requirements(self): assert a.data['index']['date_toc_fv_month'] == a.data['index']['date'] == "1991-01-01T00:00:00Z" def test_03_toc_uses_both_issns_when_available(self): - test_toc_uses_both_issns_when_available(self.app_test, 'doaj.toc') + _test_toc_uses_both_issns_when_available(self.app_test, 'doaj.toc') def test_04_toc_correctly_uses_pissn(self): - toc_correctly_uses_pissn(self.app_test, 'doaj.toc') + _test_toc_correctly_uses_pissn(self.app_test, 'doaj.toc') def test_05_toc_correctly_uses_eissn(self): - toc_correctly_uses_eissn(self.app_test, 'doaj.toc') + _test_toc_correctly_uses_eissn(self.app_test, 'doaj.toc') class TestTOCArticles(DoajTestCase): def test_03_toc_uses_both_issns_when_available(self): - test_toc_uses_both_issns_when_available(self.app_test, 'doaj.toc_articles') + _test_toc_uses_both_issns_when_available(self.app_test, 'doaj.toc_articles') def test_04_toc_correctly_uses_pissn(self): - toc_correctly_uses_pissn(self.app_test, 'doaj.toc_articles') + _test_toc_correctly_uses_pissn(self.app_test, 'doaj.toc_articles') def test_05_toc_correctly_uses_eissn(self): - toc_correctly_uses_eissn(self.app_test, 'doaj.toc_articles') + _test_toc_correctly_uses_eissn(self.app_test, 'doaj.toc_articles') From 01f270d99d1e8506caec4c580afc79dbdf9f5cc6 Mon Sep 17 00:00:00 2001 From: Ramakrishna Date: Tue, 29 Aug 2023 16:27:45 +0530 Subject: [PATCH 13/79] Corrected the verification of the owner of the article --- portality/tasks/preservation.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/portality/tasks/preservation.py b/portality/tasks/preservation.py index c71a2f4e6e..b7f3d6e832 100644 --- a/portality/tasks/preservation.py +++ b/portality/tasks/preservation.py @@ -610,10 +610,9 @@ def __process_article(self, dir_path, files, articles_list): if article: article_data = article.data - if not self.owner_of_article(article): - articles_list.add_unowned_articles(package) + is_owner = self.owner_of_article(article) - else: + if not isinstance(is_owner, bool) and is_owner == True: issn, article_id, metadata_json = self.get_article_info(article_data) try: package = ArticlePackage(dir_path, files) @@ -633,6 +632,8 @@ def __process_article(self, dir_path, files, articles_list): except Exception: articles_list.add_unbagged_articles(package) app.logger.exception(f"Error while create article ( {article_id} ) package") + else: + articles_list.add_unowned_articles(package) else: # skip the article if not found From 77aea0ae6dd0adfd25343c71e69007d5a17a67a3 Mon Sep 17 00:00:00 2001 From: Ramakrishna Date: Tue, 29 Aug 2023 17:36:48 +0530 Subject: [PATCH 14/79] corrected the conditional statement --- portality/tasks/preservation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portality/tasks/preservation.py b/portality/tasks/preservation.py index b7f3d6e832..a806174c16 100644 --- a/portality/tasks/preservation.py +++ b/portality/tasks/preservation.py @@ -612,7 +612,7 @@ def __process_article(self, dir_path, files, articles_list): is_owner = self.owner_of_article(article) - if not isinstance(is_owner, bool) and is_owner == True: + if isinstance(is_owner, bool) and is_owner == True: issn, article_id, metadata_json = self.get_article_info(article_data) try: package = ArticlePackage(dir_path, files) From 03778c3e569ba0406bb40a36bcc9d5b964f6b7d7 Mon Sep 17 00:00:00 2001 From: Ramakrishna Date: Tue, 29 Aug 2023 18:05:35 +0530 Subject: [PATCH 15/79] Use dates library instead of datetime --- portality/tasks/preservation.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/portality/tasks/preservation.py b/portality/tasks/preservation.py index a806174c16..47e82107e7 100644 --- a/portality/tasks/preservation.py +++ b/portality/tasks/preservation.py @@ -5,7 +5,6 @@ import shutil import tarfile from copy import deepcopy -from datetime import datetime from zipfile import ZipFile import requests @@ -209,7 +208,7 @@ def prepare(cls, username, **kwargs): :return: background job """ - created_time = dates.format(datetime.utcnow(), "%Y-%m-%d-%H-%M-%S") + created_time = dates.now() dir_name = username + "-" + created_time local_dir = os.path.join(Preservation.UPLOAD_DIR, dir_name) file = kwargs.get("upload_file") @@ -727,7 +726,7 @@ def __init__(self, preservation_dir, journal_dir, owner): self.preservation_dir = preservation_dir self.journal_dir = journal_dir self.package_dir = os.path.join(self.preservation_dir, journal_dir) - self.created_time = dates.format(datetime.utcnow(), "%Y-%m-%d-%H-%M-%S") + self.created_time = dates.now() self.tar_file = self.package_dir + "_" + self.created_time + ".tar.gz" self.tar_file_name = os.path.basename(self.tar_file) self.__owner = owner From 293863a876c114851b912407c164853134a8a7a1 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Thu, 31 Aug 2023 16:51:16 +0100 Subject: [PATCH 16/79] A few minor fixes for preservation and its tests --- doajtest/unit/test_task_preservation.py | 5 ++--- portality/tasks/preservation.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/doajtest/unit/test_task_preservation.py b/doajtest/unit/test_task_preservation.py index 2823c531d6..d8d62d87e8 100644 --- a/doajtest/unit/test_task_preservation.py +++ b/doajtest/unit/test_task_preservation.py @@ -53,8 +53,7 @@ class TestPreservationSetup(DoajTestCase): def initial_setup(self, package_name): super(TestPreservationSetup, self).setUp() - resources = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "unit", "resources") - articles_zip_path = test_constants.PATH_RESOURCES / "articles.zip" + articles_zip_path = test_constants.PATH_RESOURCES / package_name with open(articles_zip_path, 'rb') as zf: self.zip_file = FileStorage(BytesIO(zf.read()), filename=package_name) @@ -162,7 +161,7 @@ def tearDown(self): super(TestPreservationMultipleJournals, self).tearDown() @patch.object(Article, 'pull_by_key', mock_pull_by_key) - @patch.object(requests,"post", mock_requests_post) + @patch.object(requests, "post", mock_requests_post) @patch.object(preservation.Preservation, 'owner_of_article', mock_owner_of_article) def test_preservation_multiple_journals(self): self.preserve.save_file(self.zip_file) diff --git a/portality/tasks/preservation.py b/portality/tasks/preservation.py index c1da7a675e..4fc1cf09b9 100644 --- a/portality/tasks/preservation.py +++ b/portality/tasks/preservation.py @@ -726,7 +726,7 @@ def __init__(self, preservation_dir, journal_dir, owner): self.preservation_dir = preservation_dir self.journal_dir = journal_dir self.package_dir = os.path.join(self.preservation_dir, journal_dir) - self.created_time = dates.now() + self.created_time = dates.now_str("%Y-%m-%d-%H-%M-%S") self.tar_file = self.package_dir + "_" + self.created_time + ".tar.gz" self.tar_file_name = os.path.basename(self.tar_file) self.__owner = owner From 315384915e68cc5d89f12383b252e13c2038f468 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Fri, 1 Sep 2023 11:13:34 +0100 Subject: [PATCH 17/79] symlinks to allow preservation tests to find the resources --- .gitignore | 4 ++++ doajtest/unit/resources/invalid_article.zip | 1 + doajtest/unit/resources/multi_journals.zip | 1 + doajtest/unit/resources/valid_article.zip | 1 + 4 files changed, 7 insertions(+) create mode 120000 doajtest/unit/resources/invalid_article.zip create mode 120000 doajtest/unit/resources/multi_journals.zip create mode 120000 doajtest/unit/resources/valid_article.zip diff --git a/.gitignore b/.gitignore index 5e73cfd20a..087f3ab5a4 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,11 @@ src* build/* dist/* tmp/* + *.zip +!doajtest/unit/resources/*.zip +!doajtest/preservation_upload_test_package/*.zip + scratch.py .coverage htmlcov/* diff --git a/doajtest/unit/resources/invalid_article.zip b/doajtest/unit/resources/invalid_article.zip new file mode 120000 index 0000000000..e955a12f14 --- /dev/null +++ b/doajtest/unit/resources/invalid_article.zip @@ -0,0 +1 @@ +../../preservation_upload_test_package/invalid_article.zip \ No newline at end of file diff --git a/doajtest/unit/resources/multi_journals.zip b/doajtest/unit/resources/multi_journals.zip new file mode 120000 index 0000000000..ac64455e26 --- /dev/null +++ b/doajtest/unit/resources/multi_journals.zip @@ -0,0 +1 @@ +../../preservation_upload_test_package/multi_journals.zip \ No newline at end of file diff --git a/doajtest/unit/resources/valid_article.zip b/doajtest/unit/resources/valid_article.zip new file mode 120000 index 0000000000..ebf17a3099 --- /dev/null +++ b/doajtest/unit/resources/valid_article.zip @@ -0,0 +1 @@ +../../preservation_upload_test_package/valid_article.zip \ No newline at end of file From 015a0c8ecfc49b52ed016918076049c8f4f1fedf Mon Sep 17 00:00:00 2001 From: Ramakrishna Date: Mon, 4 Sep 2023 09:56:14 +0530 Subject: [PATCH 18/79] Check if Preservation collection is empty --- portality/view/publisher.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/portality/view/publisher.py b/portality/view/publisher.py index 2410a8323a..f2b3713ddc 100644 --- a/portality/view/publisher.py +++ b/portality/view/publisher.py @@ -290,8 +290,8 @@ def preservation(): # check if collection has been assigned for the user # collection must be in the format {"user_id1",["collection_name1","collection_id1"], # "user_id2",["collection_name2","collection_id2"]} - collection_available = True - collection_dict = app.config.get("PRESERVATION_COLLECTION") + collection_dict = app.config.get("PRESERVATION_COLLECTION", {}) + collection_available = True if collection_dict else False if collection_dict and not current_user.id in collection_dict: collection_available = False elif collection_dict: From 83de1184ff452368a39e43f877b2941f7ab49822 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Thu, 5 Oct 2023 13:29:12 +0100 Subject: [PATCH 19/79] reactivate autocomplete on publisher field --- portality/forms/application_forms.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/portality/forms/application_forms.py b/portality/forms/application_forms.py index d1f8a44d20..ff6c3ab928 100644 --- a/portality/forms/application_forms.py +++ b/portality/forms/application_forms.py @@ -169,18 +169,21 @@ class FieldDefinitions: "contexts": { "admin": { "widgets": [ + "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ ] }, "editor": { "disabled": True, "widgets": [ + "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ ] }, "associate_editor": { "disabled": True, "widgets": [ + "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ ] }, @@ -212,16 +215,19 @@ class FieldDefinitions: }, "admin": { "widgets": [ + "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ ] }, "associate_editor": { "widgets": [ + "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ ] }, "editor": { "widgets": [ + "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ ] } @@ -486,16 +492,22 @@ class FieldDefinitions: }, "admin": { "widgets": [ + "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ + {"autocomplete": {"type": "journal", "field": "bibjson.publisher.name.exact"}}, "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ ] }, "associate_editor": { "widgets": [ + "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ + {"autocomplete": {"type": "journal", "field": "bibjson.publisher.name.exact"}}, "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ ] }, "editor": { "widgets": [ + "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ + {"autocomplete": {"type": "journal", "field": "bibjson.publisher.name.exact"}}, "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ ] } From 3e4a2fb432a49f71ca1120e8f7a20c8caf31d70a Mon Sep 17 00:00:00 2001 From: Zhan4i <122616204+Zhan4i@users.noreply.github.com> Date: Fri, 6 Oct 2023 10:32:24 +0200 Subject: [PATCH 20/79] added logo De Gruyter --- cms/assets/img/sponsors/Degruyter.svg | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 cms/assets/img/sponsors/Degruyter.svg diff --git a/cms/assets/img/sponsors/Degruyter.svg b/cms/assets/img/sponsors/Degruyter.svg new file mode 100644 index 0000000000..4fcff995f5 --- /dev/null +++ b/cms/assets/img/sponsors/Degruyter.svg @@ -0,0 +1,3 @@ + + + From a725562221275de153146050938770d8fb02f9eb Mon Sep 17 00:00:00 2001 From: Zhan4i <122616204+Zhan4i@users.noreply.github.com> Date: Fri, 6 Oct 2023 10:45:59 +0200 Subject: [PATCH 21/79] Update sponsors.yml Added De Gruyter + logo --- cms/data/sponsors.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cms/data/sponsors.yml b/cms/data/sponsors.yml index 379c51cf69..2af292427e 100644 --- a/cms/data/sponsors.yml +++ b/cms/data/sponsors.yml @@ -74,6 +74,10 @@ bronze: url: https://www.digital-science.com/ logo: ds.svg +- name: De Gruyter + url: https://www.degruyter.com/ + logo: degruyter.svg + - name: eLife Sciences Publications url: https://elifesciences.org/ logo: elife.svg From 43fec2b790c5b535f83a59fb2b344ed603299ce2 Mon Sep 17 00:00:00 2001 From: Zhan4i <122616204+Zhan4i@users.noreply.github.com> Date: Fri, 6 Oct 2023 12:16:50 +0200 Subject: [PATCH 22/79] Update sponsors.yml --- cms/data/sponsors.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/data/sponsors.yml b/cms/data/sponsors.yml index 2af292427e..c497161479 100644 --- a/cms/data/sponsors.yml +++ b/cms/data/sponsors.yml @@ -76,7 +76,7 @@ bronze: - name: De Gruyter url: https://www.degruyter.com/ - logo: degruyter.svg + logo: Degruyter.svg - name: eLife Sciences Publications url: https://elifesciences.org/ From 02954cfb0071d84d5414c62dce7fe33001bcc008 Mon Sep 17 00:00:00 2001 From: philip Date: Wed, 11 Oct 2023 10:34:05 +0100 Subject: [PATCH 23/79] fix some conflict in toc.html and toc_base.html --- portality/templates/doaj/toc.html | 5 ----- 1 file changed, 5 deletions(-) diff --git a/portality/templates/doaj/toc.html b/portality/templates/doaj/toc.html index ccf3ac1a88..df9f5a787e 100644 --- a/portality/templates/doaj/toc.html +++ b/portality/templates/doaj/toc.html @@ -17,11 +17,6 @@ "Dulcinea" : "https://www.accesoabierto.net/dulcinea/lista/REVISTA/", } %} - {% 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 %} - -

About

From 407f4c38443b9053c3e718ff60cd7d712df5238c Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Wed, 11 Oct 2023 14:31:00 +0200 Subject: [PATCH 24/79] Changed order to match application form --- cms/pages/apply/seal.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cms/pages/apply/seal.md b/cms/pages/apply/seal.md index b9c4968cca..dbc370a2a5 100644 --- a/cms/pages/apply/seal.md +++ b/cms/pages/apply/seal.md @@ -21,29 +21,29 @@ There are seven criteria which a journal must meet to be eligible for the DOAJ S All seven criteria must be met for a journal to be awarded the Seal. Failure to maintain the best practice and standards described in these criteria may lead to removal of the Seal. {:.tabular-list .tabular-list--ordered} -1. Digital preservation +1. Digital preservation (archiving policy) - The journal content must be continuously deposited in one of these archives: - any archiving agency included in [Keepers Registry](https://keepers.issn.org/keepers) - Internet Archive - PubMed Central -2. Persistent article identifiers +2. Self-archiving (Repository policy) + - Authors must be permitted to deposit all versions of their paper in an institutional or subject repository. + - Preprint + - Author's Accepted Manuscript + - Published article (Version of Record) + - An embargo may not be applied. +3. Persistent article identifiers (Unique identifiers) - Articles must use persistent article identifiers. DOI, ARK or Handle are the most commonly used. - All persistent links must resolve correctly. -3. Metadata supply to DOAJ +4. Metadata supply to DOAJ - Article metadata must be uploaded to DOAJ regularly. -4. License type +5. License type - The journal must permit the use of a Creative Commons license that allows the creation of derivative products. - CC BY - CC BY-SA - CC BY-NC - CC BY-NC-SA -5. License information in articles +6. License information in articles - Creative Commons licensing information must be displayed in all full-text article formats. -6. Copyright and publishing rights +7. Copyright and publishing rights - Authors must retain unrestricted copyright and all publishing rights when publishing under any license permitted by the journal. -7. Self-archiving policy - - Authors must be permitted to deposit all versions of their paper in an institutional or subject repository. - - Preprint - - Author's Accepted Manuscript - - Published article (Version of Record) - - An embargo may not be applied. From a2ef75f4912f35855ae1d46b4f41e826bfb9e15c Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Wed, 11 Oct 2023 14:32:22 +0200 Subject: [PATCH 25/79] Update seal.md --- cms/pages/apply/seal.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cms/pages/apply/seal.md b/cms/pages/apply/seal.md index dbc370a2a5..7fc7f4d414 100644 --- a/cms/pages/apply/seal.md +++ b/cms/pages/apply/seal.md @@ -12,7 +12,7 @@ The DOAJ Seal is awarded to journals that demonstrate best practice in open acce **Journals do not need to meet the Seal criteria to be accepted into DOAJ.** -There are seven criteria which a journal must meet to be eligible for the DOAJ Seal. These relate to best practice in long term preservation, use of persistent identifiers, discoverability, reuse policies and authors' rights. +There are seven criteria which a journal must meet to be eligible for the DOAJ Seal. These relate to best practices in long-term preservation, use of persistent identifiers, discoverability, reuse policies and authors' rights. --- @@ -21,7 +21,7 @@ There are seven criteria which a journal must meet to be eligible for the DOAJ S All seven criteria must be met for a journal to be awarded the Seal. Failure to maintain the best practice and standards described in these criteria may lead to removal of the Seal. {:.tabular-list .tabular-list--ordered} -1. Digital preservation (archiving policy) +1. Digital preservation (Archiving policy) - The journal content must be continuously deposited in one of these archives: - any archiving agency included in [Keepers Registry](https://keepers.issn.org/keepers) - Internet Archive From aada3a69f4d058bc412d4ae252c8bc2384c01ad9 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Thu, 12 Oct 2023 11:27:14 +0100 Subject: [PATCH 26/79] add featuremap annotations to autocompletes --- portality/forms/application_forms.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/portality/forms/application_forms.py b/portality/forms/application_forms.py index ff6c3ab928..33cd4c1eb7 100644 --- a/portality/forms/application_forms.py +++ b/portality/forms/application_forms.py @@ -480,7 +480,7 @@ class FieldDefinitions: ], "widgets": [ "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ - {"autocomplete": {"type" : "journal", "field": "bibjson.publisher.name.exact"}}, + {"autocomplete": {"type" : "journal", "field": "bibjson.publisher.name.exact"}}, # ~~^-> Autocomplete:FormWidget~~ "full_contents" # ~~^->FullContents:FormWidget~~ ], "help": { @@ -493,21 +493,21 @@ class FieldDefinitions: "admin": { "widgets": [ "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ - {"autocomplete": {"type": "journal", "field": "bibjson.publisher.name.exact"}}, + {"autocomplete": {"type": "journal", "field": "bibjson.publisher.name.exact"}}, # ~~^-> Autocomplete:FormWidget~~ "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ ] }, "associate_editor": { "widgets": [ "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ - {"autocomplete": {"type": "journal", "field": "bibjson.publisher.name.exact"}}, + {"autocomplete": {"type": "journal", "field": "bibjson.publisher.name.exact"}}, # ~~^-> Autocomplete:FormWidget~~ "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ ] }, "editor": { "widgets": [ "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ - {"autocomplete": {"type": "journal", "field": "bibjson.publisher.name.exact"}}, + {"autocomplete": {"type": "journal", "field": "bibjson.publisher.name.exact"}}, # ~~^-> Autocomplete:FormWidget~~ "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ ] } @@ -577,7 +577,7 @@ class FieldDefinitions: }, "widgets": [ "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ - {"autocomplete": {"type" : "journal", "field": "bibjson.institution.name.exact"}}, + {"autocomplete": {"type" : "journal", "field": "bibjson.institution.name.exact"}}, # ~~^-> Autocomplete:FormWidget~~ "full_contents" # ~~^->FullContents:FormWidget~~ ] } @@ -1651,7 +1651,7 @@ class FieldDefinitions: "owner_exists" ], "widgets": [ - {"autocomplete": {"type" : "account", "field": "id", "include" : False}}, + {"autocomplete": {"type" : "account", "field": "id", "include" : False}}, # ~~^-> Autocomplete:FormWidget~~ "clickable_owner" ], "contexts" : { @@ -1709,7 +1709,7 @@ class FieldDefinitions: "label": "Group", "input": "text", "widgets": [ - {"autocomplete": {"type" : "editor_group", "field": "name", "include" : False}} + {"autocomplete": {"type" : "editor_group", "field": "name", "include" : False}} # ~~^-> Autocomplete:FormWidget~~ ], "contexts" : { "editor" : { @@ -1717,7 +1717,7 @@ class FieldDefinitions: }, "admin" : { "widgets" : [ - {"autocomplete": {"type": "editor_group", "field": "name", "include" : False}}, + {"autocomplete": {"type": "editor_group", "field": "name", "include" : False}}, # ~~^-> Autocomplete:FormWidget~~ {"load_editors" : {"field" : "editor"}} ] } From 65b217fda7f3bf5d790dadfa19e1c68b6ed16004 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Thu, 12 Oct 2023 14:14:09 +0200 Subject: [PATCH 27/79] Added l. 13-66 --- cms/pages/support/publisher-supporters.md | 61 ++++++++++++++++++++--- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/cms/pages/support/publisher-supporters.md b/cms/pages/support/publisher-supporters.md index 1d82e26b2b..4091401616 100644 --- a/cms/pages/support/publisher-supporters.md +++ b/cms/pages/support/publisher-supporters.md @@ -1,7 +1,7 @@ --- layout: sidenav include: /data/publisher-supporters.html -title: Publisher supporters +title: Publisher supporter model section: Support sticky_sidenav: true toc: true @@ -10,15 +10,62 @@ featuremap: - ~~->PublisherSupportersData:Template~~ --- -The publishers on this page have chosen to show their commitment to quality, peer-reviewed open access by supporting DOAJ. We thank them! Without them, our work would not be possible. +DOAJ relies on the support of publishers and [libraries](/support/) to ensure that its metadata and services remain free for all. The publishers on this page have chosen to show their commitment to quality, peer-reviewed open access by supporting DOAJ. We thank them as without them, our work would not be possible. -**To become a publisher supporter**, send an email to [our Help desk](mailto:helpdesk@doaj.org) and we will provide with details on how to support us. Your organisation will be listed on this page. +## 2024 pricing -'Premier' and 'Sustaining' publishers have committed to supporting DOAJ for a three-year period. 'Basic' publishers support us for one year. +We are introducing a revised and simplified model for publishers to support DOAJ for 2024 and publishing this openly in line with [our commitment to the Principles of Open Scholarly Infrastructure[(https://blog.doaj.org/2022/10/06/doaj-commits-to-the-principles-of-open-scholarly-infrastructure-posi/). We are also relaunching the set of benefits for publishers choosing to support us. -
{% include '/data/sponsors.html' %}
+We only accept support through our publisher supporter model from publishers with journals already indexed in DOAJ. Other routes to support DOAJ are as [an institution](/support/) or as [an individual via Paypal](https://www.paypal.com/donate/?campaign_id=4VXR4TJ69MDJJ). Non-commercial/institutional rates are only available to community-led, smaller publishers with limited funding. Please contact [supporters@doaj.org](mailto:supporters@doaj.org) if unsure which category applies. + +Please contact [supporters@doaj.org](mailto:supporters@doaj.org) if you want to contribute to DOAJ’s operating costs as a publisher supporter. + +## Commercial publishers + +| Band | Number of journals in DOAJ | GBPs (£)* | +|------|----------------------------|-----------| +| A | 600+ | 25,000 | +| B | 400-599 | 20,000 | +| C | 150-399 | 17,000 | +| D | 100-149 | 14,000 | +| E | 50-99 | 8000 | +| F | 30-49 | 6000 | +| G | 10-29 | 5000 | +| H | 1-9 | 3500 | + +## Non-commercial / institutional publishers + +| Band | Number of journals in DOAJ | GBPs (£)* | +|------|----------------------------|-----------| +| C | 150-399 | 3500 | +| D | 100-149 | 3000 | +| E | 50-99 | 2500 | +| F | 30-49 | 2000 | +| G | 10-29 | 1500 | +| H | 1-9 | 1000 | + +*A 50% discount is available for supporters in Low- and Middle-Income Countries according to the World Bank classification. + +## 2024 publisher benefits -## Benefits for contributing publishers and aggregators +1. Your logo on the DOAJ website +2. A post from all our social media platforms (Twitter, Facebook, LinkedIn, Mastodon, Instagram) acknowledging your organisation as a Supporter +3. A blog post at the start of the year introducing our new supporters +4. Our DOAJ Supporter logo which you can use for your website +5. Access to our Public Data Dump +6. For supporters from Bands A-E, or those contributing over the suggested amounts, a personal DOAJ contact to whom all enquiries regarding your applications and updates can be directed + +## Sponsorship opportunities + +We are particularly grateful to those publishers who can contribute over and above these amounts. In these cases, we can offer sponsorship opportunities that enhance our services and support open access globally, for example: + +- Specific technical developments +- Ambassador programme +- Webinar programmes and events + +Please get in touch to discuss. + +## 2023 benefits for publisher supporters ([A downloadable version](https://docs.google.com/document/d/1xTVxUvqLkh2-r53cYlWdSIHsPGSnhcE7gi7bRFCaJik/edit?usp=sharing) of these benefits is available.) @@ -33,4 +80,6 @@ The publishers on this page have chosen to show their commitment to quality, pee | | | A CSV file, generated annually, for recording changes in and which DOAJ updates your live records with. | | | | Exposure across all our social media channels: Twitter, Instagram, LinkedIn, Facebook, WeChat. (Stats available.) | +
{% include '/data/sponsors.html' %}
+ ## Other publisher supporters From 4adbe8629ae67105f6558002bfb95b3d460b76d2 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Thu, 12 Oct 2023 14:15:22 +0200 Subject: [PATCH 28/79] Update publisher-supporters.md --- cms/pages/support/publisher-supporters.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cms/pages/support/publisher-supporters.md b/cms/pages/support/publisher-supporters.md index 4091401616..5d2c203cce 100644 --- a/cms/pages/support/publisher-supporters.md +++ b/cms/pages/support/publisher-supporters.md @@ -20,7 +20,7 @@ We only accept support through our publisher supporter model from publishers wit Please contact [supporters@doaj.org](mailto:supporters@doaj.org) if you want to contribute to DOAJ’s operating costs as a publisher supporter. -## Commercial publishers +### Commercial publishers | Band | Number of journals in DOAJ | GBPs (£)* | |------|----------------------------|-----------| @@ -33,7 +33,7 @@ Please contact [supporters@doaj.org](mailto:supporters@doaj.org) if you want to | G | 10-29 | 5000 | | H | 1-9 | 3500 | -## Non-commercial / institutional publishers +### Non-commercial / institutional publishers | Band | Number of journals in DOAJ | GBPs (£)* | |------|----------------------------|-----------| From 3df00aca9f68cb04dacae4f3e3c849479d2231aa Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 16 Oct 2023 08:18:05 +0200 Subject: [PATCH 29/79] Edited l.63 --- cms/data/nav.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/data/nav.yml b/cms/data/nav.yml index ddd6b7cf7e..e8ec84fc22 100644 --- a/cms/data/nav.yml +++ b/cms/data/nav.yml @@ -60,7 +60,7 @@ entries: route: doaj.support # ~~->Support:WebRoute~~ - label: Publishers route: doaj.publisher_supporters # ~~->PublisherSupporters:WebRoute~~ - - label: Supporters + - label: Institutional and library supporters route: doaj.supporters # ~~->Supporters:WebRoute~~ - id: apply label: Apply From f1d5e935b0d9b21e9678540b3f54fcb833740f77 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 16 Oct 2023 08:20:05 +0200 Subject: [PATCH 30/79] Added l.65-66 --- cms/data/nav.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cms/data/nav.yml b/cms/data/nav.yml index e8ec84fc22..33c453c54f 100644 --- a/cms/data/nav.yml +++ b/cms/data/nav.yml @@ -62,6 +62,8 @@ entries: route: doaj.publisher_supporters # ~~->PublisherSupporters:WebRoute~~ - label: Institutional and library supporters route: doaj.supporters # ~~->Supporters:WebRoute~~ + - label: Publisher supporters + route: doaj.publishing_supporters # ~~->Supporters:WebRoute~~ - id: apply label: Apply footer: true From 36033094f5b16b71f6c6a43642cd79d195573683 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 16 Oct 2023 08:21:09 +0200 Subject: [PATCH 31/79] Update nav.yml --- cms/data/nav.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/data/nav.yml b/cms/data/nav.yml index 33c453c54f..f96acfafc0 100644 --- a/cms/data/nav.yml +++ b/cms/data/nav.yml @@ -63,7 +63,7 @@ entries: - label: Institutional and library supporters route: doaj.supporters # ~~->Supporters:WebRoute~~ - label: Publisher supporters - route: doaj.publishing_supporters # ~~->Supporters:WebRoute~~ + route: doaj.publishing_supporters # ~~->PublisherSupporters:WebRoute~~ - id: apply label: Apply footer: true From 15f2d0df0b2df4094d2361e1e8353951fa242846 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 16 Oct 2023 08:22:19 +0200 Subject: [PATCH 32/79] Update nav.yml --- cms/data/nav.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/cms/data/nav.yml b/cms/data/nav.yml index f96acfafc0..e8ec84fc22 100644 --- a/cms/data/nav.yml +++ b/cms/data/nav.yml @@ -62,8 +62,6 @@ entries: route: doaj.publisher_supporters # ~~->PublisherSupporters:WebRoute~~ - label: Institutional and library supporters route: doaj.supporters # ~~->Supporters:WebRoute~~ - - label: Publisher supporters - route: doaj.publishing_supporters # ~~->PublisherSupporters:WebRoute~~ - id: apply label: Apply footer: true From adb989979d473086a888c883b17a496d0e077e05 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 16 Oct 2023 10:12:37 +0200 Subject: [PATCH 33/79] Update publisher-supporters.md --- cms/pages/support/publisher-supporters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/pages/support/publisher-supporters.md b/cms/pages/support/publisher-supporters.md index 5d2c203cce..f010872aba 100644 --- a/cms/pages/support/publisher-supporters.md +++ b/cms/pages/support/publisher-supporters.md @@ -14,7 +14,7 @@ DOAJ relies on the support of publishers and [libraries](/support/) to ensure th ## 2024 pricing -We are introducing a revised and simplified model for publishers to support DOAJ for 2024 and publishing this openly in line with [our commitment to the Principles of Open Scholarly Infrastructure[(https://blog.doaj.org/2022/10/06/doaj-commits-to-the-principles-of-open-scholarly-infrastructure-posi/). We are also relaunching the set of benefits for publishers choosing to support us. +We are introducing a revised and simplified model for publishers to support DOAJ for 2024 and publishing this openly in line with [our commitment to the Principles of Open Scholarly Infrastructure](https://blog.doaj.org/2022/10/06/doaj-commits-to-the-principles-of-open-scholarly-infrastructure-posi/). We are also relaunching the set of benefits for publishers choosing to support us. We only accept support through our publisher supporter model from publishers with journals already indexed in DOAJ. Other routes to support DOAJ are as [an institution](/support/) or as [an individual via Paypal](https://www.paypal.com/donate/?campaign_id=4VXR4TJ69MDJJ). Non-commercial/institutional rates are only available to community-led, smaller publishers with limited funding. Please contact [supporters@doaj.org](mailto:supporters@doaj.org) if unsure which category applies. From 5eba6d11c52d4bd265c463b1878a9bbc4c62c4c7 Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 16 Oct 2023 13:36:03 +0100 Subject: [PATCH 34/79] make sure ArticleNotAcceptable exception is caught correctly and message is displayed as an error --- portality/bll/services/article.py | 2 ++ portality/view/publisher.py | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/portality/bll/services/article.py b/portality/bll/services/article.py index b5e829cd24..52ce61fb20 100644 --- a/portality/bll/services/article.py +++ b/portality/bll/services/article.py @@ -219,6 +219,8 @@ def create_article(self, article, account, duplicate_check=True, merge_duplicate # We do this after the permissions check because that gives a detailed result whereas this throws an exception try: self.is_acceptable(article) + except exceptions.ArticleNotAcceptable as e: + raise exceptions.ArticleNotAcceptable(message=e.message) except Exception as e: raise e diff --git a/portality/view/publisher.py b/portality/view/publisher.py index 2410a8323a..c525ce176c 100644 --- a/portality/view/publisher.py +++ b/portality/view/publisher.py @@ -4,7 +4,7 @@ from portality.app_email import EmailException from portality import models -from portality.bll.exceptions import AuthoriseException, ArticleMergeConflict, DuplicateArticleException +from portality.bll.exceptions import AuthoriseException, ArticleMergeConflict, DuplicateArticleException, ArticleNotAcceptable from portality.decorators import ssl_required, restrict_to_role, write_required from portality.dao import ESMappingMissingError from portality.forms.application_forms import ApplicationFormFactory @@ -362,7 +362,8 @@ def metadata(): Messages.flash(Messages.ARTICLE_METADATA_MERGE_CONFLICT) except DuplicateArticleException: Messages.flash(Messages.ARTICLE_METADATA_UPDATE_CONFLICT) - + except ArticleNotAcceptable as e: + Messages.flash_with_param(e.message, "error") return fc.render_template(validated=validated) From 89e6d8cbc6bfef49f739d336d7abee2b2327068b Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Mon, 16 Oct 2023 15:18:38 +0200 Subject: [PATCH 35/79] Adjusted headings --- cms/pages/apply/transparency.md | 41 ++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/cms/pages/apply/transparency.md b/cms/pages/apply/transparency.md index 0bda2aae3d..913d061882 100644 --- a/cms/pages/apply/transparency.md +++ b/cms/pages/apply/transparency.md @@ -23,13 +23,14 @@ These principles also acknowledge that publishers and editors are responsible fo ### JOURNAL CONTENT -#### 1. Name of journal +**1. Name of journal** + The journal's name should: - Be unique and not be one that is easily confused with another journal. - Not mislead potential authors and readers about the journal's origin, scope, or association with other journals and organisations. -#### 2. Website +**2. Website** - Websites should be properly supported and maintained, with particular attention given to security aspects that help protect users from viruses and malware. - As a minimum, websites should use https and not http, and all traffic should be redirected through https. Those responsible for the website should apply web standards and best ethical practices to the website's content, presentation, and application. @@ -45,20 +46,22 @@ In addition to the requirements outlined above, the following items should be cl - Authorship criteria. - ISSNs (separate for print and electronic versions). -#### 3. Publishing schedule +**3. Publishing schedule** + A journal's publishing frequency should be clearly described, and the journal must keep to its publishing schedule unless there are exceptional circumstances. -#### 4. Archiving +**4. Archiving** + A journal's plan for electronic backup and long term digital preservation of the journal content, in the event that the journal and/or publisher stops operating, should be clearly indicated. Examples include PMC and those listed in [the Keepers Registry](https://keepers.issn.org/). -#### 5. Copyright +**5. Copyright** - The copyright terms for published content should be clearly stated on the website and in the content. - The copyright terms should be separate and distinct from the copyright of the website. - The copyright holder should be named on the full text of all published articles (HTML and PDF). - If the copyright terms are described in a separate form, this should be easy to find on the website and available to all. -#### 6. Licencing +**6. Licencing** - Licencing information should be clearly described on the website. - Licencing terms should be indicated on the full text of all published articles (HTML and PDF). @@ -69,7 +72,8 @@ If Creative Commons licences are used, then the terms of that licence should als ### JOURNAL PRACTICES -#### 7. Publication ethics and related editorial policies +**7. Publication ethics and related editorial policies** + A journal should have policies on publication ethics (for example, [COPE's Core Practice guidance](https://publicationethics.org/core-practices)). These should be visible on its website, and should refer to: - Journal's policies on [authorship and contributorship](https://publicationethics.org/authorship). @@ -84,7 +88,8 @@ A journal should have policies on publication ethics (for example, [COPE's Core Editors and publishers are responsible for ensuring the integrity of the scholarly literature in their journals and should ensure they outline their policies and procedures for handling such issues when they arise. These issues include plagiarism, citation manipulation, and data falsification/fabrication, among others. Neither the journal’s policies nor the statements of its editors should encourage such misconduct, or knowingly allow such misconduct to take place. In the event that a journal's editors or publisher are made aware of any allegation of research misconduct relating to a submitted or published article in their journal, the editor or publisher should follow [COPE's guidance](https://publicationethics.org/guidance) (or equivalent) in dealing with allegations. -#### 8. Peer review +**8. Peer review** + Peer review is defined as obtaining advice on manuscripts from reviewers/experts in the manuscript’s subject area. Those individuals should not be part of the journal's editorial team. However, the specific elements of peer review may differ by journal and discipline, so the following should be clearly stated on the website: - Whether or not the content is peer reviewed. @@ -105,30 +110,31 @@ Journals should not guarantee acceptance of initial manuscript submissions. Stat The date of publication should be published with all published research. Dates of submission and acceptance are preferred as well. -#### 9. Access +**9. Access** + If any of the online content is not freely accessible to everyone, the method of gaining access (for example, registration, subscription, or pay-per-view fees) should be clearly described. If offline versions (for example, print) are available, this should be clearly described along with any associated charges. ### ORGANISATION -#### 10. Ownership and management +**10. Ownership and management** - Information about the ownership and management of a journal should be clearly indicated on the journal's website. - Organisational names should not be used in a way that could mislead potential authors and editors about the nature of the journal's owner. - If a journal is affiliated with a society, institution, or sponsor, links to their website(s) should be provided where available. -#### 11. Advisory body +**11. Advisory body** Journals should have editorial boards or other advisory bodies whose members are recognised experts in the subject areas stated in the journal's aims and scope. - The full names and affiliations of the members should be provided on the journal's website. - The list should be up to date, and members must agree to serve. - To avoid being associated with predatory or deceptive journals, journals should periodically review their board to ensure it is still relevant and appropriate. -#### 12. Editorial team/contact information +**12. Editorial team/contact information** Journals should provide the full names and affiliations of their editors as well as contact information for the editorial office, including a full mailing address, on the journal’s website. ### BUSINESS PRACTICES -#### 13. Author fees +**13. Author fees** - If author fees are charged (such as article processing charges, page charges, editorial processing charges, language editing fees, colour charges, submission fees, membership fees, or other supplementary charges), then the fees should be clearly stated on the website. - If there are no such fees, this should be clearly stated. @@ -141,14 +147,16 @@ Journals should provide the full names and affiliations of their editors as well - When and how to apply for a waiver. - Author fees or waiver status should not influence editorial decision making, and this should be clearly stated. -#### 14. Other revenue +**14. Other revenue** + Business models or revenue sources should be clearly stated on the journal's website. Examples include author fees (see section 13), subscriptions, sponsorships and subsidies, advertising (see section 15), reprints, supplements, or special issues. Business models or revenue sources (for example, reprint income, supplements, special issues, sponsorships) should not influence editorial decision making. -#### 15. Advertising +**15. Advertising** + Journals should state whether they accept advertising. If they do, they should state their advertising policy, including: - Which types of advertisements will be considered. @@ -157,7 +165,8 @@ Journals should state whether they accept advertising. If they do, they should s Advertisements should not be related in any way to editorial decision making and should be kept separate from the published content. -#### 16. Direct marketing +**16. Direct marketing** + Any direct marketing activities, including solicitation of manuscripts, that are conducted on behalf of the journal should be appropriate, well targeted, and unobtrusive. Information provided about the publisher or journal should be truthful and not misleading for readers or authors. ## Version history From 2c64863d149d73ffdbea712af01f6ba610885125 Mon Sep 17 00:00:00 2001 From: Dom Mitchell Date: Tue, 17 Oct 2023 09:12:34 +0200 Subject: [PATCH 36/79] Added l.23 --- portality/templates/publisher/help.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/portality/templates/publisher/help.html b/portality/templates/publisher/help.html index 9f4daddeb4..abf09a4cff 100644 --- a/portality/templates/publisher/help.html +++ b/portality/templates/publisher/help.html @@ -6,7 +6,7 @@

Help for publishers

-

Uploading metadata/article content a file

+

Uploading metadata/article content

There are three ways to upload article metadata to DOAJ:

@@ -20,6 +20,8 @@

Uploading metadata/article content a file

There are instructions on how to prepare and upload your XML file on our XML documentation page.

+

Are you receiving an error about one of your ISSNs that you haven't seen before? We recently changed the rules for uploading article metadata. We now require that a Print ISSN is in an issn tag and the Online ISSN is in an eissn tag. [See our sample XML file](https://doaj.org/docs/xml/#example-doaj-xml-file) for more information.

+

Failed XML uploads explained

This section explains the error messages that you may see when you upload article XML. Use the message in the 'Notes' column of your History of uploads table to correct your XML.

From 56dad008fe99b81317b08c98add36a48dd8e9e18 Mon Sep 17 00:00:00 2001 From: Sophy Date: Tue, 17 Oct 2023 10:46:26 +0100 Subject: [PATCH 37/79] =?UTF-8?q?Update=20sponsors=E2=80=99=20markup=20to?= =?UTF-8?q?=20display=20them=20all=20on=20the=20same=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SEE DOAJ/doajPM#3700 --- portality/templates/data/sponsors.html | 34 +++----------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/portality/templates/data/sponsors.html b/portality/templates/data/sponsors.html index 5dfee23989..8cd600cc6a 100644 --- a/portality/templates/data/sponsors.html +++ b/portality/templates/data/sponsors.html @@ -1,35 +1,7 @@ -{% if data.sponsors.gold %} -

Premier contributors

-
- {% for i in data.sponsors.gold %} - - {% endfor %} -
-{% endif %} - -
- -

Sustaining contributors

+

Premier contributors

- {% for i in data.sponsors.silver %} - - {% endfor %} -
- -
- -

Basic contributors

-
- {% for i in data.sponsors.bronze %} -