From bddce5a206348d18f302318bfd61d2231e42a70d Mon Sep 17 00:00:00 2001 From: Aga Date: Fri, 4 Aug 2023 09:53:58 +0100 Subject: [PATCH 01/13] make differentTo validator case insensitive --- portality/static/js/application_form.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/portality/static/js/application_form.js b/portality/static/js/application_form.js index 178aef09c4..3944845669 100644 --- a/portality/static/js/application_form.js +++ b/portality/static/js/application_form.js @@ -844,8 +844,8 @@ window.Parsley.addValidator("optionalIf", { }); window.Parsley.addValidator("differentTo", { - validateString : function(value, requirement) { - return (!value || ($("[name = " + requirement + "]")).val() !== value); + validateString : function(value, requirement, message) { + return (!value || ($("[name = " + requirement + "]")).val().toLowerCase() !== value.toLowerCase()); }, messages: { en: 'Value of this field and %s field must be different' From 05f67c761ae0d05f368803a058bbaa2f3046d5ce Mon Sep 17 00:00:00 2001 From: Aga Date: Fri, 4 Aug 2023 09:54:32 +0100 Subject: [PATCH 02/13] add DifferentTo validator to Publishers name and Institution name fields, make sure message is passed correctly --- portality/forms/application_forms.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/portality/forms/application_forms.py b/portality/forms/application_forms.py index 0065b765fc..b088a9786c 100644 --- a/portality/forms/application_forms.py +++ b/portality/forms/application_forms.py @@ -444,7 +444,8 @@ class FieldDefinitions: "label": "Publisher’s name", "input": "text", "validate": [ - {"required": {"message": "Enter the name of the journal’s publisher"}} + {"required": {"message": "Enter the name of the journal’s publisher"}}, + {"different_to": {"field": "institution_name", "message": "This field must be different than 'Society or institution’s name'"}} # ~~^-> DifferetTo:FormValidator~~ ], "widgets": [ "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ @@ -505,6 +506,10 @@ class FieldDefinitions: "a society or other type of institution, enter that here."], "placeholder": "Type or select the society or institution’s name" }, + "validate": [ + {"different_to": {"field": "publisher_name", + "message": "This field must be different than 'Publisher’s name'"}} # ~~^-> DifferetTo:FormValidator~~ + ], "widgets": [ "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ {"autocomplete": {"type" : "journal", "field": "bibjson.institution.name.exact"}}, @@ -2743,6 +2748,7 @@ class DifferentToBuilder: @staticmethod def render(settings, html_attrs): html_attrs["data-parsley-different-to"] = settings.get("field") + html_attrs["data-parsley-different-to-message"] = "

" + settings.get("message") + "

" @staticmethod def wtforms(field, settings): From 5fce92245d3cf2aaa5de59e8918feeddb17fd15e Mon Sep 17 00:00:00 2001 From: Aga Date: Fri, 4 Aug 2023 10:00:16 +0100 Subject: [PATCH 03/13] add functional test --- doajtest/testbook/new_application_form/publishers_form.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doajtest/testbook/new_application_form/publishers_form.yml b/doajtest/testbook/new_application_form/publishers_form.yml index 07f1c2e40a..72b4de2316 100644 --- a/doajtest/testbook/new_application_form/publishers_form.yml +++ b/doajtest/testbook/new_application_form/publishers_form.yml @@ -114,6 +114,13 @@ tests: - step: Click the X next to it results: - It disappears + - step: Enter the same value in Publisher's Name and Publisher's Country + - step: Click Next + results: + - "You see the error message: The value of this field and the Publisher's Country field must be different." + - step: Repeat previous step checking if the validator is case insensitive (e.g. "Publisher's name" and "publisher's Name") + results: + - The error message is still displayed - step: Repeat steps X to X for the Publisher's Name, Country, Society name, Country - step: Delete the values from Society name and country, click Next results: From 69cd7cf930dcfc86273f9632ebb912c4db6554e4 Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 16 Oct 2023 11:45:40 +0100 Subject: [PATCH 04/13] add error message to the continuations validator --- portality/forms/application_forms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/portality/forms/application_forms.py b/portality/forms/application_forms.py index a1df8b78c7..4eef1e45a8 100644 --- a/portality/forms/application_forms.py +++ b/portality/forms/application_forms.py @@ -1763,7 +1763,7 @@ class FieldDefinitions: "input": "taglist", "validate": [ {"is_issn_list": {"message": "This is not a valid ISSN"}}, # ~~^-> IsISSN:FormValidator~~ - {"different_to": {"field": "continued_by"}}, # ~~^-> DifferetTo:FormValidator~~ + {"different_to": {"field": "continued_by", "message": "The ISSN provided in both fields must be different. Please make sure to enter the ISSN of an older journal for the first field and the ISSN of a newer journal for the second field. They cannot be the same."}}, # ~~^-> DifferetTo:FormValidator~~ { "not_if" : { "fields" : [{"field" : "discontinued_date"}], @@ -1786,7 +1786,7 @@ class FieldDefinitions: "input": "taglist", "validate": [ {"is_issn_list": {"message": "This is not a valid ISSN"}}, # ~~^-> IsISSN:FormValidator~~ - {"different_to": {"field": "continues"}}, # ~~^-> DifferetTo:FormValidator~~ + {"different_to": {"field": "continues", "message": "The ISSN provided in both fields must be different. Please make sure to enter the ISSN of an older journal for the first field and the ISSN of a newer journal for the second field. They cannot be the same."}}, # ~~^-> DifferetTo:FormValidator~~ { "not_if": { "fields": [{"field": "discontinued_date"}], From c388be7ccf977a075b1086a7b2810c95bb401e4b Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 6 Nov 2023 14:16:33 +0000 Subject: [PATCH 05/13] merge and change message --- portality/forms/application_forms.py | 86 +++++++++++++--------------- 1 file changed, 39 insertions(+), 47 deletions(-) diff --git a/portality/forms/application_forms.py b/portality/forms/application_forms.py index 634839db75..ebe21abebe 100644 --- a/portality/forms/application_forms.py +++ b/portality/forms/application_forms.py @@ -417,8 +417,8 @@ class FieldDefinitions: "input": "taglist", "help": { "long_help": ["Choose upto 6 keywords that describe the subject matter of the journal. " - "Keywords must be in English.", "Use single words or short phrases (2 to 3 words) " - "that describe the journal's main topic.", "Do not add acronyms, abbreviations or descriptive sentences.", + "Keywords must be in English.", "Use single words or short phrases (2 to 3 words) " + "that describe the journal's main topic.", "Do not add acronyms, abbreviations or descriptive sentences.", "Note that the keywords may be edited by DOAJ editorial staff." ], }, "validate": [ @@ -477,7 +477,7 @@ class FieldDefinitions: "input": "text", "validate": [ {"required": {"message": "Enter the name of the journal’s publisher"}}, - {"different_to": {"field": "institution_name", "message": "This field must be different than 'Society or institution’s name'"}} # ~~^-> DifferetTo:FormValidator~~ + {"different_to": {"field": "institution_name", "message": "Publisher and Society/Institution names cannot be the same."}} # ~~^-> DifferetTo:FormValidator~~ ], "widgets": [ "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ @@ -564,6 +564,11 @@ class FieldDefinitions: {"autocomplete": {"type" : "journal", "field": "bibjson.institution.name.exact"}}, # ~~^-> Autocomplete:FormWidget~~ "full_contents" # ~~^->FullContents:FormWidget~~ ], + "validate": [ + {"different_to": {"field": "publisher_name", + "message": "Publisher and Society/Institution names cannot be the same."}} + # ~~^-> DifferetTo:FormValidator~~ + ], "contexts": { "admin": { "widgets": [ @@ -590,19 +595,6 @@ class FieldDefinitions: ] } } - "click_to_copy", # ~~^-> ClickToCopy:FormWidget~~ - ] - } - }, - "validate": [ - {"different_to": {"field": "publisher_name", - "message": "This field must be different than 'Publisher’s name'"}} # ~~^-> DifferetTo:FormValidator~~ - ], - "widgets": [ - "trim_whitespace", # ~~^-> TrimWhitespace:FormWidget~~ - {"autocomplete": {"type" : "journal", "field": "bibjson.institution.name.exact"}}, - "full_contents" # ~~^->FullContents:FormWidget~~ - ] } # ~~->$ InstitutionCountry:FormField~~ @@ -751,7 +743,7 @@ class FieldDefinitions: "field": "license_display", "value": "y", "message": "Enter the URL for any recent article that displays or embeds a license" - } + } }, "is_url" # ~~^->IsURL:FormValidator~~ ], @@ -859,7 +851,7 @@ class FieldDefinitions: "field": "review_process", "value": "other", "message": "Enter the name of another type of peer review" - } + } } ], "widgets" : [ @@ -898,8 +890,8 @@ class FieldDefinitions: "datatype": "integer", "help": { "long_help": ["Please enter the year that the journal started to publish all content as true open access, according to DOAJ's definition.", - "For journals that have flipped to open access, enter the year that the journal flipped, not the original launch date of the journal.", - "For journals that have made digitised backfiles freely available, enter the year that the journal started publishing as a fully open access title, not the date of the earliest free content."] + "For journals that have flipped to open access, enter the year that the journal flipped, not the original launch date of the journal.", + "For journals that have made digitised backfiles freely available, enter the year that the journal started publishing as a fully open access title, not the date of the earliest free content."] }, "validate": [ {"required": {"message": "Enter the Year (YYYY)."}}, @@ -951,7 +943,7 @@ class FieldDefinitions: "field": "plagiarism_detection", "value": "y", "message": "Enter the URL for the journal’s plagiarism policy page" - } + } }, "is_url" # ~~^->IsURL:FormValidator~~ ], @@ -1198,14 +1190,14 @@ class FieldDefinitions: "help": { "short_help": "Link to the journal’s waiver information.", "doaj_criteria": "You must provide a URL", - "placeholder": "https://www.my-journal.com/about#waiver" + "placeholder": "https://www.my-journal.com/about#waiver" }, "validate": [ {"required_if": { "field": "has_waiver", "value": "y", "message": "Enter the URL for the journal’s waiver information page" - } + } }, "is_url" # ~~^->IsURL:FormValidator~~ ], @@ -1253,7 +1245,7 @@ class FieldDefinitions: "field": "has_other_charges", "value": "y", "message": "Enter the URL for the journal’s fees information page" - } + } }, "is_url" # ~~^->IsURL:FormValidator~~ ], @@ -1312,7 +1304,7 @@ class FieldDefinitions: "field": "preservation_service", "value": "national_library", "message": "Enter the name(s) of the national library or libraries where the journal is archived" - } + } } ], "asynchronous_warning": [ @@ -1338,7 +1330,7 @@ class FieldDefinitions: "field": "preservation_service", "value": "other", "message": "Enter the name of another archiving policy" - } + } } ], "asynchronous_warning": [ @@ -1437,7 +1429,7 @@ class FieldDefinitions: "field": "deposit_policy", "value": "other", "message": "Enter the name of another repository policy" - } + } } ], "asynchronous_warning": [ @@ -1524,8 +1516,8 @@ class FieldDefinitions: ], "help": { "long_help": ["A persistent article identifier (PID) is used to find the article no matter where it is " - "located. The most common type of PID is the digital object identifier (DOI). ", - "Read more about PIDs."], + "located. The most common type of PID is the digital object identifier (DOI). ", + "Read more about PIDs."], }, "validate": [ {"required": {"message": "Select at least one option"}} @@ -1543,7 +1535,7 @@ class FieldDefinitions: "field": "persistent_identifiers", "value": "other", "message": "Enter the name of another type of identifier" - } + } } ], "asynchronous_warning": [ @@ -1566,7 +1558,7 @@ class FieldDefinitions: "default" : "", "help": { "long_help": ["An ORCID (Open Researcher and Contributor) iD is an alphanumeric code to uniquely identify " - "authors."], + "authors."], }, "contexts" : { "public" : { @@ -1657,7 +1649,7 @@ class FieldDefinitions: "input": "textarea", "help": { "long_help": ["The selected reason for rejection, and any additional information you include, " - "are sent to the journal contact with the rejection email."] + "are sent to the journal contact with the rejection email."] }, "validate": [ {"required_if": {"field": "quick_reject", "value": "other"}} @@ -1707,7 +1699,7 @@ class FieldDefinitions: "help" : { "render_error_box": False, "short_help" : "Set the status to 'In Progress' to signal to the applicant that you have started your review." - "Set the status to 'Completed' to alert the Editor that you have completed your review.", + "Set the status to 'Completed' to alert the Editor that you have completed your review.", "update_requests_diff": False } }, @@ -1715,7 +1707,7 @@ class FieldDefinitions: "help" : { "render_error_box" : False, "short_help" : "Revert the status to 'In Progress' to signal to the Associate Editor that further work is needed." - "Set the status to 'Ready' to alert the Managing Editor that you have completed your review.", + "Set the status to 'Ready' to alert the Managing Editor that you have completed your review.", "update_requests_diff": False } } @@ -1844,18 +1836,18 @@ class FieldDefinitions: "validate": [ {"required_if" : { "field" : "application_status", - "value" : [ - constants.APPLICATION_STATUS_READY, - constants.APPLICATION_STATUS_COMPLETED, - constants.APPLICATION_STATUS_ACCEPTED - ], - "message" : "This field is required when setting the Application Status to {y}, {z} or {a}".format( - y=constants.APPLICATION_STATUS_READY, - z=constants.APPLICATION_STATUS_COMPLETED, - a=constants.APPLICATION_STATUS_ACCEPTED - ) - } - } + "value" : [ + constants.APPLICATION_STATUS_READY, + constants.APPLICATION_STATUS_COMPLETED, + constants.APPLICATION_STATUS_ACCEPTED + ], + "message" : "This field is required when setting the Application Status to {y}, {z} or {a}".format( + y=constants.APPLICATION_STATUS_READY, + z=constants.APPLICATION_STATUS_COMPLETED, + a=constants.APPLICATION_STATUS_ACCEPTED + ) + } + } ], "widgets": [ "subject_tree" @@ -3107,7 +3099,7 @@ class MultiCheckboxBuilder(WTFormsBuilder): @staticmethod def match(field): return field.get("input") == "checkbox" and \ - (len(field.get("options", [])) > 0 or field.get("options_fn") is not None) + (len(field.get("options", [])) > 0 or field.get("options_fn") is not None) @staticmethod def wtform(formulaic_context, field, wtfargs): From e0cb904114f1a5631252550d8526c4a59bc0ac7f Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 20 Nov 2023 12:45:01 +0000 Subject: [PATCH 06/13] remove information about GA from the privacy page --- cms/pages/legal/privacy.md | 1 - 1 file changed, 1 deletion(-) diff --git a/cms/pages/legal/privacy.md b/cms/pages/legal/privacy.md index 9bd20906e5..6ff9b11cc5 100644 --- a/cms/pages/legal/privacy.md +++ b/cms/pages/legal/privacy.md @@ -104,7 +104,6 @@ Volunteer records must include a name and an email address so that we can assign When you use DOAJ, cookies are set on your machine. The cookies we set are: -* Google Analytics - we track usage of this site using Google Analytics. We do not track individuals but general paths through the site. (Being retired as of August 2023.) * jquery - we use jquery.com to load the javascript framework. * doaj.org - a small number of required cookies for the application to function, for example when you log in and when you click away the cookie consent banner. * schema - if you upload article metadata to us via the Upload Article XML tab, we place a cookie on your machine which allows us to remember which XSD schema you used the last time you uploaded XML to us: doaj or Crossref From a6369185af48855473082be0245c4c66196ce517 Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 20 Nov 2023 13:01:06 +0000 Subject: [PATCH 07/13] remove any GA settings from settings file --- portality/settings.py | 68 ------------------------------------------- 1 file changed, 68 deletions(-) diff --git a/portality/settings.py b/portality/settings.py index d561e977d8..0082ea513a 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -1216,74 +1216,6 @@ # hotjar id - only activate this in production HOTJAR_ID = "" - -###################################################### -# Google Analytics configuration -# specify in environment .cfg file - avoids sending live analytics -# events from test and dev environments -# ~~->GoogleAnalytics:ExternalService~~ - -GOOGLE_ANALYTICS_ID = '' - -# Where to put the google analytics logs -GOOGLE_ANALTYICS_LOG_DIR = None - -# Google Analytics custom dimensions. These are configured in the GA interface. -GA_DIMENSIONS = { - 'oai_res_id': 'dimension1', # In GA as OAI:Record -} - -# GA for OAI-PMH -# ~~-> OAIPMH:Feature~~ -GA_CATEGORY_OAI = 'OAI-PMH' - -# GA for Atom -# ~~-> Atom:Feature~~ -GA_CATEGORY_ATOM = 'Atom' -GA_ACTION_ACTION = 'Feed request' - -# GA for JournalCSV -# ~~-> JournalCSV:Feature~~ -GA_CATEGORY_JOURNALCSV = 'JournalCSV' -GA_ACTION_JOURNALCSV = 'Download' - -# GA for OpenURL -# ~~->OpenURL:Feature~~ -GA_CATEGORY_OPENURL = 'OpenURL' - -# GA for PublicDataDump -# ~~->PublicDataDump:Feature~~ -GA_CATEGORY_PUBLICDATADUMP = 'PublicDataDump' -GA_ACTION_PUBLICDATADUMP = 'Download' - -# GA for API -# ~~-> API:Feature~~ -GA_CATEGORY_API = 'API Hit' -GA_ACTIONS_API = { - 'search_applications': 'Search applications', - 'search_journals': 'Search journals', - 'search_articles': 'Search articles', - 'create_application': 'Create application', - 'retrieve_application': 'Retrieve application', - 'update_application': 'Update application', - 'delete_application': 'Delete application', - 'create_article': 'Create article', - 'retrieve_article': 'Retrieve article', - 'update_article': 'Update article', - 'delete_article': 'Delete article', - 'retrieve_journal': 'Retrieve journal', - 'bulk_application_create': 'Bulk application create', - 'bulk_application_delete': 'Bulk application delete', - 'bulk_article_create': 'Bulk article create', - 'bulk_article_delete': 'Bulk article delete' -} - - -# GA for fixed query widget -# ~~->FixedQueryWidget:Feature~~ -GA_CATEGORY_FQW = 'FQW' -GA_ACTION_FQW = 'Hit' - ##################################################### # Anonymised data export (for dev) configuration # ~~->AnonExport:Feature~~ From dec2c3e604eee1012d803b1c49ddf5c01fa618db Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 20 Nov 2023 13:01:27 +0000 Subject: [PATCH 08/13] remove GA script from js includes --- portality/templates/_js_includes.html | 9 --------- 1 file changed, 9 deletions(-) diff --git a/portality/templates/_js_includes.html b/portality/templates/_js_includes.html index 50f3abdeff..d18034e523 100644 --- a/portality/templates/_js_includes.html +++ b/portality/templates/_js_includes.html @@ -14,15 +14,6 @@ - - - - {%- endif -%} {# FIXME: do we need these any more? #} From 4a8118d2db2a21933b440bde3bda63e0ae6634a1 Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 20 Nov 2023 13:41:50 +0000 Subject: [PATCH 09/13] change names of settings vars from GA_* to PLAUSIBLE_* --- docs/featuremap/terminals.csv | 1 - portality/app.py | 2 - portality/lib/analytics.py | 172 ---------------------------------- portality/settings.py | 63 +++++++++++++ portality/view/api_v1.py | 4 +- portality/view/api_v2.py | 4 +- portality/view/api_v3.py | 4 +- portality/view/atom.py | 4 +- portality/view/doaj.py | 10 +- portality/view/oaipmh.py | 4 +- portality/view/openurl.py | 2 +- production.cfg | 2 - test.cfg | 2 - 13 files changed, 79 insertions(+), 195 deletions(-) delete mode 100644 portality/lib/analytics.py diff --git a/docs/featuremap/terminals.csv b/docs/featuremap/terminals.csv index 607d962ef9..adce58d86a 100644 --- a/docs/featuremap/terminals.csv +++ b/docs/featuremap/terminals.csv @@ -17,7 +17,6 @@ FieldDescriptions:Documentation Flask:Technology FlaskMail:Library GeneratedDocsIndex:Script -GoogleAnalytics:ExternalService GuideToApplying:Fragment Huey:Technology Java:Technology diff --git a/portality/app.py b/portality/app.py index ad2b58a5af..d7947132dc 100644 --- a/portality/app.py +++ b/portality/app.py @@ -109,8 +109,6 @@ def custom_static(path): abort(404) -# Configure the Google Analytics tracker -# ~~-> GoogleAnalytics:ExternalService~~ from portality.lib import plausible plausible.create_logfile(app.config.get('PLAUSIBLE_LOG_DIR', None)) diff --git a/portality/lib/analytics.py b/portality/lib/analytics.py deleted file mode 100644 index c2a1a69896..0000000000 --- a/portality/lib/analytics.py +++ /dev/null @@ -1,172 +0,0 @@ -# ~~ GoogleAnalytics:ExternalService~~ -import logging -import os -from functools import wraps - -# Logger specific to analytics -logger = logging.getLogger(__name__) -logger.setLevel(logging.DEBUG) - -# The global tracker object -tracker = None - - -class GAException(Exception): - pass - - -def create_tracker(ga_id, domain): - global tracker - if ga_id: - #tracker = UniversalAnalytics.Tracker.create(ga_id, client_id=domain) - raise GAException("GA is not running because universal-analytics is broken in Python 3") - else: - raise GAException("Invalid GA ID supplied, no tracker created.") - - -def create_logfile(log_dir=None): - filepath = __name__ + '.log' - if log_dir is not None: - if not os.path.exists(log_dir): - os.makedirs(log_dir) - filepath = os.path.join(log_dir, filepath) - fh = logging.FileHandler(filepath) - fh.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')) - logger.addHandler(fh) - - -class GAEvent(object): - category = None - action = None - label = None - value = None - fieldsobject = None - - def __init__(self, category, action, label='', value=None, fieldsobject=None): - self.category = category - self.action = action - self.label = label - self.value = value - self.fieldsobject=fieldsobject - - def submit(self): - ga_send_event(self.category, self.action, self.label, self.value, self.fieldsobject) - - -def ga_send_event(category, action, label='', value=None, fieldsobject=None): - """ - Send event data to Google Analytics. - (supposedly supporting other analytics providers as well, - check https://github.com/analytics-pros/universal-analytics-python ) - - See https://support.google.com/analytics/answer/1033068?hl=en for - guidance on how to use the various event properties this decorator - takes. - - One thing to note is that event_value must be an integer. We - don't really use that, it's for things like "total downloads" or - "number of times video played". - - The others are strings and can be anything we like. They must - take into account what previous strings we've sent so that events - can be aggregated correctly. Changing the strings you use for - categories, actions and labels to describe the same event will - split your analytics reports into two: before and after the - change of the event strings you use. - - :param category: Typically the object that was interacted with (e.g. 'Video') - :param action: The type of interaction (e.g. 'play') - :param label: Useful for categorizing events (e.g. 'Fall Campaign') - :param value: A non-negative numeric value associated with the event (e.g. 42) - :param fieldsobject: Key, value pairs which don't fit into the above categories - """ - - # Write event to file even if there's no tracker configured. - analytics_args = [category, action] - - if label != '': - analytics_args.append(label) - if value is not None: - analytics_args.append(value) - if fieldsobject is not None: - analytics_args.append(fieldsobject) - - logger.debug("Event Send %s", analytics_args) - - # Send the event to GA via the tracker - if tracker is not None: - tracker.send('event', *analytics_args) - else: - # logger.error("Google Analytics tracker is not configured.") - pass # we now know it's broken, stop spamming this in our logs. - - -def sends_ga_event(event_category, event_action, event_label='', - event_value=0, record_value_of_which_arg=''): - """ - Decorator for Flask view functions, sending event data to Google - Analytics. - - :param event_category: - :param event_action: - :param event_label: - :param event_value: - - :param record_value_of_which_arg: The name of one argument that - the view function takes. During tracking, the value of that - argument will be extracted and sent as the Event Label to the - analytics servers. NOTE! If you pass both event_label and - record_value_of_which_arg to this decorator, event_label will be - ignored and overwritten by the action that - record_value_of_which_arg causes. - - For example: - @sends_ga_event('API Hit', 'Search applications', - record_value_of_which_arg='search_query') - def search_applications(search_query): - # ... - - Then we get a hit, with search_query being set to 'computer shadows'. - This will result in an event with category "API Hit", action "Search - applications" and label "computer shadows". - - A different example: - @sends_ga_event('API Hit', 'Retrieve application', - record_value_of_which_arg='application_id') - def retrieve_application(application_id): - # ... - - Then we get a hit asking for application with id '12345'. - This will result in an event with category "API Hit", action "Retrieve - application" and label "12345". - - Clashing arguments: - @sends_ga_event('API Hit', 'Retrieve application', - event_label='Special interest action', - record_value_of_which_arg='application_id') - def retrieve_application(application_id): - # ... - - Then we get a hit asking for application with id '12345' again. - This will result in an event with category "API Hit", action "Retrieve - application" and label "12345". I.e. the event_label passed in will - be ignored, because we also passed in record_value_of_which_arg which - overrides the event label sent to the analytics servers. - - On testing: this has been tested manually on DOAJ with Google - Analytics by @emanuil-tolev & @Steven-Eardley. - """ - - def decorator(fn): - @wraps(fn) - def decorated_view(*args, **kwargs): - el = event_label - if record_value_of_which_arg in kwargs: - el = kwargs[record_value_of_which_arg] - - ga_send_event(event_category, event_action, el, event_value) - - return fn(*args, **kwargs) - - return decorated_view - return decorator diff --git a/portality/settings.py b/portality/settings.py index 0082ea513a..af04b750af 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -1216,6 +1216,69 @@ # hotjar id - only activate this in production HOTJAR_ID = "" + +###################################################### +# Google Analytics configuration +# specify in environment .cfg file - avoids sending live analytics +# events from test and dev environments +# ~~->GoogleAnalytics:ExternalService~~ + +# Google Analytics custom dimensions. These are configured in the GA interface. +PLAUSIBLE_DIMENSIONS = { + 'oai_res_id': 'dimension1', # In GA as OAI:Record +} + +# Plausible for OAI-PMH +# ~~-> OAIPMH:Feature~~ +PLAUSIBLE_CATEGORY_OAI = 'OAI-PMH' + +# Plausible for Atom +# ~~-> Atom:Feature~~ +PLAUSIBLE_CATEGORY_ATOM = 'Atom' +PLAUSIBLE_ACTION_ACTION = 'Feed request' + +# Plausible for JournalCSV +# ~~-> JournalCSV:Feature~~ +PLAUSIBLE_CATEGORY_JOURNALCSV = 'JournalCSV' +PLAUSIBLE_ACTION_JOURNALCSV = 'Download' + +# Plausible for OpenURL +# ~~->OpenURL:Feature~~ +PLAUSIBLE_CATEGORY_OPENURL = 'OpenURL' + +# Plausible for PublicDataDump +# ~~->PublicDataDump:Feature~~ +PLAUSIBLE_CATEGORY_PUBLICDATADUMP = 'PublicDataDump' +GA_ACTION_PUBLICDATADUMP = 'Download' + +# Plausible for API +# ~~-> API:Feature~~ +PLAUSIBLE_CATEGORY_API = 'API Hit' +PLAUSIBLE_ACTIONS_API = { + 'search_applications': 'Search applications', + 'search_journals': 'Search journals', + 'search_articles': 'Search articles', + 'create_application': 'Create application', + 'retrieve_application': 'Retrieve application', + 'update_application': 'Update application', + 'delete_application': 'Delete application', + 'create_article': 'Create article', + 'retrieve_article': 'Retrieve article', + 'update_article': 'Update article', + 'delete_article': 'Delete article', + 'retrieve_journal': 'Retrieve journal', + 'bulk_application_create': 'Bulk application create', + 'bulk_application_delete': 'Bulk application delete', + 'bulk_article_create': 'Bulk article create', + 'bulk_article_delete': 'Bulk article delete' +} + + +# Plausible for fixed query widget +# ~~->FixedQueryWidget:Feature~~ +PLAUSIBLE_CATEGORY_FQW = 'FQW' +PLAUSIBLE_ACTION_FQW = 'Hit' + ##################################################### # Anonymised data export (for dev) configuration # ~~->AnonExport:Feature~~ diff --git a/portality/view/api_v1.py b/portality/view/api_v1.py index 63bce62c22..783d724d4d 100644 --- a/portality/view/api_v1.py +++ b/portality/view/api_v1.py @@ -11,8 +11,8 @@ API_VERSION_NUMBER = '1.0.0' # Google Analytics category for API events -GA_CATEGORY = app.config.get('GA_CATEGORY_API', 'API Hit') -GA_ACTIONS = app.config.get('GA_ACTIONS_API', {}) +GA_CATEGORY = app.config.get('PLAUSIBLE_CATEGORY_API', 'API Hit') +GA_ACTIONS = app.config.get('PLAUSIBLE_ACTIONS_API', {}) API_UNSUPPORTED_ERROR = "Version 1 is no longer supported." diff --git a/portality/view/api_v2.py b/portality/view/api_v2.py index a4c63835d9..e3d636f75a 100644 --- a/portality/view/api_v2.py +++ b/portality/view/api_v2.py @@ -11,8 +11,8 @@ API_VERSION_NUMBER = '2.0.0' # Google Analytics category for API events -GA_CATEGORY = app.config.get('GA_CATEGORY_API', 'API Hit') -GA_ACTIONS = app.config.get('GA_ACTIONS_API', {}) +GA_CATEGORY = app.config.get('PLAUSIBLE_CATEGORY_API', 'API Hit') +GA_ACTIONS = app.config.get('PLAUSIBLE_ACTIONS_API', {}) API_UNSUPPORTED_ERROR = "Version 2 is no longer supported." diff --git a/portality/view/api_v3.py b/portality/view/api_v3.py index 9fb00fac35..d6f8e0792f 100644 --- a/portality/view/api_v3.py +++ b/portality/view/api_v3.py @@ -18,8 +18,8 @@ API_VERSION_NUMBER = '3.0.1' # OA start added 2022-03-21 # Google Analytics category for API events -GA_CATEGORY = app.config.get('GA_CATEGORY_API', 'API Hit') -GA_ACTIONS = app.config.get('GA_ACTIONS_API', {}) +GA_CATEGORY = app.config.get('PLAUSIBLE_CATEGORY_API', 'API Hit') +GA_ACTIONS = app.config.get('PLAUSIBLE_ACTIONS_API', {}) @blueprint.route('/') diff --git a/portality/view/atom.py b/portality/view/atom.py index db0cf0b7de..83c8e68765 100644 --- a/portality/view/atom.py +++ b/portality/view/atom.py @@ -14,8 +14,8 @@ @blueprint.route('/feed') -@plausible.pa_event(app.config.get('GA_CATEGORY_ATOM', 'Atom'), - action=app.config.get('GA_ACTION_ACTION', 'Feed Request')) +@plausible.pa_event(app.config.get('PLAUSIBLE_CATEGORY_ATOM', 'Atom'), + action=app.config.get('PLAUSIBLE_ACTION_ACTION', 'Feed Request')) def feed(): # get the feed for this base_url (which is just used to set the metadata of # the feed, but we want to do this outside of a request context so it diff --git a/portality/view/doaj.py b/portality/view/doaj.py index 4baac018ec..2a0e0a9250 100644 --- a/portality/view/doaj.py +++ b/portality/view/doaj.py @@ -68,8 +68,8 @@ def news(): def fqw_hit(): page = request.form.get('embedding_page') if page is not None: - plausible.send_event(app.config.get('GA_CATEGORY_FQW', 'FQW'), - action=app.config.get('GA_ACTION_FQW', 'hit'), + plausible.send_event(app.config.get('PLAUSIBLE_CATEGORY_FQW', 'FQW'), + action=app.config.get('PLAUSIBLE_ACTION_FQW', 'hit'), label=request.form.get('embedding_page')) # No content response, whether data there or not. @@ -166,8 +166,8 @@ def journal_readonly(journal_id): @blueprint.route("/csv") -@plausible.pa_event(app.config.get('GA_CATEGORY_JOURNALCSV', 'JournalCSV'), - action=app.config.get('GA_ACTION_JOURNALCSV', 'Download')) +@plausible.pa_event(app.config.get('PLAUSIBLE_CATEGORY_JOURNALCSV', 'JournalCSV'), + action=app.config.get('PLAUSIBLE_ACTION_JOURNALCSV', 'Download')) def csv_data(): csv_info = models.Cache.get_latest_csv() if csv_info is None: @@ -192,7 +192,7 @@ def sitemap(): @blueprint.route("/public-data-dump/") @api_key_required -@plausible.pa_event(app.config.get('GA_CATEGORY_PUBLICDATADUMP', 'PublicDataDump'), +@plausible.pa_event(app.config.get('PLAUSIBLE_CATEGORY_PUBLICDATADUMP', 'PublicDataDump'), action=app.config.get('GA_ACTION_PUBLICDATADUMP', 'Download')) def public_data_dump_redirect(record_type): if not current_user.has_role(constants.ROLE_PUBLIC_DATA_DUMP): diff --git a/portality/view/oaipmh.py b/portality/view/oaipmh.py index 73a5158dfe..640cd325bb 100644 --- a/portality/view/oaipmh.py +++ b/portality/view/oaipmh.py @@ -32,14 +32,14 @@ def oaipmh(specified=None): # Add the identifier to the event if there is one ident = request.values.get('identifier', None) if ident is not None: - event_payload[app.config.get('GA_DIMENSIONS')['oai_res_id']] = ident + event_payload[app.config.get('PLAUSIBLE_DIMENSIONS')['oai_res_id']] = ident # work out the verb and associated parameters verb = request.values.get("verb") event_payload['action'] = verb # Now we have enough information about the request to send to analytics. - plausible.send_event(app.config.get('GA_CATEGORY_OAI', 'OAI-PMH'), + plausible.send_event(app.config.get('PLAUSIBLE_CATEGORY_OAI', 'OAI-PMH'), **event_payload) # call the appropriate protocol operation: diff --git a/portality/view/openurl.py b/portality/view/openurl.py index 628955186a..8be5a3277a 100644 --- a/portality/view/openurl.py +++ b/portality/view/openurl.py @@ -29,7 +29,7 @@ def openurl(): return redirect(parser_response, 301) # Log this request to analytics - plausible.send_event(app.config.get('GA_CATEGORY_OPENURL', 'OpenURL'), + plausible.send_event(app.config.get('PLAUSIBLE_CATEGORY_OPENURL', 'OpenURL'), action=parser_response.genre, label=qs) diff --git a/production.cfg b/production.cfg index d9d501f253..ef5af2fd1c 100644 --- a/production.cfg +++ b/production.cfg @@ -27,8 +27,6 @@ CACHE_DIR=DATA_ROOT + "cache" ARTICLE_HISTORY_DIR=DATA_ROOT + "history/article" JOURNAL_HISTORY_DIR=DATA_ROOT + "history/journal" -GOOGLE_ANALTYICS_LOG_DIR = DATA_ROOT + 'ga_logs' - # Anonymous data exports to Amazon S3 STORE_IMPL = "portality.store.StoreS3" STORE_LOCAL_DIR = DATA_ROOT + "local_store/main" diff --git a/test.cfg b/test.cfg index ff4bd661e8..68f90ece22 100644 --- a/test.cfg +++ b/test.cfg @@ -26,8 +26,6 @@ CACHE_DIR=DATA_ROOT + "cache" ARTICLE_HISTORY_DIR=DATA_ROOT + "history/article" JOURNAL_HISTORY_DIR=DATA_ROOT + "history/journal" -GOOGLE_ANALTYICS_LOG_DIR = DATA_ROOT + 'ga_logs' - # Anonymous data exports to local disk STORE_IMPL = "portality.store.StoreLocal" STORE_LOCAL_EXPOSE = True From 6937aa5ab9fd3f420f0a6733ad81db2027bcda1f Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 20 Nov 2023 13:44:04 +0000 Subject: [PATCH 10/13] variable setting change --- portality/settings.py | 4 ++-- portality/view/doaj.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/portality/settings.py b/portality/settings.py index af04b750af..9596195c15 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -1223,7 +1223,7 @@ # events from test and dev environments # ~~->GoogleAnalytics:ExternalService~~ -# Google Analytics custom dimensions. These are configured in the GA interface. +# Plausible custom dimensions. These are configured in the GA interface. # legacy PLAUSIBLE_DIMENSIONS = { 'oai_res_id': 'dimension1', # In GA as OAI:Record } @@ -1249,7 +1249,7 @@ # Plausible for PublicDataDump # ~~->PublicDataDump:Feature~~ PLAUSIBLE_CATEGORY_PUBLICDATADUMP = 'PublicDataDump' -GA_ACTION_PUBLICDATADUMP = 'Download' +PLAUSIBLE_ACTION_PUBLICDATADUMP = 'Download' # Plausible for API # ~~-> API:Feature~~ diff --git a/portality/view/doaj.py b/portality/view/doaj.py index 2a0e0a9250..91f0f5f4b7 100644 --- a/portality/view/doaj.py +++ b/portality/view/doaj.py @@ -193,7 +193,7 @@ def sitemap(): @blueprint.route("/public-data-dump/") @api_key_required @plausible.pa_event(app.config.get('PLAUSIBLE_CATEGORY_PUBLICDATADUMP', 'PublicDataDump'), - action=app.config.get('GA_ACTION_PUBLICDATADUMP', 'Download')) + action=app.config.get('PLAUSIBLE_ACTION_PUBLICDATADUMP', 'Download')) def public_data_dump_redirect(record_type): if not current_user.has_role(constants.ROLE_PUBLIC_DATA_DUMP): abort(404) From 7a5cad9436fa712ebe0d21a86f67a440f5f9e391 Mon Sep 17 00:00:00 2001 From: Aga Date: Mon, 20 Nov 2023 13:45:46 +0000 Subject: [PATCH 11/13] change naming convention from GA_ to PLAUSIBLE_ --- portality/view/api_v1.py | 34 +++++++++++++++++----------------- portality/view/api_v2.py | 34 +++++++++++++++++----------------- portality/view/api_v3.py | 36 ++++++++++++++++++------------------ 3 files changed, 52 insertions(+), 52 deletions(-) diff --git a/portality/view/api_v1.py b/portality/view/api_v1.py index 783d724d4d..167e913436 100644 --- a/portality/view/api_v1.py +++ b/portality/view/api_v1.py @@ -11,8 +11,8 @@ API_VERSION_NUMBER = '1.0.0' # Google Analytics category for API events -GA_CATEGORY = app.config.get('PLAUSIBLE_CATEGORY_API', 'API Hit') -GA_ACTIONS = app.config.get('PLAUSIBLE_ACTIONS_API', {}) +PLAUSIBLE_CATEGORY = app.config.get('PLAUSIBLE_CATEGORY_API', 'API Hit') +PLAUSIBLE_ACTIONS = app.config.get('PLAUSIBLE_ACTIONS_API', {}) API_UNSUPPORTED_ERROR = "Version 1 is no longer supported." @@ -44,7 +44,7 @@ def search_articles(search_query): @blueprint.route("/articles", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('create_article', 'Create article')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('create_article', 'Create article')) def create_article(): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 # return redirect(url_for('api_v3.create_article', **request.args), code=301) @@ -53,7 +53,7 @@ def create_article(): @blueprint.route("/articles/", methods=["GET"]) @api_key_optional -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('retrieve_article', 'Retrieve article'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_article', 'Retrieve article'), record_value_of_which_arg='article_id') def retrieve_article(article_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -64,7 +64,7 @@ def retrieve_article(article_id): @blueprint.route("/articles/", methods=["PUT"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('update_article', 'Update article'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('update_article', 'Update article'), record_value_of_which_arg='article_id') def update_article(article_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -75,7 +75,7 @@ def update_article(article_id): @blueprint.route("/articles/", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('delete_article', 'Delete article'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('delete_article', 'Delete article'), record_value_of_which_arg='article_id') def delete_article(article_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -86,7 +86,7 @@ def delete_article(article_id): @blueprint.route("/bulk/articles", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('bulk_article_create', 'Bulk article create')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_article_create', 'Bulk article create')) def bulk_article_create(): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 # return redirect(url_for('api_v3.bulk_article_create', **request.args), code=301) @@ -96,7 +96,7 @@ def bulk_article_create(): @blueprint.route("/bulk/articles", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('bulk_article_delete', 'Bulk article delete')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_article_delete', 'Bulk article delete')) def bulk_article_delete(): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 # return redirect(url_for('api_v3.bulk_article_delete', **request.args), code=301) @@ -108,7 +108,7 @@ def bulk_article_delete(): @blueprint.route('/journals/', methods=['GET']) @api_key_optional -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('retrieve_journal', 'Retrieve journal'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_journal', 'Retrieve journal'), record_value_of_which_arg='journal_id') def retrieve_journal(journal_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -117,7 +117,7 @@ def retrieve_journal(journal_id): @blueprint.route("/bulk/applications", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('bulk_application_create', 'Bulk application create')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_application_create', 'Bulk application create')) def bulk_application_create(): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -125,7 +125,7 @@ def bulk_application_create(): @blueprint.route("/bulk/applications", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('bulk_application_delete', 'Bulk application delete')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_application_delete', 'Bulk application delete')) def bulk_application_delete(): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -133,14 +133,14 @@ def bulk_application_delete(): @blueprint.route("/applications", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('create_application', 'Create application')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('create_application', 'Create application')) def create_application(): raise Api400Error(API_UNSUPPORTED_ERROR) @blueprint.route("/applications/", methods=["GET"]) @api_key_required -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('retrieve_application', 'Retrieve application'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_application', 'Retrieve application'), record_value_of_which_arg='application_id') def retrieve_application(application_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -149,7 +149,7 @@ def retrieve_application(application_id): @blueprint.route("/applications/", methods=["PUT"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('update_application', 'Update application'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('update_application', 'Update application'), record_value_of_which_arg='application_id') def update_application(application_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -158,7 +158,7 @@ def update_application(application_id): @blueprint.route("/applications/", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('delete_application', 'Delete application'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('delete_application', 'Delete application'), record_value_of_which_arg='application_id') def delete_application(application_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -166,14 +166,14 @@ def delete_application(application_id): @blueprint.route("/search/applications/") @api_key_required -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('search_applications', 'Search applications'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_applications', 'Search applications'), record_value_of_which_arg='search_query') def search_applications(search_query): raise Api400Error(API_UNSUPPORTED_ERROR) @blueprint.route('/search/journals/') -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('search_journals', 'Search journals'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_journals', 'Search journals'), record_value_of_which_arg='search_query') def search_journals(search_query): raise Api400Error(API_UNSUPPORTED_ERROR) diff --git a/portality/view/api_v2.py b/portality/view/api_v2.py index e3d636f75a..b8eb2e1b6e 100644 --- a/portality/view/api_v2.py +++ b/portality/view/api_v2.py @@ -11,8 +11,8 @@ API_VERSION_NUMBER = '2.0.0' # Google Analytics category for API events -GA_CATEGORY = app.config.get('PLAUSIBLE_CATEGORY_API', 'API Hit') -GA_ACTIONS = app.config.get('PLAUSIBLE_ACTIONS_API', {}) +PLAUSIBLE_CATEGORY = app.config.get('PLAUSIBLE_CATEGORY_API', 'API Hit') +PLAUSIBLE_ACTIONS = app.config.get('PLAUSIBLE_ACTIONS_API', {}) API_UNSUPPORTED_ERROR = "Version 2 is no longer supported." @@ -44,7 +44,7 @@ def search_articles(search_query): @blueprint.route("/articles", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('create_article', 'Create article')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('create_article', 'Create article')) def create_article(): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 # return redirect(url_for('api_v3.create_article', **request.args), code=301) @@ -53,7 +53,7 @@ def create_article(): @blueprint.route("/articles/", methods=["GET"]) @api_key_optional -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('retrieve_article', 'Retrieve article'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_article', 'Retrieve article'), record_value_of_which_arg='article_id') def retrieve_article(article_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -64,7 +64,7 @@ def retrieve_article(article_id): @blueprint.route("/articles/", methods=["PUT"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('update_article', 'Update article'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('update_article', 'Update article'), record_value_of_which_arg='article_id') def update_article(article_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -75,7 +75,7 @@ def update_article(article_id): @blueprint.route("/articles/", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('delete_article', 'Delete article'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('delete_article', 'Delete article'), record_value_of_which_arg='article_id') def delete_article(article_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -86,7 +86,7 @@ def delete_article(article_id): @blueprint.route("/bulk/articles", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('bulk_article_create', 'Bulk article create')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_article_create', 'Bulk article create')) def bulk_article_create(): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 # return redirect(url_for('api_v3.bulk_article_create', **request.args), code=301) @@ -96,7 +96,7 @@ def bulk_article_create(): @blueprint.route("/bulk/articles", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('bulk_article_delete', 'Bulk article delete')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_article_delete', 'Bulk article delete')) def bulk_article_delete(): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 # return redirect(url_for('api_v3.bulk_article_delete', **request.args), code=301) @@ -108,7 +108,7 @@ def bulk_article_delete(): @blueprint.route('/journals/', methods=['GET']) @api_key_optional -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('retrieve_journal', 'Retrieve journal'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_journal', 'Retrieve journal'), record_value_of_which_arg='journal_id') def retrieve_journal(journal_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -119,7 +119,7 @@ def retrieve_journal(journal_id): @blueprint.route("/bulk/applications", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('bulk_application_create', 'Bulk application create')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_application_create', 'Bulk application create')) def bulk_application_create(): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -127,7 +127,7 @@ def bulk_application_create(): @blueprint.route("/bulk/applications", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('bulk_application_delete', 'Bulk application delete')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_application_delete', 'Bulk application delete')) def bulk_application_delete(): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -135,14 +135,14 @@ def bulk_application_delete(): @blueprint.route("/applications", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('create_application', 'Create application')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('create_application', 'Create application')) def create_application(): raise Api400Error(API_UNSUPPORTED_ERROR) @blueprint.route("/applications/", methods=["GET"]) @api_key_required -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('retrieve_application', 'Retrieve application'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_application', 'Retrieve application'), record_value_of_which_arg='application_id') def retrieve_application(application_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -151,7 +151,7 @@ def retrieve_application(application_id): @blueprint.route("/applications/", methods=["PUT"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('update_application', 'Update application'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('update_application', 'Update application'), record_value_of_which_arg='application_id') def update_application(application_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -160,7 +160,7 @@ def update_application(application_id): @blueprint.route("/applications/", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('delete_application', 'Delete application'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('delete_application', 'Delete application'), record_value_of_which_arg='application_id') def delete_application(application_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -168,7 +168,7 @@ def delete_application(application_id): @blueprint.route("/search/applications/") @api_key_required -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('search_applications', 'Search applications'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_applications', 'Search applications'), record_value_of_which_arg='search_query') def search_applications(search_query): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -177,7 +177,7 @@ def search_applications(search_query): @blueprint.route('/search/journals/') -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('search_journals', 'Search journals'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_journals', 'Search journals'), record_value_of_which_arg='search_query') def search_journals(search_query): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 diff --git a/portality/view/api_v3.py b/portality/view/api_v3.py index d6f8e0792f..7ab4780250 100644 --- a/portality/view/api_v3.py +++ b/portality/view/api_v3.py @@ -18,8 +18,8 @@ API_VERSION_NUMBER = '3.0.1' # OA start added 2022-03-21 # Google Analytics category for API events -GA_CATEGORY = app.config.get('PLAUSIBLE_CATEGORY_API', 'API Hit') -GA_ACTIONS = app.config.get('PLAUSIBLE_ACTIONS_API', {}) +PLAUSIBLE_CATEGORY = app.config.get('PLAUSIBLE_CATEGORY_API', 'API Hit') +PLAUSIBLE_ACTIONS = app.config.get('PLAUSIBLE_ACTIONS_API', {}) @blueprint.route('/') @@ -63,7 +63,7 @@ def missing_resource(invalid_path): swag_spec=DiscoveryApi.get_application_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. @blueprint.route("/search/applications/") @api_key_required -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('search_applications', 'Search applications'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_applications', 'Search applications'), record_value_of_which_arg='search_query') def search_applications(search_query): # get the values for the 2 other bits of search info: the page number and the page size @@ -94,7 +94,7 @@ def search_applications(search_query): @swag(swag_summary='Search journals', swag_spec=DiscoveryApi.get_journal_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. @blueprint.route('/search/journals/') -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('search_journals', 'Search journals'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_journals', 'Search journals'), record_value_of_which_arg='search_query') def search_journals(search_query): # get the values for the 2 other bits of search info: the page number and the page size @@ -125,7 +125,7 @@ def search_journals(search_query): @swag(swag_summary='Search articles', swag_spec=DiscoveryApi.get_article_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. @blueprint.route('/search/articles/') -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('search_articles', 'Search articles'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_articles', 'Search articles'), record_value_of_which_arg='search_query') def search_articles(search_query): # get the values for the 2 other bits of search info: the page number and the page size @@ -162,7 +162,7 @@ def search_articles(search_query): @write_required(api=True) @swag(swag_summary='Create an application [Authenticated, not public]', swag_spec=ApplicationsCrudApi.create_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('create_application', 'Create application')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('create_application', 'Create application')) def create_application(): # get the data from the request try: @@ -181,7 +181,7 @@ def create_application(): @api_key_required @swag(swag_summary='Retrieve an application [Authenticated, not public]', swag_spec=ApplicationsCrudApi.retrieve_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('retrieve_application', 'Retrieve application'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_application', 'Retrieve application'), record_value_of_which_arg='application_id') def retrieve_application(application_id): a = ApplicationsCrudApi.retrieve(application_id, current_user) @@ -193,7 +193,7 @@ def retrieve_application(application_id): @write_required(api=True) @swag(swag_summary='Update an application [Authenticated, not public]', swag_spec=ApplicationsCrudApi.update_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('update_application', 'Update application'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('update_application', 'Update application'), record_value_of_which_arg='application_id') def update_application(application_id): # get the data from the request @@ -214,7 +214,7 @@ def update_application(application_id): @write_required(api=True) @swag(swag_summary='Delete an application [Authenticated, not public]', swag_spec=ApplicationsCrudApi.delete_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('delete_application', 'Delete application'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('delete_application', 'Delete application'), record_value_of_which_arg='application_id') def delete_application(application_id): ApplicationsCrudApi.delete(application_id, current_user._get_current_object()) @@ -229,7 +229,7 @@ def delete_application(application_id): @write_required(api=True) @swag(swag_summary='Create an article [Authenticated, not public]', swag_spec=ArticlesCrudApi.create_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('create_article', 'Create article')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('create_article', 'Create article')) def create_article(): # get the data from the request try: @@ -248,7 +248,7 @@ def create_article(): @api_key_optional @swag(swag_summary='Retrieve an article', swag_spec=ArticlesCrudApi.retrieve_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('retrieve_article', 'Retrieve article'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_article', 'Retrieve article'), record_value_of_which_arg='article_id') def retrieve_article(article_id): a = ArticlesCrudApi.retrieve(article_id, current_user) @@ -260,7 +260,7 @@ def retrieve_article(article_id): @write_required(api=True) @swag(swag_summary='Update an article [Authenticated, not public]', swag_spec=ArticlesCrudApi.update_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('update_article', 'Update article'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('update_article', 'Update article'), record_value_of_which_arg='article_id') def update_article(article_id): # get the data from the request @@ -281,7 +281,7 @@ def update_article(article_id): @write_required(api=True) @swag(swag_summary='Delete an article [Authenticated, not public]', swag_spec=ArticlesCrudApi.delete_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('delete_article', 'Delete article'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('delete_article', 'Delete article'), record_value_of_which_arg='article_id') def delete_article(article_id): ArticlesCrudApi.delete(article_id, current_user) @@ -295,7 +295,7 @@ def delete_article(article_id): @api_key_optional @swag(swag_summary='Retrieve a journal by ID', swag_spec=JournalsCrudApi.retrieve_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('retrieve_journal', 'Retrieve journal'), +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_journal', 'Retrieve journal'), record_value_of_which_arg='journal_id') def retrieve_journal(journal_id): return jsonify_data_object(JournalsCrudApi.retrieve(journal_id, current_user)) @@ -309,7 +309,7 @@ def retrieve_journal(journal_id): @write_required(api=True) @swag(swag_summary='Create applications in bulk [Authenticated, not public]', swag_spec=ApplicationsBulkApi.create_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('bulk_application_create', 'Bulk application create')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_application_create', 'Bulk application create')) def bulk_application_create(): # get the data from the request try: @@ -334,7 +334,7 @@ def bulk_application_create(): @write_required(api=True) @swag(swag_summary='Delete applications in bulk [Authenticated, not public]', swag_spec=ApplicationsBulkApi.delete_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('bulk_application_delete', 'Bulk application delete')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_application_delete', 'Bulk application delete')) def bulk_application_delete(): # get the data from the request try: @@ -355,7 +355,7 @@ def bulk_application_delete(): @write_required(api=True) @swag(swag_summary='Bulk article creation [Authenticated, not public]', swag_spec=ArticlesBulkApi.create_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('bulk_article_create', 'Bulk article create')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_article_create', 'Bulk article create')) def bulk_article_create(): # get the data from the request try: @@ -380,7 +380,7 @@ def bulk_article_create(): @write_required(api=True) @swag(swag_summary='Bulk article delete [Authenticated, not public]', swag_spec=ArticlesBulkApi.delete_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(GA_CATEGORY, action=GA_ACTIONS.get('bulk_article_delete', 'Bulk article delete')) +@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_article_delete', 'Bulk article delete')) def bulk_article_delete(): # get the data from the request try: From f4cbb66b2bc52635b0bbf8705761cd68e3f45953 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Wed, 22 Nov 2023 16:54:48 +0000 Subject: [PATCH 12/13] Generalise the analytics config keys --- docs/featuremap/terminals.csv | 1 + portality/app.py | 3 +- portality/settings.py | 57 +++++++++++++++++------------------ portality/view/api_v1.py | 34 ++++++++++----------- portality/view/api_v2.py | 34 ++++++++++----------- portality/view/api_v3.py | 36 +++++++++++----------- portality/view/atom.py | 4 +-- portality/view/doaj.py | 12 ++++---- portality/view/oaipmh.py | 4 +-- portality/view/openurl.py | 2 +- 10 files changed, 94 insertions(+), 93 deletions(-) diff --git a/docs/featuremap/terminals.csv b/docs/featuremap/terminals.csv index adce58d86a..fdf69406d4 100644 --- a/docs/featuremap/terminals.csv +++ b/docs/featuremap/terminals.csv @@ -25,6 +25,7 @@ LCC:SourceData OpenURL:Fragment Plagiarism:FieldSet PlagiarismDetection:FormField +PlausibleAnalytics:ExternalService Privacy:Fragment Promo:Data PublisherSupporters:Data diff --git a/portality/app.py b/portality/app.py index d7947132dc..1562f379ef 100644 --- a/portality/app.py +++ b/portality/app.py @@ -108,7 +108,8 @@ def custom_static(path): return send_from_directory(os.path.dirname(target), os.path.basename(target)) abort(404) - +# Configure Analytics +# ~~-> PlausibleAnalytics:ExternalService~~ from portality.lib import plausible plausible.create_logfile(app.config.get('PLAUSIBLE_LOG_DIR', None)) diff --git a/portality/settings.py b/portality/settings.py index 9596195c15..d537c27f98 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -1218,43 +1218,51 @@ ###################################################### -# Google Analytics configuration -# specify in environment .cfg file - avoids sending live analytics -# events from test and dev environments -# ~~->GoogleAnalytics:ExternalService~~ - -# Plausible custom dimensions. These are configured in the GA interface. # legacy -PLAUSIBLE_DIMENSIONS = { - 'oai_res_id': 'dimension1', # In GA as OAI:Record +# Analytics configuration +# specify in environment .cfg file - avoids sending live analytics events from test and dev environments + +# ~~->PlausibleAnalytics:ExternalService~~ +# Plausible analytics +# root url of plausible +PLAUSIBLE_URL = "https://plausible.io" +PLAUSIBLE_JS_URL = PLAUSIBLE_URL + "/js/script.outbound-links.file-downloads.js" +PLAUSIBLE_API_URL = PLAUSIBLE_URL + "/api/event" +# site name / domain name that used to register in plausible +PLAUSIBLE_SITE_NAME = BASE_DOMAIN +PLAUSIBLE_LOG_DIR = None + +# Analytics custom dimensions. These are configured in the interface. #fixme: are these still configured since the move from GA? +ANALYTICS_DIMENSIONS = { + 'oai_res_id': 'dimension1', # In analytics as OAI:Record } # Plausible for OAI-PMH # ~~-> OAIPMH:Feature~~ -PLAUSIBLE_CATEGORY_OAI = 'OAI-PMH' +ANALYTICS_CATEGORY_OAI = 'OAI-PMH' # Plausible for Atom # ~~-> Atom:Feature~~ -PLAUSIBLE_CATEGORY_ATOM = 'Atom' -PLAUSIBLE_ACTION_ACTION = 'Feed request' +ANALYTICS_CATEGORY_ATOM = 'Atom' +ANALYTICS_ACTION_ACTION = 'Feed request' # Plausible for JournalCSV # ~~-> JournalCSV:Feature~~ -PLAUSIBLE_CATEGORY_JOURNALCSV = 'JournalCSV' -PLAUSIBLE_ACTION_JOURNALCSV = 'Download' +ANALYTICS_CATEGORY_JOURNALCSV = 'JournalCSV' +ANALYTICS_ACTION_JOURNALCSV = 'Download' # Plausible for OpenURL # ~~->OpenURL:Feature~~ -PLAUSIBLE_CATEGORY_OPENURL = 'OpenURL' +ANALYTICS_CATEGORY_OPENURL = 'OpenURL' # Plausible for PublicDataDump # ~~->PublicDataDump:Feature~~ -PLAUSIBLE_CATEGORY_PUBLICDATADUMP = 'PublicDataDump' -PLAUSIBLE_ACTION_PUBLICDATADUMP = 'Download' +ANALYTICS_CATEGORY_PUBLICDATADUMP = 'PublicDataDump' +ANALYTICS_ACTION_PUBLICDATADUMP = 'Download' # Plausible for API # ~~-> API:Feature~~ -PLAUSIBLE_CATEGORY_API = 'API Hit' -PLAUSIBLE_ACTIONS_API = { +ANALYTICS_CATEGORY_API = 'API Hit' +ANALYTICS_ACTIONS_API = { 'search_applications': 'Search applications', 'search_journals': 'Search journals', 'search_articles': 'Search articles', @@ -1276,8 +1284,8 @@ # Plausible for fixed query widget # ~~->FixedQueryWidget:Feature~~ -PLAUSIBLE_CATEGORY_FQW = 'FQW' -PLAUSIBLE_ACTION_FQW = 'Hit' +ANALYTICS_CATEGORY_FQW = 'FQW' +ANALYTICS_ACTION_FQW = 'Hit' ##################################################### # Anonymised data export (for dev) configuration @@ -1375,15 +1383,6 @@ # Editorial Dashboard - set to-do list size TODO_LIST_SIZE = 48 -####################################################### -# Plausible analytics -# root url of plausible -PLAUSIBLE_URL = "https://plausible.io" -PLAUSIBLE_JS_URL = PLAUSIBLE_URL + "/js/script.outbound-links.file-downloads.js" -PLAUSIBLE_API_URL = PLAUSIBLE_URL + "/api/event" -# site name / domain name that used to register in plausible -PLAUSIBLE_SITE_NAME = BASE_DOMAIN -PLAUSIBLE_LOG_DIR = None ######################################################### # Background tasks --- monitor_bgjobs diff --git a/portality/view/api_v1.py b/portality/view/api_v1.py index 167e913436..d230bb0be6 100644 --- a/portality/view/api_v1.py +++ b/portality/view/api_v1.py @@ -11,8 +11,8 @@ API_VERSION_NUMBER = '1.0.0' # Google Analytics category for API events -PLAUSIBLE_CATEGORY = app.config.get('PLAUSIBLE_CATEGORY_API', 'API Hit') -PLAUSIBLE_ACTIONS = app.config.get('PLAUSIBLE_ACTIONS_API', {}) +ANALYTICS_CATEGORY = app.config.get('ANALYTICS_CATEGORY_API', 'API Hit') +ANALYTICS_ACTIONS = app.config.get('ANALYTICS_ACTIONS_API', {}) API_UNSUPPORTED_ERROR = "Version 1 is no longer supported." @@ -44,7 +44,7 @@ def search_articles(search_query): @blueprint.route("/articles", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('create_article', 'Create article')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('create_article', 'Create article')) def create_article(): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 # return redirect(url_for('api_v3.create_article', **request.args), code=301) @@ -53,7 +53,7 @@ def create_article(): @blueprint.route("/articles/", methods=["GET"]) @api_key_optional -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_article', 'Retrieve article'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('retrieve_article', 'Retrieve article'), record_value_of_which_arg='article_id') def retrieve_article(article_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -64,7 +64,7 @@ def retrieve_article(article_id): @blueprint.route("/articles/", methods=["PUT"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('update_article', 'Update article'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('update_article', 'Update article'), record_value_of_which_arg='article_id') def update_article(article_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -75,7 +75,7 @@ def update_article(article_id): @blueprint.route("/articles/", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('delete_article', 'Delete article'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('delete_article', 'Delete article'), record_value_of_which_arg='article_id') def delete_article(article_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -86,7 +86,7 @@ def delete_article(article_id): @blueprint.route("/bulk/articles", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_article_create', 'Bulk article create')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('bulk_article_create', 'Bulk article create')) def bulk_article_create(): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 # return redirect(url_for('api_v3.bulk_article_create', **request.args), code=301) @@ -96,7 +96,7 @@ def bulk_article_create(): @blueprint.route("/bulk/articles", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_article_delete', 'Bulk article delete')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('bulk_article_delete', 'Bulk article delete')) def bulk_article_delete(): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 # return redirect(url_for('api_v3.bulk_article_delete', **request.args), code=301) @@ -108,7 +108,7 @@ def bulk_article_delete(): @blueprint.route('/journals/', methods=['GET']) @api_key_optional -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_journal', 'Retrieve journal'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('retrieve_journal', 'Retrieve journal'), record_value_of_which_arg='journal_id') def retrieve_journal(journal_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -117,7 +117,7 @@ def retrieve_journal(journal_id): @blueprint.route("/bulk/applications", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_application_create', 'Bulk application create')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('bulk_application_create', 'Bulk application create')) def bulk_application_create(): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -125,7 +125,7 @@ def bulk_application_create(): @blueprint.route("/bulk/applications", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_application_delete', 'Bulk application delete')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('bulk_application_delete', 'Bulk application delete')) def bulk_application_delete(): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -133,14 +133,14 @@ def bulk_application_delete(): @blueprint.route("/applications", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('create_application', 'Create application')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('create_application', 'Create application')) def create_application(): raise Api400Error(API_UNSUPPORTED_ERROR) @blueprint.route("/applications/", methods=["GET"]) @api_key_required -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_application', 'Retrieve application'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('retrieve_application', 'Retrieve application'), record_value_of_which_arg='application_id') def retrieve_application(application_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -149,7 +149,7 @@ def retrieve_application(application_id): @blueprint.route("/applications/", methods=["PUT"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('update_application', 'Update application'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('update_application', 'Update application'), record_value_of_which_arg='application_id') def update_application(application_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -158,7 +158,7 @@ def update_application(application_id): @blueprint.route("/applications/", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('delete_application', 'Delete application'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('delete_application', 'Delete application'), record_value_of_which_arg='application_id') def delete_application(application_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -166,14 +166,14 @@ def delete_application(application_id): @blueprint.route("/search/applications/") @api_key_required -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_applications', 'Search applications'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('search_applications', 'Search applications'), record_value_of_which_arg='search_query') def search_applications(search_query): raise Api400Error(API_UNSUPPORTED_ERROR) @blueprint.route('/search/journals/') -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_journals', 'Search journals'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('search_journals', 'Search journals'), record_value_of_which_arg='search_query') def search_journals(search_query): raise Api400Error(API_UNSUPPORTED_ERROR) diff --git a/portality/view/api_v2.py b/portality/view/api_v2.py index b8eb2e1b6e..873e66c65c 100644 --- a/portality/view/api_v2.py +++ b/portality/view/api_v2.py @@ -11,8 +11,8 @@ API_VERSION_NUMBER = '2.0.0' # Google Analytics category for API events -PLAUSIBLE_CATEGORY = app.config.get('PLAUSIBLE_CATEGORY_API', 'API Hit') -PLAUSIBLE_ACTIONS = app.config.get('PLAUSIBLE_ACTIONS_API', {}) +ANALYTICS_CATEGORY = app.config.get('ANALYTICS_CATEGORY_API', 'API Hit') +ANALYTICS_ACTIONS = app.config.get('ANALYTICS_ACTIONS_API', {}) API_UNSUPPORTED_ERROR = "Version 2 is no longer supported." @@ -44,7 +44,7 @@ def search_articles(search_query): @blueprint.route("/articles", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('create_article', 'Create article')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('create_article', 'Create article')) def create_article(): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 # return redirect(url_for('api_v3.create_article', **request.args), code=301) @@ -53,7 +53,7 @@ def create_article(): @blueprint.route("/articles/", methods=["GET"]) @api_key_optional -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_article', 'Retrieve article'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('retrieve_article', 'Retrieve article'), record_value_of_which_arg='article_id') def retrieve_article(article_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -64,7 +64,7 @@ def retrieve_article(article_id): @blueprint.route("/articles/", methods=["PUT"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('update_article', 'Update article'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('update_article', 'Update article'), record_value_of_which_arg='article_id') def update_article(article_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -75,7 +75,7 @@ def update_article(article_id): @blueprint.route("/articles/", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('delete_article', 'Delete article'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('delete_article', 'Delete article'), record_value_of_which_arg='article_id') def delete_article(article_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -86,7 +86,7 @@ def delete_article(article_id): @blueprint.route("/bulk/articles", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_article_create', 'Bulk article create')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('bulk_article_create', 'Bulk article create')) def bulk_article_create(): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 # return redirect(url_for('api_v3.bulk_article_create', **request.args), code=301) @@ -96,7 +96,7 @@ def bulk_article_create(): @blueprint.route("/bulk/articles", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_article_delete', 'Bulk article delete')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('bulk_article_delete', 'Bulk article delete')) def bulk_article_delete(): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 # return redirect(url_for('api_v3.bulk_article_delete', **request.args), code=301) @@ -108,7 +108,7 @@ def bulk_article_delete(): @blueprint.route('/journals/', methods=['GET']) @api_key_optional -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_journal', 'Retrieve journal'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('retrieve_journal', 'Retrieve journal'), record_value_of_which_arg='journal_id') def retrieve_journal(journal_id): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -119,7 +119,7 @@ def retrieve_journal(journal_id): @blueprint.route("/bulk/applications", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_application_create', 'Bulk application create')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('bulk_application_create', 'Bulk application create')) def bulk_application_create(): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -127,7 +127,7 @@ def bulk_application_create(): @blueprint.route("/bulk/applications", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_application_delete', 'Bulk application delete')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('bulk_application_delete', 'Bulk application delete')) def bulk_application_delete(): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -135,14 +135,14 @@ def bulk_application_delete(): @blueprint.route("/applications", methods=["POST"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('create_application', 'Create application')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('create_application', 'Create application')) def create_application(): raise Api400Error(API_UNSUPPORTED_ERROR) @blueprint.route("/applications/", methods=["GET"]) @api_key_required -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_application', 'Retrieve application'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('retrieve_application', 'Retrieve application'), record_value_of_which_arg='application_id') def retrieve_application(application_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -151,7 +151,7 @@ def retrieve_application(application_id): @blueprint.route("/applications/", methods=["PUT"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('update_application', 'Update application'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('update_application', 'Update application'), record_value_of_which_arg='application_id') def update_application(application_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -160,7 +160,7 @@ def update_application(application_id): @blueprint.route("/applications/", methods=["DELETE"]) @api_key_required @write_required(api=True) -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('delete_application', 'Delete application'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('delete_application', 'Delete application'), record_value_of_which_arg='application_id') def delete_application(application_id): raise Api400Error(API_UNSUPPORTED_ERROR) @@ -168,7 +168,7 @@ def delete_application(application_id): @blueprint.route("/search/applications/") @api_key_required -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_applications', 'Search applications'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('search_applications', 'Search applications'), record_value_of_which_arg='search_query') def search_applications(search_query): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 @@ -177,7 +177,7 @@ def search_applications(search_query): @blueprint.route('/search/journals/') -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_journals', 'Search journals'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('search_journals', 'Search journals'), record_value_of_which_arg='search_query') def search_journals(search_query): # Redirects are disabled https://github.com/DOAJ/doajPM/issues/2664 diff --git a/portality/view/api_v3.py b/portality/view/api_v3.py index 7ab4780250..adfaa4fb15 100644 --- a/portality/view/api_v3.py +++ b/portality/view/api_v3.py @@ -18,8 +18,8 @@ API_VERSION_NUMBER = '3.0.1' # OA start added 2022-03-21 # Google Analytics category for API events -PLAUSIBLE_CATEGORY = app.config.get('PLAUSIBLE_CATEGORY_API', 'API Hit') -PLAUSIBLE_ACTIONS = app.config.get('PLAUSIBLE_ACTIONS_API', {}) +ANALYTICS_CATEGORY = app.config.get('ANALYTICS_CATEGORY_API', 'API Hit') +ANALYTICS_ACTIONS = app.config.get('ANALYTICS_ACTIONS_API', {}) @blueprint.route('/') @@ -63,7 +63,7 @@ def missing_resource(invalid_path): swag_spec=DiscoveryApi.get_application_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. @blueprint.route("/search/applications/") @api_key_required -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_applications', 'Search applications'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('search_applications', 'Search applications'), record_value_of_which_arg='search_query') def search_applications(search_query): # get the values for the 2 other bits of search info: the page number and the page size @@ -94,7 +94,7 @@ def search_applications(search_query): @swag(swag_summary='Search journals', swag_spec=DiscoveryApi.get_journal_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. @blueprint.route('/search/journals/') -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_journals', 'Search journals'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('search_journals', 'Search journals'), record_value_of_which_arg='search_query') def search_journals(search_query): # get the values for the 2 other bits of search info: the page number and the page size @@ -125,7 +125,7 @@ def search_journals(search_query): @swag(swag_summary='Search articles', swag_spec=DiscoveryApi.get_article_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. @blueprint.route('/search/articles/') -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('search_articles', 'Search articles'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('search_articles', 'Search articles'), record_value_of_which_arg='search_query') def search_articles(search_query): # get the values for the 2 other bits of search info: the page number and the page size @@ -162,7 +162,7 @@ def search_articles(search_query): @write_required(api=True) @swag(swag_summary='Create an application [Authenticated, not public]', swag_spec=ApplicationsCrudApi.create_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('create_application', 'Create application')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('create_application', 'Create application')) def create_application(): # get the data from the request try: @@ -181,7 +181,7 @@ def create_application(): @api_key_required @swag(swag_summary='Retrieve an application [Authenticated, not public]', swag_spec=ApplicationsCrudApi.retrieve_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_application', 'Retrieve application'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('retrieve_application', 'Retrieve application'), record_value_of_which_arg='application_id') def retrieve_application(application_id): a = ApplicationsCrudApi.retrieve(application_id, current_user) @@ -193,7 +193,7 @@ def retrieve_application(application_id): @write_required(api=True) @swag(swag_summary='Update an application [Authenticated, not public]', swag_spec=ApplicationsCrudApi.update_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('update_application', 'Update application'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('update_application', 'Update application'), record_value_of_which_arg='application_id') def update_application(application_id): # get the data from the request @@ -214,7 +214,7 @@ def update_application(application_id): @write_required(api=True) @swag(swag_summary='Delete an application [Authenticated, not public]', swag_spec=ApplicationsCrudApi.delete_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('delete_application', 'Delete application'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('delete_application', 'Delete application'), record_value_of_which_arg='application_id') def delete_application(application_id): ApplicationsCrudApi.delete(application_id, current_user._get_current_object()) @@ -229,7 +229,7 @@ def delete_application(application_id): @write_required(api=True) @swag(swag_summary='Create an article [Authenticated, not public]', swag_spec=ArticlesCrudApi.create_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('create_article', 'Create article')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('create_article', 'Create article')) def create_article(): # get the data from the request try: @@ -248,7 +248,7 @@ def create_article(): @api_key_optional @swag(swag_summary='Retrieve an article', swag_spec=ArticlesCrudApi.retrieve_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_article', 'Retrieve article'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('retrieve_article', 'Retrieve article'), record_value_of_which_arg='article_id') def retrieve_article(article_id): a = ArticlesCrudApi.retrieve(article_id, current_user) @@ -260,7 +260,7 @@ def retrieve_article(article_id): @write_required(api=True) @swag(swag_summary='Update an article [Authenticated, not public]', swag_spec=ArticlesCrudApi.update_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('update_article', 'Update article'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('update_article', 'Update article'), record_value_of_which_arg='article_id') def update_article(article_id): # get the data from the request @@ -281,7 +281,7 @@ def update_article(article_id): @write_required(api=True) @swag(swag_summary='Delete an article [Authenticated, not public]', swag_spec=ArticlesCrudApi.delete_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('delete_article', 'Delete article'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('delete_article', 'Delete article'), record_value_of_which_arg='article_id') def delete_article(article_id): ArticlesCrudApi.delete(article_id, current_user) @@ -295,7 +295,7 @@ def delete_article(article_id): @api_key_optional @swag(swag_summary='Retrieve a journal by ID', swag_spec=JournalsCrudApi.retrieve_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('retrieve_journal', 'Retrieve journal'), +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('retrieve_journal', 'Retrieve journal'), record_value_of_which_arg='journal_id') def retrieve_journal(journal_id): return jsonify_data_object(JournalsCrudApi.retrieve(journal_id, current_user)) @@ -309,7 +309,7 @@ def retrieve_journal(journal_id): @write_required(api=True) @swag(swag_summary='Create applications in bulk [Authenticated, not public]', swag_spec=ApplicationsBulkApi.create_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_application_create', 'Bulk application create')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('bulk_application_create', 'Bulk application create')) def bulk_application_create(): # get the data from the request try: @@ -334,7 +334,7 @@ def bulk_application_create(): @write_required(api=True) @swag(swag_summary='Delete applications in bulk [Authenticated, not public]', swag_spec=ApplicationsBulkApi.delete_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_application_delete', 'Bulk application delete')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('bulk_application_delete', 'Bulk application delete')) def bulk_application_delete(): # get the data from the request try: @@ -355,7 +355,7 @@ def bulk_application_delete(): @write_required(api=True) @swag(swag_summary='Bulk article creation [Authenticated, not public]', swag_spec=ArticlesBulkApi.create_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_article_create', 'Bulk article create')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('bulk_article_create', 'Bulk article create')) def bulk_article_create(): # get the data from the request try: @@ -380,7 +380,7 @@ def bulk_article_create(): @write_required(api=True) @swag(swag_summary='Bulk article delete [Authenticated, not public]', swag_spec=ArticlesBulkApi.delete_swag()) # must be applied after @api_key_(optional|required) decorators. They don't preserve func attributes. -@plausible.pa_event(PLAUSIBLE_CATEGORY, action=PLAUSIBLE_ACTIONS.get('bulk_article_delete', 'Bulk article delete')) +@plausible.pa_event(ANALYTICS_CATEGORY, action=ANALYTICS_ACTIONS.get('bulk_article_delete', 'Bulk article delete')) def bulk_article_delete(): # get the data from the request try: diff --git a/portality/view/atom.py b/portality/view/atom.py index 83c8e68765..1046b3620a 100644 --- a/portality/view/atom.py +++ b/portality/view/atom.py @@ -14,8 +14,8 @@ @blueprint.route('/feed') -@plausible.pa_event(app.config.get('PLAUSIBLE_CATEGORY_ATOM', 'Atom'), - action=app.config.get('PLAUSIBLE_ACTION_ACTION', 'Feed Request')) +@plausible.pa_event(app.config.get('ANALYTICS_CATEGORY_ATOM', 'Atom'), + action=app.config.get('ANALYTICS_ACTION_ACTION', 'Feed Request')) def feed(): # get the feed for this base_url (which is just used to set the metadata of # the feed, but we want to do this outside of a request context so it diff --git a/portality/view/doaj.py b/portality/view/doaj.py index 91f0f5f4b7..e0cfb48ef5 100644 --- a/portality/view/doaj.py +++ b/portality/view/doaj.py @@ -68,8 +68,8 @@ def news(): def fqw_hit(): page = request.form.get('embedding_page') if page is not None: - plausible.send_event(app.config.get('PLAUSIBLE_CATEGORY_FQW', 'FQW'), - action=app.config.get('PLAUSIBLE_ACTION_FQW', 'hit'), + plausible.send_event(app.config.get('ANALYTICS_CATEGORY_FQW', 'FQW'), + action=app.config.get('ANALYTICS_ACTION_FQW', 'hit'), label=request.form.get('embedding_page')) # No content response, whether data there or not. @@ -166,8 +166,8 @@ def journal_readonly(journal_id): @blueprint.route("/csv") -@plausible.pa_event(app.config.get('PLAUSIBLE_CATEGORY_JOURNALCSV', 'JournalCSV'), - action=app.config.get('PLAUSIBLE_ACTION_JOURNALCSV', 'Download')) +@plausible.pa_event(app.config.get('ANALYTICS_CATEGORY_JOURNALCSV', 'JournalCSV'), + action=app.config.get('ANALYTICS_ACTION_JOURNALCSV', 'Download')) def csv_data(): csv_info = models.Cache.get_latest_csv() if csv_info is None: @@ -192,8 +192,8 @@ def sitemap(): @blueprint.route("/public-data-dump/") @api_key_required -@plausible.pa_event(app.config.get('PLAUSIBLE_CATEGORY_PUBLICDATADUMP', 'PublicDataDump'), - action=app.config.get('PLAUSIBLE_ACTION_PUBLICDATADUMP', 'Download')) +@plausible.pa_event(app.config.get('ANALYTICS_CATEGORY_PUBLICDATADUMP', 'PublicDataDump'), + action=app.config.get('ANALYTICS_ACTION_PUBLICDATADUMP', 'Download')) def public_data_dump_redirect(record_type): if not current_user.has_role(constants.ROLE_PUBLIC_DATA_DUMP): abort(404) diff --git a/portality/view/oaipmh.py b/portality/view/oaipmh.py index 640cd325bb..17367af6c2 100644 --- a/portality/view/oaipmh.py +++ b/portality/view/oaipmh.py @@ -32,14 +32,14 @@ def oaipmh(specified=None): # Add the identifier to the event if there is one ident = request.values.get('identifier', None) if ident is not None: - event_payload[app.config.get('PLAUSIBLE_DIMENSIONS')['oai_res_id']] = ident + event_payload[app.config.get('ANALYTICS_DIMENSIONS')['oai_res_id']] = ident # work out the verb and associated parameters verb = request.values.get("verb") event_payload['action'] = verb # Now we have enough information about the request to send to analytics. - plausible.send_event(app.config.get('PLAUSIBLE_CATEGORY_OAI', 'OAI-PMH'), + plausible.send_event(app.config.get('ANALYTICS_CATEGORY_OAI', 'OAI-PMH'), **event_payload) # call the appropriate protocol operation: diff --git a/portality/view/openurl.py b/portality/view/openurl.py index 8be5a3277a..00f5a322d4 100644 --- a/portality/view/openurl.py +++ b/portality/view/openurl.py @@ -29,7 +29,7 @@ def openurl(): return redirect(parser_response, 301) # Log this request to analytics - plausible.send_event(app.config.get('PLAUSIBLE_CATEGORY_OPENURL', 'OpenURL'), + plausible.send_event(app.config.get('ANALYTICS_CATEGORY_OPENURL', 'OpenURL'), action=parser_response.genre, label=qs) From 6aaec572d6b3c5f822886a1d9b6b529c4f0d3500 Mon Sep 17 00:00:00 2001 From: Steve Eardley Date: Wed, 22 Nov 2023 16:56:29 +0000 Subject: [PATCH 13/13] Version bump for 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 d537c27f98..6fc003c0e1 100644 --- a/portality/settings.py +++ b/portality/settings.py @@ -9,7 +9,7 @@ # Application Version information # ~~->API:Feature~~ -DOAJ_VERSION = "6.5.0" +DOAJ_VERSION = "6.5.1" API_VERSION = "3.0.1" ###################################### diff --git a/setup.py b/setup.py index ce7e2121e4..ddf508bf53 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='doaj', - version='6.5.0', + version='6.5.1', packages=find_packages(), install_requires=[ "awscli==1.20.50",