Skip to content

Commit

Permalink
Merge pull request #199 from GSA/ajax-recent-view
Browse files Browse the repository at this point in the history
Ajax recent view
  • Loading branch information
FuhuXia authored Jun 20, 2024
2 parents c533f23 + a38d76f commit b4b1296
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 11 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ CKAN version | Compatibility

### Configuration

_TODO: what configuraiton options exist?_
[Optional]
`ckanext.datagovtheme.js_recent_view = true`


This defaults to `false`. If displaying the recent view count slows down page loading, the optional parameter can be set to `true` to make the recent view count an AJAX call, improving page loading speed. If the recent view count information (package['tracking_summary']) is already present, the AJAX call is disabled to reduce overhead. Therefore, the built-in recent view count rendering must be disabled for this mechanism to take effect.


## Development
Expand Down
17 changes: 13 additions & 4 deletions ckanext/datagovtheme/blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
from ckan.plugins.toolkit import config
from ckan.lib.base import abort
from ckan.common import c, request
from ckanext.datagovtheme import helpers

from flask import Blueprint, redirect
from flask import Blueprint, redirect, jsonify

import logging
log = logging.getLogger(__name__)

pusher = Blueprint('datagovtheme', __name__)
datagovtheme_bp = Blueprint('datagovtheme', __name__)


def show():
Expand All @@ -35,7 +36,15 @@ def show():

def redirect_homepage():
CKAN_SITE_URL = config.get("ckan.site_url")
return redirect(CKAN_SITE_URL + "/dataset", code=302)
return redirect(CKAN_SITE_URL + "/dataset/", code=302)


pusher.add_url_rule('/', view_func=redirect_homepage)
def get_popuplar_count():
pkgs = request.args.get('pkgs')
return jsonify(helpers.get_pkgs_popular_count(pkgs))


datagovtheme_bp.add_url_rule('/', view_func=redirect_homepage)
datagovtheme_bp.add_url_rule("/datagovtheme/get-popular-count",
methods=['GET'],
view_func=get_popuplar_count)
36 changes: 36 additions & 0 deletions ckanext/datagovtheme/fanstatic_library/scripts/popular.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// This js file loads with datagov-popular.html snippet

jQuery(function ($) {

// This api takes a list of package ids from querystring and returns the view count for each package
var pupolar_api = "/datagovtheme/get-popular-count";

// all ids in a string, comma separated
var pkgs = {'pkgs': collect_all_packages().join(',')};

$.getJSON(pupolar_api, pkgs, function(data) {
$.each( data, function( key, val ) {
$("ul.dataset-list li.dataset-item h3.dataset-heading").each(function() {
if ($(this).attr('pkg_id') == key) {
$(this).find('span.recent-views-datagov').attr('title', val['recent']).html('<i class="fa fa-line-chart"></i> ' + val['recent'] + ' recent views');
// If the view count is greater than 10, make it visible
if (val['recent'] >= 10) {
$(this).find('span.recent-views').css('visibility', 'visible');
}else{
$(this).find('span.recent-views').css('display', 'hidden');
}
}
});
});
});

// We have pkg_id in each dataset-item, added in the template.
function collect_all_packages() {
var pkgs = [];
$("ul.dataset-list li.dataset-item h3.dataset-heading").each(function() {
pkgs.push($(this).attr('pkg_id'));
});

return pkgs;
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -2239,6 +2239,9 @@ body .tagged-ngda {
padding-left: 5px;
display: inline-block;
}
.recent-views-datagov {
visibility: hidden;
}
.bar-image {
width: 18px;
display: inline-block;
Expand Down
5 changes: 5 additions & 0 deletions ckanext/datagovtheme/fanstatic_library/webassets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,8 @@ location_autocomplete_js:
# TODO can this custom location search be replaced by ckanext-spatial? Can
# this be pushed upstream to ckanext-spatial as an enhancement?
- scripts/location_autocomplete.js

popular-js:
output: datagovtheme/popular.js
contents:
- scripts/popular.js
22 changes: 22 additions & 0 deletions ckanext/datagovtheme/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import pkg_resources

from ckan import plugins as p
from ckan.lib import base
from ckan.lib import helpers as h
from ckan import model
from ckanext.harvest.model import HarvestObject
Expand Down Expand Up @@ -762,3 +763,24 @@ def get_login_url():
return h.url_for(controller='user', action='login')

return '/user/saml2login'


def get_pkgs_popular_count(ids):
populars = {}
if ids:
pkg_ids = ids.split(',')
for pkg_id in pkg_ids:
populars[pkg_id] = model.TrackingSummary.get_for_package(pkg_id)
return populars


def render_popular(type, pkg, min, title=''):
# If the package has tracking_summary, call core helper function to render it.
if pkg.get('tracking_summary'):
return h.popular(type, pkg['tracking_summary']['recent'], min, title)

js_recent_view = asbool(config.get('ckanext.datagovtheme.js_recent_view', False))
if js_recent_view:
return base.render_snippet('snippets/datagov_popular.html')

return ''
4 changes: 3 additions & 1 deletion ckanext/datagovtheme/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ def get_helpers(self):
'convert_top_category_to_list': datagovtheme_helpers.convert_top_category_to_list,
'get_pkg_dict_extra': datagovtheme_helpers.get_pkg_dict_extra,
'get_login_url': datagovtheme_helpers.get_login_url,
'get_pkgs_popular_count': datagovtheme_helpers.get_pkgs_popular_count,
'render_popular': datagovtheme_helpers.render_popular,
}

# https://github.com/GSA/ckan/blob/datagov/ckan/config/environment.py#L70:L70
Expand All @@ -125,4 +127,4 @@ def get_helpers(self):
return helpers

def get_blueprint(self):
return blueprint.pusher
return blueprint.datagovtheme_bp
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
{% if res.name == 'Comma Seperated Values File' %}
<a itemprop="contentUrl" class="heading" href="{{ url }}" title="Comma Separated Values File">
Comma Separated Values File<span class="format-label" property="dc:format" data-format="{{ res.format.lower() or 'data' }}">{{ res.format }}</span>
{{ h.popular('views', res.tracking_summary.total, min=10) }}
{{ h.popular('views', res.tracking_summary.total, min=10) if res.tracking_summary }}
</a>
{% else %}
<a itemprop="contentUrl" class="heading" href="{{ url }}" title="{{ res.name or res.description }}">
{{ h.resource_display_name(res) | truncate(50) }}<span class="format-label" property="dc:format" data-format="{{ res.format.lower() or 'data' }}">{{ res.format }}</span>
{{ h.popular('views', res.tracking_summary.total, min=10) }}
{{ h.popular('views', res.tracking_summary.total, min=10) if res.tracking_summary }}
</a>
{% endif %}
{% endblock %}
Expand Down
5 changes: 5 additions & 0 deletions ckanext/datagovtheme/templates/snippets/datagov_popular.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<span class="recent-views recent-views-datagov" title="" xmlns="http://www.w3.org/1999/xhtml">
<i class="fa fa-line-chart"></i> &nbsp;&nbsp; recent views
</span>
{% asset 'datagovtheme/popular-js' %}

4 changes: 2 additions & 2 deletions ckanext/datagovtheme/templates/snippets/package_item.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
</span>
</div>
{% endif %}
<h3 class="dataset-heading">
<h3 class="dataset-heading" pkg_id="{{ package.id }}">
{% if package.private %}
<span class="dataset-private label label-inverse">
<i class="fa fa-lock"></i>
Expand Down Expand Up @@ -63,7 +63,7 @@ <h3 class="dataset-heading">
</span>
{% endif %}

{{ h.popular('recent views', package.tracking_summary.recent, min=10) if package.tracking_summary }}
{{ h.render_popular('recent views', package, min=10) }}
</h3>
<div class="notes">
{% if organization and show_organization %}
Expand Down
63 changes: 63 additions & 0 deletions ckanext/datagovtheme/tests/test_helpers.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# encoding: utf-8
import logging
import re
import datetime

import mock
import pytest

from ckanext.datagovtheme import helpers
import ckan.tests.factories as factories
import ckan.lib.helpers as h


################
Expand Down Expand Up @@ -136,3 +138,64 @@ def test_is_tagged_ngda():

assert helpers.is_tagged_ngda(dataset_ngda) is True
assert helpers.is_tagged_ngda(dataset_non_ngda) is False


##################
# recent view
##################


@pytest.fixture
def track(app):
"""Post some data to /_tracking directly.
This simulates what's supposed when you view a page with tracking
enabled (an ajax request posts to /_tracking).
"""

def func(url, type_="page", ip="199.204.138.90", browser="firefox"):
params = {"url": url, "type": type_}
extra_environ = {
# The tracking middleware crashes if these aren't present.
"HTTP_USER_AGENT": browser,
"REMOTE_ADDR": ip,
"HTTP_ACCEPT_LANGUAGE": "en",
"HTTP_ACCEPT_ENCODING": "gzip, deflate",
}
app.post("/_tracking", params=params, extra_environ=extra_environ)

return func


def update_tracking_summary():
"""Update CKAN's tracking summary data."""

import ckan.cli.tracking as tracking
import ckan.model

date = (datetime.datetime.now() - datetime.timedelta(days=1)).strftime(
"%Y-%m-%d"
)
tracking.update_all(engine=ckan.model.meta.engine, start_date=date)


def test_get_pkgs_popular_count(track):
factories.Dataset(id="view-id-1", name="view-id-1")
factories.Dataset(id="view-id-2", name="view-id-2")

ids = "view-id-1,view-id-2"
assert helpers.get_pkgs_popular_count(ids) == {
'view-id-1': {'recent': 0, 'total': 0},
'view-id-2': {'recent': 0, 'total': 0}
}

url = h.url_for("dataset.read", id="view-id-1")
track(url)
update_tracking_summary()

# after dataset 1 is viewed, it should have a view count of 1, dataset 2 should still have 0
assert helpers.get_pkgs_popular_count(ids) == {
'view-id-1': {'recent': 1, 'total': 1},
'view-id-2': {'recent': 0, 'total': 0}
}
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

setup(
name="ckanext-datagovtheme",
version="0.2.24",
version="0.2.25",
description="CKAN Extension to manage data.gov theme",
long_description=long_description,
classifiers=[
Expand Down

0 comments on commit b4b1296

Please sign in to comment.