@classmethod
def author(cls, book):
- return ",".join(t[0] for t in book.related_info()['tags']['author'])
+ return ",".join(t[0] for t in book.related_info()['tags'].get('author', []))
@classmethod
def href(cls, book):
def book_dict(book, fields=None):
all_fields = ['url', 'title', 'description',
'gazeta_link', 'wiki_link',
- ] + Book.formats + BookMedia.formats + [
+ ] + Book.formats + BookMedia.formats.keys() + [
'parent', 'parent_number',
'tags',
'license', 'license_description', 'source_name',
# -*- coding: utf-8 -*-
from time import mktime
+from piston.resource import Resource
def timestamp(dtime):
"converts a datetime.datetime object to a timestamp int"
return int(mktime(dtime.timetuple()))
+class CsrfExemptResource(Resource):
+ """A Custom Resource that is csrf exempt"""
+ def __init__(self, handler, authentication=None):
+ super(CsrfExemptResource, self).__init__(handler, authentication)
+ self.csrf_exempt = getattr(self.handler, 'csrf_exempt', True)
# -*- coding: utf-8 -*-
-from datetime import datetime
+from os import path
+from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
+from django.test.utils import override_settings
from django.utils import simplejson as json
-from django.conf import settings
-from api.helpers import timestamp
from catalogue.models import Book, Tag
-from picture.tests.utils import RequestFactory
from picture.forms import PictureImportForm
-from picture.models import Picture, picture_storage
+from picture.models import Picture
import picture.tests
-from django.core.files.uploadedfile import SimpleUploadedFile
-
-
-from os import path
+@override_settings(
+ API_WAIT=-1,
+ CACHES = {'api': {'BACKEND': 'django.core.cache.backends.dummy.DummyCache'},
+ 'default': {'BACKEND': 'django.core.cache.backends.dummy.DummyCache'},
+ 'permanent': {'BACKEND': 'django.core.cache.backends.dummy.DummyCache'}}
+)
class ApiTest(TestCase):
-
- def setUp(self):
- self.old_api_wait = settings.API_WAIT
- settings.API_WAIT = -1
-
- def tearDown(self):
- settings.API_WAIT = self.old_api_wait
+ pass
class ChangesTest(ApiTest):
# -*- coding: utf-8 -*-
from django.conf.urls.defaults import *
-from piston.authentication import OAuthAuthentication
+from django.views.decorators.csrf import csrf_exempt
+from django.views.generic import TemplateView
+from piston.authentication import OAuthAuthentication, oauth_access_token
from piston.resource import Resource
from api import handlers
-from catalogue.models import Book
+from api.helpers import CsrfExemptResource
auth = OAuthAuthentication(realm="Wolne Lektury")
tag_changes_resource = Resource(handler=handlers.TagChangesHandler)
changes_resource = Resource(handler=handlers.ChangesHandler)
-book_list_resource = Resource(handler=handlers.BooksHandler, authentication=auth)
+book_list_resource = CsrfExemptResource(handler=handlers.BooksHandler, authentication=auth)
#book_list_resource = Resource(handler=handlers.BooksHandler)
book_resource = Resource(handler=handlers.BookDetailHandler)
fragment_resource = Resource(handler=handlers.FragmentDetailHandler)
fragment_list_resource = Resource(handler=handlers.FragmentsHandler)
-picture_resource = Resource(handler=handlers.PictureHandler, authentication=auth)
+picture_resource = CsrfExemptResource(handler=handlers.PictureHandler, authentication=auth)
urlpatterns = patterns(
'piston.authentication',
url(r'^oauth/request_token/$', 'oauth_request_token'),
url(r'^oauth/authorize/$', 'oauth_user_auth'),
- url(r'^oauth/access_token/$', 'oauth_access_token'),
+ url(r'^oauth/access_token/$', csrf_exempt(oauth_access_token)),
) + patterns('',
- url(r'^$', 'django.views.generic.simple.direct_to_template',
- {'template': 'api/main.html'}, name='api'),
+ url(r'^$', TemplateView.as_view(template_name='api/main.html'), name='api'),
# changes handlers
--- /dev/null
+# -*- 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 optparse import make_option
+from django.contrib.sites.models import Site
+from django.core.management.base import BaseCommand
+
+
+def ancestor_has_cover(book):
+ while book.parent:
+ book = book.parent
+ if book.extra_info.get('cover_url'):
+ return True
+ return False
+
+
+current_domain = Site.objects.get_current().domain
+def full_url(obj):
+ return 'http://%s%s' % (
+ current_domain,
+ obj.get_absolute_url())
+
+
+class Command(BaseCommand):
+ option_list = BaseCommand.option_list + (
+ make_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
+ help='Suppress output'),
+ )
+ help = 'Checks cover sources and licenses.'
+
+ def handle(self, **options):
+ from collections import defaultdict
+ import re
+ from django.db import transaction
+ from catalogue.models import Book
+
+ verbose = options['verbose']
+
+ without_cover = []
+ with_ancestral_cover = []
+ by_flickr_author = defaultdict(list)
+ not_flickr = []
+ by_license = defaultdict(list)
+ no_license = []
+
+ re_flickr = re.compile(ur'https?://(?:www.)?flickr.com/photos/([^/]*)/.*')
+ re_license = re.compile(ur'.*,\s*(CC.*)')
+
+ with transaction.commit_on_success():
+ for book in Book.objects.all().order_by('slug').iterator():
+ extra_info = book.extra_info
+ if not extra_info.get('cover_url'):
+ if ancestor_has_cover(book):
+ with_ancestral_cover.append(book)
+ else:
+ without_cover.append(book)
+ else:
+ match = re_flickr.match(extra_info.get('cover_source', ''))
+ if match:
+ by_flickr_author[match.group(1)].append(book)
+ else:
+ not_flickr.append(book)
+ match = re_license.match(extra_info.get('cover_by', ''))
+ if match:
+ by_license[match.group(1)].append(book)
+ else:
+ no_license.append(book)
+
+ print """%d books with no covers, %d with ancestral covers.
+Licenses used: %s (%d covers without license).
+Flickr authors: %s (%d covers not from flickr).
+""" % (
+ len(without_cover),
+ len(with_ancestral_cover),
+ ", ".join(sorted(by_license.keys())),
+ len(no_license),
+ ", ".join(sorted(by_flickr_author.keys())),
+ len(not_flickr),
+ )
+
+ if verbose:
+ print
+ print "By license:"
+ print "==========="
+ for lic, books in by_license.items():
+ print
+ print lic
+ for book in books:
+ print full_url(book)
+
+ print
+ print "No license:"
+ print "==========="
+ for book in no_license:
+ print
+ print full_url(book)
+ print book.extra_info.get('cover_by')
+ print book.extra_info.get('cover_source')
+ print book.extra_info.get('cover_url')
+
+ print
+ print "By Flickr author:"
+ print "================="
+ for author, books in by_flickr_author.items():
+ print
+ print "author: http://flickr.com/photos/%s/" % author
+ for book in books:
+ print full_url(book)
+
+ print
+ print "Not from Flickr or source missing:"
+ print "=================================="
+ for book in not_flickr:
+ print
+ print full_url(book)
+ print book.extra_info.get('cover_by')
+ print book.extra_info.get('cover_source')
+ print book.extra_info.get('cover_url')
+
+ print
+ print "No cover:"
+ print "========="
+ for book in without_cover:
+ print full_url(book)
+
+ print
+ print "With ancestral cover:"
+ print "====================="
+ for book in with_ancestral_cover:
+ print full_url(book)
--- /dev/null
+# -*- 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 optparse import make_option
+from django.core.management.base import BaseCommand
+
+from catalogue.models import Book
+
+
+class Command(BaseCommand):
+ option_list = BaseCommand.option_list + (
+ make_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
+ help='Suppress output'),
+ make_option('-d', '--dry-run', action='store_true', dest='dry_run', default=False,
+ help="Just check for problems, don't fix them"),
+ )
+ help = 'Checks integrity of catalogue data.'
+
+ def handle(self, **options):
+ from django.db import transaction
+
+ verbose = options['verbose']
+
+ with transaction.commit_on_success():
+ for book in Book.objects.all().iterator():
+ try:
+ info = book.wldocument().book_info
+ except:
+ if verbose:
+ print "ERROR! Bad XML for book:", book.slug
+ print "To resolve: republish."
+ print
+ else:
+ should_be = [p.slug for p in info.parts]
+ is_now = [p.slug for p in book.children.all().order_by('parent_number')]
+ if should_be != is_now:
+ if verbose:
+ print "ERROR! Wrong children for book:", book.slug
+ print "Is: ", is_now
+ print "Should be:", should_be
+ print "To resolve: republish parent book."
+ print
+
+ # Check for parent l-tags.
+ parents = []
+ parent = book.parent
+ while parent:
+ parents.append(parent)
+ parent = parent.parent
+ ltags = [b.book_tag() for b in parents]
+ if set(ltags) != set(book.tags.filter(category='book')):
+ if options['verbose']:
+ print "Wrong book tags for book:", book
+ print "Is: ", ", ".join(sorted(t.slug for t in book.tags.filter(category='book')))
+ print "Should be:", ", ".join(sorted(t.slug for t in ltags))
+ if not options['dry_run']:
+ book.tags = ltags + list(book.tags.exclude(category='book'))
+ if options['verbose']:
+ print "Fixed."
+ if options['verbose']:
+ print
+
+ # TODO: check metadata tags, reset counters
make_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
make_option('-f', '--force', action='store_true', dest='force', default=False,
- help='Print status messages to stdout'),
+ help='Overwrite works already in the catalogue'),
make_option('-E', '--no-build-epub', action='store_false', dest='build_epub', default=True,
help='Don\'t build EPUB file'),
make_option('-M', '--no-build-mobi', action='store_false', dest='build_mobi', default=True,
make_option('-P', '--no-build-pdf', action='store_false', dest='build_pdf', default=True,
help='Don\'t build PDF file'),
make_option('-S', '--no-search-index', action='store_false', dest='search_index', default=True,
- help='Don\'t build PDF file'),
+ help='Skip indexing imported works for search'),
make_option('-w', '--wait-until', dest='wait_until', metavar='TIME',
help='Wait until specified time (Y-M-D h:m:s)'),
make_option('-p', '--picture', action='store_true', dest='import_picture', default=False,
--- /dev/null
+(function($) {
+ $(function() {
+
+
+
+$('.open-player').click(function(event) {
+ event.preventDefault();
+ window.open($(this).attr('href'),
+ 'player',
+ 'width=422, height=500'
+ );
+});
+
+
+
+ });
+})(jQuery);
+
.play:hover {
color: #0D7E85;
}
+
+.daisy-list {
+ list-style: none;
+}
<p>{% trans "Edited and annotated by:" %}
{% all_editors book.extra_info %}.</p>
{% endif %}
+
+{% if book.extra_info.cover_by %}
+ <p>{% trans "Cover image by:" %}
+ <a href="{{ book.extra_info.cover_source }}">
+ {{ book.extra_info.cover_by }}</a>.</p>
+{% endif %}
{% load i18n %}
+{% load url from future %}
{% load static from staticfiles %}
{% load chunks compressed catalogue_tags %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
<li><a class="menu" href="#info">{% trans "Infobox" %}</a></li>
<li><a href="{{ book.get_absolute_url }}">{% trans "Book's page" %}</a></li>
<li><a class="menu" href="#download">{% trans "Download" %}</a></li>
+ {% if related.media.mp3 or related.media.ogg %}
+ <li><a class="open-player" target="_blank" href="{% url "book_player" book.slug %}">
+ {% trans "Listen" %}</a></li>
+ {% endif %}
</ul>
</div>
<div id="info">
{% if book.pdf_file %}
<li><a href="{{ book.pdf_file.url}}">PDF</a> {% trans "to print" %}</li>
{% endif %}
- {% if book.epub_file %}
+ {% if book.epub_file %}
<li><a href="{{ book.epub_file.url}}">EPUB</a> {% trans "for a reader" %}</li>
{% endif %}
- {% if book.mobi_file %}
+ {% if book.mobi_file %}
<li><a href="{{ book.mobi_file.url}}">MOBI</a> {% trans "for Kindle" %}</li>
{% endif %}
- {% if book.txt_file %}
+ {% if book.txt_file %}
<li><a href="{{ book.txt_file.url}}">TXT</a> {% trans "for advanced usage" %}</li>
{% endif %}
- <li><a href="{% url custom_pdf_form book.slug %}">{% trans "Download a custom PDF" %}</a></li>
+ {% custom_pdf_link_li book %}
+ {% if related.media.mp3 or related.media.ogg or related.media.daisy %}
+ <li>{% trans "Download all audiobooks for this book" %}:
+ {% download_audio book %}</li>
+ {% endif %}
</ul>
</div>
<div id="header">
{% extends "catalogue/book_short.html" %}
{% load i18n %}
-{% load tag_list from catalogue_tags %}
+{% load download_audio tag_list custom_pdf_link_li from catalogue_tags %}
{% load cite_promo from social_tags %}
<h2 class="mono">{% trans "Download" %}</h2>
<ul class="plain">
<li>
- {% if related.media.mp3 or related.media.ogg %}
- {% trans "Download all audiobooks for this book" %}:
- {% if related.media.mp3 %}<a href="{% url download_zip_mp3 book.slug %}">MP3</a>{% endif %}{% if related.media.mp3 and related.media.ogg %},{% endif %}
- {% if related.media.ogg %}<a href="{% url download_zip_ogg book.slug %}">OGG</a>{% endif %}.
+ {% if related.media.mp3 or related.media.ogg or related.media.daisy %}
+ {% trans "Download all audiobooks for this book" %}:
+ {% download_audio book %}.
{% endif %}
</li>
- <li>
- <a href="{% url custom_pdf_form book.slug %}" id="custom-pdf" class="ajaxable">{% trans "Download a custom PDF" %}</a>
- </li>
+ {% custom_pdf_link_li book %}
</ul>
</div>
</div>
{% trans "See full category" %} <a href="{% catalogue_url one_tag %}">{{ one_tag }}</a>
{% else %}
<ul>
- {% for tag in tags %}
- <li><a href="{% catalogue_url choices tag %}">{{ tag }} ({{ tag.book_count }})</a></li>
- {% endfor %}
+ {% if choices %}
+ {% for tag in tags %}
+ <li><a href="{% catalogue_url choices tag %}">{{ tag }} ({{ tag.count }})</a></li>
+ {% endfor %}
+ {% else %}
+ {% for tag in tags %}
+ <li><a href="{{ tag.get_absolute_url }}">{{ tag }} ({{ tag.book_count }})</a></li>
+ {% endfor %}
+ {% endif %}
</ul>
{% endif %}
<!DOCTYPE html>
<html>
+ {% load static from staticfiles %}
{% load i18n compressed %}
{% load catalogue_tags %}
{% load thumbnail %}
<div class="player-info normal-text">
<p><a target="_blank" href="{{ book.get_absolute_url }}">{% trans "Book's page" %}</a>.</p>
- <p>{% trans "Download as" %}
- <a href="{% url download_zip_mp3 book.slug %}">MP3</a>{% if have_oggs %},
- <a href="{% url download_zip_ogg book.slug %}">Ogg Vorbis</a>{% endif %}.
- </p>
+ <p>{% trans "Download as" %} {% download_audio book False %}.</p>
{% if book.has_daisy_file %}
<p>DAISY:</p>
--- /dev/null
+{% load i18n %}
+{% load url from future %}
+{% if not NO_CUSTOM_PDF %}
+<li>
+ <a href="{% url 'custom_pdf_form' book.slug %}" id="custom-pdf"
+ class="ajaxable">{% trans "Download a custom PDF" %}</a>
+</li>
+{% endif %}
import datetime
import feedparser
+from django.conf import settings
from django import template
from django.template import Node, Variable, Template, Context
from django.core.cache import cache
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.utils.translation import ugettext as _
-from catalogue import forms
from catalogue.utils import split_tags
-from catalogue.models import Book, Fragment, Tag
+from catalogue.models import Book, BookMedia, Fragment, Tag
register = template.Library()
return reverse('catalogue.views.tagged_object_list', args=[
'/'.join((Tag.categories_dict[category], slug))
])
+
+
+@register.simple_tag
+def download_audio(book, daisy=True):
+ related = book.related_info()
+ links = []
+ if related['media'].get('mp3'):
+ links.append("<a href='%s'>%s</a>" %
+ (reverse('download_zip_mp3', args=[book.slug]),
+ BookMedia.formats['mp3'].name))
+ if related['media'].get('ogg'):
+ links.append("<a href='%s'>%s</a>" %
+ (reverse('download_zip_ogg', args=[book.slug]),
+ BookMedia.formats['ogg'].name))
+ if daisy and related['media'].get('daisy'):
+ for dsy in book.get_media('daisy'):
+ links.append("<a href='%s'>%s</a>" %
+ (dsy.file.url, BookMedia.formats['daisy'].name))
+ return ", ".join(links)
+
+
+@register.inclusion_tag("catalogue/snippets/custom_pdf_link_li.html")
+def custom_pdf_link_li(book):
+ return {
+ 'book': book,
+ 'NO_CUSTOM_PDF': settings.NO_CUSTOM_PDF,
+ }
book_themes = book_themes.items()
book_themes.sort(key=lambda s: s[0].sort_key)
+ related = book.related_info()
return render_to_response('catalogue/book_text.html', locals(),
context_instance=RequestContext(request))
submit = ugettext_lazy('Download')
honeypot = True
+ def __call__(self, *args, **kwargs):
+ if settings.NO_CUSTOM_PDF:
+ raise Http404('Custom PDF is disabled')
+ return super(CustomPDFFormView, self).__call__(*args, **kwargs)
+
def form_args(self, request, obj):
"""Override to parse view args and give additional args to the form."""
return (obj,), {}
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from django.conf.urls.defaults import *
-
+from dictionary.views import NotesView
urlpatterns = patterns('dictionary.views',
- url(r'^$', 'letter_notes', name='dictionary_notes'),
- url(r'(?P<letter>[a-z]|0-9)/$', 'letter_notes', name='dictionary_notes'),
+ url(r'^$', NotesView.as_view(), name='dictionary_notes'),
+ url(r'(?P<letter>[a-z]|0-9)/$', NotesView.as_view(), name='dictionary_notes'),
)
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
-from django.views.generic.list_detail import object_list
from dictionary.models import Note
+from django.views.generic.list import ListView
-def letter_notes(request, letter=None):
- letters = ["0-9"] + [chr(a) for a in range(ord('a'), ord('z')+1)]
- objects = Note.objects.all()
- if letter == "0-9":
- objects = objects.filter(sort_key__regex=r"^[0-9]")
- elif letter:
- objects = objects.filter(sort_key__startswith=letter)
- return object_list(request, queryset=objects, extra_context=locals())
+class NotesView(ListView):
+ def get_queryset(self):
+ self.letters = ["0-9"] + [chr(a) for a in range(ord('a'), ord('z')+1)]
+ self.letter = self.kwargs.get('letter')
+
+ objects = Note.objects.all()
+ if self.letter == "0-9":
+ objects = objects.filter(sort_key__regex=r"^[0-9]")
+ elif self.letter:
+ objects = objects.filter(sort_key__startswith=self.letter)
+ return ListView.get_queryset(self)
+
+ def get_context_data(self, **kwargs):
+ context = super(NotesView, self).get_context_data(**kwargs)
+ context['letter'] = self.letter
+ context['letters'] = self.letters
+ return context
def _media(self):
from django.conf import settings
js = ['js/SelectBox.js' , 'js/SelectFilter2.js']
- return forms.Media(js=['%s%s' % (settings.ADMIN_MEDIA_PREFIX, url) for url in js])
+ return forms.Media(js=['%sadmin/%s' % (settings.STATIC_URL, url) for url in js])
media = property(_media)
def __init__(self, verbose_name, is_stacked, attrs=None, choices=()):
# TODO: "id_" is hard-coded here. This should instead use the correct
# API to determine the ID dynamically.
output.append(u'SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n' % \
- (name, self.verbose_name.replace('"', '\\"'), int(self.is_stacked), settings.ADMIN_MEDIA_PREFIX))
+ (name, self.verbose_name.replace('"', '\\"'), int(self.is_stacked), settings.STATIC_URL + "admin/"))
return mark_safe(u''.join(output))
# KeywordAnalyzer
# Initialize jvm
-JVM = initVM(CLASSPATH)
+JVM = initVM(CLASSPATH, maxheap=settings.JVM_MAXHEAP)
import sys
import os
$('.sponsor-logos').cycle({timeout: 3000});
});
-})(jQuery)
+})(jQuery);
-/* Logo font */
-@font-face {
- /* IE version */
- font-family: WL-Nav;
- src: url(/static/fonts/WL-Nav.eot);
-}
-@font-face {
- font-family: WL-Nav;
- src: url(/static/fonts/WL-Nav.ttf) format("truetype");
-}
-
-
html {
margin: 0;
padding: 0;
.theme-list-link:after {
padding-left: 1em;
- content: "↓";
- font-family: WL-Nav;
+ content: url("/static/img/arrow-teal.png");
vertical-align: middle;
}
.theme-list-link {
.book-box-read a:before {
- content: "\2609";
- font-family: WL-Nav;
+ content: url("/static/img/read.png");
font-size: 2.25em;
margin-right: .15em;
vertical-align: middle;
}
.book-box-download a.downarrow:before {
- content: "\21E9";
- font-family: WL-Nav;
+ content: url("/static/img/download.png");
font-size: 2.25em;
margin-right: .15em;
vertical-align: middle;
}
.book-box-audiobook a:before {
- content: "\266B";
- font-family: WL-Nav;
+ content: url("/static/img/listen.png");
font-size: 2.25em;
margin-right: .15em;
vertical-align: middle;
.book-wide-box .cite {
position: relative;
- top: -0.8em;
+ top: -1em;
right: -1em;
background-color: #f7f7f7;
vertical-align: middle;
}
#lang-button:after {
padding-left: 1em;
- content: "↓";
- font-family: WL-Nav;
+ content: url("/static/img/arrow-gray.png");
vertical-align: middle;
}
#lang-menu {
}
.infopages-box .social-links a {
- font-family: WL-Nav, courier;
- font-size: 3em;
- color: #281d1c;
- margin-right: .2em;
+ margin-right: .6em;
}
}
.picture-box-tools a:before {
- content: "⇩";
- font-family: WL-Nav;
+ content: url("/static/img/download.png");
font-size: 2em;
margin-right: .25em;
vertical-align: middle;
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="14.117774"
+ height="7.4593911"
+ id="svg6288">
+ <defs
+ id="defs6290" />
+ <metadata
+ id="metadata6293">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ transform="translate(-286.99505,-661.55707)"
+ id="layer1">
+ <g
+ transform="matrix(0.52354174,0,0,0.52354174,92.72559,391.47243)"
+ id="layer1-0">
+ <path
+ d="m 397.25241,515.87986 -12.65419,12.65419 -12.74921,-12.62294 -0.78125,0.78125 13.56171,13.43544 13.40419,-13.43544 z"
+ id="rect4090"
+ style="fill:#717171;fill-opacity:1;stroke:none" />
+ </g>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="14.117774"
+ height="7.4593911"
+ id="svg6288">
+ <defs
+ id="defs6290" />
+ <metadata
+ id="metadata6293">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ transform="translate(-284.86155,-665.60555)"
+ id="layer1">
+ <g
+ transform="matrix(0.52354174,0,0,0.52354174,90.59209,395.52091)"
+ id="g5216"
+ style="fill:#0d7e85;fill-opacity:1">
+ <path
+ d="m 397.25241,515.87986 -12.65419,12.65419 -12.74921,-12.62294 -0.78125,0.78125 13.56171,13.43544 13.40419,-13.43544 z"
+ id="path5218"
+ style="fill:#0d7e85;fill-opacity:1;stroke:none" />
+ </g>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="21.03125"
+ height="21.03125"
+ id="svg6288">
+ <defs
+ id="defs6290" />
+ <metadata
+ id="metadata6293">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ transform="translate(-232.34152,-641.84656)"
+ id="layer1">
+ <g
+ transform="translate(-139.3058,123.6384)"
+ id="layer1-8"
+ style="fill:#0d7e85;fill-opacity:1">
+ <path
+ d="m 382.14732,518.20816 c -5.80761,0 -10.5,4.69238 -10.5,10.5 0,5.80762 4.69239,10.53125 10.5,10.53125 5.80762,0 10.53125,-4.72363 10.53125,-10.53125 0,-5.80762 -4.72363,-10.5 -10.53125,-10.5 z m -3.21875,7.65625 3.21875,3.28125 3.21875,-3.25 0.6875,0.625 -3.9375,4 -3.875,-4 0.6875,-0.65625 z m -0.3125,6.28125 7.0625,0 0,0.96875 -7.0625,0 0,-0.96875 z"
+ id="path3167"
+ style="fill:#0d7e85;fill-opacity:1;stroke:none" />
+ </g>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="21.03125"
+ height="20.96875"
+ id="svg6288">
+ <defs
+ id="defs6290" />
+ <metadata
+ id="metadata6293">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ transform="translate(-267.1717,-650.13426)"
+ id="layer1">
+ <g
+ transform="translate(-105.38857,136.37923)"
+ id="layer1-6"
+ style="fill:#0d7e85;fill-opacity:1">
+ <path
+ d="m 383.09152,513.75503 c -5.80553,0 -10.53125,4.67683 -10.53125,10.46875 0,5.79192 4.72572,10.5 10.53125,10.5 5.80553,0 10.5,-4.70808 10.5,-10.5 -10e-4,-5.79103 -4.69536,-10.46875 -10.5,-10.46875 z m 3.5,6.59375 0,6.625 c 0.0276,0.0977 0.0625,0.20878 0.0625,0.3125 0,0.82986 -0.92754,1.5 -2.0625,1.5 -1.13496,0 -2.03125,-0.67014 -2.03125,-1.5 0,-0.82986 0.89629,-1.5 2.03125,-1.5 0.35672,0 0.67536,0.0709 0.96875,0.1875 l 0.0312,-4.1875 -4,0.96875 0.0312,4.1875 c 0.0276,0.0977 0.0312,0.20878 0.0312,0.3125 0,0.82986 -0.92754,1.5 -2.0625,1.5 -1.13496,0 -2.03125,-0.67014 -2.03125,-1.5 0,-0.82986 0.89629,-1.5 2.03125,-1.5 0.34893,0 0.67995,0.0756 0.96875,0.1875 l 0,-4.15625 6.03125,-1.4375 z m -7,6.375 c -0.56138,0 -1.03125,0.21931 -1.03125,0.5 0,0.28069 0.46987,0.53125 1.03125,0.53125 0.56138,0 1,-0.25056 1,-0.53125 -1.2e-4,-0.28065 -0.43871,-0.5 -1,-0.5 z m 5,0.0312 c -0.56138,0 -1.03125,0.21931 -1.03125,0.5 0,0.28069 0.46987,0.53125 1.03125,0.53125 0.56138,0 1,-0.25056 1,-0.53125 -1.2e-4,-0.28065 -0.43871,-0.5 -1,-0.5 z"
+ id="path3184"
+ style="fill:#0d7e85;fill-opacity:1;stroke:none" />
+ </g>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="21.03125"
+ height="20.9375"
+ id="svg6288">
+ <defs
+ id="defs6290" />
+ <metadata
+ id="metadata6293">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ transform="translate(-225.71498,-640.7418)"
+ id="layer1">
+ <g
+ transform="translate(-138.76939,118.84837)"
+ id="layer1-3"
+ style="fill:#0d7e85;fill-opacity:1">
+ <path
+ d="m 375.01562,521.89343 c -5.80761,0 -10.53125,4.68702 -10.53125,10.46875 0,5.78173 4.72364,10.46875 10.53125,10.46875 5.80762,0 10.5,-4.68702 10.5,-10.46875 0,-5.78173 -4.69238,-10.46875 -10.5,-10.46875 z m -0.5,5.96875 c 0.15292,-0.0191 0.31239,0 0.46875,0 2.5018,0 4.52957,2.4714 6.5625,4.53125 -2.03293,2.12615 -4.0607,4.5 -6.5625,4.5 -2.5018,0 -4.46706,-2.44014 -6.5,-4.5 1.84373,-1.86896 3.73739,-4.2453 6.03125,-4.53125 z m 0.46875,1 c -2.5018,0 -3.50211,1.55979 -5.46875,3.53125 2.03294,2.05986 2.96695,3.4375 5.46875,3.4375 2.5018,0 3.46707,-1.31135 5.5,-3.4375 -2.03293,-2.05985 -2.9982,-3.53125 -5.5,-3.53125 z m 0.0312,1.03125 c 1.37294,0 2.5,1.12096 2.5,2.5 0,1.37904 -1.12706,2.46875 -2.5,2.46875 -1.37294,0 -2.46875,-1.08971 -2.46875,-2.46875 0,-1.37904 1.09581,-2.5 2.46875,-2.5 z m -0.0312,0.96875 c -0.82987,0 -1.5,0.67013 -1.5,1.5 0,0.82986 0.67013,1.5 1.5,1.5 0.82986,0 1.5,-0.67014 1.5,-1.5 0,-0.82987 -0.67014,-1.5 -1.5,-1.5 z"
+ id="path3144"
+ style="fill:#0d7e85;fill-opacity:1;stroke:none" />
+ </g>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="27"
+ height="27"
+ id="svg6088">
+ <defs
+ id="defs6090" />
+ <metadata
+ id="metadata6093">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ transform="translate(-366.81409,-521.12423)"
+ id="layer1">
+ <path
+ d="m 380.29848,521.12423 c -7.46076,0 -13.48439,6.0339 -13.48439,13.4844 0,7.4505 6.02363,13.5156 13.48439,13.5156 7.46077,0 13.51561,-6.0651 13.51561,-13.5156 0,-7.4505 -6.05484,-13.4844 -13.51561,-13.4844 z m 0.59307,9.489 2.15375,0 0,0.9989 -1.87283,0 c -0.48766,0 -0.99871,0.5039 -1.1237,0.9988 l 2.77804,0 0,1.0301 -2.80925,0 0,4.963 -1.1237,0 0,-4.963 -1.31099,0 0,-1.0301 1.31099,0 c 0,-0.9454 1.05229,-1.9977 1.99769,-1.9977 z"
+ id="path3774"
+ style="fill:#281d1c;fill-opacity:1;stroke:none" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="27"
+ height="27"
+ id="svg6088">
+ <defs
+ id="defs6090" />
+ <metadata
+ id="metadata6093">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ transform="translate(-370.36041,-525.65913)"
+ id="layer1">
+ <path
+ d="m 383.86041,525.65913 c -7.4541,0 -13.5,6.0409 -13.5,13.5 0,7.4591 6.0478,13.5 13.5,13.5 7.4541,0 13.5,-6.0409 13.5,-13.5 0,-7.4591 -6.0478,-13.5 -13.5,-13.5 z m -2.3072,9.9375 c 0.7663,0.052 1.408,0.3504 2.1513,0.7812 l -0.031,1.25 c -0.9815,-0.9169 -2.0284,-1.0444 -2.8372,-0.9687 -0.813,0 -2.1513,1.2073 -2.1513,2.375 0,1.0521 1.3098,2.5625 2.4007,2.5625 0.7638,0 1.1307,-0.01 1.5589,-0.125 l -0.031,-1.7812 -1.3095,0 0,-1.0313 2.3384,-0.031 0,3.8437 c -0.7977,0.1841 -1.8035,0.1925 -2.5255,0.1876 -2.1991,-0.015 -3.4719,-1.6067 -3.4919,-3.5313 0.1215,-1.9906 1.8329,-3.4278 3.1178,-3.5 0.2926,-0.04 0.5552,-0.049 0.8106,-0.031 z m 5.3003,1.0625 1.1224,0 0,1.9688 2.1201,0.031 0,1.0312 -2.1201,-0.031 0,2.4375 -1.1224,0 0,-2.4375 -2.1201,0.031 0,-1.0312 2.1201,-0.031 0,-1.9688 z"
+ id="path3822"
+ style="fill:#281d1c;fill-opacity:1;stroke:none" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="27"
+ height="27"
+ id="svg6088">
+ <defs
+ id="defs6090" />
+ <metadata
+ id="metadata6093">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ transform="translate(-361.5,-518.86218)"
+ id="layer1">
+ <path
+ d="m 375.01561,518.86218 c -7.46077,0 -13.51561,6.0409 -13.51561,13.5 0,7.4591 6.05484,13.5 13.51561,13.5 7.46077,0 13.48439,-6.0409 13.48439,-13.5 0,-7.4591 -6.02362,-13.5 -13.48439,-13.5 z m 0.78035,9.3437 0.93641,0 0,4.9063 2.80925,-2.5625 1.18613,0 -3.02774,2.7813 3.1526,3.1875 -1.21734,0 -2.9029,-2.9063 0,2.9063 -0.93641,0 0,-8.3126 z m -3.87052,2.1876 c 0.6577,0 1.16089,0.2286 1.49826,0.6562 0.33736,0.424 0.49942,1.0484 0.49943,1.875 l 0,3.5938 -0.93642,0 0,-3.5626 c 0,-0.5665 -0.10086,-0.9997 -0.31214,-1.2812 -0.21128,-0.2815 -0.51385,-0.4375 -0.93642,-0.4375 -0.50776,0 -0.92428,0.1928 -1.21734,0.5313 -0.29307,0.3385 -0.43699,0.7906 -0.43699,1.375 l 0,3.375 -0.93642,0 0,-5.9688 0.93642,0 0,0.9063 c 0.22491,-0.3599 0.47706,-0.6031 0.78035,-0.7813 0.30669,-0.1781 0.66256,-0.2812 1.06127,-0.2812 z"
+ id="path3781"
+ style="fill:#281d1c;fill-opacity:1;stroke:none" />
+ </g>
+</svg>
});
-$('.open-player').click(function(event) {
- event.preventDefault();
- window.open($(this).attr('href'),
- 'player',
- 'width=422, height=500'
- );
-});
-
-
$('.book-list-index').click(function(){
$('.book-list-show-index').hide('slow');
if($(this).parent().next('ul:not(:hidden)').length == 0){
{% extends "base.html" %}
+{% load static from staticfiles %}
{% load cache chunks i18n catalogue_tags infopages_tags social_tags %}
<div class="social-links">
<a href="http://pl-pl.facebook.com/pages/Wolne-Lektury/203084073268"
- title='Wolne Lektury @ Facebook'>f</a>
+ title='Wolne Lektury @ Facebook'>
+ <img src="{% static "img/social/f.png" %}" />
+ </a>
<a href="http://nk.pl/profile/30441509"
- title='Wolne Lektury @ NK'>nk</a>
+ title='Wolne Lektury @ NK'>
+ <img src="{% static "img/social/nk.png" %}" />
+ </a>
</div>
</div>
* `Python 2.6+ <http://python.org>`_
* Everyting from the ``requirements.txt`` file
* a library for your database of choice
- (see `DBs supported by Django <http://docs.djangoproject.com/en/dev/topics/install/#get-your-database-running>`_)
-* `puLucene <https://github.com/fnp/pylucene/>`_ for search
-* Librarian dependencies, see lib/librarian/README.md
+ (see `DBs supported by Django <http://docs.djangoproject.com/en/dev/topics/install/#get-your-database-running>`_)
+* `pyLucene <https://github.com/fnp/pylucene/>`_ for search
+* Librarian dependencies for generating PDF and MOBI files,
+ see lib/librarian/README.md
Installation
copy_localsettings()
symlink_current_release()
migrate()
+ collectstatic()
restart_webserver()
def deploy_version(version):
if env.use_south:
run('../../../ve/bin/python manage.py migrate' % env, pty=True)
+def collectstatic():
+ """Collect static files"""
+ print '>>> collectstatic'
+ require('project_name', provided_by=[staging, production])
+ with cd('%(path)s/releases/current/%(project_name)s' % env):
+ run('../../../ve/bin/python manage.py collectstatic --noinput' % env, pty=True)
+
def restart_webserver():
"Restart the web server"
print '>>> restart webserver'
-Subproject commit 9e13b0c994e9d481008bef7006a74609adfd16f8
+Subproject commit fed2483b39e23ecd91ec2d04495a4caac208e94c
HONEYPOT_FIELD_NAME = 'miut'
+PAGINATION_INVALID_PAGE_RAISES_404 = True
+THUMBNAIL_QUALITY = 95
+TRANSLATION_REGISTRY = "wolnelektury.translation"
-PAGINATION_INVALID_PAGE_RAISES_404 = True
-THUMBNAIL_QUALITY = 95
-TRANSLATION_REGISTRY = "wolnelektury.translation"
-
-
# seconds until a changes appears in the changes api
API_WAIT = 10
# limit number of filtering tags
MAX_TAG_LIST = 6
+NO_SEARCH_INDEX = False
NO_BUILD_EPUB = False
NO_BUILD_TXT = False
-NO_BUILD_PDF = False
-NO_BUILD_MOBI = False
-NO_SEARCH_INDEX = False
+# You'll need XeLaTeX to generate PDF files.
+NO_BUILD_PDF = True
+NO_CUSTOM_PDF = True
+# You'll need Calibre installed to generate MOBI files.
+NO_BUILD_MOBI = True
ALL_EPUB_ZIP = 'wolnelektury_pl_epub'
ALL_PDF_ZIP = 'wolnelektury_pl_pdf'
# set to 'new' or 'old' to skip time-consuming test
# for TeX morefloats library version
LIBRARIAN_PDF_MOREFLOATS = None
+
+# Max memory used by search
+JVM_MAXHEAP = '256m'
'js/base.js',
'pdcounter/pdcounter.js',
'sponsors/js/sponsors.js',
+ 'player/openplayer.js',
'js/search.js',
),
'output_filename': 'js/player.min.js',
},
'book': {
- 'source_filenames': ('js/jquery.eventdelegation.js', 'js/jquery.scrollto.js', 'js/jquery.highlightfade.js', 'js/book.js',),
+ 'source_filenames': [
+ 'js/jquery.eventdelegation.js',
+ 'js/jquery.scrollto.js',
+ 'js/jquery.highlightfade.js',
+ 'js/book.js',
+ 'player/openplayer.js',
+ ],
'output_filename': 'js/book.min.js',
},
'book_ie': {
from django.conf.urls.defaults import *
from django.conf import settings
from django.contrib import admin
+from django.views.generic import RedirectView
import wolnelektury_core.views
url(r'^i18n/', include('django.conf.urls.i18n')),
)
-urlpatterns += patterns('django.views.generic.simple',
+urlpatterns += patterns('',
# old static pages - redirected
- url(r'^1procent/$', 'redirect_to',
- {'url': 'http://nowoczesnapolska.org.pl/wesprzyj_nas/'}),
- url(r'^epub/$', 'redirect_to',
- {'url': '/katalog/lektury/'}),
- url(r'^mozesz-nam-pomoc/$', 'redirect_to',
- {'url': '/info/mozesz-nam-pomoc'}),
- url(r'^o-projekcie/$', 'redirect_to',
- {'url': '/info/o-projekcie'}),
- url(r'^widget/$', 'redirect_to',
- {'url': '/info/widget'}),
- url(r'^wolontariat/$', 'redirect_to',
- {'url': '/info/mozesz-nam-pomoc/'}),
+ url(r'^1procent/$', RedirectView.as_view(
+ url='http://nowoczesnapolska.org.pl/wesprzyj_nas/')),
+ url(r'^epub/$', RedirectView.as_view(
+ url='/katalog/lektury/')),
+ url(r'^mozesz-nam-pomoc/$', RedirectView.as_view(
+ url='/info/mozesz-nam-pomoc')),
+ url(r'^o-projekcie/$', RedirectView.as_view(
+ url='/info/o-projekcie')),
+ url(r'^widget/$', RedirectView.as_view(
+ url='/info/widget')),
+ url(r'^wolontariat/$', RedirectView.as_view(
+ url='/info/mozesz-nam-pomoc/')),
)