From e72cc37d128594fe004581f7cd23a887fe24b68e Mon Sep 17 00:00:00 2001 From: Jesse Vickery Date: Thu, 1 Aug 2024 16:59:36 +0000 Subject: [PATCH 1/2] feat(templates): status badges; - Added status badges. --- ckanext/xloader/config_declaration.yaml | 16 ++++ ckanext/xloader/helpers.py | 79 +++++++++++++++++++ ckanext/xloader/plugin.py | 2 + .../static/badges/en/datastore-active.svg | 1 + .../static/badges/en/datastore-complete.svg | 1 + .../static/badges/en/datastore-error.svg | 1 + .../static/badges/en/datastore-inactive.svg | 1 + .../static/badges/en/datastore-pending.svg | 1 + .../static/badges/en/datastore-running.svg | 1 + .../static/badges/en/datastore-unknown.svg | 1 + .../static/badges/fr/datastore-active.svg | 1 + .../static/badges/fr/datastore-complete.svg | 1 + .../static/badges/fr/datastore-error.svg | 1 + .../static/badges/fr/datastore-inactive.svg | 1 + .../static/badges/fr/datastore-pending.svg | 1 + .../static/badges/fr/datastore-running.svg | 1 + .../static/badges/fr/datastore-unknown.svg | 1 + .../templates/package/resource_read.html | 8 ++ .../package/snippets/resource_info.html | 6 ++ .../package/snippets/resource_item.html | 5 ++ 20 files changed, 130 insertions(+) create mode 100644 ckanext/xloader/public/static/badges/en/datastore-active.svg create mode 100644 ckanext/xloader/public/static/badges/en/datastore-complete.svg create mode 100644 ckanext/xloader/public/static/badges/en/datastore-error.svg create mode 100644 ckanext/xloader/public/static/badges/en/datastore-inactive.svg create mode 100644 ckanext/xloader/public/static/badges/en/datastore-pending.svg create mode 100644 ckanext/xloader/public/static/badges/en/datastore-running.svg create mode 100644 ckanext/xloader/public/static/badges/en/datastore-unknown.svg create mode 100644 ckanext/xloader/public/static/badges/fr/datastore-active.svg create mode 100644 ckanext/xloader/public/static/badges/fr/datastore-complete.svg create mode 100644 ckanext/xloader/public/static/badges/fr/datastore-error.svg create mode 100644 ckanext/xloader/public/static/badges/fr/datastore-inactive.svg create mode 100644 ckanext/xloader/public/static/badges/fr/datastore-pending.svg create mode 100644 ckanext/xloader/public/static/badges/fr/datastore-running.svg create mode 100644 ckanext/xloader/public/static/badges/fr/datastore-unknown.svg create mode 100644 ckanext/xloader/templates/package/snippets/resource_info.html diff --git a/ckanext/xloader/config_declaration.yaml b/ckanext/xloader/config_declaration.yaml index 73120218..6d85e896 100644 --- a/ckanext/xloader/config_declaration.yaml +++ b/ckanext/xloader/config_declaration.yaml @@ -136,5 +136,21 @@ groups: that is not in ckanext.xloader.formats after a Resource is updated. type: bool required: false + - key: ckanext.xloader.show_badges + default: True + example: False + description: | + Controls whether or not the status badges display in the front end. + type: bool + required: false + - key: ckanext.xloader.debug_badges + default: False + example: True + description: | + Controls whether or not the status badges display all of the statuses. By default, + the badges will display "pending", "running", and "error". With debug_badges enabled, + they will also display "complete", "active", "inactive", and "unknown". + type: bool + required: false diff --git a/ckanext/xloader/helpers.py b/ckanext/xloader/helpers.py index 5712c81c..59de42d0 100644 --- a/ckanext/xloader/helpers.py +++ b/ckanext/xloader/helpers.py @@ -1,5 +1,7 @@ import ckan.plugins.toolkit as toolkit from ckanext.xloader.utils import XLoaderFormats +from markupsafe import Markup +from html import escape as html_escape def xloader_status(resource_id): @@ -42,3 +44,80 @@ def is_resource_supported_by_xloader(res_dict, check_access=True): else: is_supported_url_type = True return (is_supported_format or is_datastore_active) and user_has_access and is_supported_url_type + + +def xloader_badge(resource): + # type: (dict) -> str + """ + Displays a custom badge for the status of Xloader and DataStore for the specified resource. + """ + if not toolkit.asbool(toolkit.config.get('ckanext.xloader.show_badges', True)): + return '' + + if not XLoaderFormats.is_it_an_xloader_format(resource.get('format')): + # we only want to show badges for supported xloader formats + return '' + + is_datastore_active = resource.get('datastore_active', False) + + try: + xloader_job = toolkit.get_action("xloader_status")({'ignore_auth': True}, + {"resource_id": resource.get('id')}) + except toolkit.ObjectNotFound: + xloader_job = {} + + if xloader_job.get('status') == 'complete': + # the xloader task is complete, show datastore active or inactive. + # xloader will delete the datastore table at the beggining of the job run. + # so this will only be true if the job is fully finished. + status = 'active' if is_datastore_active else 'inactive' + elif xloader_job.get('status') in ['submitting', 'pending', 'running', 'running_but_viewable', 'error']: + # the job is running or pending or errored + # show the xloader status + status = xloader_job.get('status') + if status == 'running_but_viewable': + # treat running_but_viewable the same as running + status = 'running' + elif status == 'submitting': + # treat submitting the same as pending + status = 'pending' + else: + # we do not know what the status is + status = 'unknown' + + messages = { + 'pending': toolkit._('Data awaiting load to DataStore'), + 'running': toolkit._('Loading data into DataStore'), + 'complete': toolkit._('Data loaded into DataStore'), + 'error': toolkit._('Failed to load data into DataStore'), + 'active': toolkit._('Data available in DataStore'), + 'inactive': toolkit._('Resource not active in DataStore'), + 'unknown': toolkit._('DataStore status unknown'), + } + debug_level_statuses = ['complete', 'active', 'inactive', 'unknown'] + + if status in debug_level_statuses and not toolkit.asbool(toolkit.config.get('ckanext.xloader.debug_badges', False)): + return '' + + badge_url = toolkit.h.url_for_static('/static/badges/{lang}/datastore-{status}.svg'.format( + lang=toolkit.h.lang(), status=status)) + + title = toolkit.h.render_datetime(xloader_job.get('last_updated'), with_hours=True) \ + if xloader_job.get('last_updated') else '' + + try: + toolkit.check_access('resource_update', {'user': toolkit.g.user}, {'id': resource.get('id')}) + pusher_url = toolkit.h.url_for('xloader.resource_data', + id=resource.get('package_id'), + resource_id=resource.get('id')) + + return Markup(u'{alt}'.format( + pusher_url=pusher_url, + badge_url=badge_url, + alt=html_escape(messages[status], quote=True), + title=html_escape(title, quote=True))) + except toolkit.NotAuthorized: + return Markup(u'{alt}'.format( + badge_url=badge_url, + alt=html_escape(messages[status], quote=True), + title=html_escape(title, quote=True))) diff --git a/ckanext/xloader/plugin.py b/ckanext/xloader/plugin.py index 05d629c8..aef1fd98 100644 --- a/ckanext/xloader/plugin.py +++ b/ckanext/xloader/plugin.py @@ -51,6 +51,7 @@ def get_blueprint(self): def update_config(self, config): toolkit.add_template_directory(config, 'templates') + toolkit.add_public_directory(config, 'public') # IConfigurable @@ -206,6 +207,7 @@ def get_helpers(self): "xloader_status": xloader_helpers.xloader_status, "xloader_status_description": xloader_helpers.xloader_status_description, "is_resource_supported_by_xloader": xloader_helpers.is_resource_supported_by_xloader, + "xloader_badge": xloader_helpers.xloader_badge, } diff --git a/ckanext/xloader/public/static/badges/en/datastore-active.svg b/ckanext/xloader/public/static/badges/en/datastore-active.svg new file mode 100644 index 00000000..4a1d1ce9 --- /dev/null +++ b/ckanext/xloader/public/static/badges/en/datastore-active.svg @@ -0,0 +1 @@ +datastore: activedatastoreactive \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/en/datastore-complete.svg b/ckanext/xloader/public/static/badges/en/datastore-complete.svg new file mode 100644 index 00000000..7cbfd824 --- /dev/null +++ b/ckanext/xloader/public/static/badges/en/datastore-complete.svg @@ -0,0 +1 @@ +datastore: completedatastorecomplete \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/en/datastore-error.svg b/ckanext/xloader/public/static/badges/en/datastore-error.svg new file mode 100644 index 00000000..fe74ebe3 --- /dev/null +++ b/ckanext/xloader/public/static/badges/en/datastore-error.svg @@ -0,0 +1 @@ +datastore: errordatastoreerror \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/en/datastore-inactive.svg b/ckanext/xloader/public/static/badges/en/datastore-inactive.svg new file mode 100644 index 00000000..5de623d0 --- /dev/null +++ b/ckanext/xloader/public/static/badges/en/datastore-inactive.svg @@ -0,0 +1 @@ +datastore: inactivedatastoreinactive \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/en/datastore-pending.svg b/ckanext/xloader/public/static/badges/en/datastore-pending.svg new file mode 100644 index 00000000..49867a51 --- /dev/null +++ b/ckanext/xloader/public/static/badges/en/datastore-pending.svg @@ -0,0 +1 @@ +datastore: pendingdatastorepending \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/en/datastore-running.svg b/ckanext/xloader/public/static/badges/en/datastore-running.svg new file mode 100644 index 00000000..ab3cce1e --- /dev/null +++ b/ckanext/xloader/public/static/badges/en/datastore-running.svg @@ -0,0 +1 @@ +datastore: runningdatastorerunning \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/en/datastore-unknown.svg b/ckanext/xloader/public/static/badges/en/datastore-unknown.svg new file mode 100644 index 00000000..a190db75 --- /dev/null +++ b/ckanext/xloader/public/static/badges/en/datastore-unknown.svg @@ -0,0 +1 @@ +datastore: unknowndatastoreunknown \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/fr/datastore-active.svg b/ckanext/xloader/public/static/badges/fr/datastore-active.svg new file mode 100644 index 00000000..4a1d1ce9 --- /dev/null +++ b/ckanext/xloader/public/static/badges/fr/datastore-active.svg @@ -0,0 +1 @@ +datastore: activedatastoreactive \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/fr/datastore-complete.svg b/ckanext/xloader/public/static/badges/fr/datastore-complete.svg new file mode 100644 index 00000000..f0e226d4 --- /dev/null +++ b/ckanext/xloader/public/static/badges/fr/datastore-complete.svg @@ -0,0 +1 @@ +datastore: complètedatastorecomplète \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/fr/datastore-error.svg b/ckanext/xloader/public/static/badges/fr/datastore-error.svg new file mode 100644 index 00000000..48f14fb6 --- /dev/null +++ b/ckanext/xloader/public/static/badges/fr/datastore-error.svg @@ -0,0 +1 @@ +datastore: erreurdatastoreerreur \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/fr/datastore-inactive.svg b/ckanext/xloader/public/static/badges/fr/datastore-inactive.svg new file mode 100644 index 00000000..5de623d0 --- /dev/null +++ b/ckanext/xloader/public/static/badges/fr/datastore-inactive.svg @@ -0,0 +1 @@ +datastore: inactivedatastoreinactive \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/fr/datastore-pending.svg b/ckanext/xloader/public/static/badges/fr/datastore-pending.svg new file mode 100644 index 00000000..29acb160 --- /dev/null +++ b/ckanext/xloader/public/static/badges/fr/datastore-pending.svg @@ -0,0 +1 @@ +datastore: en attentedatastoreen attente \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/fr/datastore-running.svg b/ckanext/xloader/public/static/badges/fr/datastore-running.svg new file mode 100644 index 00000000..230db15f --- /dev/null +++ b/ckanext/xloader/public/static/badges/fr/datastore-running.svg @@ -0,0 +1 @@ +datastore: en cours d'exécutiondatastoreen cours d'exécution \ No newline at end of file diff --git a/ckanext/xloader/public/static/badges/fr/datastore-unknown.svg b/ckanext/xloader/public/static/badges/fr/datastore-unknown.svg new file mode 100644 index 00000000..91f4285f --- /dev/null +++ b/ckanext/xloader/public/static/badges/fr/datastore-unknown.svg @@ -0,0 +1 @@ +datastore: inconnuedatastoreinconnue \ No newline at end of file diff --git a/ckanext/xloader/templates/package/resource_read.html b/ckanext/xloader/templates/package/resource_read.html index 3ab1476e..09183a3f 100644 --- a/ckanext/xloader/templates/package/resource_read.html +++ b/ckanext/xloader/templates/package/resource_read.html @@ -1,5 +1,13 @@ {% ckan_extends %} +{% block resource_read_url %} + {% set badge = h.xloader_badge(res) %} + {% if badge %} + {{ badge }}

+ {% endif %} + {{ super() }} +{% endblock %} + {% block action_manage_inner %} {{ super() }} {% if h.is_resource_supported_by_xloader(res) %} diff --git a/ckanext/xloader/templates/package/snippets/resource_info.html b/ckanext/xloader/templates/package/snippets/resource_info.html new file mode 100644 index 00000000..2bdea4d3 --- /dev/null +++ b/ckanext/xloader/templates/package/snippets/resource_info.html @@ -0,0 +1,6 @@ +{% ckan_extends %} + +{% block resource_info %} + {{ super() }} + {{ h.xloader_badge(res) }} +{% endblock %} diff --git a/ckanext/xloader/templates/package/snippets/resource_item.html b/ckanext/xloader/templates/package/snippets/resource_item.html index 70bf99c4..8226bd1f 100644 --- a/ckanext/xloader/templates/package/snippets/resource_item.html +++ b/ckanext/xloader/templates/package/snippets/resource_item.html @@ -13,3 +13,8 @@ {% endif %} {{ super() }} {% endblock %} + +{% block resource_item_title %} + {{ super() }} + {{ h.xloader_badge(res) }} +{% endblock %} From e7eee6d923f9a7f1caebcf189a3790eff6f00db5 Mon Sep 17 00:00:00 2001 From: Jesse Vickery Date: Fri, 9 Aug 2024 14:21:05 +0000 Subject: [PATCH 2/2] fix(logic): reverse debug logic; - Reverse debug badge logic. --- ckanext/xloader/helpers.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ckanext/xloader/helpers.py b/ckanext/xloader/helpers.py index 59de42d0..864d0731 100644 --- a/ckanext/xloader/helpers.py +++ b/ckanext/xloader/helpers.py @@ -86,17 +86,19 @@ def xloader_badge(resource): status = 'unknown' messages = { + # Default messages 'pending': toolkit._('Data awaiting load to DataStore'), 'running': toolkit._('Loading data into DataStore'), - 'complete': toolkit._('Data loaded into DataStore'), 'error': toolkit._('Failed to load data into DataStore'), + # Debug messages + 'complete': toolkit._('Data loaded into DataStore'), 'active': toolkit._('Data available in DataStore'), 'inactive': toolkit._('Resource not active in DataStore'), 'unknown': toolkit._('DataStore status unknown'), } - debug_level_statuses = ['complete', 'active', 'inactive', 'unknown'] + basic_statuses = ['pending', 'running', 'error'] - if status in debug_level_statuses and not toolkit.asbool(toolkit.config.get('ckanext.xloader.debug_badges', False)): + if status not in basic_statuses and not toolkit.asbool(toolkit.config.get('ckanext.xloader.debug_badges', False)): return '' badge_url = toolkit.h.url_for_static('/static/badges/{lang}/datastore-{status}.svg'.format(