From: zuber@web50.webfaction.com Date: Mon, 20 Oct 2008 14:18:18 +0000 (-0500) Subject: Merged with branch 1.0. X-Git-Url: https://git.mdrn.pl/wolnelektury.git/commitdiff_plain/3f84dfec54e97d5d5b4f8a1d37c2a1e8ba8a2933?hp=9b97d5a2faa6f56b439dcefe9c7bb23e0a84b39c Merged with branch 1.0. --- diff --git a/.hgtags b/.hgtags index e32cfc62d..0edbce637 100644 --- a/.hgtags +++ b/.hgtags @@ -1,7 +1 @@ -57ed361b5c5cea4c3fc6d4ea1d8c2a9addb087e2 wolnelektury-0.9 -5f1b5a4c1444518b6b4d151a9a20baf061b77179 wolnelektury-0.9 -4da7f67e38ed4599d3925c92a7fab8f61467bfc3 wolnelektury-0.9 -fed64f1e09c1859829839fe8c09dc1c2848389a4 wolnelektury-0.9.1 -5eee4534e79b9102c6e7c579cc2a6c8d74de9c05 wolnelektury-0.9.2 -293052c8f613021de21e6d036e48652f4a414b35 wolnelektury-0.9.3 -13036b75ecc3711e9270342fc8d7cd41d2676d6b wolnelektury-0.9.4 +fa4bcbf759901d7444c98e3f0a3a9aa7da1b8a1b wolnelektury-1.0 diff --git a/apps/catalogue/fields.py b/apps/catalogue/fields.py index e1a356ef0..d091b77c1 100644 --- a/apps/catalogue/fields.py +++ b/apps/catalogue/fields.py @@ -1,10 +1,66 @@ # -*- coding: utf-8 -*- +import datetime + +from django.conf import settings +from django.db import models +from django.db.models import signals from django import forms from django.forms.widgets import flatatt from django.forms.util import smart_unicode +from django.utils import simplejson as json from django.utils.html import escape from django.utils.safestring import mark_safe -from django.utils.simplejson import dumps + + +class JSONEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, datetime.datetime): + return obj.strftime('%Y-%m-%d %H:%M:%S') + elif isinstance(obj, datetime.date): + return obj.strftime('%Y-%m-%d') + elif isinstance(obj, datetime.time): + return obj.strftime('%H:%M:%S') + return json.JSONEncoder.default(self, obj) + + +def dumps(data): + return JSONEncoder().encode(data) + + +def loads(str): + return json.loads(str, encoding=settings.DEFAULT_CHARSET) + + +class JSONField(models.TextField): + def db_type(self): + return 'text' + + def get_internal_type(self): + return 'TextField' + + def pre_save(self, model_instance, add): + value = getattr(model_instance, self.attname, None) + return dumps(value) + + def contribute_to_class(self, cls, name): + super(JSONField, self).contribute_to_class(cls, name) + signals.post_init.connect(self.post_init, sender=cls) + + def get_json(model_instance): + return dumps(getattr(model_instance, self.attname, None)) + setattr(cls, 'get_%s_json' % self.name, get_json) + + def set_json(model_instance, json): + return setattr(model_instance, self.attname, loads(json)) + setattr(cls, 'set_%s_json' % self.name, set_json) + + def post_init(self, **kwargs): + instance = kwargs.get('instance', None) + value = self.value_from_object(instance) + if (value): + setattr(instance, self.attname, loads(value)) + else: + setattr(instance, self.attname, None) class JQueryAutoCompleteWidget(forms.TextInput): @@ -32,7 +88,7 @@ class JQueryAutoCompleteWidget(forms.TextInput): final_attrs['id'] = 'id_%s' % name html = u''' - ''' % { 'attrs' : flatatt(final_attrs), diff --git a/apps/catalogue/migrations/0002_add_extra_info_to_book.py b/apps/catalogue/migrations/0002_add_extra_info_to_book.py new file mode 100644 index 000000000..145d7116c --- /dev/null +++ b/apps/catalogue/migrations/0002_add_extra_info_to_book.py @@ -0,0 +1,11 @@ +from south.db import db +from catalogue.fields import JSONField + +class Migration: + + def forwards(self): + db.add_column('catalogue_book', 'extra_info', JSONField()) + + def backwards(self): + db.delete_column('catalogue_book', 'extra_info') + diff --git a/apps/catalogue/models.py b/apps/catalogue/models.py index 60d278580..483fddab0 100644 --- a/apps/catalogue/models.py +++ b/apps/catalogue/models.py @@ -10,6 +10,7 @@ from django.core.urlresolvers import reverse from newtagging.models import TagBase from newtagging import managers +from catalogue.fields import JSONField from librarian import html, dcparser @@ -21,6 +22,7 @@ TAG_CATEGORIES = ( ('genre', _('genre')), ('theme', _('theme')), ('set', _('set')), + ('book', _('book')), ) @@ -41,7 +43,7 @@ class Tag(TagBase): db_index=True, choices=TAG_CATEGORIES) description = models.TextField(_('description'), blank=True) main_page = models.BooleanField(_('main page'), default=False, db_index=True, help_text=_('Show tag on main page')) - + user = models.ForeignKey(User, blank=True, null=True) book_count = models.IntegerField(_('book count'), default=0, blank=False, null=False) @@ -84,6 +86,7 @@ class Book(models.Model): created_at = models.DateTimeField(_('creation date'), auto_now=True) _short_html = models.TextField(_('short HTML'), editable=False) parent_number = models.IntegerField(_('parent number'), default=0) + extra_info = JSONField(_('extra information')) # Formats xml_file = models.FileField(_('XML file'), upload_to=book_upload_path('xml'), blank=True) @@ -97,6 +100,7 @@ class Book(models.Model): objects = models.Manager() tagged = managers.ModelTaggedItemManager(Tag) tags = managers.TagDescriptor(Tag) + @property def name(self): @@ -106,7 +110,7 @@ class Book(models.Model): if len(self._short_html): return mark_safe(self._short_html) else: - tags = self.tags.filter(~Q(category__in=('set', 'theme'))) + tags = self.tags.filter(~Q(category__in=('set', 'theme', 'book'))) tags = [u'%s' % (tag.get_absolute_url(), tag.name) for tag in tags] formats = [] @@ -167,6 +171,7 @@ class Book(models.Model): book_shelves = list(book.tags.filter(category='set')) book.title = book_info.title + book.extra_info = book_info.to_dict() book._short_html = '' book.save() @@ -184,6 +189,15 @@ class Book(models.Model): tag.category = category tag.save() book_tags.append(tag) + + book_tag, created = Tag.objects.get_or_create(slug=('l-' + book.slug)[:120]) + if created: + book_tag.name = book.title[:50] + book_tag.sort_key = ('l-' + book.slug)[:120] + book_tag.category = 'book' + book_tag.save() + book_tags.append(book_tag) + book.tags = book_tags if hasattr(book_info, 'parts'): @@ -193,7 +207,14 @@ class Book(models.Model): child_book.parent = book child_book.parent_number = n child_book.save() - + + book_descendants = list(book.children.all()) + while len(book_descendants) > 0: + child_book = book_descendants.pop(0) + for fragment in child_book.fragments.all(): + fragment.tags = set(list(fragment.tags) + [book_tag]) + book_descendants += list(child_book.children.all()) + # Save XML and HTML files book.xml_file.save('%s.xml' % book.slug, File(file(xml_file)), save=False) @@ -226,7 +247,7 @@ class Book(models.Model): tag.save() themes.append(tag) new_fragment.save() - new_fragment.tags = list(book.tags) + themes + new_fragment.tags = set(list(book.tags) + themes + [book_tag]) book_themes += themes book_themes = set(book_themes) diff --git a/apps/catalogue/urls.py b/apps/catalogue/urls.py index b24212ea5..dc8cc9bdf 100644 --- a/apps/catalogue/urls.py +++ b/apps/catalogue/urls.py @@ -17,6 +17,8 @@ urlpatterns = patterns('catalogue.views', # Public interface. Do not change this URLs. url(r'^lektura/(?P[a-zA-Z0-9-]+)\.html$', 'book_text', name='book_text'), url(r'^lektura/(?P[a-zA-Z0-9-]+)/$', 'book_detail', name='book_detail'), + url(r'^lektura/(?P[a-zA-Z0-9-]+)/motyw/(?P[a-zA-Z0-9-]+)/$', + 'book_fragments', name='book_fragments'), url(r'^(?P[a-zA-Z0-9-/]*)/$', 'tagged_object_list', name='tagged_object_list'), ) diff --git a/apps/catalogue/views.py b/apps/catalogue/views.py index c9d6ab227..1718d9765 100644 --- a/apps/catalogue/views.py +++ b/apps/catalogue/views.py @@ -67,6 +67,9 @@ def tagged_object_list(request, tags=''): except models.Tag.DoesNotExist: raise Http404 + if len([tag for tag in tags if tag.category == 'book']): + raise Http404 + model = models.Book shelf = [tag for tag in tags if tag.category == 'set'] shelf_is_set = (len(tags) == 1 and tags[0].category == 'set') @@ -76,7 +79,7 @@ def tagged_object_list(request, tags=''): user_is_owner = (len(shelf) and request.user.is_authenticated() and request.user == shelf[0].user) - extra_where = 'NOT catalogue_tag.category = "set"' + extra_where = 'catalogue_tag.category NOT IN ("set", "book")' related_tags = models.Tag.objects.related_for_model(tags, model, counts=True, extra={'where': [extra_where]}) categories = split_tags(related_tags) @@ -93,11 +96,25 @@ def tagged_object_list(request, tags=''): ) +def book_fragments(request, book_slug, theme_slug): + book = get_object_or_404(models.Book, slug=book_slug) + book_tag = get_object_or_404(models.Tag, slug='l-' + book_slug) + theme = get_object_or_404(models.Tag, slug=theme_slug) + fragments = models.Fragment.tagged.with_all([book_tag, theme]) + + form = forms.SearchForm() + return render_to_response('catalogue/book_fragments.html', locals(), + context_instance=RequestContext(request)) + + def book_detail(request, slug): book = get_object_or_404(models.Book, slug=slug) + book_tag = get_object_or_404(models.Tag, slug = 'l-' + slug) tags = list(book.tags.filter(~Q(category='set'))) categories = split_tags(tags) book_children = book.children.all().order_by('parent_number') + extra_where = 'catalogue_tag.category = "theme"' + book_themes = models.Tag.objects.related_for_model(book_tag, models.Fragment, counts=True, extra={'where': [extra_where]}) form = forms.SearchForm() return render_to_response('catalogue/book_detail.html', locals(), @@ -124,9 +141,9 @@ def _tags_starting_with(prefix, user): books = models.Book.objects.filter(title__icontains=prefix) tags = models.Tag.objects.filter(name__icontains=prefix) if user.is_authenticated(): - tags = tags.filter(~Q(category='set') | Q(user=user)) + tags = tags.filter(~Q(category='book') & (~Q(category='set') | Q(user=user))) else: - tags = tags.filter(~Q(category='set')) + tags = tags.filter(~Q(category='book') & ~Q(category='set')) return list(books) + list(tags) @@ -157,7 +174,7 @@ def search(request): def tags_starting_with(request): - prefix = request.GET['q'] + prefix = request.GET.get('q', '') # Prefix must have at least 2 characters if len(prefix) < 2: return HttpResponse('') diff --git a/books/01/zapolska_moralnosc_pani_dulskiej1.2.xml b/books/01/zapolska_moralnosc_pani_dulskiej1.2.xml index 1fcc337a5..b64ec7a70 100644 --- a/books/01/zapolska_moralnosc_pani_dulskiej1.2.xml +++ b/books/01/zapolska_moralnosc_pani_dulskiej1.2.xml @@ -1,4 +1,32 @@ + + + + Zapolska, Gabriela + Moralność pani Dulskiej + Sekuła, Aleksandra + Sutkowska, Olga + Fundacja Nowoczesna Polska + Modernizm + Dramat + Tragifarsa + Komedia + Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl). Reprodukcja cyfrowa wykonana przez Bibliotekę Narodową z egzemplarza pochodzącego ze zbiorów BN. + http://wolnelektury.pl/katalog/lektura/moralnosc-pani-dulskiej + http://www.polona.pl/dlibra/doccontent2?id=582&from=&from=generalsearch&dirids=1&lang=pl + Zapolska, Gabriela (1857-1921), Moralność pani Dulskiej: komedya w trzech aktach, Tow. Akc. S. Orgelbranda S-ów, Warszawa, 1907 + Domena publiczna - Gabriela Zapolska, herbu Korwin, właśc. Maria Gabriela Korwin-Piotro, zm. 17 grudnia 1921 + 1921 + xml + text + text + 2007-11-10 + G + L + pol + + + diff --git a/lib/librarian/book2html.xslt b/lib/librarian/book2html.xslt index d5e21cf75..71f118209 100644 --- a/lib/librarian/book2html.xslt +++ b/lib/librarian/book2html.xslt @@ -5,18 +5,17 @@ - +
@@ -219,8 +353,8 @@
- - +
diff --git a/lib/librarian/dcparser.py b/lib/librarian/dcparser.py index 871ff3a92..a4106863d 100644 --- a/lib/librarian/dcparser.py +++ b/lib/librarian/dcparser.py @@ -134,6 +134,8 @@ class BookInfo(object): raise ParseError(e) description = tree.find('//' + book_info.RDF('Description')) + book_info.wiki_url = description.get(cls.RDF('about'), None) + if description is None: raise ParseError('no Description tag found in document') @@ -157,6 +159,9 @@ class BookInfo(object): root = etree.Element(self.RDF('RDF')) description = etree.SubElement(root, self.RDF('Description')) + if self.wiki_url: + description.set(self.RDF('about'), self.wiki_url) + for tag, (attribute, converter) in self.mapping.iteritems(): if hasattr(self, attribute): e = etree.Element(tag) @@ -165,6 +170,17 @@ class BookInfo(object): return unicode(etree.tostring(root, 'utf-8'), 'utf-8') + def to_dict(self): + etree._namespace_map[str(self.RDF)] = 'rdf' + etree._namespace_map[str(self.DC)] = 'dc' + + result = {'about': self.wiki_url} + for tag, (attribute, converter) in self.mapping.iteritems(): + if hasattr(self, attribute): + result[attribute] = unicode(getattr(self, attribute)) + + return result + def parse(file_name): return BookInfo.from_file(file_name) diff --git a/lib/librarian/html.py b/lib/librarian/html.py index f5ad1389d..b279e5dd5 100644 --- a/lib/librarian/html.py +++ b/lib/librarian/html.py @@ -53,7 +53,7 @@ def transform(input_filename, output_filename): doc = etree.parse(doc_file, parser) result = doc.xslt(style) - if result.find('//h1') is not None: + if result.find('//p') is not None: add_anchors(result.getroot()) add_table_of_contents(result.getroot()) result.write(output_filename, xml_declaration=False, pretty_print=True, encoding='utf-8') diff --git a/migrations/001_add_book_count_to_shelf.py b/migrations/001_add_book_count_to_shelf.py deleted file mode 100644 index 4af55a172..000000000 --- a/migrations/001_add_book_count_to_shelf.py +++ /dev/null @@ -1,16 +0,0 @@ -from django.core.management import setup_environ -import settings - -setup_environ(settings) - -from catalogue.models import Tag, Book -from django.db import connection - -query = 'ALTER TABLE catalogue_tag ADD COLUMN book_count integer NOT NULL DEFAULT 0' - -cursor = connection.cursor() -cursor.execute(query) - -for shelf in Tag.objects.filter(category='set'): - shelf.book_count = len(Book.tagged.with_all(shelf)) - shelf.save() diff --git a/wolnelektury/deploy/wolnelektury.fcgi b/wolnelektury/deploy/wolnelektury.fcgi index ba9fbef3f..1f9c621c1 100644 --- a/wolnelektury/deploy/wolnelektury.fcgi +++ b/wolnelektury/deploy/wolnelektury.fcgi @@ -1,4 +1,5 @@ #!/usr/bin/env python +import os from os.path import abspath, dirname, join import sys diff --git a/wolnelektury/templates/base.html b/wolnelektury/templates/base.html index 1c60b4151..0cc4ff5dc 100644 --- a/wolnelektury/templates/base.html +++ b/wolnelektury/templates/base.html @@ -100,11 +100,13 @@

* Ładowanie

- - + + diff --git a/wolnelektury/templates/catalogue/book_detail.html b/wolnelektury/templates/catalogue/book_detail.html index a61396af3..1ffcccc1a 100644 --- a/wolnelektury/templates/catalogue/book_detail.html +++ b/wolnelektury/templates/catalogue/book_detail.html @@ -12,6 +12,7 @@
+

Na podstawie: {{ book.extra_info.source_name }}

{% if book.has_description %}
{{ book.description|safe }} @@ -79,17 +80,18 @@ {{ tag }} {% endfor %} +
  • Lektura na wiki projektu
  • +
  • Lektura w CBN Polona
  • +
  • Kod źródłowy utworu (XML)
  • - {% if categories.theme %} -

    Motywy w utworze

    -
      - {% for theme in categories.theme %} -
    • {{ theme }}
    • - {% endfor %} -
    - {% endif %} +

    Motywy w utworze

    +
    @@ -99,4 +101,4 @@

    * Ładowanie

    -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/wolnelektury/templates/catalogue/book_fragments.html b/wolnelektury/templates/catalogue/book_fragments.html new file mode 100644 index 000000000..4f1c0ebad --- /dev/null +++ b/wolnelektury/templates/catalogue/book_fragments.html @@ -0,0 +1,37 @@ +{% extends "base.html" %} +{% load catalogue_tags pagination_tags %} + +{% block title %}Motyw {{ theme }} w utworze {{ book }} w WolneLektury.pl{% endblock %} + +{% block bodyid %}tagged-object-list{% endblock %} + +{% block body %} +

    Motyw {{ theme }} w utworze {{ book }}

    +
    +

    {{ form.q }} lub wróć do strony utworu

    +
    + + {% autopaginate fragments 10 %} +
    +
      + {% for fragment in fragments %} +
    1. {{ fragment.short_html }}
    2. + {% endfor %} +
    + {% paginate %} +
    +
    +
    + Zobacz opis utworu {{ book }} +
    +
    +
    +
    +
    +
    + +
    +

    * Ładowanie

    +
    +
    +{% endblock %} \ No newline at end of file diff --git a/wolnelektury/templates/catalogue/book_text.html b/wolnelektury/templates/catalogue/book_text.html index 8a6b0f639..d3f6a1c73 100644 --- a/wolnelektury/templates/catalogue/book_text.html +++ b/wolnelektury/templates/catalogue/book_text.html @@ -34,11 +34,13 @@ {{ book.html_file.read|safe }} - - + +