Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frontend Status Badges #224

Merged
merged 7 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions ckanext/xloader/config_declaration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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


79 changes: 79 additions & 0 deletions ckanext/xloader/helpers.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down Expand Up @@ -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':
duttonw marked this conversation as resolved.
Show resolved Hide resolved
# 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)):
duttonw marked this conversation as resolved.
Show resolved Hide resolved
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'<a href="{pusher_url}" class="loader-badge"><img src="{badge_url}" alt="{alt}" title="{title}"/></a>'.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'<span class="loader-badge"><img src="{badge_url}" alt="{alt}" title="{title}"/></span>'.format(
badge_url=badge_url,
alt=html_escape(messages[status], quote=True),
title=html_escape(title, quote=True)))
2 changes: 2 additions & 0 deletions ckanext/xloader/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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,
}


Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading