deprecated
httplib2
-django-ssify==0.2.7
raven
def get_queryset(self):
qs = Book.objects.filter(preview=True)
# FIXME: temporary workaround for a problem with iOS app; see #3954.
- if 'Darwin' in self.request.META['HTTP_USER_AGENT'] and 'debug' not in self.request.GET:
+ if 'Darwin' in self.request.META.get('HTTP_USER_AGENT', '') and 'debug' not in self.request.GET:
qs = qs.none()
return qs
"""Just run `build` on FieldFile, can't pass it directly to Celery."""
task_logger.info("%s -> %s" % (obj.slug, field_name))
ret = self.build(getattr(obj, field_name))
- obj.flush_includes()
+ obj.clear_cache()
return ret
def set_file_permissions(self, fieldfile):
from django.utils.deconstruct import deconstructible
import jsonfield
from fnpdjango.storage import BofhFileSystemStorage
-from ssify import flush_ssi_includes
from librarian.cover import WLCover
from librarian.html import transform_abstrakt
b.ancestor.add(parent)
parent = parent.parent
- def flush_includes(self, languages=True):
+ def clear_cache(self):
clear_cached_renders(self.mini_box)
clear_cached_renders(self.mini_box_nolink)
- if not languages:
- return
- if languages is True:
- languages = [lc for (lc, _ln) in settings.LANGUAGES]
- flush_ssi_includes([
- template % (self.pk, lang)
- for template in [
- '/katalog/b/%d/short.%s.html',
- '/katalog/b/%d/wide.%s.html',
- '/api/include/book/%d.%s.json',
- '/api/include/book/%d.%s.xml',
- ]
- for lang in languages
- ])
def cover_info(self, inherit=True):
"""Returns a dictionary to serve as fallback for BookInfo.
from django.db import models
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
-from ssify import flush_ssi_includes
import re
+from wolnelektury.utils import cached_render, clear_cached_renders
class Collection(models.Model):
from catalogue.models import Book
return Book.objects.filter(self.get_query())
- def flush_includes(self, languages=True):
- if not languages:
- return
- if languages is True:
- languages = [lc for (lc, _ln) in settings.LANGUAGES]
+ @cached_render('catalogue/collection_box.html')
+ def box(self):
+ return {
+ 'collection': self
+ }
- flush_ssi_includes([
- '/katalog/%s.json' % lang for lang in languages])
+ def clear_cache(self):
+ clear_cached_renders(self.box)
from django.utils.translation import ugettext_lazy as _
from newtagging import managers
from catalogue.models import Tag
-from ssify import flush_ssi_includes
+from wolnelektury.utils import cached_render, clear_cached_renders
class Fragment(models.Model):
tags = managers.TagDescriptor(Tag)
tag_relations = GenericRelation(Tag.intermediary_table_model)
- short_html_url_name = 'catalogue_fragment_short'
-
class Meta:
ordering = ('book', 'anchor',)
verbose_name = _('fragment')
"""Returns short version of the fragment."""
return self.short_text if self.short_text else self.text
+ @cached_render('catalogue/fragment_short.html')
+ def midi_box(self):
+ return {'fragment': self}
+
+ @cached_render('catalogue/fragment_promo.html')
+ def promo_box(self):
+ return {'fragment': self}
+
@property
def themes(self):
return self.tags.filter(category='theme')
- def flush_includes(self, languages=True):
- if not languages:
- return
- if languages is True:
- languages = [lc for (lc, _ln) in settings.LANGUAGES]
- flush_ssi_includes([
- template % (self.pk, lang)
- for template in [
- '/katalog/f/%d/short.%s.html',
- '/api/include/fragment/%d.%s.json',
- '/api/include/fragment/%d.%s.xml',
- ]
- for lang in languages
- ])
+ def clear_cache(self):
+ clear_cached_renders(self.midi_box)
+ clear_cached_renders(self.promo_box)
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
for book in Book.objects.all():
source = book.extra_info.get('source_url', '')
if self.netloc in source or (old_netloc != self.netloc and old_netloc in source):
- book.flush_includes()
+ book.clear_cache()
return ret
from django.utils.translation import ugettext_lazy as _
from newtagging.models import TagManager, TaggedItemManager
-from ssify import flush_ssi_includes
# Those are hard-coded here so that makemessages sees them.
created_at = models.DateTimeField(_('creation date'), auto_now_add=True, db_index=True)
changed_at = models.DateTimeField(_('creation date'), auto_now=True, db_index=True)
- after_change = Signal(providing_args=['instance', 'languages'])
+ after_change = Signal(providing_args=['instance'])
intermediary_table_model = TagRelation
objects = TagManager()
app_label = 'catalogue'
def save(self, *args, **kwargs):
- flush_cache = flush_all_includes = False
- if self.pk and self.category != 'set':
- # Flush the whole views cache.
- # Seem a little harsh, but changed tag names, descriptions
- # and links come up at any number of places.
- flush_cache = True
-
- # Find in which languages we need to flush related includes.
- old_self = type(self).objects.get(pk=self.pk)
- # Category shouldn't normally be changed, but just in case.
- if self.category != old_self.category:
- flush_all_includes = True
- languages_changed = self.languages_changed(old_self)
-
+ existing = self.pk and self.category != 'set'
ret = super(Tag, self).save(*args, **kwargs)
-
- if flush_cache:
- caches[settings.CACHE_MIDDLEWARE_ALIAS].clear()
- if flush_all_includes:
- flush_ssi_includes()
- else:
- self.flush_includes()
- self.after_change.send(sender=type(self), instance=self, languages=languages_changed)
-
+ if existing:
+ self.after_change.send(sender=type(self), instance=self)
return ret
- def languages_changed(self, old):
- all_langs = [lc for (lc, _ln) in settings.LANGUAGES]
- if (old.category, old.slug) != (self.category, self.slug):
- return all_langs
- languages = set()
- for lang in all_langs:
- name_field = 'name_%s' % lang
- if getattr(old, name_field) != getattr(self, name_field):
- languages.add(lang)
- return languages
-
- def flush_includes(self, languages=True):
- if not languages:
- return
- if languages is True:
- languages = [lc for (lc, _ln) in settings.LANGUAGES]
- flush_ssi_includes([
- template % (self.pk, lang)
- for template in [
- '/api/include/tag/%d.%s.json',
- '/api/include/tag/%d.%s.xml',
- ]
- for lang in languages
- ])
- flush_ssi_includes([
- '/katalog/%s.json' % lang for lang in languages])
-
def __str__(self):
return self.name
from django.core.exceptions import ImproperlyConfigured
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
-from ssify import flush_ssi_includes
from newtagging.models import tags_updated
from picture.models import Picture, PictureArea
from .models import BookMedia, Book, Collection, Fragment, Tag
@receiver(post_save, sender=Collection)
def collection_save(sender, instance, **kwargs):
caches[settings.CACHE_MIDDLEWARE_ALIAS].clear()
- flush_ssi_includes([
- '/katalog/%s.json' % lang
- for lang in [lc for (lc, _ln) in settings.LANGUAGES]])
-@receiver(post_delete, sender=Collection)
-def collection_delete(sender, instance, **kwargs):
- flush_ssi_includes([
- '/katalog/%s.json' % lang
- for lang in [lc for (lc, _ln) in settings.LANGUAGES]])
-
####
# Book
####
caches['template_fragments'].clear()
except ImproperlyConfigured:
pass
- instance.flush_includes()
+ instance.clear_cache()
@receiver(post_delete, sender=Book)
def book_delete(sender, instance, **kwargs):
caches[settings.CACHE_MIDDLEWARE_ALIAS].clear()
- flush_ssi_includes([
- '/katalog/%s.json' % lang
- for lang in [lc for (lc, _ln) in settings.LANGUAGES]])
if not settings.NO_SEARCH_INDEX:
# remove the book from search index, when it is deleted.
@receiver(Tag.after_change)
-def tag_after_change(sender, instance, languages, **kwargs):
+def tag_after_change(sender, instance, **kwargs):
caches[settings.CACHE_MIDDLEWARE_ALIAS].clear()
- flush_ssi_includes([
- '/katalog/%s.json' % lang
- for lang in [lc for (lc, _ln) in settings.LANGUAGES]])
for model in Book, Picture:
for model_instance in model.tagged.with_all([instance]).only('pk'):
- model_instance.flush_includes()
+ model_instance.clear_cache()
if instance.category == 'author':
for model in Fragment, PictureArea:
for model_instance in model.tagged.with_all([instance]).only('pk'):
- model_instance.flush_includes()
+ model_instance.clear_cache()
@receiver(tags_updated)
return
caches[settings.CACHE_MIDDLEWARE_ALIAS].clear()
- instance.flush_includes()
- flush_ssi_includes([
- '/katalog/%s.json' % lang
- for lang in [lc for (lc, _ln) in settings.LANGUAGES]])
+ instance.clear_cache()
{% load i18n %}
{% load choose_fragment license_icon from catalogue_tags %}
{% load choose_cite from social_tags %}
-{% load ssi_include from ssify %}
{% block box-class %}book-wide-box{% endblock %}
{% block right-column %}
<div class="right-column">
<div class="quote">
- {% choose_cite book.pk as cite_promo %}
- {% choose_fragment book.pk unless=cite_promo as fragment_promo %}
- {{ cite_promo.if }}
- {% ssi_include 'social_cite' pk=cite_promo %}
- {{ cite_promo.endif }}
- {{ fragment_promo.if }}
- {% ssi_include 'catalogue_fragment_promo' pk=fragment_promo %}
- {{ fragment_promo.endif }}
+ {% choose_cite book as cite_promo %}
+ {% if cite_promo %}
+ {{ cite.promo_box }}
+ {% else %}
+ {% choose_fragment book as fragment_promo %}
+ {% if fragment_promo %}
+ {{ fragment_promo.promo_box }}
+ {% endif %}
+ {% endif %}
</div>
{% include 'catalogue/snippets/jplayer.html' %}
</div>
{% extends "base/base.html" %}
{% load i18n %}
{% load catalogue_tags %}
-{% load ssi_include from ssify %}
{% block titleextra %}{% trans "Collections" %}{% endblock %}
<h1>{% trans "Collections" %}</h1>
{% for obj in best %}
- {% ssi_include 'catalogue_collection_box' pk=obj.pk %}
+ {{ obj.box }}
{% endfor %}
<h2>{% trans "All collections" %}</h2>
{% if random %}
{% catalogue_random_book random_excluded_books as random_book %}
- {% picture_random_picture random_excluded_pics unless=random_book as random_pic %}
{% if random_book %}
{{ random_book.mini_box }}
- {% endif %}
- {% if random_pic %}
- {{ random_pic.mini_box }}
+ {% else %}
+ {% picture_random_picture random_excluded_pics as random_pic %}
+ {% if random_pic %}
+ {{ random_pic.mini_box }}
+ {% endif %}
{% endif %}
{% endif %}
{% endspaceless %}
{% load pagination_tags %}
{% load inline_tag_list from catalogue_tags %}
{% load book_searched from search_tags %}
-{% load ssi_include from ssify %}
{% block titleextra %}{% trans "Search" %}{% endblock %}
{% load likes_book from social_tags %}
-{% likes_book book.pk as likes %}
-<div class="star {{ likes.if }}{{ likes.else }}un{{ likes.endif }}like">
+{% likes_book book as likes %}
+<div class="star {% if not likes %}un{% endif %}like">
<div class="if-like" >
<a id="social-book-sets-{{ book.slug }}" data-callback='social-book-sets'
class='ajaxable' href='{% url "social_book_sets" book.slug %}'>★</a>
{% load pagination_tags %}
{% load class_name from catalogue_tags %}
{% load status from catalogue_tags %}
- {% load ssi_include from ssify %}
{% autopaginate object_list 10 %}
{% if item|class_name == 'Book' %}
{% include "catalogue/book_short.html" with book=item %}
{% else %}
- {% ssi_include item.short_html_url_name pk=item.pk %}
+ {{ item.midi_box }}
{% endif %}
</li>
{% endfor %}
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
-from ssify import ssi_variable
-
from catalogue.helpers import get_audiobook_tags
from catalogue.models import Book, BookMedia, Fragment, Tag, Source
from catalogue.constants import LICENSES
# @register.inclusion_tag('catalogue/tag_list.html')
def tag_list(tags, choices=None, category=None, list_type='books'):
- # print(tags, choices, category)
if choices is None:
choices = []
def catalogue_random_book(exclude_ids):
from .. import app_settings
if random() < app_settings.RELATED_RANDOM_PICTURE_CHANCE:
- print('yay, picture')
return None
queryset = Book.objects.exclude(pk__in=exclude_ids)
count = queryset.count()
return None
-@ssi_variable(register, patch_response=[add_never_cache_headers])
-def choose_fragment(request, book_id=None, tag_ids=None, unless=False):
- if unless:
- return None
-
- if book_id is not None:
- fragment = Book.objects.get(pk=book_id).choose_fragment()
+@register.simple_tag
+def choose_fragment(book=None, tag_ids=None):
+ if book is not None:
+ fragment = book.choose_fragment()
else:
if tag_ids is not None:
tags = Tag.objects.filter(pk__in=tag_ids)
fragments = Fragment.objects.all().order_by().only('id')
fragment_count = fragments.count()
fragment = fragments[randint(0, fragment_count - 1)] if fragment_count else None
- return fragment.pk if fragment is not None else None
+ return fragment
@register.filter
'default': {'BACKEND': 'django.core.cache.backends.dummy.DummyCache'},
},
SOLR=settings.SOLR_TEST,
- SSIFY_RENDER=False,
)
class WLTestCase(TestCase):
"""
'daisy/',
# 'autor/jane-doe/gatunek/genre/',
# 'autor/jane-doe/gatunek/genre/motyw/sielanka/',
- 'b/%d/short.pl.html' % self.book.pk,
- 'b/%d/wide.pl.html' % self.book.pk,
- 'f/%d/promo.pl.html' % self.book.fragments.all()[0].pk,
- 'f/%d/short.pl.html' % self.book.fragments.all()[0].pk,
],
404: [
'lektury/nonexistent/', # Nonexistent Collection.
'autor/nonexistent/', # Nonexistent author.
'motyw/nonexistent/', # Nonexistent theme.
'zh.json', # Nonexistent language.
- 'b/%d/short.pl.html' % (self.book.pk + 100), # Nonexistent book.
- 'b/%d/wide.pl.html' % (self.book.pk + 100), # Nonexistent book.
- 'f/%d/promo.pl.html' % (self.book.fragments.all()[0].pk + 100), # Nonexistent fragment.
- 'f/%d/short.pl.html' % (self.book.fragments.all()[0].pk + 100), # Nonexistent fragment.
]
}
prefix = '/katalog/'
url(r'^obraz/(?P<slug>%s).html$' % SLUG, picture.views.picture_viewer, name='picture_viewer'),
url(r'^obraz/(?P<slug>%s)/$' % SLUG, picture.views.picture_detail, name='picture_detail'),
- url(r'^p/(?P<pk>\d+)/short\.(?P<lang>.+)\.html', picture.views.picture_short, name='picture_short'),
- url(r'^pa/(?P<pk>\d+)/short\.(?P<lang>.+)\.html', picture.views.picturearea_short, name='picture_area_short'),
-
# old search page - redirected
url(r'^szukaj/$', RedirectView.as_view(
url='/szukaj/', query_string=True, permanent=True)),
url(r'^okladka-ridero/(?P<slug>%s).png$' % SLUG, views.ridero_cover),
url(r'^isbn/(?P<book_format>(pdf|epub|mobi|txt|html))/(?P<slug>%s)/' % SLUG, views.get_isbn),
- # Includes.
- url(r'^b/(?P<pk>\d+)/short\.(?P<lang>.+)\.html', views.book_short, name='catalogue_book_short'),
- url(r'^b/(?P<pk>\d+)/wide\.(?P<lang>.+)\.html', views.book_wide, name='catalogue_book_wide'),
- url(r'^f/(?P<pk>\d+)/promo\.(?P<lang>.+)\.html', views.fragment_promo, name='catalogue_fragment_promo'),
- url(r'^f/(?P<pk>\d+)/short\.(?P<lang>.+)\.html', views.fragment_short, name='catalogue_fragment_short'),
- url(r'^t/(?P<pk>\d+)/box\.(?P<lang>.+)\.html', views.tag_box, name='catalogue_tag_box'),
- url(r'^c/(?P<pk>.+)/box\.(?P<lang>.+)\.html', views.collection_box, name='catalogue_collection_box'),
-
# This should be the last pattern.
url(r'^galeria/(?P<tags>[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'gallery'},
name='tagged_object_list_gallery'),
from club.models import Membership
from pdcounter import views as pdcounter_views
from picture.models import Picture, PictureArea
-from ssify import ssi_included, ssi_expect, SsiVariable as Var
from catalogue import constants
from catalogue import forms
from catalogue.helpers import get_top_level_related_tags
return obj.pretty_title()
-####
-# Includes
-####
-
-
-@ssi_included(get_ssi_vars=lambda pk: (lambda ipk: (
- ('ssify.get_csrf_token',),
- ('social_tags.likes_book', (ipk,)),
- ('social_tags.book_shelf_tags', (ipk,)),
- ))(ssi_expect(pk, int)))
-def book_short(request, pk):
- book = get_object_or_404(Book, pk=pk)
-
- return render(request, 'catalogue/book_short.html', {
- 'book': book,
- })
-
-
-@ssi_included(
- get_ssi_vars=lambda pk: book_short.get_ssi_vars(pk) +
- (lambda ipk: (
- ('social_tags.choose_cite', [ipk]),
- ('catalogue_tags.choose_fragment', [ipk], {
- 'unless': Var('social_tags.choose_cite', [ipk])}),
- ))(ssi_expect(pk, int)))
-def book_wide(request, pk):
- book = get_object_or_404(Book, pk=pk)
-
- return render(request, 'catalogue/book_wide.html', {
- 'book': book,
- })
-
-
-@ssi_included
-def fragment_short(request, pk):
- fragment = get_object_or_404(Fragment, pk=pk)
- return render(request, 'catalogue/fragment_short.html', {'fragment': fragment})
-
-
-@ssi_included
-def fragment_promo(request, pk):
- fragment = get_object_or_404(Fragment, pk=pk)
- return render(request, 'catalogue/fragment_promo.html', {'fragment': fragment})
-
-
-@ssi_included
-def tag_box(request, pk):
- tag = get_object_or_404(Tag, pk=pk)
- assert tag.category != 'set'
-
- return render(request, 'catalogue/tag_box.html', {
- 'tag': tag,
- })
-
-
-@ssi_included
-def collection_box(request, pk):
- collection = get_object_or_404(Collection, pk=pk)
-
- return render(request, 'catalogue/collection_box.html', {
- 'collection': collection,
- })
-
-
def tag_catalogue(request, category):
if category == 'theme':
tags = Tag.objects.usage_for_model(
print('Notify end:', offer)
# The 'WL fund' list needs to be updated.
caches[settings.CACHE_MIDDLEWARE_ALIAS].clear()
- offer.flush_includes()
+ offer.clear_cache()
offer.notify_end()
current = Offer.current()
from django.utils.timezone import utc
from django.utils.translation import ugettext_lazy as _, override
import getpaid
-from ssify import flush_ssi_includes
from catalogue.models import Book
from catalogue.utils import get_random_hash
from polls.models import Poll
+from wolnelektury.utils import cached_render, clear_cached_renders
from . import app_settings
self.book_id is not None and self.pk is not None and
type(self).objects.values('book').get(pk=self.pk)['book'] != self.book_id)
retval = super(Offer, self).save(*args, **kw)
- self.flush_includes()
+ self.clear_cache()
if published_now:
self.notify_published()
return retval
- def flush_includes(self):
- flush_ssi_includes([
- template % (self.pk, lang)
- for template in [
- '/wesprzyj/o/%d/top-bar.%s.html',
- '/wesprzyj/o/%d/detail-bar.%s.html',
- '/wesprzyj/o/%d/list-bar.%s.html',
- '/wesprzyj/o/%d/status.%s.html',
- '/wesprzyj/o/%d/status-more.%s.html',
- ] + [
- '/wesprzyj/o/%%d/fundings/%d.%%s.html' % page
- for page in range(1, len(self.funding_payed()) // 10 + 2)
- ]
- for lang in [lc for (lc, _ln) in settings.LANGUAGES]
- ])
+ def clear_cache(self):
+ clear_cached_renders(self.top_bar)
+ clear_cached_renders(self.list_bar)
+ clear_cached_renders(self.detail_bar)
+ clear_cached_renders(self.status)
+ clear_cached_renders(self.status_more)
def is_current(self):
return self.start <= date.today() <= self.end and self == self.current()
'current': self.current(),
})
+ def basic_info(self):
+ offer_sum = self.sum()
+ return {
+ 'offer': self,
+ 'sum': offset_sum,
+ 'is_current': self.is_current(),
+ 'is_win': offer_sum >= self.target,
+ 'missing': self.target - offer_sum,
+ 'percentage': 100 * offer_sum / self.target,
+
+ 'show_title': True,
+ 'show_title_calling': True,
+ }
+
+ @cached_render('funding/includes/funding.html')
+ def top_bar(self):
+ ctx = self.basic_info()
+ ctx.update({
+ 'link': True,
+ 'closeable': True,
+ 'add_class': 'funding-top-header',
+ })
+ return ctx
+
+ @cached_render('funding/includes/funding.html')
+ def list_bar(self):
+ ctx = self.basic_info()
+ ctx.update({
+ 'link': True,
+ 'show_title_calling': False,
+ })
+ return ctx
+
+ @cached_render('funding/includes/funding.html')
+ def detail_bar(self):
+ ctx = self.basic_info()
+ ctx.update({
+ 'show_title': False,
+ })
+ return ctx
+
+ @cached_render('funding/includes/offer_status.html')
+ def status(self):
+ return {'offer': self}
+
+ @cached_render('funding/includes/offer_status_more.html')
+ def status_more(self):
+ return {'offer': self}
+
class Perk(models.Model):
""" A perk offer.
if self.email and not self.notify_key:
self.notify_key = get_random_hash(self.email)
ret = super(Funding, self).save(*args, **kwargs)
- self.offer.flush_includes()
+ self.offer.clear_cache()
return ret
@classmethod
{% load fnp_share %}
{% load thumbnail %}
{% load build_absolute_uri from fnp_common %}
-{% load ssi_include from ssify %}
+{% load fundings from funding_tags %}
{% block titleextra %}{{ object }}{% endblock %}
{% block body %}
<h1>{{ object }}</h1>
- {% ssi_include 'funding_detail_bar' pk=object.pk %}
+ {{ object.detail_bar }}
<div class="white-box">
<div class="funding-details-intro">
{% if object.cover %}
<div class="normal-text">
<h3>{% trans "Help free the book!" %}</h3>
{{ object.description|safe }}
- {% ssi_include 'funding_status' pk=object.pk %}
+ {{ object.status }}
<a href='//nowoczesnapolska.org.pl/pomoz-nam/wesprzyj-nas/' target="_blank" style='float:right;border:1px solid #ddd;padding: 1em;margin:0 0 1em 1em;background:#eee;'><img src='//nowoczesnapolska.org.pl/wp-content/themes/koed/annoy/procent.png' alt='1%' style='float:left;margin-right: 1em;margin-top:.2em;'>Możesz też przekazać<br/>1% podatku na rozwój biblioteki. →</a>
- {% ssi_include 'funding_status_more' pk=object.pk %}
+ {{ object.status_more }}
<p><a href="{% url 'infopage' 'wesprzyj' %}">{% trans "Learn more" %}</a>.</p>
</div>
<h2>{% trans "Supporters" %}:</h2>
<div class="white-box normal-text">
- {% ssi_include 'funding_fundings' pk=object.pk page=page %}
+ {% fundings object %}
</div>
{% endblock %}
{% extends "base/base.html" %}
{% load i18n %}
-{% load ssi_include from ssify %}
{% load pagination_tags %}
{% block titleextra %}{% trans "All fundraisers" %}{% endblock %}
<h2>{% trans "Previous fundraisers:" %}</h2>
{% endif %}
- {% ssi_include 'funding_list_bar' pk=offer.pk %}
+ {{ offer.list_bar }}
<div class="white-box normal-text">
{% if is_current %}
<h3>{% trans "Help free the book!" %}</h3>
{{ offer.description|safe }}
{% endif %}
- {% ssi_include 'funding_status' pk=offer.pk %}
- {% ssi_include 'funding_status_more' pk=offer.pk %}
+ {{ offer.status }}
+ {{ offer.status_more }}
</div>
{% if is_current and not forloop.last %}
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from django import template
-from ssify import ssi_variable
-from ssify.utils import ssi_cache_control
+from django.template.loader import render_to_string
+from django.core.paginator import Paginator, InvalidPage
from ..models import Offer
from ..utils import sanitize_payment_title
-from ..views import offer_bar
+
register = template.Library()
-@ssi_variable(register, patch_response=[ssi_cache_control(must_revalidate=True, max_age=0)])
-def current_offer(request=None):
+@register.simple_tag
+def funding_top_bar():
offer = Offer.current()
- return offer.pk if offer is not None else None
+ return offer.top_bar() if offer is not None else ''
-@register.inclusion_tag('funding/includes/funding.html')
-def funding_top_bar():
- return offer_bar(Offer.current(), link=True, closeable=True, add_class="funding-top-header")
+register.filter(sanitize_payment_title)
-register.filter(sanitize_payment_title)
+@register.simple_tag(takes_context=True)
+def fundings(context, offer):
+ fundings = offer.funding_payed()
+ page = context['request'].GET.get('page', 1)
+ paginator = Paginator(fundings, 10, 2)
+ try:
+ page_obj = paginator.page(int(page))
+ except InvalidPage:
+ return ''
+ else:
+ return render_to_string("funding/includes/fundings.html", {
+ "paginator": paginator,
+ "page_obj": page_obj,
+ "fundings": page_obj.object_list,
+ })
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
url(r'^wylacz_email/$', views.DisableNotifications.as_view(), name='funding_disable_notifications'),
url(r'^getpaid/', include('getpaid.urls')),
-
- # Includes
- url(r'^o/(?P<pk>\d+)/top-bar\.(?P<lang>.+)\.html$', views.top_bar, name='funding_top_bar'),
- url(r'^o/(?P<pk>\d+)/detail-bar\.(?P<lang>.+)\.html$', views.detail_bar, name='funding_detail_bar'),
- url(r'^o/(?P<pk>\d+)/list-bar\.(?P<lang>.+)\.html$', views.list_bar, name='funding_list_bar'),
- url(r'^o/(?P<pk>\d+)/status\.(?P<lang>.+)\.html$', views.offer_status, name='funding_status'),
- url(r'^o/(?P<pk>\d+)/status-more\.(?P<lang>.+)\.html$', views.offer_status_more, name='funding_status_more'),
- url(r'^o/(?P<pk>\d+)/fundings/(?P<page>\d+)\.(?P<lang>.+)\.html$', views.offer_fundings, name='funding_fundings'),
]
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from django.core.paginator import Paginator, InvalidPage
from django.http import Http404
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import TemplateView, FormView, ListView
from getpaid.models import Payment
-from ssify import ssi_included
-from ssify.utils import ssi_cache_control
from . import app_settings
from .forms import FundingForm
from .models import Offer, Spent, Funding
def get_context_data(self, **kwargs):
ctx = super(OfferDetailView, self).get_context_data(**kwargs)
ctx['object'] = self.object
- ctx['page'] = self.request.GET.get('page', 1)
if self.object.is_current():
ctx['funding_no_show_current'] = True
return ctx
def post(self, *args, **kwargs):
self.object.disable_notifications()
return redirect(self.request.get_full_path())
-
-
-def offer_bar(offer, link=False, closeable=False, show_title=True, show_title_calling=True, add_class=""):
- if offer:
- offer_sum = offer.sum()
- else:
- return {}
- return {
- 'offer': offer,
- 'sum': offer_sum,
- 'is_current': offer.is_current(),
- 'is_win': offer_sum >= offer.target,
- 'missing': offer.target - offer_sum,
- 'percentage': 100 * offer_sum / offer.target,
- 'link': link,
- 'closeable': closeable,
- 'show_title': show_title,
- 'show_title_calling': show_title_calling,
- 'add_class': add_class,
- }
-
-
-def render_offer_bar(request, pk, link=False, closeable=False, show_title=True, show_title_calling=True, add_class=""):
- offer = get_object_or_404(Offer, pk=pk)
- return render(request, "funding/includes/funding.html",
- offer_bar(offer, link, closeable, show_title, show_title_calling, add_class))
-
-
-@ssi_included(patch_response=[ssi_cache_control(must_revalidate=True)])
-def top_bar(request, pk):
- return render_offer_bar(request, pk, link=True, closeable=True, add_class="funding-top-header")
-
-
-@ssi_included(patch_response=[ssi_cache_control(must_revalidate=True)])
-def list_bar(request, pk):
- return render_offer_bar(request, pk, link=True, show_title_calling=False)
-
-
-@ssi_included(patch_response=[ssi_cache_control(must_revalidate=True)])
-def detail_bar(request, pk):
- return render_offer_bar(request, pk, show_title=False)
-
-
-@ssi_included(patch_response=[ssi_cache_control(must_revalidate=True)])
-def offer_status(request, pk):
- offer = get_object_or_404(Offer, pk=pk)
- return render(request, "funding/includes/offer_status.html", {'offer': offer})
-
-
-@ssi_included(patch_response=[ssi_cache_control(must_revalidate=True)])
-def offer_status_more(request, pk):
- offer = get_object_or_404(Offer, pk=pk)
- return render(request, "funding/includes/offer_status_more.html", {'offer': offer})
-
-
-@ssi_included(patch_response=[ssi_cache_control(must_revalidate=True)])
-def offer_fundings(request, pk, page):
- offer = get_object_or_404(Offer, pk=pk)
- fundings = offer.funding_payed()
- paginator = Paginator(fundings, 10, 2)
- try:
- page_obj = paginator.page(int(page))
- except InvalidPage:
- raise Http404
- return render(request, "funding/includes/fundings.html", {
- "paginator": paginator,
- "page_obj": page_obj,
- "fundings": page_obj.object_list,
- })
from django.core.files.storage import FileSystemStorage
from django.urls import reverse
from slugify import slugify
-from ssify import flush_ssi_includes
from catalogue.models.tag import prefetched_relations
from catalogue.utils import split_tags
pa.area = coords
return pa
- def flush_includes(self, languages=True):
- if not languages:
- return
- if languages is True:
- languages = [lc for (lc, _ln) in settings.LANGUAGES]
- flush_ssi_includes([
- template % (self.pk, lang)
- for template in [
- '/katalog/pa/%d/short.%s.html',
- ]
- for lang in languages
- ])
+ @cached_render('picture/picturearea_short.html')
+ def midi_box(self):
+ themes = self.tags.filter(category='theme')
+ things = self.tags.filter(category='thing')
+ return {
+ 'area': self,
+ 'theme': themes[0] if themes else None,
+ 'thing': things[0] if things else None,
+ }
+
+ def clear_cache(self):
+ clear_cached_renders(self.midi_box)
class Picture(models.Model):
'picture': self,
}
+ @cached_render('picture/picture_short.html')
+ def midi_box(self):
+ return {
+ 'picture': self,
+ }
+
def related_themes(self):
return catalogue.models.Tag.objects.usage_for_queryset(
self.areas.all(), counts=True).filter(category__in=('theme', 'thing'))
- def flush_includes(self, languages=True):
+ def clear_cache(self):
clear_cached_renders(self.mini_box)
- if not languages:
- return
- if languages is True:
- languages = [lc for (lc, _ln) in settings.LANGUAGES]
- flush_ssi_includes([
- template % (self.pk, lang)
- for template in [
- '/katalog/p/%d/short.%s.html',
- '/katalog/p/%d/mini.%s.html',
- ]
- for lang in languages
- ])
+ clear_cached_renders(self.midi_box)
def search_index(self, picture_info=None, index=None, index_tags=True, commit=True):
if index is None:
{% load static from staticfiles %}
{% load catalogue_tags %}
{% load thumbnail %}
-{% load ssi_include from ssify %}
{% block title %}{{ picture.pretty_title }}{% endblock %}
@register.simple_tag
-def picture_random_picture(exclude_ids, unless=None):
- if unless:
- return None
+def picture_random_picture(exclude_ids):
queryset = Picture.objects.exclude(pk__in=exclude_ids).exclude(image_file='')
count = queryset.count()
if count:
from django.conf import settings
from django.contrib.auth.decorators import permission_required
from django.shortcuts import render, get_object_or_404, render
-from picture.models import Picture, PictureArea
+from picture.models import Picture
from catalogue.utils import split_tags
-from ssify import ssi_included
from sponsors.models import Sponsor
from wolnelektury.utils import ajax
return HttpResponse(_("Picture imported successfully"))
else:
return HttpResponse(_("Error importing file: %r") % import_form.errors)
-
-
-@ssi_included
-def picture_short(request, pk):
- picture = get_object_or_404(Picture, pk=pk)
-
- return render(request, 'picture/picture_short.html', {
- 'picture': picture,
- })
-
-
-@ssi_included
-def picturearea_short(request, pk):
- area = get_object_or_404(PictureArea, pk=pk)
- themes = area.tags.filter(category='theme')
- things = area.tags.filter(category='thing')
- return render(request, 'picture/picturearea_short.html', {
- 'area': area,
- 'theme': themes[0] if themes else None,
- 'thing': things[0] if things else None,
- })
from django.core.exceptions import ValidationError
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _, string_concat
-from ssify import flush_ssi_includes
from catalogue.models import Book
+from wolnelektury.utils import cached_render, clear_cached_renders
class BannerGroup(models.Model):
def save(self, *args, **kwargs):
ret = super(Cite, self).save(*args, **kwargs)
- self.flush_includes()
+ self.clear_cache()
return ret
- def flush_includes(self):
- flush_ssi_includes([
- template % (self.pk, lang)
- for template in [
- '/ludzie/cite/%s.%s.html',
- '/ludzie/cite_main/%s.%s.html',
- ]
- for lang in [lc for (lc, _ln) in settings.LANGUAGES]] +
- ['/ludzie/cite_info/%s.html' % self.pk])
+ @cached_render('social/cite_promo.html')
+ def main_box(self):
+ return {
+ 'cite': self,
+ 'main': True,
+ }
+
+ def clear_cache(self):
+ clear_cached_renders(self.main_box)
class Carousel(models.Model):
{% for banner in banners %}
{% if banner %}
- {% include 'social/cite_promo.html' with cite=banner main=True %}
+ {{ banner.main_box }}
{% endif %}
{% endfor %}
</div>
from django.utils.functional import lazy
from django.utils.cache import add_never_cache_headers
from catalogue.models import Book
-from ssify import ssi_variable
-from ssify.utils import ssi_vary_on_cookie
from social.utils import likes, get_or_choose_cite
from ..models import Carousel, Cite
register = template.Library()
-@ssi_variable(register, patch_response=[ssi_vary_on_cookie])
-def likes_book(request, book_id):
- return likes(request.user, Book.objects.get(pk=book_id), request)
-
-
-@ssi_variable(register, name='choose_cite', patch_response=[add_never_cache_headers])
-def choose_cite_tag(request, book_id=None, tag_ids=None):
- cite = get_or_choose_cite(request, book_id, tag_ids)
- return cite.pk if cite is not None else None
+@register.simple_tag(takes_context=True)
+def likes_book(context, book):
+ request = context['request']
+ return likes(request.user, book, request)
-@register.inclusion_tag('social/cite_promo.html')
-def render_cite(cite):
- return {
- 'cite': cite,
- }
+@register.simple_tag(takes_context=True)
+def choose_cite(context, book_id=None, tag_ids=None):
+ request = context['request']
+ return get_or_choose_cite(request, book_id, tag_ids)
-@ssi_variable(register, patch_response=[ssi_vary_on_cookie])
-def book_shelf_tags(request, book_id):
+@register.simple_tag(takes_context=True)
+def book_shelf_tags(context, book_id):
+ request = context['request']
if not request.user.is_authenticated():
return ''
book = Book.objects.get(pk=book_id)
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
url(r'^lektura/(?P<slug>[a-z0-9-]+)/nie_lubie/$', views.unlike_book, name='social_unlike_book'),
url(r'^lektura/(?P<slug>[a-z0-9-]+)/polki/$', never_cache(views.ObjectSetsFormView()), name='social_book_sets'),
url(r'^polka/$', views.my_shelf, name='social_my_shelf'),
-
- # Includes
- url(r'^cite/(?P<pk>\d+)\.(?P<lang>.+)\.html$', views.cite, name='social_cite'),
- url(r'^cite_main/(?P<pk>\d+)\.(?P<lang>.+)\.html$', views.cite, {'main': True}, name='social_cite_main'),
- url(r'^cite_info/(?P<pk>\d+).html$', views.cite_info, name='social_cite_info'),
]
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from ajaxable.utils import AjaxableFormView
from catalogue.models import Book
-from ssify import ssi_included
from social import forms
-from .models import Cite
# ====================
def form_args(self, request, obj):
return (obj, request.user), {}
-
-
-@ssi_included
-def cite(request, pk, main=False):
- cite = get_object_or_404(Cite, pk=pk)
- return render(request, 'social/cite_promo.html', {
- 'main': main,
- 'cite': cite,
- })
-
-
-@ssi_included(use_lang=False)
-def cite_info(request, pk):
- cite = get_object_or_404(Cite, pk=pk)
- return render(request, 'social/cite_info.html', {
- 'cite': cite,
- })
'fnpdjango',
'getpaid',
'getpaid.backends.payu',
- 'ssify',
'django_extensions',
'raven.contrib.django.raven_compat',
'club.apps.ClubConfig',
MIDDLEWARE_CLASSES = [
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
- 'ssify.middleware.SsiMiddleware',
'django.middleware.cache.UpdateCacheMiddleware',
- 'ssify.middleware.PrepareForCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.admindocs.middleware.XViewMiddleware',
'fnp_django_pagination.middleware.PaginationMiddleware',
- 'ssify.middleware.LocaleMiddleware',
+ 'django.middleware.locale.LocaleMiddleware',
'maintenancemode.middleware.MaintenanceModeMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'127.0.0.1:11211',
]
},
- 'ssify': {
- 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
- 'TIMEOUT': None,
- 'KEY_PREFIX': 'ssify',
- 'LOCATION': [
- '127.0.0.1:11211',
- ],
- },
'template_fragments': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'TIMEOUT': 86400,
to just flush the cache on those instances.
If changes become too often, relevant bits should be separated
- as ssi_included views and flushed individually when needed.
+ and cached and flushed individually when needed.
"""
if sender in (Catalog, Library, InfoPage, Author, BookStub, Spent):
{% extends "base/base.html" %}
+{% load latest_blog_posts from blog %}
{% load carousel from social_tags %}
{% load static from staticfiles %}
{% load i18n catalogue_tags infopages_tags %}
-{% load ssi_include from ssify %}
{% load cache %}
{% load funding_tags %}
{% get_current_language as LANGUAGE_CODE %}
{% if collection %}
<section>
<h1>{% trans "Collections" %}</h1>
- {% cache 3600 collection_box collection.pk LANGUAGE_CODE %}
- {% include 'catalogue/collection_box.html' %}
- {% endcache %}
+ {{ collection.box }}
<a class="more" href="{% url 'catalogue_collections' %}">{% trans "See collections catalog" %}</a>
</section>
{% endif %}
<section class="infopages-box">
<h1>{% trans "News" %}</h1>
- {% ssi_include 'latest_blog_posts' %}
+ {% cache 1800 latest_blog_posts %}
+ {% latest_blog_posts %}
+ {% endcache %}
</section>
<section class="infopages-box">
--- /dev/null
+from datetime import date
+from django.conf import settings
+from django.template import Library
+import feedparser
+
+
+register = Library()
+
+
+@register.inclusion_tag('latest_blog_posts.html')
+def latest_blog_posts(feed_url=None, posts_to_show=5):
+ if feed_url is None:
+ feed_url = settings.LATEST_BLOG_POSTS
+ posts = []
+ try:
+ feed = feedparser.parse(str(feed_url))
+ for i in range(posts_to_show):
+ pub_date = feed['entries'][i].published_parsed
+ published = date(pub_date[0], pub_date[1], pub_date[2])
+ posts.append({
+ 'title': feed['entries'][i].title,
+ 'summary': feed['entries'][i].summary,
+ 'link': feed['entries'][i].link,
+ 'date': published,
+ })
+ except:
+ pass
+ return {
+ 'posts': posts
+ }
url(r'^uzytkownik/logout/$', views.logout_then_redirect, name='logout'),
url(r'^uzytkownik/zaloguj-utworz/$', views.LoginRegisterFormView(), name='login_register'),
url(r'^uzytkownik/social/signup/$', views.SocialSignupView.as_view(), name='socialaccount_signup'),
-
- # Includes.
- url(r'^latests_blog_posts.html$', views.latest_blog_posts, name='latest_blog_posts'),
]
urlpatterns += [
from ajaxable.utils import AjaxableFormView
from ajaxable.utils import placeholdized
from catalogue.models import Book, Collection, Tag, Fragment
-from ssify import ssi_included
from social.utils import get_or_choose_cite
from wolnelektury.forms import RegistrationForm, SocialSignupForm
return render(request, "user.html")
-@ssi_included(use_lang=False, timeout=1800)
-def latest_blog_posts(request, feed_url=None, posts_to_show=5):
- if feed_url is None:
- feed_url = settings.LATEST_BLOG_POSTS
- try:
- feed = feedparser.parse(str(feed_url))
- posts = []
- for i in range(posts_to_show):
- pub_date = feed['entries'][i].published_parsed
- published = date(pub_date[0], pub_date[1], pub_date[2])
- posts.append({
- 'title': feed['entries'][i].title,
- 'summary': feed['entries'][i].summary,
- 'link': feed['entries'][i].link,
- 'date': published,
- })
- except:
- posts = []
- return render(request, 'latest_blog_posts.html', {'posts': posts})
-
-
-@ssi_included(use_lang=False)
def widget(request):
return render(request, 'widget.html')