forked from openlibhums/janeway
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
openlibhums#1322: most downloaded article (pr openlibhums#1344)
* Partial commit. * Form now works as expected. * Initial pass over. * Changed title on OLH theme * Switched to Processed Values. * Fixed query. * Partial: adds dt filtering. * openlibhums#1322: Use natural join filters instead of subquery * When articles have the same number of accesses, order by title. * Brought most popular articles to Default and Material. * Reset featured. * Resets featured templates. * Added new popular homepage element.
- Loading branch information
Showing
13 changed files
with
459 additions
and
1 deletion.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
from django import forms | ||
|
||
from utils import setting_handler | ||
from core.homepage_elements.popular import plugin_settings, logic | ||
|
||
|
||
class FeaturedForm(forms.Form): | ||
|
||
def __init__(self, *args, **kwargs): | ||
self.journal = kwargs.pop('journal', None) | ||
super(FeaturedForm, self).__init__(*args, **kwargs) | ||
|
||
most_popular, num_most_popular, most_popular_time = logic.get_popular_article_settings( | ||
self.journal | ||
) | ||
|
||
self.fields['num_most_popular'].initial = num_most_popular | ||
self.fields['most_popular'].initial = most_popular | ||
self.fields['most_popular_time'].initial = most_popular_time | ||
|
||
most_popular = forms.BooleanField( | ||
label='Display Most Popular Articles', | ||
help_text='Displays the most popular articles.', | ||
required=False, | ||
) | ||
num_most_popular = forms.IntegerField( | ||
label='Number of Most Popular Articles to Display', | ||
help_text='Determines how many popular articles we should display.', | ||
) | ||
most_popular_time = forms.ChoiceField( | ||
choices=( | ||
('weekly', 'Weekly'), | ||
('monthly', 'Monthly'), | ||
('yearly', 'Yearly'), | ||
), | ||
label='Number of Most Popular Articles to Display', | ||
help_text='Determines how many popular articles we should display.', | ||
) | ||
|
||
def save(self, commit=True): | ||
most_popular = self.cleaned_data.get('most_popular') | ||
num_most_popular = self.cleaned_data.get('num_most_popular', 0) | ||
most_popular_time = self.cleaned_data.get('most_popular_time') | ||
|
||
if commit: | ||
setting_handler.save_plugin_setting( | ||
plugin_settings.get_self(), | ||
'most_popular', | ||
most_popular, | ||
self.journal, | ||
) | ||
|
||
setting_handler.save_plugin_setting( | ||
plugin_settings.get_self(), | ||
'num_most_popular', | ||
num_most_popular, | ||
self.journal, | ||
) | ||
|
||
setting_handler.save_plugin_setting( | ||
plugin_settings.get_self(), | ||
'most_popular_time', | ||
most_popular_time, | ||
self.journal, | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from core.homepage_elements.popular import logic | ||
|
||
|
||
def yield_homepage_element_context(request, homepage_elements): | ||
if homepage_elements is not None and homepage_elements.filter( | ||
name='Popular Articles', | ||
).exists(): | ||
|
||
most_popular, number, time = logic.get_popular_article_settings( | ||
request.journal | ||
) | ||
|
||
popular_articles = logic.get_most_popular_articles( | ||
request.journal, | ||
number, | ||
time, | ||
) | ||
|
||
return { | ||
'popular_articles': popular_articles, | ||
'most_popular': most_popular, | ||
} | ||
else: | ||
return {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
from datetime import timedelta | ||
|
||
from django.db.models import Count | ||
from django.utils import timezone | ||
|
||
from submission import models as sm | ||
from utils import setting_handler | ||
from core.homepage_elements.popular import plugin_settings | ||
|
||
|
||
def get_popular_article_settings(journal): | ||
plugin = plugin_settings.get_self() | ||
|
||
try: | ||
most_popular = setting_handler.get_plugin_setting( | ||
plugin, | ||
'most_popular', | ||
journal, | ||
).processed_value | ||
except IndexError: | ||
most_popular = False | ||
|
||
try: | ||
num_most_popular = setting_handler.get_plugin_setting( | ||
plugin, | ||
'num_most_popular', | ||
journal, | ||
).processed_value | ||
except IndexError: | ||
num_most_popular = 0 | ||
try: | ||
most_popular_time = setting_handler.get_plugin_setting( | ||
plugin, | ||
'most_popular_time', | ||
journal, | ||
).processed_value | ||
except IndexError: | ||
most_popular_time = 'weekly' | ||
|
||
return most_popular, num_most_popular, most_popular_time | ||
|
||
|
||
def calc_start_date(time): | ||
date_time = timezone.now() | ||
|
||
if time == 'weekly': | ||
delta = 7 | ||
elif time == 'monthly': | ||
delta = 30 | ||
else: | ||
delta = 365 | ||
|
||
return date_time - timedelta(days=delta) | ||
|
||
|
||
def get_most_popular_articles(journal, number, time): | ||
start_date = calc_start_date(time) | ||
|
||
articles = sm.Article.objects.filter( | ||
journal=journal, | ||
stage=sm.STAGE_PUBLISHED, | ||
articleaccess__accessed__gte=start_date, | ||
).annotate( | ||
access_count=Count("articleaccess") | ||
).order_by('-access_count', 'title')[:number] | ||
|
||
return articles |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
from django.db.utils import OperationalError | ||
from django.contrib.contenttypes.models import ContentType | ||
|
||
from utils import models | ||
from utils.logger import get_logger | ||
|
||
logger = get_logger(__name__) | ||
|
||
PLUGIN_NAME = 'Popular Articles' | ||
DESCRIPTION = 'This is a homepage element that renders popular articles.' | ||
AUTHOR = 'Martin Paul Eve' | ||
VERSION = '1.0' | ||
|
||
|
||
def get_self(): | ||
try: | ||
plugin = models.Plugin.objects.get( | ||
name=PLUGIN_NAME, | ||
) | ||
return plugin | ||
except models.Plugin.DoesNotExist: | ||
return None | ||
|
||
|
||
def install(): | ||
import core.models as core_models | ||
import journal.models as journal_models | ||
|
||
plugin, c = models.Plugin.objects.get_or_create( | ||
name=PLUGIN_NAME, | ||
version=VERSION, | ||
enabled=True, | ||
display_name='Popular Articles', | ||
homepage_element=True, | ||
) | ||
|
||
if c: | ||
logger.debug('Plugin {} created'.format(PLUGIN_NAME)) | ||
|
||
models.PluginSetting.objects.get_or_create( | ||
name='most_popular', | ||
plugin=plugin, | ||
defaults={ | ||
'pretty_name': 'Display Most Popular Articles', | ||
'types': 'boolean', | ||
'description': 'Displays the most popular articles.', | ||
'is_translatable': False, | ||
} | ||
) | ||
|
||
models.PluginSetting.objects.get_or_create( | ||
name='num_most_popular', | ||
plugin=plugin, | ||
defaults={ | ||
'pretty_name': 'Number of Most Popular Articles to Display', | ||
'types': 'number', | ||
'description': 'Determines how many popular articles we should display.', | ||
'is_translatable': False, | ||
} | ||
) | ||
|
||
models.PluginSetting.objects.get_or_create( | ||
name='most_popular_time', | ||
plugin=plugin, | ||
defaults={ | ||
'pretty_name': 'Most Popular Timescale', | ||
'types': 'text', | ||
'description': 'Select from this week, this month or this year.', | ||
'is_translatable': False, | ||
} | ||
) | ||
|
||
if c: | ||
logger.debug('Setting created') | ||
|
||
# check whether this homepage element has already been installed for all journals | ||
journals = journal_models.Journal.objects.all() | ||
|
||
for journal in journals: | ||
content_type = ContentType.objects.get_for_model(journal) | ||
element, created = core_models.HomepageElement.objects.get_or_create( | ||
name=PLUGIN_NAME, | ||
configure_url='popular_articles_setup', | ||
template_path='journal/homepage_elements/popular.html', | ||
content_type=content_type, | ||
object_id=journal.pk, | ||
has_config=True, | ||
) | ||
|
||
element.save() | ||
|
||
|
||
def hook_registry(): | ||
try: | ||
install() | ||
return { | ||
'yield_homepage_element_context': { | ||
'module': 'core.homepage_elements.popular.hooks', | ||
'function': 'yield_homepage_element_context', | ||
'name': PLUGIN_NAME, | ||
} | ||
} | ||
except OperationalError: | ||
# if we get here the database hasn't yet been created | ||
return {} | ||
except BaseException: | ||
return {} |
41 changes: 41 additions & 0 deletions
41
src/core/homepage_elements/popular/templates/popular_setup.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{% extends "admin/core/base.html" %} | ||
{% load foundation %} | ||
{% load static from staticfiles %} | ||
|
||
{% block title %}Popular Articles Manager{% endblock title %} | ||
{% block admin-header %}Popular Articles Manager{% endblock %} | ||
|
||
{% block breadcrumbs %} | ||
{{ block.super }} | ||
<li><a href="{% url 'core_manager_index' %}">Manager</a></li> | ||
<li><a href="{% url 'home_settings_index' %}">Journal Home Settings</a></li> | ||
<li>Popular Articles Manager</li> | ||
{% endblock %} | ||
|
||
{% block body %} | ||
<div class="box"> | ||
<div class="title-area"> | ||
<h2>Display Most Popular Articles</h2> | ||
</div> | ||
<div class="content"> | ||
<div class="row expanded"> | ||
<div class="large-6 columns"> | ||
<p>You can override the display of this block with the most popular articles rather than | ||
featured.</p> | ||
<form method="POST"> | ||
{% csrf_token %} | ||
{{ form|foundation }} | ||
<button name="form" class="success button">Save</button> | ||
</form> | ||
</div> | ||
</div> | ||
|
||
</div> | ||
</div> | ||
{% endblock body %} | ||
|
||
{% block js %} | ||
{% include "elements/datatables.html" with target="#featured" %} | ||
{% endblock js %} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from django.conf.urls import url | ||
from core.homepage_elements.popular import views | ||
|
||
urlpatterns = [ | ||
# Featured Articles | ||
url(r'^manager/$', views.featured_articles, name='popular_articles_setup'), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from django.urls import reverse | ||
from django.shortcuts import redirect, render | ||
from django.contrib import messages | ||
|
||
from core.homepage_elements.popular import forms | ||
|
||
from security.decorators import editor_user_required | ||
|
||
|
||
@editor_user_required | ||
def featured_articles(request): | ||
form = forms.FeaturedForm(journal=request.journal) | ||
|
||
if request.POST: | ||
|
||
if 'form' in request.POST: | ||
form = forms.FeaturedForm(request.POST, journal=request.journal) | ||
|
||
if form.is_valid(): | ||
form.save() | ||
messages.add_message( | ||
request, | ||
messages.SUCCESS, | ||
'Settings saved.', | ||
) | ||
return redirect(reverse('popular_articles_setup')) | ||
|
||
template = 'popular_setup.html' | ||
context = { | ||
'form': form, | ||
} | ||
|
||
return render(request, template, context) |
40 changes: 40 additions & 0 deletions
40
src/themes/OLH/templates/journal/homepage_elements/popular.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
{% load static from staticfiles %} | ||
{% load i18n %} | ||
|
||
<section> | ||
<div class="row column text-center"> | ||
{% if most_downloaded %} | ||
<h2 class="title">{% trans 'Most Popular Articles' %}</h2> | ||
{% else %} | ||
<h2 class="title">{% trans 'Featured Articles' %}</h2> | ||
{% endif %} | ||
</div> | ||
<div class="row" data-equalizer data-equalize-on="medium"> | ||
{% for article in popular_articles %} | ||
<div class="large-4 columns{% if forloop.last %} end{% endif %}" > | ||
<div class="box" data-equalizer-watch> | ||
<a href="{% if article.is_remote %}{{ article.remote_url }}{% else %}{{ article.url }}{% endif %}" | ||
class="box-link"></a> | ||
|
||
{% if article.large_image_file %} | ||
<img src="{% url 'article_file_download' 'id' article.id article.large_image_file.id %}" | ||
alt="{{ article.title|striptags }}" class="feature-article-image"> | ||
{% elif article.journal.default_large_image %} | ||
<img src="{{ article.journal.default_large_image.url }}" | ||
alt="{{ article.title|striptags }}" class="feature-article-image"> | ||
{% else %} | ||
<img src="{% static 'common/img/sample/article-small.jpg' %}" | ||
alt="{{ article.title|striptags }}" class="feature-article-image"> | ||
{% endif %} | ||
|
||
<div class="content"> | ||
<p>{{ article.author_list }}</p> | ||
<p><strong>{{ article.title|safe|truncatechars:200 }}</strong></p> | ||
</div> | ||
</div> | ||
</div> | ||
{% if forloop.counter|divisibleby:3 %}</div> | ||
<div class="row">{% endif %} | ||
{% endfor %} | ||
</div> | ||
</section> |
Oops, something went wrong.