Sync entries button

This commit is contained in:
datalets 2017-10-14 23:57:39 +02:00
parent a11d8a2796
commit 65944deaf5
4 changed files with 43 additions and 70 deletions

View file

@ -7,120 +7,92 @@ from django.conf.urls import url
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.shortcuts import redirect
from wagtail.contrib.modeladmin.helpers import AdminURLHelper, ButtonHelper from wagtail.contrib.modeladmin.helpers import AdminURLHelper, ButtonHelper
from wagtail.contrib.modeladmin.options import ModelAdmin from wagtail.contrib.modeladmin.options import ModelAdmin
from wagtail.contrib.modeladmin.views import IndexView from wagtail.contrib.modeladmin.views import IndexView
from wagtail.wagtailadmin import messages
from feedler.models import Entry from feedler.models import Entry
from feedler.refresh import refresh_streams
from feedler.models.admin import FeedlySettings
class ExportButtonHelper(ButtonHelper): class RefreshButtonHelper(ButtonHelper):
""" """
This helper constructs all the necessary attributes to create a button. This helper constructs a refresh button
There is a lot of boilerplate just for the classnames to be right :(
""" """
button_classnames = ['icon', 'icon-download']
export_button_classnames = ['icon', 'icon-download'] def refresh_button(self, classnames_add=None, classnames_exclude=None):
if classnames_add is None: classnames_add = []
def export_button(self, classnames_add=None, classnames_exclude=None): if classnames_exclude is None: classnames_exclude = []
if classnames_add is None: classnames = self.button_classnames + classnames_add
classnames_add = []
if classnames_exclude is None:
classnames_exclude = []
classnames = self.export_button_classnames + classnames_add
cn = self.finalise_classname(classnames, classnames_exclude) cn = self.finalise_classname(classnames, classnames_exclude)
text = _('Export {}'.format(self.verbose_name_plural.title())) text = _('Sync {}'.format(self.verbose_name_plural.title()))
return { return {
'url': self.url_helper.get_action_url('export', query_params=self.request.GET), 'url': self.url_helper.get_action_url('refresh', query_params=self.request.GET),
'label': text, 'label': text, 'classname': cn, 'title': text,
'classname': cn,
'title': text,
} }
class RefreshAdminURLHelper(AdminURLHelper):
class ExportAdminURLHelper(AdminURLHelper):
""" """
This helper constructs the different urls. This helper constructs the different urls, to overwrite the default behaviour
and append the filters to the action.
This is mostly just to overwrite the default behaviour
which consider any action other than 'create', 'choose_parent' and 'index'
as `object specific` and will try to add the object PK to the url
which is not what we want for the `export` option.
In addition, it appends the filters to the action.
""" """
non_object_specific_actions = ('create', 'choose_parent', 'index', 'refresh')
non_object_specific_actions = ('create', 'choose_parent', 'index', 'export')
def get_action_url(self, action, *args, **kwargs): def get_action_url(self, action, *args, **kwargs):
query_params = kwargs.pop('query_params', None) query_params = kwargs.pop('query_params', None)
url_name = self.get_action_url_name(action) url_name = self.get_action_url_name(action)
if action in self.non_object_specific_actions: if action in self.non_object_specific_actions:
url = reverse(url_name) url = reverse(url_name)
else: else:
url = reverse(url_name, args=args, kwargs=kwargs) url = reverse(url_name, args=args, kwargs=kwargs)
if query_params: if query_params:
url += '?{params}'.format(params=query_params.urlencode()) url += '?{params}'.format(params=query_params.urlencode())
return url return url
def get_action_url_pattern(self, action): def get_action_url_pattern(self, action):
if action in self.non_object_specific_actions: if action in self.non_object_specific_actions:
return self._get_action_url_pattern(action) return self._get_action_url_pattern(action)
return self._get_object_specific_action_url_pattern(action) return self._get_object_specific_action_url_pattern(action)
class RefreshView(IndexView):
class ExportView(IndexView):
""" """
A Class Based View which will generate A Class Based View which will handle the button click
""" """
# def export_csv(self):
def export_csv(self): # data = self.queryset.all()
data = self.queryset.all() # response = ...
response = ... # return response
return response
@method_decorator(login_required) @method_decorator(login_required)
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
super().dispatch(request, *args, **kwargs) super().dispatch(request, *args, **kwargs)
return self.export_csv() if not refresh_streams(FeedlySettings.for_site(request.site)):
messages.error(
request, _('Sorry, could not refresh streams. Please contact your administrator.'))
return redirect('/admin/feedler/entry/')
class ExportModelAdminMixin(object): class EntryModelAdminMixin(object):
""" """
A mixin to add to your model admin which hooks the different helpers, the view A mixin to add to your model admin which hooks the different helpers, the view
and register the new urls. and register the new urls.
""" """
button_helper_class = RefreshButtonHelper
button_helper_class = ExportButtonHelper url_helper_class = RefreshAdminURLHelper
url_helper_class = ExportAdminURLHelper view_class = RefreshView
export_view_class = ExportView
def get_admin_urls_for_registration(self): def get_admin_urls_for_registration(self):
urls = super().get_admin_urls_for_registration() urls = super().get_admin_urls_for_registration()
urls += ( urls += (
url( url(
self.url_helper.get_action_url_pattern('export'), self.url_helper.get_action_url_pattern('refresh'),
self.export_view, self.refresh_view,
name=self.url_helper.get_action_url_name('export') name=self.url_helper.get_action_url_name('refresh')
), ),
) )
return urls return urls
def export_view(self, request): def refresh_view(self, request):
kwargs = {'model_admin': self} kwargs = {'model_admin': self}
view_class = self.export_view_class view_class = self.view_class
return view_class.as_view(**kwargs)(request) return view_class.as_view(**kwargs)(request)
class MenuModelAdmin(ExportModelAdminMixin, ModelAdmin):
model = Entry

View file

@ -72,3 +72,4 @@ def refresh_stream(stream, settings, retry=False):
entry = feedparser.parse(entry, raw_entry, stream) entry = feedparser.parse(entry, raw_entry, stream)
# Persist resulting object # Persist resulting object
entry.save() entry.save()
return True

View file

@ -3,9 +3,9 @@
{% block header_extra %} {% block header_extra %}
{% if user_can_create %} {% if user_can_create %}
<div class="right"> <div class="right">
<div class="addbutton"> <div style="position: relative; top: -1px;">
{% include 'modeladmin/includes/button.html' with button=view.button_helper.export_button %} {% include 'modeladmin/includes/button.html' with button=view.button_helper.refresh_button %}
</div> </div>
</div> </div>
{% endif %} {% endif %}
{{ block.super }}{% comment %}Show original buttons{% endcomment %} {{ block.super }}{% comment %}Show original buttons{% endcomment %}

View file

@ -3,10 +3,10 @@
from wagtail.contrib.modeladmin.options import ( from wagtail.contrib.modeladmin.options import (
ModelAdmin, modeladmin_register) ModelAdmin, modeladmin_register)
from .admin import ExportModelAdminMixin from .admin import EntryModelAdminMixin
from .models import Entry, Stream from .models import Entry, Stream
class EntryModelAdmin(ExportModelAdminMixin, ModelAdmin): class EntryModelAdmin(EntryModelAdminMixin, ModelAdmin):
model = Entry model = Entry
menu_icon = 'date' menu_icon = 'date'
menu_order = 200 menu_order = 200