From: Radek Czajka Date: Thu, 19 Jan 2012 14:46:10 +0000 (+0100) Subject: Merge branch 'pretty' of github.com:fnp/wolnelektury into pretty X-Git-Url: https://git.mdrn.pl/wolnelektury.git/commitdiff_plain/276656dcc680e1a35103d310dea046152ddc3785?ds=inline;hp=-c Merge branch 'pretty' of github.com:fnp/wolnelektury into pretty Conflicts: wolnelektury/static/css/book_box.css wolnelektury/templates/catalogue/book_wide.html --- 276656dcc680e1a35103d310dea046152ddc3785 diff --combined apps/catalogue/models.py index 1f6210d20,3ccdcadeb..ebecc36b4 --- a/apps/catalogue/models.py +++ b/apps/catalogue/models.py @@@ -7,7 -7,7 +7,7 @@@ from collections import namedtupl from django.db import models from django.db.models import permalink, Q import django.dispatch -from django.core.cache import cache +from django.core.cache import get_cache from django.core.files.storage import DefaultStorage from django.utils.translation import ugettext_lazy as _ from django.contrib.auth.models import User @@@ -17,7 -17,6 +17,7 @@@ from django.utils.safestring import mar from django.utils.translation import get_language from django.core.urlresolvers import reverse from django.db.models.signals import post_save, m2m_changed, pre_delete +import jsonfield from django.conf import settings @@@ -31,6 -30,7 +31,6 @@@ from glob import glo import re from os import path - import search # Those are hard-coded here so that makemessages sees them. @@@ -44,8 -44,8 +44,8 @@@ TAG_CATEGORIES = ('book', _('book')), ) -# not quite, but Django wants you to set a timeout -CACHE_FOREVER = 2419200 # 28 days + +permanent_cache = get_cache('permanent') class TagSubcategoryManager(models.Manager): @@@ -372,9 -372,6 +372,9 @@@ class Book(models.Model) formats = ebook_formats + ['html', 'xml'] parent = models.ForeignKey('self', blank=True, null=True, related_name='children') + + _related_info = jsonfield.JSONField(blank=True, null=True, editable=False) + objects = models.Manager() tagged = managers.ModelTaggedItemManager(Tag) tags = managers.TagDescriptor(Tag) @@@ -453,11 -450,58 +453,11 @@@ if self.id is None: return - cache_key = "Book.short_html/%d/%s" - for lang, langname in settings.LANGUAGES: - cache.delete(cache_key % (self.id, lang)) - cache.delete("Book.mini_box/%d" % (self.id, )) + type(self).objects.filter(pk=self.pk).update(_related_info=None) # Fragment.short_html relies on book's tags, so reset it here too for fragm in self.fragments.all(): fragm.reset_short_html() - def short_html(self): - if self.id: - cache_key = "Book.short_html/%d/%s" % (self.id, get_language()) - short_html = cache.get(cache_key) - else: - short_html = None - - if short_html is not None: - return mark_safe(short_html) - else: - tags = self.tags.filter(category__in=('author', 'kind', 'genre', 'epoch')) - tags = split_tags(tags) - - formats = {} - # files generated during publication - for ebook_format in self.ebook_formats: - if self.has_media(ebook_format): - formats[ebook_format] = self.get_media(ebook_format) - - - short_html = unicode(render_to_string('catalogue/book_short.html', - {'book': self, 'tags': tags, 'formats': formats})) - - if self.id: - cache.set(cache_key, short_html, CACHE_FOREVER) - return mark_safe(short_html) - - def mini_box(self): - if self.id: - cache_key = "Book.mini_box/%d" % (self.id, ) - short_html = cache.get(cache_key) - else: - short_html = None - - if short_html is None: - authors = self.tags.filter(category='author') - - short_html = unicode(render_to_string('catalogue/book_mini_box.html', - {'book': self, 'authors': authors, 'STATIC_URL': settings.STATIC_URL})) - - if self.id: - cache.set(cache_key, short_html, CACHE_FOREVER) - return mark_safe(short_html) - def has_description(self): return len(self.description) > 0 has_description.short_description = _('description') @@@ -748,7 -792,8 +748,8 @@@ book.build_mobi() if not settings.NO_SEARCH_INDEX and search_index: - index_book.delay(book.id, book_info) + book.search_index() + #index_book.delay(book.id, book_info) book_descendants = list(book.children.all()) descendants_tags = set() @@@ -774,30 -819,12 +775,30 @@@ cls.published.send(sender=book) return book + def related_info(self): + """Keeps info about related objects (tags, media) in cache field.""" + if self._related_info is not None: + return self._related_info + else: + rel = {'tags': {}, 'media': {}} + tags = self.tags.filter(category__in=( + 'author', 'kind', 'genre', 'epoch')) + tags = split_tags(tags) + for category in tags: + rel['tags'][category] = [ + (t.name, t.get_absolute_url()) for t in tags[category]] + for media_format in BookMedia.formats: + rel['media'][media_format] = self.has_media(media_format) + if self.pk: + type(self).objects.filter(pk=self.pk).update(_related_info=rel) + return rel + def reset_tag_counter(self): if self.id is None: return cache_key = "Book.tag_counter/%d" % self.id - cache.delete(cache_key) + permanent_cache.delete(cache_key) if self.parent: self.parent.reset_tag_counter() @@@ -805,7 -832,7 +806,7 @@@ def tag_counter(self): if self.id: cache_key = "Book.tag_counter/%d" % self.id - tags = cache.get(cache_key) + tags = permanent_cache.get(cache_key) else: tags = None @@@ -818,7 -845,7 +819,7 @@@ tags[tag.pk] = 1 if self.id: - cache.set(cache_key, tags, CACHE_FOREVER) + permanent_cache.set(cache_key, tags) return tags def reset_theme_counter(self): @@@ -826,7 -853,7 +827,7 @@@ return cache_key = "Book.theme_counter/%d" % self.id - cache.delete(cache_key) + permanent_cache.delete(cache_key) if self.parent: self.parent.reset_theme_counter() @@@ -834,7 -861,7 +835,7 @@@ def theme_counter(self): if self.id: cache_key = "Book.theme_counter/%d" % self.id - tags = cache.get(cache_key) + tags = permanent_cache.get(cache_key) else: tags = None @@@ -845,7 -872,7 +846,7 @@@ tags[tag.pk] = tags.get(tag.pk, 0) + 1 if self.id: - cache.set(cache_key, tags, CACHE_FOREVER) + permanent_cache.set(cache_key, tags) return tags def pretty_title(self, html_links=False): @@@ -977,12 -1004,12 +978,12 @@@ class Fragment(models.Model) cache_key = "Fragment.short_html/%d/%s" for lang, langname in settings.LANGUAGES: - cache.delete(cache_key % (self.id, lang)) + permanent_cache.delete(cache_key % (self.id, lang)) def short_html(self): if self.id: cache_key = "Fragment.short_html/%d/%s" % (self.id, get_language()) - short_html = cache.get(cache_key) + short_html = permanent_cache.get(cache_key) else: short_html = None @@@ -992,28 -1019,10 +993,28 @@@ short_html = unicode(render_to_string('catalogue/fragment_short.html', {'fragment': self})) if self.id: - cache.set(cache_key, short_html, CACHE_FOREVER) + permanent_cache.set(cache_key, short_html) return mark_safe(short_html) +class Collection(models.Model): + """A collection of books, which might be defined before publishing them.""" + title = models.CharField(_('title'), max_length=120, db_index=True) + slug = models.SlugField(_('slug'), max_length=120, primary_key=True) + description = models.TextField(_('description'), null=True, blank=True) + + models.SlugField(_('slug'), max_length=120, unique=True, db_index=True) + book_slugs = models.TextField(_('book slugs')) + + class Meta: + ordering = ('title',) + verbose_name = _('collection') + verbose_name_plural = _('collections') + + def __unicode__(self): + return self.title + + ########### # # SIGNALS diff --combined wolnelektury/static/css/book_box.css index b816fc01a,273cde5f1..ca58a634e --- a/wolnelektury/static/css/book_box.css +++ b/wolnelektury/static/css/book_box.css @@@ -1,8 -1,5 +1,8 @@@ -.book-wide-box, .book-mini-box, .book-box { +.book-mini-box, .Book-item { display: inline-block; +} + +.book-wide-box, .book-box { margin: 0; vertical-align: top; } @@@ -18,14 -15,28 +18,28 @@@ .book-wide-box { width: 98.5em; + + /** This is a fullpage box, it must be aligned with the top menu. + This corresponds to a .1em margin below **/ margin-left: -0.1em; } + /* + * A mini-box wraps it's contents (image + label) in an + * other boxes have an inner box as a wrapper. + */ + + .book-box-inner { + /* min, so it can grow */ + min-height: 19.75em; + margin: .5em; + } + .book-mini-box a, .book-box-inner { display: block; color: black; border: 1px solid #ddd; - height: 20em; + /* height: 20em; */ padding: .8em 1em; margin: .1em; background: #fff; @@@ -39,15 -50,17 +53,17 @@@ margin: .1em; overflow: hidden; } - .book-box-inner { - height: 19.75em; - margin: .5em; - } + .book-wide-box .book-box-inner { - height: 24.4em; + /* min, so it can grow */ + min-height: 24.4em; } + /*.book-wide-box.search-result .book-box-inner, .book-wide-box.search-result blockquote { + height: auto !important; + }*/ + .book-mini-box img, .book-box img, .book-wide-box img { width: 13.9em; height: 19.3em; @@@ -77,7 -90,6 +93,7 @@@ .book-box-body { height: 17em; overflow: hidden; + position: relative; } .book-wide-box .book-box-body { @@@ -149,22 -161,12 +165,22 @@@ margin-left: 14em; } -.book-box-tools a.downarrow:before { +.book-box-read a:before { content: "\2609"; font-family: WL-Nav; font-size: 2.25em; margin-right: .15em; vertical-align: middle; + font-weight: normal; +} + +.book-box-download a:before { + content: "\21E9"; + font-family: WL-Nav; + font-size: 2.25em; + margin-right: .15em; + vertical-align: middle; + font-weight: normal; } .book-box-audiobook a:before { @@@ -173,7 -175,6 +189,7 @@@ font-size: 2.25em; margin-right: .15em; vertical-align: middle; + font-weight: normal; } ul.book-box-tools { @@@ -212,10 -213,16 +228,16 @@@ vertical-align: center; } - .book-wide-box blockquote div { + .book-wide-box blockquote div.cite-text { padding: 0.888em; } + .book-wide-box blockquote p.cite-more { + display: inline; + font-size: 0.611em; + float: right; + } + ul.inline-items, ul.inline-items li { margin: 0; padding: 0; @@@ -225,52 -232,20 +247,54 @@@ ul.inline-items li display: inline-block; } - .book-wide-box #other-tools { + .book-wide-box .other-tools { float: left; width: 14.5em; margin: 6em 0 0 1.5em; } - .book-wide-box #other-download { + .book-wide-box .other-download { float: left; width: 22.5em; - margin: 6em 1.5em 0em 1.5em + margin: 6em 1.5em 0em 1.5em; } + - - +.star { + font-size: 2.25em; + margin-right: .5em; + position: absolute; + right: 0; +} +.star button::-moz-focus-inner { + padding: 0; + border: 0 +} +.if-unlike button { + font-size: 1em; + font-family: inherit; + border: 0; + background: none; + margin: 0; + padding: 0; +} + +.if-like a { + display:block; + text-align:right; + padding: 0; +} + +.like .if-unlike { + display: none; +} + +.unlike .if-like { + display: none; +} + + .snippets .snippet-text { + font-size: 1.2em; + margin: 1.083em 0em; -} ++} diff --combined wolnelektury/templates/catalogue/book_wide.html index a13f1a634,bbdd333e9..cd52ff182 --- a/wolnelektury/templates/catalogue/book_wide.html +++ b/wolnelektury/templates/catalogue/book_wide.html @@@ -6,12 -6,13 +6,13 @@@ {% block right-column %}
+ {% block quote %}
Ten, który walczy z potworami powinien zadbać, by sam nie stał się potworem. Gdy długo spoglądamy w otchłań, otchłań spogląda również w nas.
+ {% endblock %}
- -
+

{% trans "See" %}

    {% if extra_info.source_url %} @@@ -28,14 -29,14 +29,14 @@@ {% endif %}
-
+

{% trans "Download" %}