From: Radek Czajka Date: Fri, 3 Feb 2012 14:07:51 +0000 (+0100) Subject: cover previews X-Git-Url: https://git.mdrn.pl/redakcja.git/commitdiff_plain/0da29a22a23a90561df3d201a299f3007c84d524?hp=1019e504d3ffa1edc034428d5e3b5cbf7bd2fc4f cover previews --- diff --git a/apps/catalogue/templates/catalogue/book_detail.html b/apps/catalogue/templates/catalogue/book_detail.html index bfd4ef5c..077ec475 100755 --- a/apps/catalogue/templates/catalogue/book_detail.html +++ b/apps/catalogue/templates/catalogue/book_detail.html @@ -41,6 +41,8 @@

{% trans "Publication" %}

+ +

{% trans "Last published" %}: {% if book.last_published %} {{ book.last_published }} @@ -79,6 +81,7 @@

{% endif %} +
diff --git a/apps/catalogue/urls.py b/apps/catalogue/urls.py index 3ea7ffe5..9bd56bbe 100644 --- a/apps/catalogue/urls.py +++ b/apps/catalogue/urls.py @@ -32,6 +32,7 @@ urlpatterns = patterns('catalogue.views', url(r'^book/(?P[^/]+)/html$', 'book_html', name="catalogue_book_html"), url(r'^book/(?P[^/]+)/epub$', 'book_epub', name="catalogue_book_epub"), url(r'^book/(?P[^/]+)/pdf$', 'book_pdf', name="catalogue_book_pdf"), + url(r'^chunk_add/(?P[^/]+)/(?P[^/]+)/$', 'chunk_add', name="catalogue_chunk_add"), url(r'^chunk_edit/(?P[^/]+)/(?P[^/]+)/$', diff --git a/apps/cover/__init__.py b/apps/cover/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/cover/models.py b/apps/cover/models.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/cover/urls.py b/apps/cover/urls.py new file mode 100644 index 00000000..24d7448a --- /dev/null +++ b/apps/cover/urls.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 +from django.conf.urls.defaults import patterns, url + + +urlpatterns = patterns('cover.views', + url(r'^preview/$', 'preview_from_xml', name='cover_preview'), + url(r'^preview/(?P[^/]+)/$', 'preview', name='cover_preview'), + url(r'^preview/(?P[^/]+)/(?P[^/]+)/$', + 'preview', name='cover_preview'), + url(r'^preview/(?P[^/]+)/(?P[^/]+)/(?P\d+)/$', + 'preview', name='cover_preview'), +) diff --git a/apps/cover/views.py b/apps/cover/views.py new file mode 100644 index 00000000..29fd117a --- /dev/null +++ b/apps/cover/views.py @@ -0,0 +1,66 @@ +# Create your views here. +import os.path +from django.conf import settings +from django.http import HttpResponse, Http404 +from catalogue.models import Chunk +from django.views.decorators.http import require_POST +from django.views.decorators.csrf import csrf_exempt +from django.shortcuts import render + + +PREVIEW_SIZE = (216, 300) + +def preview(request, book, chunk=None, rev=None): + """Creates a cover image. + + If chunk and rev number are given, use version from given revision. + If rev is not given, use publishable version. + """ + import Image + from librarian.cover import WLCover + from librarian.dcparser import BookInfo + + chunk = Chunk.get(book, chunk) + if rev is not None: + try: + revision = chunk.at_revision(rev) + except Chunk.change_model.DoesNotExist: + raise Http404 + else: + revision = chunk.publishable() + if revision is None: + raise Http404 + xml = revision.materialize().encode('utf-8') + + info = BookInfo.from_string(xml) + cover = WLCover(info) + response = HttpResponse(mimetype=cover.mime_type()) + image = cover.image().resize(PREVIEW_SIZE, Image.ANTIALIAS) + image.save(response, cover.format) + return response + + +@csrf_exempt +@require_POST +def preview_from_xml(request): + from hashlib import sha1 + import Image + from os import makedirs + from lxml import etree + from librarian.cover import WLCover + from librarian.dcparser import BookInfo + + xml = request.POST['xml'] + info = BookInfo.from_string(xml.encode('utf-8')) + coverid = sha1(etree.tostring(info.to_etree())).hexdigest() + cover = WLCover(info) + + cover_dir = 'cover/preview' + try: + makedirs(os.path.join(settings.MEDIA_ROOT, cover_dir)) + except OSError: + pass + fname = os.path.join(cover_dir, "%s.%s" % (coverid, cover.ext())) + image = cover.image().resize(PREVIEW_SIZE, Image.ANTIALIAS) + image.save(os.path.join(settings.MEDIA_ROOT, fname)) + return HttpResponse(os.path.join(settings.MEDIA_URL, fname)) diff --git a/apps/wiki/locale/pl/LC_MESSAGES/django.mo b/apps/wiki/locale/pl/LC_MESSAGES/django.mo index d886dcec..6f74d926 100644 Binary files a/apps/wiki/locale/pl/LC_MESSAGES/django.mo and b/apps/wiki/locale/pl/LC_MESSAGES/django.mo differ diff --git a/apps/wiki/locale/pl/LC_MESSAGES/django.po b/apps/wiki/locale/pl/LC_MESSAGES/django.po index 0182abed..bfd802fd 100644 --- a/apps/wiki/locale/pl/LC_MESSAGES/django.po +++ b/apps/wiki/locale/pl/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: Platforma Redakcyjna\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-11-30 16:07+0100\n" -"PO-Revision-Date: 2011-11-30 16:08+0100\n" +"POT-Creation-Date: 2012-02-03 15:08+0100\n" +"PO-Revision-Date: 2012-02-03 15:09+0100\n" "Last-Translator: Radek Czajka \n" "Language-Team: Fundacja Nowoczesna Polska \n" "Language: \n" @@ -219,38 +219,42 @@ msgid "Source code" msgstr "Kod źródłowy" #: templates/wiki/tabs/summary_view.html:9 +msgid "Refresh from working copy" +msgstr "Odśwież z edytowanej wersji" + +#: templates/wiki/tabs/summary_view.html:13 msgid "Title" msgstr "Tytuł" -#: templates/wiki/tabs/summary_view.html:13 +#: templates/wiki/tabs/summary_view.html:17 msgid "Go to the book's page" msgstr "Przejdź do strony książki" -#: templates/wiki/tabs/summary_view.html:16 +#: templates/wiki/tabs/summary_view.html:20 msgid "Document ID" msgstr "ID dokumentu" -#: templates/wiki/tabs/summary_view.html:20 +#: templates/wiki/tabs/summary_view.html:24 msgid "Current version" msgstr "Aktualna wersja" -#: templates/wiki/tabs/summary_view.html:23 +#: templates/wiki/tabs/summary_view.html:27 msgid "Last edited by" msgstr "Ostatnio edytowane przez" -#: templates/wiki/tabs/summary_view.html:27 +#: templates/wiki/tabs/summary_view.html:31 msgid "Link to gallery" msgstr "Link do galerii" -#: templates/wiki/tabs/summary_view.html:32 +#: templates/wiki/tabs/summary_view.html:36 msgid "Characters in document" msgstr "Znaków w dokumencie" -#: templates/wiki/tabs/summary_view.html:33 +#: templates/wiki/tabs/summary_view.html:37 msgid "pages" msgstr "stron maszynopisu" -#: templates/wiki/tabs/summary_view.html:33 +#: templates/wiki/tabs/summary_view.html:37 msgid "untagged" msgstr "nieotagowane" diff --git a/apps/wiki/templates/wiki/tabs/summary_view.html b/apps/wiki/templates/wiki/tabs/summary_view.html index bcea34da..ade3097f 100644 --- a/apps/wiki/templates/wiki/tabs/summary_view.html +++ b/apps/wiki/templates/wiki/tabs/summary_view.html @@ -3,7 +3,11 @@
- +
+

+

+

diff --git a/redakcja/static/css/filelist.css b/redakcja/static/css/filelist.css index 166def07..c7a65f31 100644 --- a/redakcja/static/css/filelist.css +++ b/redakcja/static/css/filelist.css @@ -223,4 +223,12 @@ a:hover { .wall .publish { background-color: #fdc; -} \ No newline at end of file +} + +.cover-preview { + width: 216px; + height: 300px; + float: left; + margin-right: 2em; +} +} diff --git a/redakcja/static/css/summary.css b/redakcja/static/css/summary.css index 6c05e0be..1520c36b 100644 --- a/redakcja/static/css/summary.css +++ b/redakcja/static/css/summary.css @@ -6,16 +6,15 @@ padding: 1em; } -#summary-view .book-cover { +#summary-view .summary-cover-area { float: left; margin: 1em; margin-right: 2em; +} +#summary-view .book-cover { height: 300px; width: 212px; - - - border: 1px dashed black; } #summary-view p { diff --git a/redakcja/static/js/wiki/view_summary.js b/redakcja/static/js/wiki/view_summary.js index de6fcf15..8fdf4b96 100644 --- a/redakcja/static/js/wiki/view_summary.js +++ b/redakcja/static/js/wiki/view_summary.js @@ -1,11 +1,32 @@ (function($){ function SummaryPerspective(options) { + var old_callback = options.callback || function() {}; + + options.callback = function() { + var self = this; + + // first time page is rendered + $('#summary-cover-refresh').click(function() { + self.refreshCover(); + }); + + old_callback.call(this); + } + $.wiki.Perspective.call(this, options); }; SummaryPerspective.prototype = new $.wiki.Perspective(); + SummaryPerspective.prototype.refreshCover = function() { + this.doc.refreshCover({ + success: function(text) { + $('#summary-cover').attr('src', text); + } + }); + }; + SummaryPerspective.prototype.showCharCount = function() { var cc; try { diff --git a/redakcja/static/js/wiki/wikiapi.js b/redakcja/static/js/wiki/wikiapi.js index 4a4da5a7..d901e847 100644 --- a/redakcja/static/js/wiki/wikiapi.js +++ b/redakcja/static/js/wiki/wikiapi.js @@ -50,6 +50,9 @@ if (vname == "ajax_document_pubmark") return base_path + "/pubmark/" + arguments[1] + '/'; + if (vname == "ajax_cover_preview") + return "/cover/preview/"; + console.log("Couldn't reverse match:", vname); return "/404.html"; }; @@ -383,6 +386,25 @@ }); }; + WikiDocument.prototype.refreshCover = function(params) { + var self = this; + var data = { + xml: self.text // TODO: send just DC + }; + $.ajax({ + url: reverse("ajax_cover_preview"), + type: "POST", + data: data, + success: function(data) { + params.success(data); + }, + error: function(xhr) { + // params.failure("Nie udało się odświeżyć okładki - błąd serwera."); + } + }); + }; + + WikiDocument.prototype.getLength = function(params) { var xml = this.text.replace(/\/(\s+)/g, '
$1'); var parser = new DOMParser(); diff --git a/redakcja/urls.py b/redakcja/urls.py index 4aedf58f..1f8a7ff3 100644 --- a/redakcja/urls.py +++ b/redakcja/urls.py @@ -26,6 +26,7 @@ urlpatterns = patterns('', url(r'^documents/', include('catalogue.urls')), url(r'^apiclient/', include('apiclient.urls')), url(r'^editor/', include('wiki.urls')), + url(r'^cover/', include('cover.urls')), # Static files (should be served by Apache) url(r'^%s(?P.+)$' % settings.MEDIA_URL[1:], 'django.views.static.serve',