From 357027375ff8867f42ca34bcbfb5a78b5b185fc3 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 29 Dec 2015 15:19:14 +0100 Subject: [PATCH 01/16] Code layout change. --- .gitignore | 6 ++---- apps/wolnelektury_core/__init__.py | 5 ----- lib/pyscss_compiler.py | 19 ------------------ .../requirements-dev.txt | 0 .../requirements-test.txt | 0 .../requirements.txt | 0 {apps => src}/ajaxable/__init__.py | 0 .../ajaxable/locale/pl/LC_MESSAGES/django.mo | Bin .../ajaxable/locale/pl/LC_MESSAGES/django.po | 0 {apps => src}/ajaxable/models.py | 0 .../ajaxable/templates/ajaxable/form.html | 0 .../templates/ajaxable/form_on_page.html | 0 .../ajaxable/templatetags/__init__.py | 0 .../ajaxable/templatetags/ajaxable_tags.py | 0 {apps => src}/ajaxable/utils.py | 0 {apps => src}/api/__init__.py | 0 {apps => src}/api/emitters.py | 0 {apps => src}/api/handlers.py | 0 {apps => src}/api/helpers.py | 0 .../api/locale/pl/LC_MESSAGES/django.mo | Bin .../api/locale/pl/LC_MESSAGES/django.po | 0 {apps => src}/api/management/__init__.py | 0 .../api/management/commands/__init__.py | 0 .../api/management/commands/mobileinit.py | 0 {apps => src}/api/migrations/0001_initial.py | 0 .../api/migrations/0002_auto_20151221_1225.py | 0 {apps => src}/api/migrations/__init__.py | 0 {apps => src}/api/models.py | 0 {apps => src}/api/settings.py | 0 {apps => src}/api/templates/api/main.html | 0 .../api/templates/oauth/challenge.html | 0 {apps => src}/api/tests.py | 0 {apps => src}/api/urls.py | 0 {lib => src}/basicauth.py | 0 {apps => src}/catalogue/__init__.py | 0 {apps => src}/catalogue/admin.py | 0 {apps => src}/catalogue/apps.py | 0 {apps => src}/catalogue/constants.py | 0 {apps => src}/catalogue/feeds.py | 0 {apps => src}/catalogue/fields.py | 0 .../catalogue/fixtures/collection-boy.json | 0 {apps => src}/catalogue/forms.py | 0 {apps => src}/catalogue/helpers.py | 0 {apps => src}/catalogue/import_utils.py | 0 .../catalogue/locale/de/LC_MESSAGES/django.mo | Bin .../catalogue/locale/de/LC_MESSAGES/django.po | 0 .../catalogue/locale/en/LC_MESSAGES/django.mo | Bin .../catalogue/locale/en/LC_MESSAGES/django.po | 0 .../catalogue/locale/es/LC_MESSAGES/django.mo | Bin .../catalogue/locale/es/LC_MESSAGES/django.po | 0 .../catalogue/locale/fr/LC_MESSAGES/django.mo | Bin .../catalogue/locale/fr/LC_MESSAGES/django.po | 0 .../catalogue/locale/it/LC_MESSAGES/django.mo | Bin .../catalogue/locale/it/LC_MESSAGES/django.po | 0 .../catalogue/locale/jp/LC_MESSAGES/django.mo | Bin .../catalogue/locale/jp/LC_MESSAGES/django.po | 0 .../catalogue/locale/lt/LC_MESSAGES/django.mo | Bin .../catalogue/locale/lt/LC_MESSAGES/django.po | 0 .../catalogue/locale/pl/LC_MESSAGES/django.mo | Bin .../catalogue/locale/pl/LC_MESSAGES/django.po | 0 .../catalogue/locale/ru/LC_MESSAGES/django.mo | Bin .../catalogue/locale/ru/LC_MESSAGES/django.po | 0 .../catalogue/locale/uk/LC_MESSAGES/django.mo | Bin .../catalogue/locale/uk/LC_MESSAGES/django.po | 0 .../catalogue/management/__init__.py | 0 .../catalogue/management/commands/__init__.py | 0 .../management/commands/checkcovers.py | 0 .../management/commands/checkintegrity.py | 0 .../management/commands/importbooks.py | 2 +- .../catalogue/management/commands/pack.py | 0 .../management/commands/report_dead_links.py | 0 .../management/commands/savemedia.py | 0 .../catalogue/migrations/0001_initial.py | 0 .../migrations/0002_book_ancestor.py | 0 .../migrations/0003_populate_ancestors.py | 0 ...0004_remove_booktags_count_related_info.py | 0 .../migrations/0005_auto_20141016_1337.py | 0 .../migrations/0006_auto_20141022_1059.py | 0 .../migrations/0007_auto_20151123_1529.py | 0 .../migrations/0008_auto_20151221_1225.py | 0 .../catalogue/migrations/__init__.py | 0 {apps => src}/catalogue/models/__init__.py | 0 {apps => src}/catalogue/models/book.py | 0 {apps => src}/catalogue/models/bookmedia.py | 0 {apps => src}/catalogue/models/collection.py | 0 {apps => src}/catalogue/models/fragment.py | 0 {apps => src}/catalogue/models/source.py | 0 {apps => src}/catalogue/models/tag.py | 0 {apps => src}/catalogue/signals.py | 0 .../catalogue/static/jplayer/Jplayer.swf | Bin .../static/jplayer/jplayer.blue.monday.css | 0 .../static/jplayer/jplayer.blue.monday.jpg | Bin .../jplayer/jplayer.blue.monday.seeking.gif | Bin .../jplayer.blue.monday.video.play.png | Bin .../static/jplayer/jplayer.playlist.min.js | 0 .../static/jplayer/jquery.jplayer.min.js | 0 .../catalogue/static/player/openplayer.js | 0 .../catalogue/static/player/player.css | 0 .../catalogue/static/player/player.js | 0 {apps => src}/catalogue/tasks.py | 0 .../templates/catalogue/audiobook_list.html | 0 .../templates/catalogue/book_detail.html | 0 .../templates/catalogue/book_fragments.html | 0 .../templates/catalogue/book_info.html | 0 .../templates/catalogue/book_list.html | 0 .../templates/catalogue/book_mini_box.html | 0 .../templates/catalogue/book_searched.html | 0 .../templates/catalogue/book_short.html | 0 .../templates/catalogue/book_text.html | 0 .../templates/catalogue/book_wide.html | 0 .../templates/catalogue/catalogue.html | 0 .../templates/catalogue/collection.html | 0 .../templates/catalogue/collection_list.html | 0 .../templates/catalogue/daisy_list.html | 0 .../catalogue/differentiate_tags.html | 0 .../templates/catalogue/fragment_promo.html | 0 .../templates/catalogue/fragment_short.html | 0 .../templates/catalogue/inline_tag_list.html | 0 .../catalogue/templates/catalogue/menu.html | 0 .../templates/catalogue/picture_detail.html | 0 .../templates/catalogue/picture_list.html | 0 .../catalogue/templates/catalogue/player.html | 0 .../catalogue/recent_audiobooks_list.html | 0 .../catalogue/recent_daisy_list.html | 0 .../templates/catalogue/recent_list.html | 0 .../templates/catalogue/related_books.html | 0 .../catalogue/search_multiple_hits.html | 0 .../templates/catalogue/search_no_hits.html | 0 .../templates/catalogue/search_too_short.html | 0 .../catalogue/snippets/audiobook_list.html | 0 .../catalogue/snippets/book_list.html | 0 .../catalogue/snippets/book_list_nav.html | 0 .../snippets/custom_pdf_link_li.html | 0 .../catalogue/snippets/license_icon.html | 0 .../templates/catalogue/tag_list.html | 0 .../templates/catalogue/tag_list_split.html | 0 .../catalogue/tagged_object_list.html | 0 .../templates/catalogue/viewer_base.html | 0 .../templates/catalogue/work-list.html | 0 .../catalogue/templatetags/__init__.py | 0 .../catalogue/templatetags/catalogue_tags.py | 0 {apps => src}/catalogue/test_utils.py | 0 {apps => src}/catalogue/tests/__init__.py | 0 {apps => src}/catalogue/tests/book_import.py | 0 {apps => src}/catalogue/tests/bookmedia.py | 0 {apps => src}/catalogue/tests/cover.py | 0 .../tests/files/fraszka-do-anusie.xml | 0 .../catalogue/tests/files/fraszki.xml | 0 {apps => src}/catalogue/tests/search.py | 0 {apps => src}/catalogue/tests/tags.py | 0 {apps => src}/catalogue/tests/templatetags.py | 0 {apps => src}/catalogue/tests/visit.py | 0 {apps => src}/catalogue/translation.py | 0 {apps => src}/catalogue/urls.py | 0 {apps => src}/catalogue/utils.py | 0 {apps => src}/catalogue/views.py | 0 {apps => src}/chunks/__init__.py | 0 {apps => src}/chunks/admin.py | 0 .../chunks/locale/de/LC_MESSAGES/django.mo | Bin .../chunks/locale/de/LC_MESSAGES/django.po | 0 .../chunks/locale/en/LC_MESSAGES/django.mo | Bin .../chunks/locale/en/LC_MESSAGES/django.po | 0 .../chunks/locale/es/LC_MESSAGES/django.mo | Bin .../chunks/locale/es/LC_MESSAGES/django.po | 0 .../chunks/locale/fr/LC_MESSAGES/django.mo | Bin .../chunks/locale/fr/LC_MESSAGES/django.po | 0 .../chunks/locale/it/LC_MESSAGES/django.mo | Bin .../chunks/locale/it/LC_MESSAGES/django.po | 0 .../chunks/locale/jp/LC_MESSAGES/django.mo | Bin .../chunks/locale/jp/LC_MESSAGES/django.po | 0 .../chunks/locale/lt/LC_MESSAGES/django.mo | Bin .../chunks/locale/lt/LC_MESSAGES/django.po | 0 .../chunks/locale/pl/LC_MESSAGES/django.mo | Bin .../chunks/locale/pl/LC_MESSAGES/django.po | 0 .../chunks/locale/ru/LC_MESSAGES/django.mo | Bin .../chunks/locale/ru/LC_MESSAGES/django.po | 0 .../chunks/locale/uk/LC_MESSAGES/django.mo | Bin .../chunks/locale/uk/LC_MESSAGES/django.po | 0 .../chunks/migrations/0001_initial.py | 0 .../migrations/0002_auto_20140911_1253.py | 0 .../migrations/0003_auto_20151221_1225.py | 0 {apps => src}/chunks/migrations/__init__.py | 0 {apps => src}/chunks/models.py | 0 {apps => src}/chunks/translation.py | 0 {apps => src}/chunks/urls.py | 0 {apps => src}/chunks/views.py | 0 {apps => src}/dictionary/__init__.py | 0 {apps => src}/dictionary/constants.py | 0 .../locale/pl/LC_MESSAGES/django.mo | Bin .../locale/pl/LC_MESSAGES/django.po | 0 .../dictionary/migrations/0001_initial.py | 0 .../migrations/0002_auto_20141006_1422.py | 0 .../migrations/0003_auto_20141023_1445.py | 0 .../migrations/0004_auto_20151221_1225.py | 0 .../dictionary/migrations/__init__.py | 0 {apps => src}/dictionary/models.py | 0 .../templates/dictionary/note_list.html | 0 .../dictionary/templatetags/__init__.py | 0 .../dictionary/templatetags/set_get.py | 0 {apps => src}/dictionary/tests.py | 0 {apps => src}/dictionary/urls.py | 0 {apps => src}/dictionary/views.py | 0 {apps => src}/funding/__init__.py | 0 {apps => src}/funding/admin.py | 0 {apps => src}/funding/forms.py | 0 .../funding/locale/pl/LC_MESSAGES/django.mo | Bin .../funding/locale/pl/LC_MESSAGES/django.po | 0 {apps => src}/funding/management/__init__.py | 0 .../funding/management/commands/__init__.py | 0 .../management/commands/funding_notify.py | 0 .../funding/migrations/0001_initial.py | 0 .../migrations/0002_auto_20151221_1225.py | 0 {apps => src}/funding/migrations/__init__.py | 0 {apps => src}/funding/models.py | 0 .../funding/static/funding/funding.js | 0 .../admin/funding/offer/change_form.html | 0 .../funding/disable_notifications.html | 0 .../funding/templates/funding/email/base.txt | 0 .../funding/templates/funding/email/end.txt | 0 .../funding/templates/funding/email/near.txt | 0 .../templates/funding/email/published.txt | 0 .../templates/funding/email/thanks.txt | 0 .../templates/funding/includes/funding.html | 0 .../templates/funding/includes/fundings.html | 0 .../funding/includes/offer_status.html | 0 .../funding/includes/offer_status_more.html | 0 .../funding/templates/funding/no_thanks.html | 0 .../templates/funding/offer_detail.html | 0 .../funding/templates/funding/offer_list.html | 0 .../funding/snippets/any_remaining.html | 0 .../funding/templates/funding/thanks.html | 0 .../templates/funding/widgets/amount.html | 0 .../funding/templates/funding/wlfund.html | 0 .../funding/templatetags/__init__.py | 0 .../funding/templatetags/funding_tags.py | 0 {apps => src}/funding/tests.py | 0 {apps => src}/funding/urls.py | 0 {apps => src}/funding/utils.py | 0 {apps => src}/funding/views.py | 0 {apps => src}/funding/widgets.py | 0 {apps => src}/infopages/__init__.py | 0 {apps => src}/infopages/admin.py | 0 .../infopages/fixtures/infopages.json | 0 .../infopages/locale/de/LC_MESSAGES/django.mo | Bin .../infopages/locale/de/LC_MESSAGES/django.po | 0 .../infopages/locale/es/LC_MESSAGES/django.mo | Bin .../infopages/locale/es/LC_MESSAGES/django.po | 0 .../infopages/locale/pl/LC_MESSAGES/django.mo | Bin .../infopages/locale/pl/LC_MESSAGES/django.po | 0 .../infopages/locale/uk/LC_MESSAGES/django.mo | Bin .../infopages/locale/uk/LC_MESSAGES/django.po | 0 .../infopages/migrations/0001_initial.py | 0 .../migrations/0002_auto_20151221_1225.py | 0 .../infopages/migrations/__init__.py | 0 {apps => src}/infopages/models.py | 0 .../templates/infopages/infopage.html | 0 .../templates/infopages/on_main.html | 0 .../infopages/templatetags/__init__.py | 0 .../infopages/templatetags/infopages_tags.py | 0 {apps => src}/infopages/translation.py | 0 {apps => src}/infopages/urls.py | 0 {apps => src}/infopages/views.py | 0 {apps => src}/lesmianator/__init__.py | 0 .../locale/pl/LC_MESSAGES/django.mo | Bin .../locale/pl/LC_MESSAGES/django.po | 0 .../lesmianator/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../management/commands/lesmianator.py | 0 .../lesmianator/migrations/0001_initial.py | 0 .../migrations/0002_auto_20151221_1225.py | 0 .../lesmianator/migrations/__init__.py | 0 {apps => src}/lesmianator/models.py | 0 .../templates/lesmianator/lesmianator.html | 0 .../templates/lesmianator/poem.html | 0 {apps => src}/lesmianator/urls.py | 0 {apps => src}/lesmianator/views.py | 0 {apps => src}/libraries/__init__.py | 0 {apps => src}/libraries/admin.py | 0 .../libraries/locale/pl/LC_MESSAGES/django.mo | Bin .../libraries/locale/pl/LC_MESSAGES/django.po | 0 .../libraries/migrations/0001_initial.py | 0 .../migrations/0002_auto_20151221_1225.py | 0 .../libraries/migrations/__init__.py | 0 {apps => src}/libraries/models.py | 0 .../templates/libraries/catalog_view.html | 0 .../templates/libraries/library_view.html | 0 .../templates/libraries/main_view.html | 0 {apps => src}/libraries/urls.py | 0 {apps => src}/libraries/views.py | 0 manage.py => src/manage.py | 4 +--- {apps => src}/newtagging/__init__.py | 0 {apps => src}/newtagging/admin.py | 0 .../locale/de/LC_MESSAGES/django.mo | Bin .../locale/de/LC_MESSAGES/django.po | 0 .../locale/en/LC_MESSAGES/django.mo | Bin .../locale/en/LC_MESSAGES/django.po | 0 .../locale/es/LC_MESSAGES/django.mo | Bin .../locale/es/LC_MESSAGES/django.po | 0 .../locale/fr/LC_MESSAGES/django.mo | Bin .../locale/fr/LC_MESSAGES/django.po | 0 .../locale/it/LC_MESSAGES/django.mo | Bin .../locale/it/LC_MESSAGES/django.po | 0 .../locale/jp/LC_MESSAGES/django.mo | Bin .../locale/jp/LC_MESSAGES/django.po | 0 .../locale/lt/LC_MESSAGES/django.mo | Bin .../locale/lt/LC_MESSAGES/django.po | 0 .../locale/pl/LC_MESSAGES/django.mo | Bin .../locale/pl/LC_MESSAGES/django.po | 0 .../locale/ru/LC_MESSAGES/django.mo | Bin .../locale/ru/LC_MESSAGES/django.po | 0 .../locale/uk/LC_MESSAGES/django.mo | Bin .../locale/uk/LC_MESSAGES/django.po | 0 {apps => src}/newtagging/managers.py | 0 {apps => src}/newtagging/models.py | 0 {apps => src}/newtagging/views.py | 0 {apps => src}/oai/__init__.py | 0 {apps => src}/oai/handlers.py | 0 {apps => src}/oai/tests/__init__.py | 0 {apps => src}/oai/tests/files/antygona.xml | 0 .../oai/tests/files/lubie-kiedy-kobieta.xml | 0 {apps => src}/oai/tests/oaipmhapi.py | 0 {apps => src}/oai/urls.py | 0 {apps => src}/oai/views.py | 0 {apps => src}/opds/__init__.py | 0 {apps => src}/opds/tests/__init__.py | 0 {apps => src}/opds/tests/files/do-doktora.xml | 0 {apps => src}/opds/urls.py | 0 {apps => src}/opds/views.py | 0 {apps => src}/pdcounter/__init__.py | 0 {apps => src}/pdcounter/admin.py | 0 {apps => src}/pdcounter/fixtures/lista.json | 0 .../pdcounter/locale/de/LC_MESSAGES/django.mo | Bin .../pdcounter/locale/de/LC_MESSAGES/django.po | 0 .../pdcounter/locale/en/LC_MESSAGES/django.mo | Bin .../pdcounter/locale/en/LC_MESSAGES/django.po | 0 .../pdcounter/locale/es/LC_MESSAGES/django.mo | Bin .../pdcounter/locale/es/LC_MESSAGES/django.po | 0 .../pdcounter/locale/fr/LC_MESSAGES/django.mo | Bin .../pdcounter/locale/fr/LC_MESSAGES/django.po | 0 .../pdcounter/locale/it/LC_MESSAGES/django.mo | Bin .../pdcounter/locale/it/LC_MESSAGES/django.po | 0 .../pdcounter/locale/jp/LC_MESSAGES/django.mo | Bin .../pdcounter/locale/jp/LC_MESSAGES/django.po | 0 .../pdcounter/locale/lt/LC_MESSAGES/django.mo | Bin .../pdcounter/locale/lt/LC_MESSAGES/django.po | 0 .../pdcounter/locale/pl/LC_MESSAGES/django.mo | Bin .../pdcounter/locale/pl/LC_MESSAGES/django.po | 0 .../pdcounter/locale/ru/LC_MESSAGES/django.mo | Bin .../pdcounter/locale/ru/LC_MESSAGES/django.po | 0 .../pdcounter/locale/uk/LC_MESSAGES/django.mo | Bin .../pdcounter/locale/uk/LC_MESSAGES/django.po | 0 .../pdcounter/migrations/0001_initial.py | 0 .../migrations/0002_auto_20151221_1225.py | 0 .../pdcounter/migrations/__init__.py | 0 {apps => src}/pdcounter/models.py | 0 .../pdcounter/static/pdcounter/pdcounter.js | 0 .../templates/pdcounter/author_detail.html | 0 .../templates/pdcounter/book_stub_detail.html | 0 .../pdcounter/templatetags/__init__.py | 0 .../pdcounter/templatetags/time_tags.py | 0 {apps => src}/pdcounter/views.py | 0 {apps => src}/picture/__init__.py | 0 {apps => src}/picture/admin.py | 0 {apps => src}/picture/engine.py | 0 {apps => src}/picture/forms.py | 0 .../picture/locale/de/LC_MESSAGES/django.mo | Bin .../picture/locale/de/LC_MESSAGES/django.po | 0 .../picture/locale/en/LC_MESSAGES/django.mo | Bin .../picture/locale/en/LC_MESSAGES/django.po | 0 .../picture/locale/es/LC_MESSAGES/django.mo | Bin .../picture/locale/es/LC_MESSAGES/django.po | 0 .../picture/locale/fr/LC_MESSAGES/django.mo | Bin .../picture/locale/fr/LC_MESSAGES/django.po | 0 .../picture/locale/it/LC_MESSAGES/django.mo | Bin .../picture/locale/it/LC_MESSAGES/django.po | 0 .../picture/locale/jp/LC_MESSAGES/django.mo | Bin .../picture/locale/jp/LC_MESSAGES/django.po | 0 .../picture/locale/lt/LC_MESSAGES/django.mo | Bin .../picture/locale/lt/LC_MESSAGES/django.po | 0 .../picture/locale/pl/LC_MESSAGES/django.mo | Bin .../picture/locale/pl/LC_MESSAGES/django.po | 0 .../picture/locale/ru/LC_MESSAGES/django.mo | Bin .../picture/locale/ru/LC_MESSAGES/django.po | 0 .../picture/locale/uk/LC_MESSAGES/django.mo | Bin .../picture/locale/uk/LC_MESSAGES/django.po | 0 .../picture/migrations/0001_initial.py | 0 .../0002_remove_picture__related_info.py | 0 .../migrations/0003_auto_20140924_1559.py | 0 .../migrations/0004_auto_20141016_1337.py | 0 .../migrations/0005_auto_20141022_1001.py | 0 .../migrations/0006_auto_20151221_1225.py | 0 {apps => src}/picture/migrations/__init__.py | 0 {apps => src}/picture/models.py | 0 {apps => src}/picture/tasks.py | 0 .../admin/picture/picture/change_list.html | 0 .../picture/templates/picture/collection.html | 0 .../templates/picture/picture_detail.html | 0 .../templates/picture/picture_info.html | 0 .../templates/picture/picture_list_thumb.html | 0 .../templates/picture/picture_mini_box.html | 0 .../templates/picture/picture_short.html | 0 .../templates/picture/picture_viewer.html | 0 .../templates/picture/picture_wide.html | 0 .../templates/picture/picturearea_short.html | 0 .../picture/templatetags/__init__.py | 0 .../picture/templatetags/picture_tags.py | 0 {apps => src}/picture/tests/__init__.py | 0 .../files/kandinsky-composition-viii.png | Bin .../files/kandinsky-composition-viii.xml | 0 {apps => src}/picture/tests/picture_import.py | 0 {apps => src}/picture/views.py | 0 {apps => src}/polls/__init__.py | 0 {apps => src}/polls/admin.py | 0 {apps => src}/polls/forms.py | 0 .../polls/locale/pl/LC_MESSAGES/django.mo | Bin .../polls/locale/pl/LC_MESSAGES/django.po | 0 .../polls/migrations/0001_initial.py | 0 .../migrations/0002_auto_20151221_1225.py | 0 {apps => src}/polls/migrations/__init__.py | 0 {apps => src}/polls/models.py | 0 {apps => src}/polls/templates/polls/poll.html | 0 .../polls/templates/polls/tags/poll.html | 0 {apps => src}/polls/templatetags/__init__.py | 0 .../polls/templatetags/polls_tags.py | 0 {apps => src}/polls/urls.py | 0 {apps => src}/polls/views.py | 0 {apps => src}/reporting/__init__.py | 0 .../reporting/locale/pl/LC_MESSAGES/django.mo | Bin .../reporting/locale/pl/LC_MESSAGES/django.po | 0 {apps => src}/reporting/models.py | 0 .../templates/reporting/catalogue.csv | 0 .../templates/reporting/catalogue.texml | 0 .../reporting/templates/reporting/main.html | 0 .../reporting/templatetags/__init__.py | 0 .../reporting/templatetags/reporting_stats.py | 0 {apps => src}/reporting/urls.py | 0 {apps => src}/reporting/utils.py | 0 {apps => src}/reporting/views.py | 0 {apps => src}/search/__init__.py | 0 {apps => src}/search/context_processors.py | 0 {apps => src}/search/custom.py | 0 {apps => src}/search/fields.py | 0 {apps => src}/search/forms.py | 0 {apps => src}/search/index.py | 0 .../search/locale/de/LC_MESSAGES/django.mo | Bin .../search/locale/de/LC_MESSAGES/django.po | 0 .../search/locale/en/LC_MESSAGES/django.mo | Bin .../search/locale/en/LC_MESSAGES/django.po | 0 .../search/locale/es/LC_MESSAGES/django.mo | Bin .../search/locale/es/LC_MESSAGES/django.po | 0 .../search/locale/fr/LC_MESSAGES/django.mo | Bin .../search/locale/fr/LC_MESSAGES/django.po | 0 .../search/locale/it/LC_MESSAGES/django.mo | Bin .../search/locale/it/LC_MESSAGES/django.po | 0 .../search/locale/jp/LC_MESSAGES/django.mo | Bin .../search/locale/jp/LC_MESSAGES/django.po | 0 .../search/locale/lt/LC_MESSAGES/django.mo | Bin .../search/locale/lt/LC_MESSAGES/django.po | 0 .../search/locale/pl/LC_MESSAGES/django.mo | Bin .../search/locale/pl/LC_MESSAGES/django.po | 0 .../search/locale/ru/LC_MESSAGES/django.mo | Bin .../search/locale/ru/LC_MESSAGES/django.po | 0 .../search/locale/uk/LC_MESSAGES/django.mo | Bin .../search/locale/uk/LC_MESSAGES/django.po | 0 {apps => src}/search/management/__init__.py | 0 .../search/management/commands/__init__.py | 0 .../search/management/commands/reindex.py | 0 .../search/management/commands/snippets.py | 0 {apps => src}/search/mock_search.py | 0 .../search/templates/newsearch/search.html | 0 {apps => src}/search/templatetags/__init__.py | 0 .../search/templatetags/search_tags.py | 0 {apps => src}/search/tests/__init__.py | 0 {apps => src}/search/tests/index.py | 0 {apps => src}/search/urls.py | 0 {apps => src}/search/views.py | 0 {apps => src}/social/__init__.py | 0 {apps => src}/social/admin.py | 0 {apps => src}/social/forms.py | 0 .../social/locale/pl/LC_MESSAGES/django.mo | Bin .../social/locale/pl/LC_MESSAGES/django.po | 0 .../social/migrations/0001_initial.py | 0 .../migrations/0002_auto_20151221_1225.py | 0 {apps => src}/social/migrations/__init__.py | 0 {apps => src}/social/models.py | 0 .../social/templates/social/cite_info.html | 0 .../social/templates/social/cite_promo.html | 0 .../social/templates/social/my_shelf.html | 0 .../social/templates/social/sets_form.html | 0 .../social/templates/social/shelf_tags.html | 0 {apps => src}/social/templatetags/__init__.py | 0 .../social/templatetags/social_tags.py | 0 {apps => src}/social/urls.py | 0 {apps => src}/social/utils.py | 0 {apps => src}/social/views.py | 0 {lib => src}/sortify.py | 0 {apps => src}/sponsors/__init__.py | 0 {apps => src}/sponsors/admin.py | 0 .../sponsors/locale/de/LC_MESSAGES/django.mo | Bin .../sponsors/locale/de/LC_MESSAGES/django.po | 0 .../sponsors/locale/en/LC_MESSAGES/django.mo | Bin .../sponsors/locale/en/LC_MESSAGES/django.po | 0 .../sponsors/locale/es/LC_MESSAGES/django.mo | Bin .../sponsors/locale/es/LC_MESSAGES/django.po | 0 .../sponsors/locale/fr/LC_MESSAGES/django.mo | Bin .../sponsors/locale/fr/LC_MESSAGES/django.po | 0 .../sponsors/locale/it/LC_MESSAGES/django.mo | Bin .../sponsors/locale/it/LC_MESSAGES/django.po | 0 .../sponsors/locale/jp/LC_MESSAGES/django.mo | Bin .../sponsors/locale/jp/LC_MESSAGES/django.po | 0 .../sponsors/locale/lt/LC_MESSAGES/django.mo | Bin .../sponsors/locale/lt/LC_MESSAGES/django.po | 0 .../sponsors/locale/pl/LC_MESSAGES/django.mo | Bin .../sponsors/locale/pl/LC_MESSAGES/django.po | 0 .../sponsors/locale/ru/LC_MESSAGES/django.mo | Bin .../sponsors/locale/ru/LC_MESSAGES/django.po | 0 .../sponsors/locale/uk/LC_MESSAGES/django.mo | Bin .../sponsors/locale/uk/LC_MESSAGES/django.po | 0 .../sponsors/migrations/0001_initial.py | 0 .../migrations/0002_auto_20151221_1225.py | 0 {apps => src}/sponsors/migrations/__init__.py | 0 {apps => src}/sponsors/models.py | 0 .../static/sponsors/css/footer_admin.css | 0 .../sponsors/static/sponsors/css/sponsors.css | 0 .../static/sponsors/js/footer_admin.js | 0 .../static/sponsors/js/jquery.json.min.js | 0 .../sponsors/static/sponsors/js/sponsors.js | 0 .../sponsors/templates/sponsors/page.html | 0 {apps => src}/sponsors/urls.py | 0 {apps => src}/sponsors/views.py | 0 {apps => src}/sponsors/widgets.py | 0 {apps => src}/stats/__init__.py | 0 {apps => src}/stats/models.py | 0 {apps => src}/stats/tasks.py | 0 {apps => src}/stats/utils.py | 0 {apps => src}/suggest/__init__.py | 0 {apps => src}/suggest/admin.py | 0 {apps => src}/suggest/forms.py | 0 .../suggest/locale/de/LC_MESSAGES/django.mo | Bin .../suggest/locale/de/LC_MESSAGES/django.po | 0 .../suggest/locale/en/LC_MESSAGES/django.mo | Bin .../suggest/locale/en/LC_MESSAGES/django.po | 0 .../suggest/locale/es/LC_MESSAGES/django.mo | Bin .../suggest/locale/es/LC_MESSAGES/django.po | 0 .../suggest/locale/fr/LC_MESSAGES/django.mo | Bin .../suggest/locale/fr/LC_MESSAGES/django.po | 0 .../suggest/locale/it/LC_MESSAGES/django.mo | Bin .../suggest/locale/it/LC_MESSAGES/django.po | 0 .../suggest/locale/jp/LC_MESSAGES/django.mo | Bin .../suggest/locale/jp/LC_MESSAGES/django.po | 0 .../suggest/locale/lt/LC_MESSAGES/django.mo | Bin .../suggest/locale/lt/LC_MESSAGES/django.po | 0 .../suggest/locale/pl/LC_MESSAGES/django.mo | Bin .../suggest/locale/pl/LC_MESSAGES/django.po | 0 .../suggest/locale/ru/LC_MESSAGES/django.mo | Bin .../suggest/locale/ru/LC_MESSAGES/django.po | 0 .../suggest/locale/uk/LC_MESSAGES/django.mo | Bin .../suggest/locale/uk/LC_MESSAGES/django.po | 0 .../suggest/migrations/0001_initial.py | 0 .../migrations/0002_auto_20151221_1225.py | 0 {apps => src}/suggest/migrations/__init__.py | 0 {apps => src}/suggest/models.py | 0 .../suggest/templates/publishing_suggest.html | 0 {apps => src}/suggest/urls.py | 0 {apps => src}/suggest/views.py | 0 {apps => src}/waiter/__init__.py | 0 .../waiter/locale/pl/LC_MESSAGES/django.mo | Bin .../waiter/locale/pl/LC_MESSAGES/django.po | 0 .../waiter/migrations/0001_initial.py | 0 {apps => src}/waiter/migrations/__init__.py | 0 {apps => src}/waiter/models.py | 0 {apps => src}/waiter/settings.py | 0 {apps => src}/waiter/tasks.py | 0 .../waiter/templates/waiter/wait.html | 0 {apps => src}/waiter/urls.py | 0 {apps => src}/waiter/utils.py | 0 {apps => src}/waiter/views.py | 0 src/wolnelektury/__init__.py | 7 +++++++ .../wolnelektury}/apps.py | 2 +- {wolnelektury => src/wolnelektury}/celery.py | 0 .../wolnelektury}/context_processors.py | 0 .../locale-contrib/de/LC_MESSAGES/django.mo | Bin .../locale-contrib/de/LC_MESSAGES/django.po | 0 .../wolnelektury}/locale-contrib/django.pot | 0 .../locale-contrib/en/LC_MESSAGES/django.mo | Bin .../locale-contrib/en/LC_MESSAGES/django.po | 0 .../locale-contrib/es/LC_MESSAGES/django.mo | Bin .../locale-contrib/es/LC_MESSAGES/django.po | 0 .../locale-contrib/fr/LC_MESSAGES/django.mo | Bin .../locale-contrib/fr/LC_MESSAGES/django.po | 0 .../locale-contrib/it/LC_MESSAGES/django.mo | Bin .../locale-contrib/it/LC_MESSAGES/django.po | 0 .../locale-contrib/lt/LC_MESSAGES/django.mo | Bin .../locale-contrib/lt/LC_MESSAGES/django.po | 0 .../locale-contrib/pl/LC_MESSAGES/django.mo | Bin .../locale-contrib/pl/LC_MESSAGES/django.po | 0 .../locale-contrib/ru/LC_MESSAGES/django.mo | Bin .../locale-contrib/ru/LC_MESSAGES/django.po | 0 .../locale-contrib/uk/LC_MESSAGES/django.mo | Bin .../locale-contrib/uk/LC_MESSAGES/django.po | 0 .../locale/de/LC_MESSAGES/django.mo | Bin .../locale/de/LC_MESSAGES/django.po | 0 .../locale/en/LC_MESSAGES/django.mo | Bin .../locale/en/LC_MESSAGES/django.po | 0 .../locale/es/LC_MESSAGES/django.mo | Bin .../locale/es/LC_MESSAGES/django.po | 0 .../locale/fr/LC_MESSAGES/django.mo | Bin .../locale/fr/LC_MESSAGES/django.po | 0 .../locale/it/LC_MESSAGES/django.mo | Bin .../locale/it/LC_MESSAGES/django.po | 0 .../locale/jp/LC_MESSAGES/django.mo | Bin .../locale/jp/LC_MESSAGES/django.po | 0 .../locale/lt/LC_MESSAGES/django.mo | Bin .../locale/lt/LC_MESSAGES/django.po | 0 .../locale/pl/LC_MESSAGES/django.mo | Bin .../locale/pl/LC_MESSAGES/django.po | 0 .../locale/ru/LC_MESSAGES/django.mo | Bin .../locale/ru/LC_MESSAGES/django.po | 0 .../locale/uk/LC_MESSAGES/django.mo | Bin .../locale/uk/LC_MESSAGES/django.po | 0 .../wolnelektury}/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../management/commands/localepack.py | 0 .../management/commands/translation2po.py | 0 .../wolnelektury}/management/profile.py | 0 .../wolnelektury}/middleware.py | 0 .../wolnelektury/migrations}/__init__.py | 0 .../migrations/getpaid/0001_initial.py | 0 .../getpaid/0002_auto_20151221_1225.py | 0 .../migrations/getpaid}/__init__.py | 0 .../migrations/piston/0001_initial.py | 0 .../migrations/piston}/__init__.py | 0 .../wolnelektury}/settings/__init__.py | 4 ++-- .../wolnelektury}/settings/auth.py | 0 .../wolnelektury}/settings/basic.py | 0 .../wolnelektury}/settings/cache.py | 0 .../wolnelektury}/settings/celery.py | 0 .../wolnelektury}/settings/contrib.py | 0 .../wolnelektury}/settings/custom.py | 0 .../wolnelektury}/settings/locale.py | 0 src/wolnelektury/settings/paths.py | 6 ++++++ .../wolnelektury}/settings/static.py | 8 ++++---- .../wolnelektury}/signals.py | 0 .../wolnelektury}/static/css/annoy.css | 0 .../static/css/jquery.countdown.css | 0 .../wolnelektury}/static/css/master.book.css | 0 .../static/css/master.picture.css | 0 .../wolnelektury}/static/css/new.book.css | 0 .../wolnelektury}/static/css/picture_box.css | 0 .../wolnelektury}/static/css/simple.css | 0 .../ui-bg_diagonals-thick_18_b81900_40x40.png | Bin .../ui-bg_diagonals-thick_20_666666_40x40.png | Bin .../images/ui-bg_flat_10_000000_40x100.png | Bin .../images/ui-bg_glass_100_f6f6f6_1x400.png | Bin .../images/ui-bg_glass_100_fdf5ce_1x400.png | Bin .../images/ui-bg_glass_65_ffffff_1x400.png | Bin .../ui-bg_gloss-wave_35_f6a828_500x100.png | Bin .../ui-bg_highlight-soft_100_eeeeee_1x100.png | Bin .../ui-bg_highlight-soft_75_ffe45c_1x100.png | Bin .../images/ui-icons_222222_256x240.png | Bin .../images/ui-icons_228ef1_256x240.png | Bin .../images/ui-icons_ef8c08_256x240.png | Bin .../images/ui-icons_ffd27a_256x240.png | Bin .../images/ui-icons_ffffff_256x240.png | Bin .../ui-lightness/jquery-ui-1.8.16.custom.css | 0 .../wolnelektury}/static/img/1percent-big.png | Bin .../static/img/android-poster.png | Bin .../wolnelektury}/static/img/arrow-down.png | Bin .../wolnelektury}/static/img/arrow-gray.png | Bin .../wolnelektury}/static/img/arrow-gray.svg | 0 .../wolnelektury}/static/img/arrow-teal.png | Bin .../wolnelektury}/static/img/arrow-teal.svg | 0 .../wolnelektury}/static/img/arrow-up.png | Bin .../static/img/auth/facebook.png | Bin .../wolnelektury}/static/img/auth/google.png | Bin .../wolnelektury}/static/img/auth/openid.png | Bin .../wolnelektury}/static/img/auth/twitter.png | Bin .../img/backdrop/boltron-3212284622.jpg | Bin .../static/img/backdrop/book-drawer2.jpg | Bin .../img/backdrop/horiavarlan-4268896468.jpg | Bin .../wolnelektury}/static/img/bg-header.png | Bin .../wolnelektury}/static/img/bg.png | Bin .../wolnelektury}/static/img/book-parent.png | Bin .../wolnelektury}/static/img/book.png | Bin .../static/img/doodle/20110908-android.png | Bin .../static/img/doodle/20110908-logo.png | Bin .../wolnelektury}/static/img/download.png | Bin .../wolnelektury}/static/img/download.svg | 0 .../wolnelektury}/static/img/epub-www.jpg | Bin .../wolnelektury}/static/img/epub.png | Bin .../wolnelektury}/static/img/favicon.ico | Bin .../wolnelektury}/static/img/favicon.png | Bin .../wolnelektury}/static/img/indicator.gif | Bin .../static/img/kindle-poster-260.png | Bin .../static/img/kindle-poster.png | Bin .../static/img/licenses/cc-by-sa.png | Bin .../static/img/licenses/cc-by-sa.svg | 0 .../wolnelektury}/static/img/listen.png | Bin .../wolnelektury}/static/img/listen.svg | 0 .../wolnelektury}/static/img/logo-220.png | Bin .../wolnelektury}/static/img/logo-bez.png | Bin .../wolnelektury}/static/img/logo-big.png | Bin .../wolnelektury}/static/img/logo-fbc.png | Bin .../wolnelektury}/static/img/logo-neon.png | Bin .../wolnelektury}/static/img/logo.png | Bin .../wolnelektury}/static/img/logo_nck.jpg | Bin .../static/img/logo_nck_200horiz_trans.png | Bin .../static/img/logo_nck_200trans.png | Bin .../wolnelektury}/static/img/mobi.png | Bin .../wolnelektury}/static/img/odt.png | Bin .../wolnelektury}/static/img/payu.png | Bin .../wolnelektury}/static/img/pdf.png | Bin .../wolnelektury}/static/img/procent.png | Bin .../static/img/progress-pixel.png | Bin .../wolnelektury}/static/img/read.png | Bin .../wolnelektury}/static/img/read.svg | 0 .../wolnelektury}/static/img/s5/blank.gif | Bin .../wolnelektury}/static/img/s5/bodybg.gif | Bin .../wolnelektury}/static/img/s5/iepngfix.htc | 0 .../wolnelektury}/static/img/search.png | Bin .../static/img/social/bigfacebook.png | Bin .../static/img/social/biggoogle.png | Bin .../wolnelektury}/static/img/social/bignk.png | Bin .../static/img/social/bigtwitter.png | Bin .../wolnelektury}/static/img/social/f.png | Bin .../wolnelektury}/static/img/social/f.svg | 0 .../wolnelektury}/static/img/social/gplus.png | Bin .../wolnelektury}/static/img/social/gplus.svg | 0 .../wolnelektury}/static/img/social/nk.png | Bin .../wolnelektury}/static/img/social/nk.svg | 0 .../wolnelektury}/static/img/speaker.png | Bin .../wolnelektury}/static/img/turniej-maly.png | Bin .../wolnelektury}/static/img/txt.png | Bin .../wolnelektury}/static/img/wiatrak.png | Bin .../wolnelektury}/static/img/wl_icon_64.png | Bin .../wolnelektury}/static/img/zabawnik.png | Bin .../wolnelektury}/static/js/annoy.js | 0 .../wolnelektury}/static/js/base.js | 0 .../wolnelektury}/static/js/book.js | 0 .../wolnelektury}/static/js/book_text/info.js | 0 .../wolnelektury}/static/js/book_text/menu.js | 0 .../wolnelektury}/static/js/book_text/note.js | 0 .../static/js/book_text/settings.js | 0 .../wolnelektury}/static/js/book_text/toc.js | 0 .../static/js/contrib/ierange-m2.js | 0 .../js/contrib/jquery-ui-1.8.16.custom.min.js | 0 .../static/js/contrib/jquery.autocomplete.js | 0 .../static/js/contrib/jquery.countdown-de.js | 0 .../static/js/contrib/jquery.countdown-es.js | 0 .../static/js/contrib/jquery.countdown-fr.js | 0 .../static/js/contrib/jquery.countdown-lt.js | 0 .../static/js/contrib/jquery.countdown-pl.js | 0 .../static/js/contrib/jquery.countdown-ru.js | 0 .../static/js/contrib/jquery.countdown-uk.js | 0 .../static/js/contrib/jquery.countdown.js | 0 .../static/js/contrib/jquery.cycle.min.js | 0 .../js/contrib/jquery.eventdelegation.js | 0 .../static/js/contrib/jquery.form.js | 0 .../static/js/contrib/jquery.highlightfade.js | 0 .../static/js/contrib/jquery.jqmodal.js | 0 .../wolnelektury}/static/js/contrib/jquery.js | 0 .../static/js/contrib/jquery.scrollto.js | 0 .../js/contrib/modernizr.custom.19652.js | 0 .../static/js/contrib/progressSpin.min.js | 0 .../static/js/contrib/raphael-min.js | 0 .../wolnelektury}/static/js/dialogs.js | 0 .../wolnelektury}/static/js/locale.js | 0 .../wolnelektury}/static/js/picture.js | 0 .../wolnelektury}/static/js/search.js | 0 .../wolnelektury}/static/js/widget.js | 0 .../wolnelektury}/static/js/widget_run.js | 0 .../wolnelektury}/static/opensearch.xml | 0 .../wolnelektury}/static/scss/book_text.scss | 0 .../static/scss/book_text/body.scss | 0 .../static/scss/book_text/book_box.scss | 0 .../static/scss/book_text/box.scss | 0 .../static/scss/book_text/const.scss | 0 .../static/scss/book_text/info.scss | 0 .../static/scss/book_text/menu.scss | 0 .../static/scss/book_text/note.scss | 0 .../static/scss/book_text/numbering.scss | 0 .../static/scss/book_text/other.scss | 0 .../static/scss/book_text/settings.scss | 0 .../static/scss/book_text/themes.scss | 0 .../static/scss/book_text/toc.scss | 0 .../static/scss/dictionary/dictionary.scss | 0 .../static/scss/funding/funding.scss | 0 .../wolnelektury}/static/scss/main.scss | 0 .../wolnelektury}/static/scss/main/auth.scss | 0 .../wolnelektury}/static/scss/main/base.scss | 0 .../static/scss/main/book_box.scss | 0 .../static/scss/main/book_list.scss | 0 .../static/scss/main/catalogue.scss | 0 .../wolnelektury}/static/scss/main/cite.scss | 0 .../wolnelektury}/static/scss/main/const.scss | 0 .../static/scss/main/dialogs.scss | 0 .../static/scss/main/footer.scss | 0 .../wolnelektury}/static/scss/main/form.scss | 0 .../static/scss/main/fragment.scss | 0 .../static/scss/main/header.scss | 0 .../static/scss/main/hidden.scss | 0 .../static/scss/main/main_content.scss | 0 .../static/scss/main/main_page.scss | 0 .../wolnelektury}/static/scss/main/menu.scss | 0 .../static/scss/main/picture_box.scss | 0 .../static/scss/main/search.scss | 0 .../wolnelektury}/static/scss/main/tag.scss | 0 .../static/scss/polls/polls.scss | 0 .../static/scss/social/shelf_tags.scss | 0 .../wolnelektury}/static/scss/tools.scss | 0 .../wolnelektury}/static/scss/widget.scss | 0 .../wolnelektury}/templates/404.html | 0 .../wolnelektury}/templates/500.html | 0 .../wolnelektury}/templates/503.html | 0 .../wolnelektury}/templates/account/base.html | 0 .../templates/admin/base_site.html | 0 .../admin/catalogue/book/change_form.html | 0 .../admin/catalogue/book/change_list.html | 0 .../wolnelektury}/templates/annoy.html | 0 .../wolnelektury}/templates/auth/login.html | 0 .../templates/auth/login_register.html | 0 .../templates/auth/register.html | 0 .../wolnelektury}/templates/base.html | 0 .../wolnelektury}/templates/info/join_us.html | 0 .../templates/latest_blog_posts.html | 0 .../wolnelektury}/templates/main_page.html | 0 .../wolnelektury}/templates/openid/login.html | 0 .../templates/pagination/pagination.html | 0 .../templates/piston/authorize_token.html | 0 .../wolnelektury}/templates/publish_plan.html | 0 .../wolnelektury}/templates/site_base.html | 0 .../templates/socialaccount/connections.html | 0 .../socialaccount/login_cancelled.html | 0 .../socialaccount/snippets/login_extra.html | 0 .../socialaccount/snippets/provider_list.html | 0 .../wolnelektury}/templates/superbase.html | 0 .../wolnelektury}/templates/user.html | 0 .../wolnelektury}/templates/widget.html | 0 .../wolnelektury/templatetags}/__init__.py | 0 .../wolnelektury}/templatetags/common_tags.py | 0 .../wolnelektury}/templatetags/switch_tag.py | 0 {wolnelektury => src/wolnelektury}/urls.py | 12 +++++------ {wolnelektury => src/wolnelektury}/utils.py | 0 .../wolnelektury}/views.py | 0 {wolnelektury => src/wolnelektury}/wsgi.py | 5 +---- wolnelektury/__init__.py | 1 - wolnelektury/settings/paths.py | 3 --- 847 files changed, 31 insertions(+), 53 deletions(-) delete mode 100644 apps/wolnelektury_core/__init__.py delete mode 100644 lib/pyscss_compiler.py rename requirements-dev.txt => requirements/requirements-dev.txt (100%) rename requirements-test.txt => requirements/requirements-test.txt (100%) rename requirements.txt => requirements/requirements.txt (100%) rename {apps => src}/ajaxable/__init__.py (100%) rename {apps => src}/ajaxable/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/ajaxable/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/ajaxable/models.py (100%) rename {apps => src}/ajaxable/templates/ajaxable/form.html (100%) rename {apps => src}/ajaxable/templates/ajaxable/form_on_page.html (100%) rename {apps => src}/ajaxable/templatetags/__init__.py (100%) rename {apps => src}/ajaxable/templatetags/ajaxable_tags.py (100%) rename {apps => src}/ajaxable/utils.py (100%) rename {apps => src}/api/__init__.py (100%) rename {apps => src}/api/emitters.py (100%) rename {apps => src}/api/handlers.py (100%) rename {apps => src}/api/helpers.py (100%) rename {apps => src}/api/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/api/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/api/management/__init__.py (100%) rename {apps => src}/api/management/commands/__init__.py (100%) rename {apps => src}/api/management/commands/mobileinit.py (100%) rename {apps => src}/api/migrations/0001_initial.py (100%) rename {apps => src}/api/migrations/0002_auto_20151221_1225.py (100%) rename {apps => src}/api/migrations/__init__.py (100%) rename {apps => src}/api/models.py (100%) rename {apps => src}/api/settings.py (100%) rename {apps => src}/api/templates/api/main.html (100%) rename {apps => src}/api/templates/oauth/challenge.html (100%) rename {apps => src}/api/tests.py (100%) rename {apps => src}/api/urls.py (100%) rename {lib => src}/basicauth.py (100%) rename {apps => src}/catalogue/__init__.py (100%) rename {apps => src}/catalogue/admin.py (100%) rename {apps => src}/catalogue/apps.py (100%) rename {apps => src}/catalogue/constants.py (100%) rename {apps => src}/catalogue/feeds.py (100%) rename {apps => src}/catalogue/fields.py (100%) rename {apps => src}/catalogue/fixtures/collection-boy.json (100%) rename {apps => src}/catalogue/forms.py (100%) rename {apps => src}/catalogue/helpers.py (100%) rename {apps => src}/catalogue/import_utils.py (100%) rename {apps => src}/catalogue/locale/de/LC_MESSAGES/django.mo (100%) rename {apps => src}/catalogue/locale/de/LC_MESSAGES/django.po (100%) rename {apps => src}/catalogue/locale/en/LC_MESSAGES/django.mo (100%) rename {apps => src}/catalogue/locale/en/LC_MESSAGES/django.po (100%) rename {apps => src}/catalogue/locale/es/LC_MESSAGES/django.mo (100%) rename {apps => src}/catalogue/locale/es/LC_MESSAGES/django.po (100%) rename {apps => src}/catalogue/locale/fr/LC_MESSAGES/django.mo (100%) rename {apps => src}/catalogue/locale/fr/LC_MESSAGES/django.po (100%) rename {apps => src}/catalogue/locale/it/LC_MESSAGES/django.mo (100%) rename {apps => src}/catalogue/locale/it/LC_MESSAGES/django.po (100%) rename {apps => src}/catalogue/locale/jp/LC_MESSAGES/django.mo (100%) rename {apps => src}/catalogue/locale/jp/LC_MESSAGES/django.po (100%) rename {apps => src}/catalogue/locale/lt/LC_MESSAGES/django.mo (100%) rename {apps => src}/catalogue/locale/lt/LC_MESSAGES/django.po (100%) rename {apps => src}/catalogue/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/catalogue/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/catalogue/locale/ru/LC_MESSAGES/django.mo (100%) rename {apps => src}/catalogue/locale/ru/LC_MESSAGES/django.po (100%) rename {apps => src}/catalogue/locale/uk/LC_MESSAGES/django.mo (100%) rename {apps => src}/catalogue/locale/uk/LC_MESSAGES/django.po (100%) rename {apps => src}/catalogue/management/__init__.py (100%) rename {apps => src}/catalogue/management/commands/__init__.py (100%) rename {apps => src}/catalogue/management/commands/checkcovers.py (100%) rename {apps => src}/catalogue/management/commands/checkintegrity.py (100%) rename {apps => src}/catalogue/management/commands/importbooks.py (99%) rename {apps => src}/catalogue/management/commands/pack.py (100%) rename {apps => src}/catalogue/management/commands/report_dead_links.py (100%) rename {apps => src}/catalogue/management/commands/savemedia.py (100%) rename {apps => src}/catalogue/migrations/0001_initial.py (100%) rename {apps => src}/catalogue/migrations/0002_book_ancestor.py (100%) rename {apps => src}/catalogue/migrations/0003_populate_ancestors.py (100%) rename {apps => src}/catalogue/migrations/0004_remove_booktags_count_related_info.py (100%) rename {apps => src}/catalogue/migrations/0005_auto_20141016_1337.py (100%) rename {apps => src}/catalogue/migrations/0006_auto_20141022_1059.py (100%) rename {apps => src}/catalogue/migrations/0007_auto_20151123_1529.py (100%) rename {apps => src}/catalogue/migrations/0008_auto_20151221_1225.py (100%) rename {apps => src}/catalogue/migrations/__init__.py (100%) rename {apps => src}/catalogue/models/__init__.py (100%) rename {apps => src}/catalogue/models/book.py (100%) rename {apps => src}/catalogue/models/bookmedia.py (100%) rename {apps => src}/catalogue/models/collection.py (100%) rename {apps => src}/catalogue/models/fragment.py (100%) rename {apps => src}/catalogue/models/source.py (100%) rename {apps => src}/catalogue/models/tag.py (100%) rename {apps => src}/catalogue/signals.py (100%) rename {apps => src}/catalogue/static/jplayer/Jplayer.swf (100%) rename {apps => src}/catalogue/static/jplayer/jplayer.blue.monday.css (100%) rename {apps => src}/catalogue/static/jplayer/jplayer.blue.monday.jpg (100%) rename {apps => src}/catalogue/static/jplayer/jplayer.blue.monday.seeking.gif (100%) rename {apps => src}/catalogue/static/jplayer/jplayer.blue.monday.video.play.png (100%) rename {apps => src}/catalogue/static/jplayer/jplayer.playlist.min.js (100%) rename {apps => src}/catalogue/static/jplayer/jquery.jplayer.min.js (100%) rename {apps => src}/catalogue/static/player/openplayer.js (100%) rename {apps => src}/catalogue/static/player/player.css (100%) rename {apps => src}/catalogue/static/player/player.js (100%) rename {apps => src}/catalogue/tasks.py (100%) rename {apps => src}/catalogue/templates/catalogue/audiobook_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/book_detail.html (100%) rename {apps => src}/catalogue/templates/catalogue/book_fragments.html (100%) rename {apps => src}/catalogue/templates/catalogue/book_info.html (100%) rename {apps => src}/catalogue/templates/catalogue/book_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/book_mini_box.html (100%) rename {apps => src}/catalogue/templates/catalogue/book_searched.html (100%) rename {apps => src}/catalogue/templates/catalogue/book_short.html (100%) rename {apps => src}/catalogue/templates/catalogue/book_text.html (100%) rename {apps => src}/catalogue/templates/catalogue/book_wide.html (100%) rename {apps => src}/catalogue/templates/catalogue/catalogue.html (100%) rename {apps => src}/catalogue/templates/catalogue/collection.html (100%) rename {apps => src}/catalogue/templates/catalogue/collection_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/daisy_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/differentiate_tags.html (100%) rename {apps => src}/catalogue/templates/catalogue/fragment_promo.html (100%) rename {apps => src}/catalogue/templates/catalogue/fragment_short.html (100%) rename {apps => src}/catalogue/templates/catalogue/inline_tag_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/menu.html (100%) rename {apps => src}/catalogue/templates/catalogue/picture_detail.html (100%) rename {apps => src}/catalogue/templates/catalogue/picture_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/player.html (100%) rename {apps => src}/catalogue/templates/catalogue/recent_audiobooks_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/recent_daisy_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/recent_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/related_books.html (100%) rename {apps => src}/catalogue/templates/catalogue/search_multiple_hits.html (100%) rename {apps => src}/catalogue/templates/catalogue/search_no_hits.html (100%) rename {apps => src}/catalogue/templates/catalogue/search_too_short.html (100%) rename {apps => src}/catalogue/templates/catalogue/snippets/audiobook_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/snippets/book_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/snippets/book_list_nav.html (100%) rename {apps => src}/catalogue/templates/catalogue/snippets/custom_pdf_link_li.html (100%) rename {apps => src}/catalogue/templates/catalogue/snippets/license_icon.html (100%) rename {apps => src}/catalogue/templates/catalogue/tag_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/tag_list_split.html (100%) rename {apps => src}/catalogue/templates/catalogue/tagged_object_list.html (100%) rename {apps => src}/catalogue/templates/catalogue/viewer_base.html (100%) rename {apps => src}/catalogue/templates/catalogue/work-list.html (100%) rename {apps => src}/catalogue/templatetags/__init__.py (100%) rename {apps => src}/catalogue/templatetags/catalogue_tags.py (100%) rename {apps => src}/catalogue/test_utils.py (100%) rename {apps => src}/catalogue/tests/__init__.py (100%) rename {apps => src}/catalogue/tests/book_import.py (100%) rename {apps => src}/catalogue/tests/bookmedia.py (100%) rename {apps => src}/catalogue/tests/cover.py (100%) rename {apps => src}/catalogue/tests/files/fraszka-do-anusie.xml (100%) rename {apps => src}/catalogue/tests/files/fraszki.xml (100%) rename {apps => src}/catalogue/tests/search.py (100%) rename {apps => src}/catalogue/tests/tags.py (100%) rename {apps => src}/catalogue/tests/templatetags.py (100%) rename {apps => src}/catalogue/tests/visit.py (100%) rename {apps => src}/catalogue/translation.py (100%) rename {apps => src}/catalogue/urls.py (100%) rename {apps => src}/catalogue/utils.py (100%) rename {apps => src}/catalogue/views.py (100%) rename {apps => src}/chunks/__init__.py (100%) rename {apps => src}/chunks/admin.py (100%) rename {apps => src}/chunks/locale/de/LC_MESSAGES/django.mo (100%) rename {apps => src}/chunks/locale/de/LC_MESSAGES/django.po (100%) rename {apps => src}/chunks/locale/en/LC_MESSAGES/django.mo (100%) rename {apps => src}/chunks/locale/en/LC_MESSAGES/django.po (100%) rename {apps => src}/chunks/locale/es/LC_MESSAGES/django.mo (100%) rename {apps => src}/chunks/locale/es/LC_MESSAGES/django.po (100%) rename {apps => src}/chunks/locale/fr/LC_MESSAGES/django.mo (100%) rename {apps => src}/chunks/locale/fr/LC_MESSAGES/django.po (100%) rename {apps => src}/chunks/locale/it/LC_MESSAGES/django.mo (100%) rename {apps => src}/chunks/locale/it/LC_MESSAGES/django.po (100%) rename {apps => src}/chunks/locale/jp/LC_MESSAGES/django.mo (100%) rename {apps => src}/chunks/locale/jp/LC_MESSAGES/django.po (100%) rename {apps => src}/chunks/locale/lt/LC_MESSAGES/django.mo (100%) rename {apps => src}/chunks/locale/lt/LC_MESSAGES/django.po (100%) rename {apps => src}/chunks/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/chunks/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/chunks/locale/ru/LC_MESSAGES/django.mo (100%) rename {apps => src}/chunks/locale/ru/LC_MESSAGES/django.po (100%) rename {apps => src}/chunks/locale/uk/LC_MESSAGES/django.mo (100%) rename {apps => src}/chunks/locale/uk/LC_MESSAGES/django.po (100%) rename {apps => src}/chunks/migrations/0001_initial.py (100%) rename {apps => src}/chunks/migrations/0002_auto_20140911_1253.py (100%) rename {apps => src}/chunks/migrations/0003_auto_20151221_1225.py (100%) rename {apps => src}/chunks/migrations/__init__.py (100%) rename {apps => src}/chunks/models.py (100%) rename {apps => src}/chunks/translation.py (100%) rename {apps => src}/chunks/urls.py (100%) rename {apps => src}/chunks/views.py (100%) rename {apps => src}/dictionary/__init__.py (100%) rename {apps => src}/dictionary/constants.py (100%) rename {apps => src}/dictionary/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/dictionary/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/dictionary/migrations/0001_initial.py (100%) rename {apps => src}/dictionary/migrations/0002_auto_20141006_1422.py (100%) rename {apps => src}/dictionary/migrations/0003_auto_20141023_1445.py (100%) rename {apps => src}/dictionary/migrations/0004_auto_20151221_1225.py (100%) rename {apps => src}/dictionary/migrations/__init__.py (100%) rename {apps => src}/dictionary/models.py (100%) rename {apps => src}/dictionary/templates/dictionary/note_list.html (100%) rename {apps => src}/dictionary/templatetags/__init__.py (100%) rename {apps => src}/dictionary/templatetags/set_get.py (100%) rename {apps => src}/dictionary/tests.py (100%) rename {apps => src}/dictionary/urls.py (100%) rename {apps => src}/dictionary/views.py (100%) rename {apps => src}/funding/__init__.py (100%) rename {apps => src}/funding/admin.py (100%) rename {apps => src}/funding/forms.py (100%) rename {apps => src}/funding/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/funding/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/funding/management/__init__.py (100%) rename {apps => src}/funding/management/commands/__init__.py (100%) rename {apps => src}/funding/management/commands/funding_notify.py (100%) rename {apps => src}/funding/migrations/0001_initial.py (100%) rename {apps => src}/funding/migrations/0002_auto_20151221_1225.py (100%) rename {apps => src}/funding/migrations/__init__.py (100%) rename {apps => src}/funding/models.py (100%) rename {apps => src}/funding/static/funding/funding.js (100%) rename {apps => src}/funding/templates/admin/funding/offer/change_form.html (100%) rename {apps => src}/funding/templates/funding/disable_notifications.html (100%) rename {apps => src}/funding/templates/funding/email/base.txt (100%) rename {apps => src}/funding/templates/funding/email/end.txt (100%) rename {apps => src}/funding/templates/funding/email/near.txt (100%) rename {apps => src}/funding/templates/funding/email/published.txt (100%) rename {apps => src}/funding/templates/funding/email/thanks.txt (100%) rename {apps => src}/funding/templates/funding/includes/funding.html (100%) rename {apps => src}/funding/templates/funding/includes/fundings.html (100%) rename {apps => src}/funding/templates/funding/includes/offer_status.html (100%) rename {apps => src}/funding/templates/funding/includes/offer_status_more.html (100%) rename {apps => src}/funding/templates/funding/no_thanks.html (100%) rename {apps => src}/funding/templates/funding/offer_detail.html (100%) rename {apps => src}/funding/templates/funding/offer_list.html (100%) rename {apps => src}/funding/templates/funding/snippets/any_remaining.html (100%) rename {apps => src}/funding/templates/funding/thanks.html (100%) rename {apps => src}/funding/templates/funding/widgets/amount.html (100%) rename {apps => src}/funding/templates/funding/wlfund.html (100%) rename {apps => src}/funding/templatetags/__init__.py (100%) rename {apps => src}/funding/templatetags/funding_tags.py (100%) rename {apps => src}/funding/tests.py (100%) rename {apps => src}/funding/urls.py (100%) rename {apps => src}/funding/utils.py (100%) rename {apps => src}/funding/views.py (100%) rename {apps => src}/funding/widgets.py (100%) rename {apps => src}/infopages/__init__.py (100%) rename {apps => src}/infopages/admin.py (100%) rename {apps => src}/infopages/fixtures/infopages.json (100%) rename {apps => src}/infopages/locale/de/LC_MESSAGES/django.mo (100%) rename {apps => src}/infopages/locale/de/LC_MESSAGES/django.po (100%) rename {apps => src}/infopages/locale/es/LC_MESSAGES/django.mo (100%) rename {apps => src}/infopages/locale/es/LC_MESSAGES/django.po (100%) rename {apps => src}/infopages/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/infopages/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/infopages/locale/uk/LC_MESSAGES/django.mo (100%) rename {apps => src}/infopages/locale/uk/LC_MESSAGES/django.po (100%) rename {apps => src}/infopages/migrations/0001_initial.py (100%) rename {apps => src}/infopages/migrations/0002_auto_20151221_1225.py (100%) rename {apps => src}/infopages/migrations/__init__.py (100%) rename {apps => src}/infopages/models.py (100%) rename {apps => src}/infopages/templates/infopages/infopage.html (100%) rename {apps => src}/infopages/templates/infopages/on_main.html (100%) rename {apps => src}/infopages/templatetags/__init__.py (100%) rename {apps => src}/infopages/templatetags/infopages_tags.py (100%) rename {apps => src}/infopages/translation.py (100%) rename {apps => src}/infopages/urls.py (100%) rename {apps => src}/infopages/views.py (100%) rename {apps => src}/lesmianator/__init__.py (100%) rename {apps => src}/lesmianator/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/lesmianator/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/lesmianator/management/__init__.py (100%) rename {apps => src}/lesmianator/management/commands/__init__.py (100%) rename {apps => src}/lesmianator/management/commands/lesmianator.py (100%) rename {apps => src}/lesmianator/migrations/0001_initial.py (100%) rename {apps => src}/lesmianator/migrations/0002_auto_20151221_1225.py (100%) rename {apps => src}/lesmianator/migrations/__init__.py (100%) rename {apps => src}/lesmianator/models.py (100%) rename {apps => src}/lesmianator/templates/lesmianator/lesmianator.html (100%) rename {apps => src}/lesmianator/templates/lesmianator/poem.html (100%) rename {apps => src}/lesmianator/urls.py (100%) rename {apps => src}/lesmianator/views.py (100%) rename {apps => src}/libraries/__init__.py (100%) rename {apps => src}/libraries/admin.py (100%) rename {apps => src}/libraries/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/libraries/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/libraries/migrations/0001_initial.py (100%) rename {apps => src}/libraries/migrations/0002_auto_20151221_1225.py (100%) rename {apps => src}/libraries/migrations/__init__.py (100%) rename {apps => src}/libraries/models.py (100%) rename {apps => src}/libraries/templates/libraries/catalog_view.html (100%) rename {apps => src}/libraries/templates/libraries/library_view.html (100%) rename {apps => src}/libraries/templates/libraries/main_view.html (100%) rename {apps => src}/libraries/urls.py (100%) rename {apps => src}/libraries/views.py (100%) rename manage.py => src/manage.py (76%) rename {apps => src}/newtagging/__init__.py (100%) rename {apps => src}/newtagging/admin.py (100%) rename {apps => src}/newtagging/locale/de/LC_MESSAGES/django.mo (100%) rename {apps => src}/newtagging/locale/de/LC_MESSAGES/django.po (100%) rename {apps => src}/newtagging/locale/en/LC_MESSAGES/django.mo (100%) rename {apps => src}/newtagging/locale/en/LC_MESSAGES/django.po (100%) rename {apps => src}/newtagging/locale/es/LC_MESSAGES/django.mo (100%) rename {apps => src}/newtagging/locale/es/LC_MESSAGES/django.po (100%) rename {apps => src}/newtagging/locale/fr/LC_MESSAGES/django.mo (100%) rename {apps => src}/newtagging/locale/fr/LC_MESSAGES/django.po (100%) rename {apps => src}/newtagging/locale/it/LC_MESSAGES/django.mo (100%) rename {apps => src}/newtagging/locale/it/LC_MESSAGES/django.po (100%) rename {apps => src}/newtagging/locale/jp/LC_MESSAGES/django.mo (100%) rename {apps => src}/newtagging/locale/jp/LC_MESSAGES/django.po (100%) rename {apps => src}/newtagging/locale/lt/LC_MESSAGES/django.mo (100%) rename {apps => src}/newtagging/locale/lt/LC_MESSAGES/django.po (100%) rename {apps => src}/newtagging/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/newtagging/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/newtagging/locale/ru/LC_MESSAGES/django.mo (100%) rename {apps => src}/newtagging/locale/ru/LC_MESSAGES/django.po (100%) rename {apps => src}/newtagging/locale/uk/LC_MESSAGES/django.mo (100%) rename {apps => src}/newtagging/locale/uk/LC_MESSAGES/django.po (100%) rename {apps => src}/newtagging/managers.py (100%) rename {apps => src}/newtagging/models.py (100%) rename {apps => src}/newtagging/views.py (100%) rename {apps => src}/oai/__init__.py (100%) rename {apps => src}/oai/handlers.py (100%) rename {apps => src}/oai/tests/__init__.py (100%) rename {apps => src}/oai/tests/files/antygona.xml (100%) rename {apps => src}/oai/tests/files/lubie-kiedy-kobieta.xml (100%) rename {apps => src}/oai/tests/oaipmhapi.py (100%) rename {apps => src}/oai/urls.py (100%) rename {apps => src}/oai/views.py (100%) rename {apps => src}/opds/__init__.py (100%) rename {apps => src}/opds/tests/__init__.py (100%) rename {apps => src}/opds/tests/files/do-doktora.xml (100%) rename {apps => src}/opds/urls.py (100%) rename {apps => src}/opds/views.py (100%) rename {apps => src}/pdcounter/__init__.py (100%) rename {apps => src}/pdcounter/admin.py (100%) rename {apps => src}/pdcounter/fixtures/lista.json (100%) rename {apps => src}/pdcounter/locale/de/LC_MESSAGES/django.mo (100%) rename {apps => src}/pdcounter/locale/de/LC_MESSAGES/django.po (100%) rename {apps => src}/pdcounter/locale/en/LC_MESSAGES/django.mo (100%) rename {apps => src}/pdcounter/locale/en/LC_MESSAGES/django.po (100%) rename {apps => src}/pdcounter/locale/es/LC_MESSAGES/django.mo (100%) rename {apps => src}/pdcounter/locale/es/LC_MESSAGES/django.po (100%) rename {apps => src}/pdcounter/locale/fr/LC_MESSAGES/django.mo (100%) rename {apps => src}/pdcounter/locale/fr/LC_MESSAGES/django.po (100%) rename {apps => src}/pdcounter/locale/it/LC_MESSAGES/django.mo (100%) rename {apps => src}/pdcounter/locale/it/LC_MESSAGES/django.po (100%) rename {apps => src}/pdcounter/locale/jp/LC_MESSAGES/django.mo (100%) rename {apps => src}/pdcounter/locale/jp/LC_MESSAGES/django.po (100%) rename {apps => src}/pdcounter/locale/lt/LC_MESSAGES/django.mo (100%) rename {apps => src}/pdcounter/locale/lt/LC_MESSAGES/django.po (100%) rename {apps => src}/pdcounter/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/pdcounter/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/pdcounter/locale/ru/LC_MESSAGES/django.mo (100%) rename {apps => src}/pdcounter/locale/ru/LC_MESSAGES/django.po (100%) rename {apps => src}/pdcounter/locale/uk/LC_MESSAGES/django.mo (100%) rename {apps => src}/pdcounter/locale/uk/LC_MESSAGES/django.po (100%) rename {apps => src}/pdcounter/migrations/0001_initial.py (100%) rename {apps => src}/pdcounter/migrations/0002_auto_20151221_1225.py (100%) rename {apps => src}/pdcounter/migrations/__init__.py (100%) rename {apps => src}/pdcounter/models.py (100%) rename {apps => src}/pdcounter/static/pdcounter/pdcounter.js (100%) rename {apps => src}/pdcounter/templates/pdcounter/author_detail.html (100%) rename {apps => src}/pdcounter/templates/pdcounter/book_stub_detail.html (100%) rename {apps => src}/pdcounter/templatetags/__init__.py (100%) rename {apps => src}/pdcounter/templatetags/time_tags.py (100%) rename {apps => src}/pdcounter/views.py (100%) rename {apps => src}/picture/__init__.py (100%) rename {apps => src}/picture/admin.py (100%) rename {apps => src}/picture/engine.py (100%) rename {apps => src}/picture/forms.py (100%) rename {apps => src}/picture/locale/de/LC_MESSAGES/django.mo (100%) rename {apps => src}/picture/locale/de/LC_MESSAGES/django.po (100%) rename {apps => src}/picture/locale/en/LC_MESSAGES/django.mo (100%) rename {apps => src}/picture/locale/en/LC_MESSAGES/django.po (100%) rename {apps => src}/picture/locale/es/LC_MESSAGES/django.mo (100%) rename {apps => src}/picture/locale/es/LC_MESSAGES/django.po (100%) rename {apps => src}/picture/locale/fr/LC_MESSAGES/django.mo (100%) rename {apps => src}/picture/locale/fr/LC_MESSAGES/django.po (100%) rename {apps => src}/picture/locale/it/LC_MESSAGES/django.mo (100%) rename {apps => src}/picture/locale/it/LC_MESSAGES/django.po (100%) rename {apps => src}/picture/locale/jp/LC_MESSAGES/django.mo (100%) rename {apps => src}/picture/locale/jp/LC_MESSAGES/django.po (100%) rename {apps => src}/picture/locale/lt/LC_MESSAGES/django.mo (100%) rename {apps => src}/picture/locale/lt/LC_MESSAGES/django.po (100%) rename {apps => src}/picture/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/picture/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/picture/locale/ru/LC_MESSAGES/django.mo (100%) rename {apps => src}/picture/locale/ru/LC_MESSAGES/django.po (100%) rename {apps => src}/picture/locale/uk/LC_MESSAGES/django.mo (100%) rename {apps => src}/picture/locale/uk/LC_MESSAGES/django.po (100%) rename {apps => src}/picture/migrations/0001_initial.py (100%) rename {apps => src}/picture/migrations/0002_remove_picture__related_info.py (100%) rename {apps => src}/picture/migrations/0003_auto_20140924_1559.py (100%) rename {apps => src}/picture/migrations/0004_auto_20141016_1337.py (100%) rename {apps => src}/picture/migrations/0005_auto_20141022_1001.py (100%) rename {apps => src}/picture/migrations/0006_auto_20151221_1225.py (100%) rename {apps => src}/picture/migrations/__init__.py (100%) rename {apps => src}/picture/models.py (100%) rename {apps => src}/picture/tasks.py (100%) rename {apps => src}/picture/templates/admin/picture/picture/change_list.html (100%) rename {apps => src}/picture/templates/picture/collection.html (100%) rename {apps => src}/picture/templates/picture/picture_detail.html (100%) rename {apps => src}/picture/templates/picture/picture_info.html (100%) rename {apps => src}/picture/templates/picture/picture_list_thumb.html (100%) rename {apps => src}/picture/templates/picture/picture_mini_box.html (100%) rename {apps => src}/picture/templates/picture/picture_short.html (100%) rename {apps => src}/picture/templates/picture/picture_viewer.html (100%) rename {apps => src}/picture/templates/picture/picture_wide.html (100%) rename {apps => src}/picture/templates/picture/picturearea_short.html (100%) rename {apps => src}/picture/templatetags/__init__.py (100%) rename {apps => src}/picture/templatetags/picture_tags.py (100%) rename {apps => src}/picture/tests/__init__.py (100%) rename {apps => src}/picture/tests/files/kandinsky-composition-viii.png (100%) rename {apps => src}/picture/tests/files/kandinsky-composition-viii.xml (100%) rename {apps => src}/picture/tests/picture_import.py (100%) rename {apps => src}/picture/views.py (100%) rename {apps => src}/polls/__init__.py (100%) rename {apps => src}/polls/admin.py (100%) rename {apps => src}/polls/forms.py (100%) rename {apps => src}/polls/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/polls/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/polls/migrations/0001_initial.py (100%) rename {apps => src}/polls/migrations/0002_auto_20151221_1225.py (100%) rename {apps => src}/polls/migrations/__init__.py (100%) rename {apps => src}/polls/models.py (100%) rename {apps => src}/polls/templates/polls/poll.html (100%) rename {apps => src}/polls/templates/polls/tags/poll.html (100%) rename {apps => src}/polls/templatetags/__init__.py (100%) rename {apps => src}/polls/templatetags/polls_tags.py (100%) rename {apps => src}/polls/urls.py (100%) rename {apps => src}/polls/views.py (100%) rename {apps => src}/reporting/__init__.py (100%) rename {apps => src}/reporting/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/reporting/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/reporting/models.py (100%) rename {apps => src}/reporting/templates/reporting/catalogue.csv (100%) rename {apps => src}/reporting/templates/reporting/catalogue.texml (100%) rename {apps => src}/reporting/templates/reporting/main.html (100%) rename {apps => src}/reporting/templatetags/__init__.py (100%) rename {apps => src}/reporting/templatetags/reporting_stats.py (100%) rename {apps => src}/reporting/urls.py (100%) rename {apps => src}/reporting/utils.py (100%) rename {apps => src}/reporting/views.py (100%) rename {apps => src}/search/__init__.py (100%) rename {apps => src}/search/context_processors.py (100%) rename {apps => src}/search/custom.py (100%) rename {apps => src}/search/fields.py (100%) rename {apps => src}/search/forms.py (100%) rename {apps => src}/search/index.py (100%) rename {apps => src}/search/locale/de/LC_MESSAGES/django.mo (100%) rename {apps => src}/search/locale/de/LC_MESSAGES/django.po (100%) rename {apps => src}/search/locale/en/LC_MESSAGES/django.mo (100%) rename {apps => src}/search/locale/en/LC_MESSAGES/django.po (100%) rename {apps => src}/search/locale/es/LC_MESSAGES/django.mo (100%) rename {apps => src}/search/locale/es/LC_MESSAGES/django.po (100%) rename {apps => src}/search/locale/fr/LC_MESSAGES/django.mo (100%) rename {apps => src}/search/locale/fr/LC_MESSAGES/django.po (100%) rename {apps => src}/search/locale/it/LC_MESSAGES/django.mo (100%) rename {apps => src}/search/locale/it/LC_MESSAGES/django.po (100%) rename {apps => src}/search/locale/jp/LC_MESSAGES/django.mo (100%) rename {apps => src}/search/locale/jp/LC_MESSAGES/django.po (100%) rename {apps => src}/search/locale/lt/LC_MESSAGES/django.mo (100%) rename {apps => src}/search/locale/lt/LC_MESSAGES/django.po (100%) rename {apps => src}/search/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/search/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/search/locale/ru/LC_MESSAGES/django.mo (100%) rename {apps => src}/search/locale/ru/LC_MESSAGES/django.po (100%) rename {apps => src}/search/locale/uk/LC_MESSAGES/django.mo (100%) rename {apps => src}/search/locale/uk/LC_MESSAGES/django.po (100%) rename {apps => src}/search/management/__init__.py (100%) rename {apps => src}/search/management/commands/__init__.py (100%) rename {apps => src}/search/management/commands/reindex.py (100%) rename {apps => src}/search/management/commands/snippets.py (100%) rename {apps => src}/search/mock_search.py (100%) rename {apps => src}/search/templates/newsearch/search.html (100%) rename {apps => src}/search/templatetags/__init__.py (100%) rename {apps => src}/search/templatetags/search_tags.py (100%) rename {apps => src}/search/tests/__init__.py (100%) rename {apps => src}/search/tests/index.py (100%) rename {apps => src}/search/urls.py (100%) rename {apps => src}/search/views.py (100%) rename {apps => src}/social/__init__.py (100%) rename {apps => src}/social/admin.py (100%) rename {apps => src}/social/forms.py (100%) rename {apps => src}/social/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/social/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/social/migrations/0001_initial.py (100%) rename {apps => src}/social/migrations/0002_auto_20151221_1225.py (100%) rename {apps => src}/social/migrations/__init__.py (100%) rename {apps => src}/social/models.py (100%) rename {apps => src}/social/templates/social/cite_info.html (100%) rename {apps => src}/social/templates/social/cite_promo.html (100%) rename {apps => src}/social/templates/social/my_shelf.html (100%) rename {apps => src}/social/templates/social/sets_form.html (100%) rename {apps => src}/social/templates/social/shelf_tags.html (100%) rename {apps => src}/social/templatetags/__init__.py (100%) rename {apps => src}/social/templatetags/social_tags.py (100%) rename {apps => src}/social/urls.py (100%) rename {apps => src}/social/utils.py (100%) rename {apps => src}/social/views.py (100%) rename {lib => src}/sortify.py (100%) rename {apps => src}/sponsors/__init__.py (100%) rename {apps => src}/sponsors/admin.py (100%) rename {apps => src}/sponsors/locale/de/LC_MESSAGES/django.mo (100%) rename {apps => src}/sponsors/locale/de/LC_MESSAGES/django.po (100%) rename {apps => src}/sponsors/locale/en/LC_MESSAGES/django.mo (100%) rename {apps => src}/sponsors/locale/en/LC_MESSAGES/django.po (100%) rename {apps => src}/sponsors/locale/es/LC_MESSAGES/django.mo (100%) rename {apps => src}/sponsors/locale/es/LC_MESSAGES/django.po (100%) rename {apps => src}/sponsors/locale/fr/LC_MESSAGES/django.mo (100%) rename {apps => src}/sponsors/locale/fr/LC_MESSAGES/django.po (100%) rename {apps => src}/sponsors/locale/it/LC_MESSAGES/django.mo (100%) rename {apps => src}/sponsors/locale/it/LC_MESSAGES/django.po (100%) rename {apps => src}/sponsors/locale/jp/LC_MESSAGES/django.mo (100%) rename {apps => src}/sponsors/locale/jp/LC_MESSAGES/django.po (100%) rename {apps => src}/sponsors/locale/lt/LC_MESSAGES/django.mo (100%) rename {apps => src}/sponsors/locale/lt/LC_MESSAGES/django.po (100%) rename {apps => src}/sponsors/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/sponsors/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/sponsors/locale/ru/LC_MESSAGES/django.mo (100%) rename {apps => src}/sponsors/locale/ru/LC_MESSAGES/django.po (100%) rename {apps => src}/sponsors/locale/uk/LC_MESSAGES/django.mo (100%) rename {apps => src}/sponsors/locale/uk/LC_MESSAGES/django.po (100%) rename {apps => src}/sponsors/migrations/0001_initial.py (100%) rename {apps => src}/sponsors/migrations/0002_auto_20151221_1225.py (100%) rename {apps => src}/sponsors/migrations/__init__.py (100%) rename {apps => src}/sponsors/models.py (100%) rename {apps => src}/sponsors/static/sponsors/css/footer_admin.css (100%) rename {apps => src}/sponsors/static/sponsors/css/sponsors.css (100%) rename {apps => src}/sponsors/static/sponsors/js/footer_admin.js (100%) rename {apps => src}/sponsors/static/sponsors/js/jquery.json.min.js (100%) rename {apps => src}/sponsors/static/sponsors/js/sponsors.js (100%) rename {apps => src}/sponsors/templates/sponsors/page.html (100%) rename {apps => src}/sponsors/urls.py (100%) rename {apps => src}/sponsors/views.py (100%) rename {apps => src}/sponsors/widgets.py (100%) rename {apps => src}/stats/__init__.py (100%) rename {apps => src}/stats/models.py (100%) rename {apps => src}/stats/tasks.py (100%) rename {apps => src}/stats/utils.py (100%) rename {apps => src}/suggest/__init__.py (100%) rename {apps => src}/suggest/admin.py (100%) rename {apps => src}/suggest/forms.py (100%) rename {apps => src}/suggest/locale/de/LC_MESSAGES/django.mo (100%) rename {apps => src}/suggest/locale/de/LC_MESSAGES/django.po (100%) rename {apps => src}/suggest/locale/en/LC_MESSAGES/django.mo (100%) rename {apps => src}/suggest/locale/en/LC_MESSAGES/django.po (100%) rename {apps => src}/suggest/locale/es/LC_MESSAGES/django.mo (100%) rename {apps => src}/suggest/locale/es/LC_MESSAGES/django.po (100%) rename {apps => src}/suggest/locale/fr/LC_MESSAGES/django.mo (100%) rename {apps => src}/suggest/locale/fr/LC_MESSAGES/django.po (100%) rename {apps => src}/suggest/locale/it/LC_MESSAGES/django.mo (100%) rename {apps => src}/suggest/locale/it/LC_MESSAGES/django.po (100%) rename {apps => src}/suggest/locale/jp/LC_MESSAGES/django.mo (100%) rename {apps => src}/suggest/locale/jp/LC_MESSAGES/django.po (100%) rename {apps => src}/suggest/locale/lt/LC_MESSAGES/django.mo (100%) rename {apps => src}/suggest/locale/lt/LC_MESSAGES/django.po (100%) rename {apps => src}/suggest/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/suggest/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/suggest/locale/ru/LC_MESSAGES/django.mo (100%) rename {apps => src}/suggest/locale/ru/LC_MESSAGES/django.po (100%) rename {apps => src}/suggest/locale/uk/LC_MESSAGES/django.mo (100%) rename {apps => src}/suggest/locale/uk/LC_MESSAGES/django.po (100%) rename {apps => src}/suggest/migrations/0001_initial.py (100%) rename {apps => src}/suggest/migrations/0002_auto_20151221_1225.py (100%) rename {apps => src}/suggest/migrations/__init__.py (100%) rename {apps => src}/suggest/models.py (100%) rename {apps => src}/suggest/templates/publishing_suggest.html (100%) rename {apps => src}/suggest/urls.py (100%) rename {apps => src}/suggest/views.py (100%) rename {apps => src}/waiter/__init__.py (100%) rename {apps => src}/waiter/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps => src}/waiter/locale/pl/LC_MESSAGES/django.po (100%) rename {apps => src}/waiter/migrations/0001_initial.py (100%) rename {apps => src}/waiter/migrations/__init__.py (100%) rename {apps => src}/waiter/models.py (100%) rename {apps => src}/waiter/settings.py (100%) rename {apps => src}/waiter/tasks.py (100%) rename {apps => src}/waiter/templates/waiter/wait.html (100%) rename {apps => src}/waiter/urls.py (100%) rename {apps => src}/waiter/utils.py (100%) rename {apps => src}/waiter/views.py (100%) create mode 100644 src/wolnelektury/__init__.py rename {apps/wolnelektury_core => src/wolnelektury}/apps.py (90%) rename {wolnelektury => src/wolnelektury}/celery.py (100%) rename {apps/wolnelektury_core => src/wolnelektury}/context_processors.py (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/de/LC_MESSAGES/django.mo (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/de/LC_MESSAGES/django.po (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/django.pot (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/en/LC_MESSAGES/django.mo (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/en/LC_MESSAGES/django.po (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/es/LC_MESSAGES/django.mo (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/es/LC_MESSAGES/django.po (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/fr/LC_MESSAGES/django.mo (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/fr/LC_MESSAGES/django.po (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/it/LC_MESSAGES/django.mo (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/it/LC_MESSAGES/django.po (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/lt/LC_MESSAGES/django.mo (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/lt/LC_MESSAGES/django.po (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/pl/LC_MESSAGES/django.mo (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/pl/LC_MESSAGES/django.po (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/ru/LC_MESSAGES/django.mo (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/ru/LC_MESSAGES/django.po (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/uk/LC_MESSAGES/django.mo (100%) rename {wolnelektury => src/wolnelektury}/locale-contrib/uk/LC_MESSAGES/django.po (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/de/LC_MESSAGES/django.mo (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/de/LC_MESSAGES/django.po (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/en/LC_MESSAGES/django.mo (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/en/LC_MESSAGES/django.po (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/es/LC_MESSAGES/django.mo (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/es/LC_MESSAGES/django.po (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/fr/LC_MESSAGES/django.mo (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/fr/LC_MESSAGES/django.po (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/it/LC_MESSAGES/django.mo (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/it/LC_MESSAGES/django.po (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/jp/LC_MESSAGES/django.mo (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/jp/LC_MESSAGES/django.po (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/lt/LC_MESSAGES/django.mo (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/lt/LC_MESSAGES/django.po (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/pl/LC_MESSAGES/django.mo (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/pl/LC_MESSAGES/django.po (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/ru/LC_MESSAGES/django.mo (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/ru/LC_MESSAGES/django.po (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/uk/LC_MESSAGES/django.mo (100%) rename {apps/wolnelektury_core => src/wolnelektury}/locale/uk/LC_MESSAGES/django.po (100%) rename {apps/wolnelektury_core => src/wolnelektury}/management/__init__.py (100%) rename {apps/wolnelektury_core => src/wolnelektury}/management/commands/__init__.py (100%) rename {apps/wolnelektury_core => src/wolnelektury}/management/commands/localepack.py (100%) rename {apps/wolnelektury_core => src/wolnelektury}/management/commands/translation2po.py (100%) rename {apps/wolnelektury_core => src/wolnelektury}/management/profile.py (100%) rename {wolnelektury => src/wolnelektury}/middleware.py (100%) rename {apps/wolnelektury_core/templatetags => src/wolnelektury/migrations}/__init__.py (100%) rename {wolnelektury => src/wolnelektury}/migrations/getpaid/0001_initial.py (100%) rename {wolnelektury => src/wolnelektury}/migrations/getpaid/0002_auto_20151221_1225.py (100%) rename {wolnelektury/migrations => src/wolnelektury/migrations/getpaid}/__init__.py (100%) rename {wolnelektury => src/wolnelektury}/migrations/piston/0001_initial.py (100%) rename {wolnelektury/migrations/getpaid => src/wolnelektury/migrations/piston}/__init__.py (100%) rename {wolnelektury => src/wolnelektury}/settings/__init__.py (97%) rename {wolnelektury => src/wolnelektury}/settings/auth.py (100%) rename {wolnelektury => src/wolnelektury}/settings/basic.py (100%) rename {wolnelektury => src/wolnelektury}/settings/cache.py (100%) rename {wolnelektury => src/wolnelektury}/settings/celery.py (100%) rename {wolnelektury => src/wolnelektury}/settings/contrib.py (100%) rename {wolnelektury => src/wolnelektury}/settings/custom.py (100%) rename {wolnelektury => src/wolnelektury}/settings/locale.py (100%) create mode 100644 src/wolnelektury/settings/paths.py rename {wolnelektury => src/wolnelektury}/settings/static.py (96%) rename {apps/wolnelektury_core => src/wolnelektury}/signals.py (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/annoy.css (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/jquery.countdown.css (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/master.book.css (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/master.picture.css (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/new.book.css (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/picture_box.css (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/simple.css (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-icons_222222_256x240.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-icons_228ef1_256x240.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-icons_ef8c08_256x240.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-icons_ffd27a_256x240.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/images/ui-icons_ffffff_256x240.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/css/ui-lightness/jquery-ui-1.8.16.custom.css (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/1percent-big.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/android-poster.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/arrow-down.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/arrow-gray.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/arrow-gray.svg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/arrow-teal.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/arrow-teal.svg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/arrow-up.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/auth/facebook.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/auth/google.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/auth/openid.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/auth/twitter.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/backdrop/boltron-3212284622.jpg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/backdrop/book-drawer2.jpg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/backdrop/horiavarlan-4268896468.jpg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/bg-header.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/bg.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/book-parent.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/book.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/doodle/20110908-android.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/doodle/20110908-logo.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/download.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/download.svg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/epub-www.jpg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/epub.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/favicon.ico (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/favicon.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/indicator.gif (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/kindle-poster-260.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/kindle-poster.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/licenses/cc-by-sa.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/licenses/cc-by-sa.svg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/listen.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/listen.svg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/logo-220.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/logo-bez.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/logo-big.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/logo-fbc.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/logo-neon.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/logo.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/logo_nck.jpg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/logo_nck_200horiz_trans.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/logo_nck_200trans.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/mobi.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/odt.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/payu.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/pdf.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/procent.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/progress-pixel.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/read.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/read.svg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/s5/blank.gif (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/s5/bodybg.gif (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/s5/iepngfix.htc (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/search.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/social/bigfacebook.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/social/biggoogle.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/social/bignk.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/social/bigtwitter.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/social/f.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/social/f.svg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/social/gplus.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/social/gplus.svg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/social/nk.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/social/nk.svg (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/speaker.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/turniej-maly.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/txt.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/wiatrak.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/wl_icon_64.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/img/zabawnik.png (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/annoy.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/base.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/book.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/book_text/info.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/book_text/menu.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/book_text/note.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/book_text/settings.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/book_text/toc.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/ierange-m2.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery-ui-1.8.16.custom.min.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.autocomplete.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.countdown-de.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.countdown-es.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.countdown-fr.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.countdown-lt.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.countdown-pl.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.countdown-ru.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.countdown-uk.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.countdown.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.cycle.min.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.eventdelegation.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.form.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.highlightfade.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.jqmodal.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/jquery.scrollto.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/modernizr.custom.19652.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/progressSpin.min.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/contrib/raphael-min.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/dialogs.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/locale.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/picture.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/search.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/widget.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/js/widget_run.js (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/opensearch.xml (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text/body.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text/book_box.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text/box.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text/const.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text/info.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text/menu.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text/note.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text/numbering.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text/other.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text/settings.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text/themes.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/book_text/toc.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/dictionary/dictionary.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/funding/funding.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/auth.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/base.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/book_box.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/book_list.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/catalogue.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/cite.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/const.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/dialogs.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/footer.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/form.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/fragment.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/header.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/hidden.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/main_content.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/main_page.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/menu.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/picture_box.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/search.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/main/tag.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/polls/polls.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/social/shelf_tags.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/tools.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/static/scss/widget.scss (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/404.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/500.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/503.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/account/base.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/admin/base_site.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/admin/catalogue/book/change_form.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/admin/catalogue/book/change_list.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/annoy.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/auth/login.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/auth/login_register.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/auth/register.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/base.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/info/join_us.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/latest_blog_posts.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/main_page.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/openid/login.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/pagination/pagination.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/piston/authorize_token.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/publish_plan.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/site_base.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/socialaccount/connections.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/socialaccount/login_cancelled.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/socialaccount/snippets/login_extra.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/socialaccount/snippets/provider_list.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/superbase.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/user.html (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templates/widget.html (100%) rename {wolnelektury/migrations/piston => src/wolnelektury/templatetags}/__init__.py (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templatetags/common_tags.py (100%) rename {apps/wolnelektury_core => src/wolnelektury}/templatetags/switch_tag.py (100%) rename {wolnelektury => src/wolnelektury}/urls.py (87%) rename {wolnelektury => src/wolnelektury}/utils.py (100%) rename {apps/wolnelektury_core => src/wolnelektury}/views.py (100%) rename {wolnelektury => src/wolnelektury}/wsgi.py (80%) delete mode 100644 wolnelektury/__init__.py delete mode 100644 wolnelektury/settings/paths.py diff --git a/.gitignore b/.gitignore index 4ddf5e924..fd63a8e47 100644 --- a/.gitignore +++ b/.gitignore @@ -9,10 +9,10 @@ fabfile_local.py .sass-cache # Compress output -/static +/var # SCSS output -apps/wolnelektury_core/static/scss/*.css +apps/wolnelektury/static/scss/*.css # Python garbage *.pyc @@ -36,8 +36,6 @@ thumbs.db # Tags file TAGS -media -search_index doc/_build reports diff --git a/apps/wolnelektury_core/__init__.py b/apps/wolnelektury_core/__init__.py deleted file mode 100644 index 56037a03e..000000000 --- a/apps/wolnelektury_core/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# -*- 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. -# -default_app_config = 'wolnelektury_core.apps.WLCoreConfig' diff --git a/lib/pyscss_compiler.py b/lib/pyscss_compiler.py deleted file mode 100644 index b57d59e0b..000000000 --- a/lib/pyscss_compiler.py +++ /dev/null @@ -1,19 +0,0 @@ -from os.path import dirname -from django.conf import settings -from pipeline.compilers import SubProcessCompiler - - -class PySCSSCompiler(SubProcessCompiler): - output_extension = 'css' - - def match_file(self, filename): - return filename.endswith('.scss') - - def compile_file(self, infile, outfile, outdated=False, force=False): - command = "%s %s < %s > %s" % ( - settings.PIPELINE_PYSCSS_BINARY, - settings.PIPELINE_PYSCSS_ARGUMENTS, - infile, - outfile - ) - return self.execute_command(command, cwd=dirname(infile)) diff --git a/requirements-dev.txt b/requirements/requirements-dev.txt similarity index 100% rename from requirements-dev.txt rename to requirements/requirements-dev.txt diff --git a/requirements-test.txt b/requirements/requirements-test.txt similarity index 100% rename from requirements-test.txt rename to requirements/requirements-test.txt diff --git a/requirements.txt b/requirements/requirements.txt similarity index 100% rename from requirements.txt rename to requirements/requirements.txt diff --git a/apps/ajaxable/__init__.py b/src/ajaxable/__init__.py similarity index 100% rename from apps/ajaxable/__init__.py rename to src/ajaxable/__init__.py diff --git a/apps/ajaxable/locale/pl/LC_MESSAGES/django.mo b/src/ajaxable/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/ajaxable/locale/pl/LC_MESSAGES/django.mo rename to src/ajaxable/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/ajaxable/locale/pl/LC_MESSAGES/django.po b/src/ajaxable/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/ajaxable/locale/pl/LC_MESSAGES/django.po rename to src/ajaxable/locale/pl/LC_MESSAGES/django.po diff --git a/apps/ajaxable/models.py b/src/ajaxable/models.py similarity index 100% rename from apps/ajaxable/models.py rename to src/ajaxable/models.py diff --git a/apps/ajaxable/templates/ajaxable/form.html b/src/ajaxable/templates/ajaxable/form.html similarity index 100% rename from apps/ajaxable/templates/ajaxable/form.html rename to src/ajaxable/templates/ajaxable/form.html diff --git a/apps/ajaxable/templates/ajaxable/form_on_page.html b/src/ajaxable/templates/ajaxable/form_on_page.html similarity index 100% rename from apps/ajaxable/templates/ajaxable/form_on_page.html rename to src/ajaxable/templates/ajaxable/form_on_page.html diff --git a/apps/ajaxable/templatetags/__init__.py b/src/ajaxable/templatetags/__init__.py similarity index 100% rename from apps/ajaxable/templatetags/__init__.py rename to src/ajaxable/templatetags/__init__.py diff --git a/apps/ajaxable/templatetags/ajaxable_tags.py b/src/ajaxable/templatetags/ajaxable_tags.py similarity index 100% rename from apps/ajaxable/templatetags/ajaxable_tags.py rename to src/ajaxable/templatetags/ajaxable_tags.py diff --git a/apps/ajaxable/utils.py b/src/ajaxable/utils.py similarity index 100% rename from apps/ajaxable/utils.py rename to src/ajaxable/utils.py diff --git a/apps/api/__init__.py b/src/api/__init__.py similarity index 100% rename from apps/api/__init__.py rename to src/api/__init__.py diff --git a/apps/api/emitters.py b/src/api/emitters.py similarity index 100% rename from apps/api/emitters.py rename to src/api/emitters.py diff --git a/apps/api/handlers.py b/src/api/handlers.py similarity index 100% rename from apps/api/handlers.py rename to src/api/handlers.py diff --git a/apps/api/helpers.py b/src/api/helpers.py similarity index 100% rename from apps/api/helpers.py rename to src/api/helpers.py diff --git a/apps/api/locale/pl/LC_MESSAGES/django.mo b/src/api/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/api/locale/pl/LC_MESSAGES/django.mo rename to src/api/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/api/locale/pl/LC_MESSAGES/django.po b/src/api/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/api/locale/pl/LC_MESSAGES/django.po rename to src/api/locale/pl/LC_MESSAGES/django.po diff --git a/apps/api/management/__init__.py b/src/api/management/__init__.py similarity index 100% rename from apps/api/management/__init__.py rename to src/api/management/__init__.py diff --git a/apps/api/management/commands/__init__.py b/src/api/management/commands/__init__.py similarity index 100% rename from apps/api/management/commands/__init__.py rename to src/api/management/commands/__init__.py diff --git a/apps/api/management/commands/mobileinit.py b/src/api/management/commands/mobileinit.py similarity index 100% rename from apps/api/management/commands/mobileinit.py rename to src/api/management/commands/mobileinit.py diff --git a/apps/api/migrations/0001_initial.py b/src/api/migrations/0001_initial.py similarity index 100% rename from apps/api/migrations/0001_initial.py rename to src/api/migrations/0001_initial.py diff --git a/apps/api/migrations/0002_auto_20151221_1225.py b/src/api/migrations/0002_auto_20151221_1225.py similarity index 100% rename from apps/api/migrations/0002_auto_20151221_1225.py rename to src/api/migrations/0002_auto_20151221_1225.py diff --git a/apps/api/migrations/__init__.py b/src/api/migrations/__init__.py similarity index 100% rename from apps/api/migrations/__init__.py rename to src/api/migrations/__init__.py diff --git a/apps/api/models.py b/src/api/models.py similarity index 100% rename from apps/api/models.py rename to src/api/models.py diff --git a/apps/api/settings.py b/src/api/settings.py similarity index 100% rename from apps/api/settings.py rename to src/api/settings.py diff --git a/apps/api/templates/api/main.html b/src/api/templates/api/main.html similarity index 100% rename from apps/api/templates/api/main.html rename to src/api/templates/api/main.html diff --git a/apps/api/templates/oauth/challenge.html b/src/api/templates/oauth/challenge.html similarity index 100% rename from apps/api/templates/oauth/challenge.html rename to src/api/templates/oauth/challenge.html diff --git a/apps/api/tests.py b/src/api/tests.py similarity index 100% rename from apps/api/tests.py rename to src/api/tests.py diff --git a/apps/api/urls.py b/src/api/urls.py similarity index 100% rename from apps/api/urls.py rename to src/api/urls.py diff --git a/lib/basicauth.py b/src/basicauth.py similarity index 100% rename from lib/basicauth.py rename to src/basicauth.py diff --git a/apps/catalogue/__init__.py b/src/catalogue/__init__.py similarity index 100% rename from apps/catalogue/__init__.py rename to src/catalogue/__init__.py diff --git a/apps/catalogue/admin.py b/src/catalogue/admin.py similarity index 100% rename from apps/catalogue/admin.py rename to src/catalogue/admin.py diff --git a/apps/catalogue/apps.py b/src/catalogue/apps.py similarity index 100% rename from apps/catalogue/apps.py rename to src/catalogue/apps.py diff --git a/apps/catalogue/constants.py b/src/catalogue/constants.py similarity index 100% rename from apps/catalogue/constants.py rename to src/catalogue/constants.py diff --git a/apps/catalogue/feeds.py b/src/catalogue/feeds.py similarity index 100% rename from apps/catalogue/feeds.py rename to src/catalogue/feeds.py diff --git a/apps/catalogue/fields.py b/src/catalogue/fields.py similarity index 100% rename from apps/catalogue/fields.py rename to src/catalogue/fields.py diff --git a/apps/catalogue/fixtures/collection-boy.json b/src/catalogue/fixtures/collection-boy.json similarity index 100% rename from apps/catalogue/fixtures/collection-boy.json rename to src/catalogue/fixtures/collection-boy.json diff --git a/apps/catalogue/forms.py b/src/catalogue/forms.py similarity index 100% rename from apps/catalogue/forms.py rename to src/catalogue/forms.py diff --git a/apps/catalogue/helpers.py b/src/catalogue/helpers.py similarity index 100% rename from apps/catalogue/helpers.py rename to src/catalogue/helpers.py diff --git a/apps/catalogue/import_utils.py b/src/catalogue/import_utils.py similarity index 100% rename from apps/catalogue/import_utils.py rename to src/catalogue/import_utils.py diff --git a/apps/catalogue/locale/de/LC_MESSAGES/django.mo b/src/catalogue/locale/de/LC_MESSAGES/django.mo similarity index 100% rename from apps/catalogue/locale/de/LC_MESSAGES/django.mo rename to src/catalogue/locale/de/LC_MESSAGES/django.mo diff --git a/apps/catalogue/locale/de/LC_MESSAGES/django.po b/src/catalogue/locale/de/LC_MESSAGES/django.po similarity index 100% rename from apps/catalogue/locale/de/LC_MESSAGES/django.po rename to src/catalogue/locale/de/LC_MESSAGES/django.po diff --git a/apps/catalogue/locale/en/LC_MESSAGES/django.mo b/src/catalogue/locale/en/LC_MESSAGES/django.mo similarity index 100% rename from apps/catalogue/locale/en/LC_MESSAGES/django.mo rename to src/catalogue/locale/en/LC_MESSAGES/django.mo diff --git a/apps/catalogue/locale/en/LC_MESSAGES/django.po b/src/catalogue/locale/en/LC_MESSAGES/django.po similarity index 100% rename from apps/catalogue/locale/en/LC_MESSAGES/django.po rename to src/catalogue/locale/en/LC_MESSAGES/django.po diff --git a/apps/catalogue/locale/es/LC_MESSAGES/django.mo b/src/catalogue/locale/es/LC_MESSAGES/django.mo similarity index 100% rename from apps/catalogue/locale/es/LC_MESSAGES/django.mo rename to src/catalogue/locale/es/LC_MESSAGES/django.mo diff --git a/apps/catalogue/locale/es/LC_MESSAGES/django.po b/src/catalogue/locale/es/LC_MESSAGES/django.po similarity index 100% rename from apps/catalogue/locale/es/LC_MESSAGES/django.po rename to src/catalogue/locale/es/LC_MESSAGES/django.po diff --git a/apps/catalogue/locale/fr/LC_MESSAGES/django.mo b/src/catalogue/locale/fr/LC_MESSAGES/django.mo similarity index 100% rename from apps/catalogue/locale/fr/LC_MESSAGES/django.mo rename to src/catalogue/locale/fr/LC_MESSAGES/django.mo diff --git a/apps/catalogue/locale/fr/LC_MESSAGES/django.po b/src/catalogue/locale/fr/LC_MESSAGES/django.po similarity index 100% rename from apps/catalogue/locale/fr/LC_MESSAGES/django.po rename to src/catalogue/locale/fr/LC_MESSAGES/django.po diff --git a/apps/catalogue/locale/it/LC_MESSAGES/django.mo b/src/catalogue/locale/it/LC_MESSAGES/django.mo similarity index 100% rename from apps/catalogue/locale/it/LC_MESSAGES/django.mo rename to src/catalogue/locale/it/LC_MESSAGES/django.mo diff --git a/apps/catalogue/locale/it/LC_MESSAGES/django.po b/src/catalogue/locale/it/LC_MESSAGES/django.po similarity index 100% rename from apps/catalogue/locale/it/LC_MESSAGES/django.po rename to src/catalogue/locale/it/LC_MESSAGES/django.po diff --git a/apps/catalogue/locale/jp/LC_MESSAGES/django.mo b/src/catalogue/locale/jp/LC_MESSAGES/django.mo similarity index 100% rename from apps/catalogue/locale/jp/LC_MESSAGES/django.mo rename to src/catalogue/locale/jp/LC_MESSAGES/django.mo diff --git a/apps/catalogue/locale/jp/LC_MESSAGES/django.po b/src/catalogue/locale/jp/LC_MESSAGES/django.po similarity index 100% rename from apps/catalogue/locale/jp/LC_MESSAGES/django.po rename to src/catalogue/locale/jp/LC_MESSAGES/django.po diff --git a/apps/catalogue/locale/lt/LC_MESSAGES/django.mo b/src/catalogue/locale/lt/LC_MESSAGES/django.mo similarity index 100% rename from apps/catalogue/locale/lt/LC_MESSAGES/django.mo rename to src/catalogue/locale/lt/LC_MESSAGES/django.mo diff --git a/apps/catalogue/locale/lt/LC_MESSAGES/django.po b/src/catalogue/locale/lt/LC_MESSAGES/django.po similarity index 100% rename from apps/catalogue/locale/lt/LC_MESSAGES/django.po rename to src/catalogue/locale/lt/LC_MESSAGES/django.po diff --git a/apps/catalogue/locale/pl/LC_MESSAGES/django.mo b/src/catalogue/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/catalogue/locale/pl/LC_MESSAGES/django.mo rename to src/catalogue/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/catalogue/locale/pl/LC_MESSAGES/django.po b/src/catalogue/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/catalogue/locale/pl/LC_MESSAGES/django.po rename to src/catalogue/locale/pl/LC_MESSAGES/django.po diff --git a/apps/catalogue/locale/ru/LC_MESSAGES/django.mo b/src/catalogue/locale/ru/LC_MESSAGES/django.mo similarity index 100% rename from apps/catalogue/locale/ru/LC_MESSAGES/django.mo rename to src/catalogue/locale/ru/LC_MESSAGES/django.mo diff --git a/apps/catalogue/locale/ru/LC_MESSAGES/django.po b/src/catalogue/locale/ru/LC_MESSAGES/django.po similarity index 100% rename from apps/catalogue/locale/ru/LC_MESSAGES/django.po rename to src/catalogue/locale/ru/LC_MESSAGES/django.po diff --git a/apps/catalogue/locale/uk/LC_MESSAGES/django.mo b/src/catalogue/locale/uk/LC_MESSAGES/django.mo similarity index 100% rename from apps/catalogue/locale/uk/LC_MESSAGES/django.mo rename to src/catalogue/locale/uk/LC_MESSAGES/django.mo diff --git a/apps/catalogue/locale/uk/LC_MESSAGES/django.po b/src/catalogue/locale/uk/LC_MESSAGES/django.po similarity index 100% rename from apps/catalogue/locale/uk/LC_MESSAGES/django.po rename to src/catalogue/locale/uk/LC_MESSAGES/django.po diff --git a/apps/catalogue/management/__init__.py b/src/catalogue/management/__init__.py similarity index 100% rename from apps/catalogue/management/__init__.py rename to src/catalogue/management/__init__.py diff --git a/apps/catalogue/management/commands/__init__.py b/src/catalogue/management/commands/__init__.py similarity index 100% rename from apps/catalogue/management/commands/__init__.py rename to src/catalogue/management/commands/__init__.py diff --git a/apps/catalogue/management/commands/checkcovers.py b/src/catalogue/management/commands/checkcovers.py similarity index 100% rename from apps/catalogue/management/commands/checkcovers.py rename to src/catalogue/management/commands/checkcovers.py diff --git a/apps/catalogue/management/commands/checkintegrity.py b/src/catalogue/management/commands/checkintegrity.py similarity index 100% rename from apps/catalogue/management/commands/checkintegrity.py rename to src/catalogue/management/commands/checkintegrity.py diff --git a/apps/catalogue/management/commands/importbooks.py b/src/catalogue/management/commands/importbooks.py similarity index 99% rename from apps/catalogue/management/commands/importbooks.py rename to src/catalogue/management/commands/importbooks.py index a15faa0b6..338fea6aa 100644 --- a/apps/catalogue/management/commands/importbooks.py +++ b/src/catalogue/management/commands/importbooks.py @@ -12,7 +12,7 @@ from django.core.management.color import color_style from django.core.files import File from catalogue.utils import trim_query_log from librarian.picture import ImageStore -from wolnelektury_core.management.profile import profile +from wolnelektury.management.profile import profile from catalogue.models import Book from picture.models import Picture diff --git a/apps/catalogue/management/commands/pack.py b/src/catalogue/management/commands/pack.py similarity index 100% rename from apps/catalogue/management/commands/pack.py rename to src/catalogue/management/commands/pack.py diff --git a/apps/catalogue/management/commands/report_dead_links.py b/src/catalogue/management/commands/report_dead_links.py similarity index 100% rename from apps/catalogue/management/commands/report_dead_links.py rename to src/catalogue/management/commands/report_dead_links.py diff --git a/apps/catalogue/management/commands/savemedia.py b/src/catalogue/management/commands/savemedia.py similarity index 100% rename from apps/catalogue/management/commands/savemedia.py rename to src/catalogue/management/commands/savemedia.py diff --git a/apps/catalogue/migrations/0001_initial.py b/src/catalogue/migrations/0001_initial.py similarity index 100% rename from apps/catalogue/migrations/0001_initial.py rename to src/catalogue/migrations/0001_initial.py diff --git a/apps/catalogue/migrations/0002_book_ancestor.py b/src/catalogue/migrations/0002_book_ancestor.py similarity index 100% rename from apps/catalogue/migrations/0002_book_ancestor.py rename to src/catalogue/migrations/0002_book_ancestor.py diff --git a/apps/catalogue/migrations/0003_populate_ancestors.py b/src/catalogue/migrations/0003_populate_ancestors.py similarity index 100% rename from apps/catalogue/migrations/0003_populate_ancestors.py rename to src/catalogue/migrations/0003_populate_ancestors.py diff --git a/apps/catalogue/migrations/0004_remove_booktags_count_related_info.py b/src/catalogue/migrations/0004_remove_booktags_count_related_info.py similarity index 100% rename from apps/catalogue/migrations/0004_remove_booktags_count_related_info.py rename to src/catalogue/migrations/0004_remove_booktags_count_related_info.py diff --git a/apps/catalogue/migrations/0005_auto_20141016_1337.py b/src/catalogue/migrations/0005_auto_20141016_1337.py similarity index 100% rename from apps/catalogue/migrations/0005_auto_20141016_1337.py rename to src/catalogue/migrations/0005_auto_20141016_1337.py diff --git a/apps/catalogue/migrations/0006_auto_20141022_1059.py b/src/catalogue/migrations/0006_auto_20141022_1059.py similarity index 100% rename from apps/catalogue/migrations/0006_auto_20141022_1059.py rename to src/catalogue/migrations/0006_auto_20141022_1059.py diff --git a/apps/catalogue/migrations/0007_auto_20151123_1529.py b/src/catalogue/migrations/0007_auto_20151123_1529.py similarity index 100% rename from apps/catalogue/migrations/0007_auto_20151123_1529.py rename to src/catalogue/migrations/0007_auto_20151123_1529.py diff --git a/apps/catalogue/migrations/0008_auto_20151221_1225.py b/src/catalogue/migrations/0008_auto_20151221_1225.py similarity index 100% rename from apps/catalogue/migrations/0008_auto_20151221_1225.py rename to src/catalogue/migrations/0008_auto_20151221_1225.py diff --git a/apps/catalogue/migrations/__init__.py b/src/catalogue/migrations/__init__.py similarity index 100% rename from apps/catalogue/migrations/__init__.py rename to src/catalogue/migrations/__init__.py diff --git a/apps/catalogue/models/__init__.py b/src/catalogue/models/__init__.py similarity index 100% rename from apps/catalogue/models/__init__.py rename to src/catalogue/models/__init__.py diff --git a/apps/catalogue/models/book.py b/src/catalogue/models/book.py similarity index 100% rename from apps/catalogue/models/book.py rename to src/catalogue/models/book.py diff --git a/apps/catalogue/models/bookmedia.py b/src/catalogue/models/bookmedia.py similarity index 100% rename from apps/catalogue/models/bookmedia.py rename to src/catalogue/models/bookmedia.py diff --git a/apps/catalogue/models/collection.py b/src/catalogue/models/collection.py similarity index 100% rename from apps/catalogue/models/collection.py rename to src/catalogue/models/collection.py diff --git a/apps/catalogue/models/fragment.py b/src/catalogue/models/fragment.py similarity index 100% rename from apps/catalogue/models/fragment.py rename to src/catalogue/models/fragment.py diff --git a/apps/catalogue/models/source.py b/src/catalogue/models/source.py similarity index 100% rename from apps/catalogue/models/source.py rename to src/catalogue/models/source.py diff --git a/apps/catalogue/models/tag.py b/src/catalogue/models/tag.py similarity index 100% rename from apps/catalogue/models/tag.py rename to src/catalogue/models/tag.py diff --git a/apps/catalogue/signals.py b/src/catalogue/signals.py similarity index 100% rename from apps/catalogue/signals.py rename to src/catalogue/signals.py diff --git a/apps/catalogue/static/jplayer/Jplayer.swf b/src/catalogue/static/jplayer/Jplayer.swf similarity index 100% rename from apps/catalogue/static/jplayer/Jplayer.swf rename to src/catalogue/static/jplayer/Jplayer.swf diff --git a/apps/catalogue/static/jplayer/jplayer.blue.monday.css b/src/catalogue/static/jplayer/jplayer.blue.monday.css similarity index 100% rename from apps/catalogue/static/jplayer/jplayer.blue.monday.css rename to src/catalogue/static/jplayer/jplayer.blue.monday.css diff --git a/apps/catalogue/static/jplayer/jplayer.blue.monday.jpg b/src/catalogue/static/jplayer/jplayer.blue.monday.jpg similarity index 100% rename from apps/catalogue/static/jplayer/jplayer.blue.monday.jpg rename to src/catalogue/static/jplayer/jplayer.blue.monday.jpg diff --git a/apps/catalogue/static/jplayer/jplayer.blue.monday.seeking.gif b/src/catalogue/static/jplayer/jplayer.blue.monday.seeking.gif similarity index 100% rename from apps/catalogue/static/jplayer/jplayer.blue.monday.seeking.gif rename to src/catalogue/static/jplayer/jplayer.blue.monday.seeking.gif diff --git a/apps/catalogue/static/jplayer/jplayer.blue.monday.video.play.png b/src/catalogue/static/jplayer/jplayer.blue.monday.video.play.png similarity index 100% rename from apps/catalogue/static/jplayer/jplayer.blue.monday.video.play.png rename to src/catalogue/static/jplayer/jplayer.blue.monday.video.play.png diff --git a/apps/catalogue/static/jplayer/jplayer.playlist.min.js b/src/catalogue/static/jplayer/jplayer.playlist.min.js similarity index 100% rename from apps/catalogue/static/jplayer/jplayer.playlist.min.js rename to src/catalogue/static/jplayer/jplayer.playlist.min.js diff --git a/apps/catalogue/static/jplayer/jquery.jplayer.min.js b/src/catalogue/static/jplayer/jquery.jplayer.min.js similarity index 100% rename from apps/catalogue/static/jplayer/jquery.jplayer.min.js rename to src/catalogue/static/jplayer/jquery.jplayer.min.js diff --git a/apps/catalogue/static/player/openplayer.js b/src/catalogue/static/player/openplayer.js similarity index 100% rename from apps/catalogue/static/player/openplayer.js rename to src/catalogue/static/player/openplayer.js diff --git a/apps/catalogue/static/player/player.css b/src/catalogue/static/player/player.css similarity index 100% rename from apps/catalogue/static/player/player.css rename to src/catalogue/static/player/player.css diff --git a/apps/catalogue/static/player/player.js b/src/catalogue/static/player/player.js similarity index 100% rename from apps/catalogue/static/player/player.js rename to src/catalogue/static/player/player.js diff --git a/apps/catalogue/tasks.py b/src/catalogue/tasks.py similarity index 100% rename from apps/catalogue/tasks.py rename to src/catalogue/tasks.py diff --git a/apps/catalogue/templates/catalogue/audiobook_list.html b/src/catalogue/templates/catalogue/audiobook_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/audiobook_list.html rename to src/catalogue/templates/catalogue/audiobook_list.html diff --git a/apps/catalogue/templates/catalogue/book_detail.html b/src/catalogue/templates/catalogue/book_detail.html similarity index 100% rename from apps/catalogue/templates/catalogue/book_detail.html rename to src/catalogue/templates/catalogue/book_detail.html diff --git a/apps/catalogue/templates/catalogue/book_fragments.html b/src/catalogue/templates/catalogue/book_fragments.html similarity index 100% rename from apps/catalogue/templates/catalogue/book_fragments.html rename to src/catalogue/templates/catalogue/book_fragments.html diff --git a/apps/catalogue/templates/catalogue/book_info.html b/src/catalogue/templates/catalogue/book_info.html similarity index 100% rename from apps/catalogue/templates/catalogue/book_info.html rename to src/catalogue/templates/catalogue/book_info.html diff --git a/apps/catalogue/templates/catalogue/book_list.html b/src/catalogue/templates/catalogue/book_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/book_list.html rename to src/catalogue/templates/catalogue/book_list.html diff --git a/apps/catalogue/templates/catalogue/book_mini_box.html b/src/catalogue/templates/catalogue/book_mini_box.html similarity index 100% rename from apps/catalogue/templates/catalogue/book_mini_box.html rename to src/catalogue/templates/catalogue/book_mini_box.html diff --git a/apps/catalogue/templates/catalogue/book_searched.html b/src/catalogue/templates/catalogue/book_searched.html similarity index 100% rename from apps/catalogue/templates/catalogue/book_searched.html rename to src/catalogue/templates/catalogue/book_searched.html diff --git a/apps/catalogue/templates/catalogue/book_short.html b/src/catalogue/templates/catalogue/book_short.html similarity index 100% rename from apps/catalogue/templates/catalogue/book_short.html rename to src/catalogue/templates/catalogue/book_short.html diff --git a/apps/catalogue/templates/catalogue/book_text.html b/src/catalogue/templates/catalogue/book_text.html similarity index 100% rename from apps/catalogue/templates/catalogue/book_text.html rename to src/catalogue/templates/catalogue/book_text.html diff --git a/apps/catalogue/templates/catalogue/book_wide.html b/src/catalogue/templates/catalogue/book_wide.html similarity index 100% rename from apps/catalogue/templates/catalogue/book_wide.html rename to src/catalogue/templates/catalogue/book_wide.html diff --git a/apps/catalogue/templates/catalogue/catalogue.html b/src/catalogue/templates/catalogue/catalogue.html similarity index 100% rename from apps/catalogue/templates/catalogue/catalogue.html rename to src/catalogue/templates/catalogue/catalogue.html diff --git a/apps/catalogue/templates/catalogue/collection.html b/src/catalogue/templates/catalogue/collection.html similarity index 100% rename from apps/catalogue/templates/catalogue/collection.html rename to src/catalogue/templates/catalogue/collection.html diff --git a/apps/catalogue/templates/catalogue/collection_list.html b/src/catalogue/templates/catalogue/collection_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/collection_list.html rename to src/catalogue/templates/catalogue/collection_list.html diff --git a/apps/catalogue/templates/catalogue/daisy_list.html b/src/catalogue/templates/catalogue/daisy_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/daisy_list.html rename to src/catalogue/templates/catalogue/daisy_list.html diff --git a/apps/catalogue/templates/catalogue/differentiate_tags.html b/src/catalogue/templates/catalogue/differentiate_tags.html similarity index 100% rename from apps/catalogue/templates/catalogue/differentiate_tags.html rename to src/catalogue/templates/catalogue/differentiate_tags.html diff --git a/apps/catalogue/templates/catalogue/fragment_promo.html b/src/catalogue/templates/catalogue/fragment_promo.html similarity index 100% rename from apps/catalogue/templates/catalogue/fragment_promo.html rename to src/catalogue/templates/catalogue/fragment_promo.html diff --git a/apps/catalogue/templates/catalogue/fragment_short.html b/src/catalogue/templates/catalogue/fragment_short.html similarity index 100% rename from apps/catalogue/templates/catalogue/fragment_short.html rename to src/catalogue/templates/catalogue/fragment_short.html diff --git a/apps/catalogue/templates/catalogue/inline_tag_list.html b/src/catalogue/templates/catalogue/inline_tag_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/inline_tag_list.html rename to src/catalogue/templates/catalogue/inline_tag_list.html diff --git a/apps/catalogue/templates/catalogue/menu.html b/src/catalogue/templates/catalogue/menu.html similarity index 100% rename from apps/catalogue/templates/catalogue/menu.html rename to src/catalogue/templates/catalogue/menu.html diff --git a/apps/catalogue/templates/catalogue/picture_detail.html b/src/catalogue/templates/catalogue/picture_detail.html similarity index 100% rename from apps/catalogue/templates/catalogue/picture_detail.html rename to src/catalogue/templates/catalogue/picture_detail.html diff --git a/apps/catalogue/templates/catalogue/picture_list.html b/src/catalogue/templates/catalogue/picture_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/picture_list.html rename to src/catalogue/templates/catalogue/picture_list.html diff --git a/apps/catalogue/templates/catalogue/player.html b/src/catalogue/templates/catalogue/player.html similarity index 100% rename from apps/catalogue/templates/catalogue/player.html rename to src/catalogue/templates/catalogue/player.html diff --git a/apps/catalogue/templates/catalogue/recent_audiobooks_list.html b/src/catalogue/templates/catalogue/recent_audiobooks_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/recent_audiobooks_list.html rename to src/catalogue/templates/catalogue/recent_audiobooks_list.html diff --git a/apps/catalogue/templates/catalogue/recent_daisy_list.html b/src/catalogue/templates/catalogue/recent_daisy_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/recent_daisy_list.html rename to src/catalogue/templates/catalogue/recent_daisy_list.html diff --git a/apps/catalogue/templates/catalogue/recent_list.html b/src/catalogue/templates/catalogue/recent_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/recent_list.html rename to src/catalogue/templates/catalogue/recent_list.html diff --git a/apps/catalogue/templates/catalogue/related_books.html b/src/catalogue/templates/catalogue/related_books.html similarity index 100% rename from apps/catalogue/templates/catalogue/related_books.html rename to src/catalogue/templates/catalogue/related_books.html diff --git a/apps/catalogue/templates/catalogue/search_multiple_hits.html b/src/catalogue/templates/catalogue/search_multiple_hits.html similarity index 100% rename from apps/catalogue/templates/catalogue/search_multiple_hits.html rename to src/catalogue/templates/catalogue/search_multiple_hits.html diff --git a/apps/catalogue/templates/catalogue/search_no_hits.html b/src/catalogue/templates/catalogue/search_no_hits.html similarity index 100% rename from apps/catalogue/templates/catalogue/search_no_hits.html rename to src/catalogue/templates/catalogue/search_no_hits.html diff --git a/apps/catalogue/templates/catalogue/search_too_short.html b/src/catalogue/templates/catalogue/search_too_short.html similarity index 100% rename from apps/catalogue/templates/catalogue/search_too_short.html rename to src/catalogue/templates/catalogue/search_too_short.html diff --git a/apps/catalogue/templates/catalogue/snippets/audiobook_list.html b/src/catalogue/templates/catalogue/snippets/audiobook_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/snippets/audiobook_list.html rename to src/catalogue/templates/catalogue/snippets/audiobook_list.html diff --git a/apps/catalogue/templates/catalogue/snippets/book_list.html b/src/catalogue/templates/catalogue/snippets/book_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/snippets/book_list.html rename to src/catalogue/templates/catalogue/snippets/book_list.html diff --git a/apps/catalogue/templates/catalogue/snippets/book_list_nav.html b/src/catalogue/templates/catalogue/snippets/book_list_nav.html similarity index 100% rename from apps/catalogue/templates/catalogue/snippets/book_list_nav.html rename to src/catalogue/templates/catalogue/snippets/book_list_nav.html diff --git a/apps/catalogue/templates/catalogue/snippets/custom_pdf_link_li.html b/src/catalogue/templates/catalogue/snippets/custom_pdf_link_li.html similarity index 100% rename from apps/catalogue/templates/catalogue/snippets/custom_pdf_link_li.html rename to src/catalogue/templates/catalogue/snippets/custom_pdf_link_li.html diff --git a/apps/catalogue/templates/catalogue/snippets/license_icon.html b/src/catalogue/templates/catalogue/snippets/license_icon.html similarity index 100% rename from apps/catalogue/templates/catalogue/snippets/license_icon.html rename to src/catalogue/templates/catalogue/snippets/license_icon.html diff --git a/apps/catalogue/templates/catalogue/tag_list.html b/src/catalogue/templates/catalogue/tag_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/tag_list.html rename to src/catalogue/templates/catalogue/tag_list.html diff --git a/apps/catalogue/templates/catalogue/tag_list_split.html b/src/catalogue/templates/catalogue/tag_list_split.html similarity index 100% rename from apps/catalogue/templates/catalogue/tag_list_split.html rename to src/catalogue/templates/catalogue/tag_list_split.html diff --git a/apps/catalogue/templates/catalogue/tagged_object_list.html b/src/catalogue/templates/catalogue/tagged_object_list.html similarity index 100% rename from apps/catalogue/templates/catalogue/tagged_object_list.html rename to src/catalogue/templates/catalogue/tagged_object_list.html diff --git a/apps/catalogue/templates/catalogue/viewer_base.html b/src/catalogue/templates/catalogue/viewer_base.html similarity index 100% rename from apps/catalogue/templates/catalogue/viewer_base.html rename to src/catalogue/templates/catalogue/viewer_base.html diff --git a/apps/catalogue/templates/catalogue/work-list.html b/src/catalogue/templates/catalogue/work-list.html similarity index 100% rename from apps/catalogue/templates/catalogue/work-list.html rename to src/catalogue/templates/catalogue/work-list.html diff --git a/apps/catalogue/templatetags/__init__.py b/src/catalogue/templatetags/__init__.py similarity index 100% rename from apps/catalogue/templatetags/__init__.py rename to src/catalogue/templatetags/__init__.py diff --git a/apps/catalogue/templatetags/catalogue_tags.py b/src/catalogue/templatetags/catalogue_tags.py similarity index 100% rename from apps/catalogue/templatetags/catalogue_tags.py rename to src/catalogue/templatetags/catalogue_tags.py diff --git a/apps/catalogue/test_utils.py b/src/catalogue/test_utils.py similarity index 100% rename from apps/catalogue/test_utils.py rename to src/catalogue/test_utils.py diff --git a/apps/catalogue/tests/__init__.py b/src/catalogue/tests/__init__.py similarity index 100% rename from apps/catalogue/tests/__init__.py rename to src/catalogue/tests/__init__.py diff --git a/apps/catalogue/tests/book_import.py b/src/catalogue/tests/book_import.py similarity index 100% rename from apps/catalogue/tests/book_import.py rename to src/catalogue/tests/book_import.py diff --git a/apps/catalogue/tests/bookmedia.py b/src/catalogue/tests/bookmedia.py similarity index 100% rename from apps/catalogue/tests/bookmedia.py rename to src/catalogue/tests/bookmedia.py diff --git a/apps/catalogue/tests/cover.py b/src/catalogue/tests/cover.py similarity index 100% rename from apps/catalogue/tests/cover.py rename to src/catalogue/tests/cover.py diff --git a/apps/catalogue/tests/files/fraszka-do-anusie.xml b/src/catalogue/tests/files/fraszka-do-anusie.xml similarity index 100% rename from apps/catalogue/tests/files/fraszka-do-anusie.xml rename to src/catalogue/tests/files/fraszka-do-anusie.xml diff --git a/apps/catalogue/tests/files/fraszki.xml b/src/catalogue/tests/files/fraszki.xml similarity index 100% rename from apps/catalogue/tests/files/fraszki.xml rename to src/catalogue/tests/files/fraszki.xml diff --git a/apps/catalogue/tests/search.py b/src/catalogue/tests/search.py similarity index 100% rename from apps/catalogue/tests/search.py rename to src/catalogue/tests/search.py diff --git a/apps/catalogue/tests/tags.py b/src/catalogue/tests/tags.py similarity index 100% rename from apps/catalogue/tests/tags.py rename to src/catalogue/tests/tags.py diff --git a/apps/catalogue/tests/templatetags.py b/src/catalogue/tests/templatetags.py similarity index 100% rename from apps/catalogue/tests/templatetags.py rename to src/catalogue/tests/templatetags.py diff --git a/apps/catalogue/tests/visit.py b/src/catalogue/tests/visit.py similarity index 100% rename from apps/catalogue/tests/visit.py rename to src/catalogue/tests/visit.py diff --git a/apps/catalogue/translation.py b/src/catalogue/translation.py similarity index 100% rename from apps/catalogue/translation.py rename to src/catalogue/translation.py diff --git a/apps/catalogue/urls.py b/src/catalogue/urls.py similarity index 100% rename from apps/catalogue/urls.py rename to src/catalogue/urls.py diff --git a/apps/catalogue/utils.py b/src/catalogue/utils.py similarity index 100% rename from apps/catalogue/utils.py rename to src/catalogue/utils.py diff --git a/apps/catalogue/views.py b/src/catalogue/views.py similarity index 100% rename from apps/catalogue/views.py rename to src/catalogue/views.py diff --git a/apps/chunks/__init__.py b/src/chunks/__init__.py similarity index 100% rename from apps/chunks/__init__.py rename to src/chunks/__init__.py diff --git a/apps/chunks/admin.py b/src/chunks/admin.py similarity index 100% rename from apps/chunks/admin.py rename to src/chunks/admin.py diff --git a/apps/chunks/locale/de/LC_MESSAGES/django.mo b/src/chunks/locale/de/LC_MESSAGES/django.mo similarity index 100% rename from apps/chunks/locale/de/LC_MESSAGES/django.mo rename to src/chunks/locale/de/LC_MESSAGES/django.mo diff --git a/apps/chunks/locale/de/LC_MESSAGES/django.po b/src/chunks/locale/de/LC_MESSAGES/django.po similarity index 100% rename from apps/chunks/locale/de/LC_MESSAGES/django.po rename to src/chunks/locale/de/LC_MESSAGES/django.po diff --git a/apps/chunks/locale/en/LC_MESSAGES/django.mo b/src/chunks/locale/en/LC_MESSAGES/django.mo similarity index 100% rename from apps/chunks/locale/en/LC_MESSAGES/django.mo rename to src/chunks/locale/en/LC_MESSAGES/django.mo diff --git a/apps/chunks/locale/en/LC_MESSAGES/django.po b/src/chunks/locale/en/LC_MESSAGES/django.po similarity index 100% rename from apps/chunks/locale/en/LC_MESSAGES/django.po rename to src/chunks/locale/en/LC_MESSAGES/django.po diff --git a/apps/chunks/locale/es/LC_MESSAGES/django.mo b/src/chunks/locale/es/LC_MESSAGES/django.mo similarity index 100% rename from apps/chunks/locale/es/LC_MESSAGES/django.mo rename to src/chunks/locale/es/LC_MESSAGES/django.mo diff --git a/apps/chunks/locale/es/LC_MESSAGES/django.po b/src/chunks/locale/es/LC_MESSAGES/django.po similarity index 100% rename from apps/chunks/locale/es/LC_MESSAGES/django.po rename to src/chunks/locale/es/LC_MESSAGES/django.po diff --git a/apps/chunks/locale/fr/LC_MESSAGES/django.mo b/src/chunks/locale/fr/LC_MESSAGES/django.mo similarity index 100% rename from apps/chunks/locale/fr/LC_MESSAGES/django.mo rename to src/chunks/locale/fr/LC_MESSAGES/django.mo diff --git a/apps/chunks/locale/fr/LC_MESSAGES/django.po b/src/chunks/locale/fr/LC_MESSAGES/django.po similarity index 100% rename from apps/chunks/locale/fr/LC_MESSAGES/django.po rename to src/chunks/locale/fr/LC_MESSAGES/django.po diff --git a/apps/chunks/locale/it/LC_MESSAGES/django.mo b/src/chunks/locale/it/LC_MESSAGES/django.mo similarity index 100% rename from apps/chunks/locale/it/LC_MESSAGES/django.mo rename to src/chunks/locale/it/LC_MESSAGES/django.mo diff --git a/apps/chunks/locale/it/LC_MESSAGES/django.po b/src/chunks/locale/it/LC_MESSAGES/django.po similarity index 100% rename from apps/chunks/locale/it/LC_MESSAGES/django.po rename to src/chunks/locale/it/LC_MESSAGES/django.po diff --git a/apps/chunks/locale/jp/LC_MESSAGES/django.mo b/src/chunks/locale/jp/LC_MESSAGES/django.mo similarity index 100% rename from apps/chunks/locale/jp/LC_MESSAGES/django.mo rename to src/chunks/locale/jp/LC_MESSAGES/django.mo diff --git a/apps/chunks/locale/jp/LC_MESSAGES/django.po b/src/chunks/locale/jp/LC_MESSAGES/django.po similarity index 100% rename from apps/chunks/locale/jp/LC_MESSAGES/django.po rename to src/chunks/locale/jp/LC_MESSAGES/django.po diff --git a/apps/chunks/locale/lt/LC_MESSAGES/django.mo b/src/chunks/locale/lt/LC_MESSAGES/django.mo similarity index 100% rename from apps/chunks/locale/lt/LC_MESSAGES/django.mo rename to src/chunks/locale/lt/LC_MESSAGES/django.mo diff --git a/apps/chunks/locale/lt/LC_MESSAGES/django.po b/src/chunks/locale/lt/LC_MESSAGES/django.po similarity index 100% rename from apps/chunks/locale/lt/LC_MESSAGES/django.po rename to src/chunks/locale/lt/LC_MESSAGES/django.po diff --git a/apps/chunks/locale/pl/LC_MESSAGES/django.mo b/src/chunks/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/chunks/locale/pl/LC_MESSAGES/django.mo rename to src/chunks/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/chunks/locale/pl/LC_MESSAGES/django.po b/src/chunks/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/chunks/locale/pl/LC_MESSAGES/django.po rename to src/chunks/locale/pl/LC_MESSAGES/django.po diff --git a/apps/chunks/locale/ru/LC_MESSAGES/django.mo b/src/chunks/locale/ru/LC_MESSAGES/django.mo similarity index 100% rename from apps/chunks/locale/ru/LC_MESSAGES/django.mo rename to src/chunks/locale/ru/LC_MESSAGES/django.mo diff --git a/apps/chunks/locale/ru/LC_MESSAGES/django.po b/src/chunks/locale/ru/LC_MESSAGES/django.po similarity index 100% rename from apps/chunks/locale/ru/LC_MESSAGES/django.po rename to src/chunks/locale/ru/LC_MESSAGES/django.po diff --git a/apps/chunks/locale/uk/LC_MESSAGES/django.mo b/src/chunks/locale/uk/LC_MESSAGES/django.mo similarity index 100% rename from apps/chunks/locale/uk/LC_MESSAGES/django.mo rename to src/chunks/locale/uk/LC_MESSAGES/django.mo diff --git a/apps/chunks/locale/uk/LC_MESSAGES/django.po b/src/chunks/locale/uk/LC_MESSAGES/django.po similarity index 100% rename from apps/chunks/locale/uk/LC_MESSAGES/django.po rename to src/chunks/locale/uk/LC_MESSAGES/django.po diff --git a/apps/chunks/migrations/0001_initial.py b/src/chunks/migrations/0001_initial.py similarity index 100% rename from apps/chunks/migrations/0001_initial.py rename to src/chunks/migrations/0001_initial.py diff --git a/apps/chunks/migrations/0002_auto_20140911_1253.py b/src/chunks/migrations/0002_auto_20140911_1253.py similarity index 100% rename from apps/chunks/migrations/0002_auto_20140911_1253.py rename to src/chunks/migrations/0002_auto_20140911_1253.py diff --git a/apps/chunks/migrations/0003_auto_20151221_1225.py b/src/chunks/migrations/0003_auto_20151221_1225.py similarity index 100% rename from apps/chunks/migrations/0003_auto_20151221_1225.py rename to src/chunks/migrations/0003_auto_20151221_1225.py diff --git a/apps/chunks/migrations/__init__.py b/src/chunks/migrations/__init__.py similarity index 100% rename from apps/chunks/migrations/__init__.py rename to src/chunks/migrations/__init__.py diff --git a/apps/chunks/models.py b/src/chunks/models.py similarity index 100% rename from apps/chunks/models.py rename to src/chunks/models.py diff --git a/apps/chunks/translation.py b/src/chunks/translation.py similarity index 100% rename from apps/chunks/translation.py rename to src/chunks/translation.py diff --git a/apps/chunks/urls.py b/src/chunks/urls.py similarity index 100% rename from apps/chunks/urls.py rename to src/chunks/urls.py diff --git a/apps/chunks/views.py b/src/chunks/views.py similarity index 100% rename from apps/chunks/views.py rename to src/chunks/views.py diff --git a/apps/dictionary/__init__.py b/src/dictionary/__init__.py similarity index 100% rename from apps/dictionary/__init__.py rename to src/dictionary/__init__.py diff --git a/apps/dictionary/constants.py b/src/dictionary/constants.py similarity index 100% rename from apps/dictionary/constants.py rename to src/dictionary/constants.py diff --git a/apps/dictionary/locale/pl/LC_MESSAGES/django.mo b/src/dictionary/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/dictionary/locale/pl/LC_MESSAGES/django.mo rename to src/dictionary/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/dictionary/locale/pl/LC_MESSAGES/django.po b/src/dictionary/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/dictionary/locale/pl/LC_MESSAGES/django.po rename to src/dictionary/locale/pl/LC_MESSAGES/django.po diff --git a/apps/dictionary/migrations/0001_initial.py b/src/dictionary/migrations/0001_initial.py similarity index 100% rename from apps/dictionary/migrations/0001_initial.py rename to src/dictionary/migrations/0001_initial.py diff --git a/apps/dictionary/migrations/0002_auto_20141006_1422.py b/src/dictionary/migrations/0002_auto_20141006_1422.py similarity index 100% rename from apps/dictionary/migrations/0002_auto_20141006_1422.py rename to src/dictionary/migrations/0002_auto_20141006_1422.py diff --git a/apps/dictionary/migrations/0003_auto_20141023_1445.py b/src/dictionary/migrations/0003_auto_20141023_1445.py similarity index 100% rename from apps/dictionary/migrations/0003_auto_20141023_1445.py rename to src/dictionary/migrations/0003_auto_20141023_1445.py diff --git a/apps/dictionary/migrations/0004_auto_20151221_1225.py b/src/dictionary/migrations/0004_auto_20151221_1225.py similarity index 100% rename from apps/dictionary/migrations/0004_auto_20151221_1225.py rename to src/dictionary/migrations/0004_auto_20151221_1225.py diff --git a/apps/dictionary/migrations/__init__.py b/src/dictionary/migrations/__init__.py similarity index 100% rename from apps/dictionary/migrations/__init__.py rename to src/dictionary/migrations/__init__.py diff --git a/apps/dictionary/models.py b/src/dictionary/models.py similarity index 100% rename from apps/dictionary/models.py rename to src/dictionary/models.py diff --git a/apps/dictionary/templates/dictionary/note_list.html b/src/dictionary/templates/dictionary/note_list.html similarity index 100% rename from apps/dictionary/templates/dictionary/note_list.html rename to src/dictionary/templates/dictionary/note_list.html diff --git a/apps/dictionary/templatetags/__init__.py b/src/dictionary/templatetags/__init__.py similarity index 100% rename from apps/dictionary/templatetags/__init__.py rename to src/dictionary/templatetags/__init__.py diff --git a/apps/dictionary/templatetags/set_get.py b/src/dictionary/templatetags/set_get.py similarity index 100% rename from apps/dictionary/templatetags/set_get.py rename to src/dictionary/templatetags/set_get.py diff --git a/apps/dictionary/tests.py b/src/dictionary/tests.py similarity index 100% rename from apps/dictionary/tests.py rename to src/dictionary/tests.py diff --git a/apps/dictionary/urls.py b/src/dictionary/urls.py similarity index 100% rename from apps/dictionary/urls.py rename to src/dictionary/urls.py diff --git a/apps/dictionary/views.py b/src/dictionary/views.py similarity index 100% rename from apps/dictionary/views.py rename to src/dictionary/views.py diff --git a/apps/funding/__init__.py b/src/funding/__init__.py similarity index 100% rename from apps/funding/__init__.py rename to src/funding/__init__.py diff --git a/apps/funding/admin.py b/src/funding/admin.py similarity index 100% rename from apps/funding/admin.py rename to src/funding/admin.py diff --git a/apps/funding/forms.py b/src/funding/forms.py similarity index 100% rename from apps/funding/forms.py rename to src/funding/forms.py diff --git a/apps/funding/locale/pl/LC_MESSAGES/django.mo b/src/funding/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/funding/locale/pl/LC_MESSAGES/django.mo rename to src/funding/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/funding/locale/pl/LC_MESSAGES/django.po b/src/funding/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/funding/locale/pl/LC_MESSAGES/django.po rename to src/funding/locale/pl/LC_MESSAGES/django.po diff --git a/apps/funding/management/__init__.py b/src/funding/management/__init__.py similarity index 100% rename from apps/funding/management/__init__.py rename to src/funding/management/__init__.py diff --git a/apps/funding/management/commands/__init__.py b/src/funding/management/commands/__init__.py similarity index 100% rename from apps/funding/management/commands/__init__.py rename to src/funding/management/commands/__init__.py diff --git a/apps/funding/management/commands/funding_notify.py b/src/funding/management/commands/funding_notify.py similarity index 100% rename from apps/funding/management/commands/funding_notify.py rename to src/funding/management/commands/funding_notify.py diff --git a/apps/funding/migrations/0001_initial.py b/src/funding/migrations/0001_initial.py similarity index 100% rename from apps/funding/migrations/0001_initial.py rename to src/funding/migrations/0001_initial.py diff --git a/apps/funding/migrations/0002_auto_20151221_1225.py b/src/funding/migrations/0002_auto_20151221_1225.py similarity index 100% rename from apps/funding/migrations/0002_auto_20151221_1225.py rename to src/funding/migrations/0002_auto_20151221_1225.py diff --git a/apps/funding/migrations/__init__.py b/src/funding/migrations/__init__.py similarity index 100% rename from apps/funding/migrations/__init__.py rename to src/funding/migrations/__init__.py diff --git a/apps/funding/models.py b/src/funding/models.py similarity index 100% rename from apps/funding/models.py rename to src/funding/models.py diff --git a/apps/funding/static/funding/funding.js b/src/funding/static/funding/funding.js similarity index 100% rename from apps/funding/static/funding/funding.js rename to src/funding/static/funding/funding.js diff --git a/apps/funding/templates/admin/funding/offer/change_form.html b/src/funding/templates/admin/funding/offer/change_form.html similarity index 100% rename from apps/funding/templates/admin/funding/offer/change_form.html rename to src/funding/templates/admin/funding/offer/change_form.html diff --git a/apps/funding/templates/funding/disable_notifications.html b/src/funding/templates/funding/disable_notifications.html similarity index 100% rename from apps/funding/templates/funding/disable_notifications.html rename to src/funding/templates/funding/disable_notifications.html diff --git a/apps/funding/templates/funding/email/base.txt b/src/funding/templates/funding/email/base.txt similarity index 100% rename from apps/funding/templates/funding/email/base.txt rename to src/funding/templates/funding/email/base.txt diff --git a/apps/funding/templates/funding/email/end.txt b/src/funding/templates/funding/email/end.txt similarity index 100% rename from apps/funding/templates/funding/email/end.txt rename to src/funding/templates/funding/email/end.txt diff --git a/apps/funding/templates/funding/email/near.txt b/src/funding/templates/funding/email/near.txt similarity index 100% rename from apps/funding/templates/funding/email/near.txt rename to src/funding/templates/funding/email/near.txt diff --git a/apps/funding/templates/funding/email/published.txt b/src/funding/templates/funding/email/published.txt similarity index 100% rename from apps/funding/templates/funding/email/published.txt rename to src/funding/templates/funding/email/published.txt diff --git a/apps/funding/templates/funding/email/thanks.txt b/src/funding/templates/funding/email/thanks.txt similarity index 100% rename from apps/funding/templates/funding/email/thanks.txt rename to src/funding/templates/funding/email/thanks.txt diff --git a/apps/funding/templates/funding/includes/funding.html b/src/funding/templates/funding/includes/funding.html similarity index 100% rename from apps/funding/templates/funding/includes/funding.html rename to src/funding/templates/funding/includes/funding.html diff --git a/apps/funding/templates/funding/includes/fundings.html b/src/funding/templates/funding/includes/fundings.html similarity index 100% rename from apps/funding/templates/funding/includes/fundings.html rename to src/funding/templates/funding/includes/fundings.html diff --git a/apps/funding/templates/funding/includes/offer_status.html b/src/funding/templates/funding/includes/offer_status.html similarity index 100% rename from apps/funding/templates/funding/includes/offer_status.html rename to src/funding/templates/funding/includes/offer_status.html diff --git a/apps/funding/templates/funding/includes/offer_status_more.html b/src/funding/templates/funding/includes/offer_status_more.html similarity index 100% rename from apps/funding/templates/funding/includes/offer_status_more.html rename to src/funding/templates/funding/includes/offer_status_more.html diff --git a/apps/funding/templates/funding/no_thanks.html b/src/funding/templates/funding/no_thanks.html similarity index 100% rename from apps/funding/templates/funding/no_thanks.html rename to src/funding/templates/funding/no_thanks.html diff --git a/apps/funding/templates/funding/offer_detail.html b/src/funding/templates/funding/offer_detail.html similarity index 100% rename from apps/funding/templates/funding/offer_detail.html rename to src/funding/templates/funding/offer_detail.html diff --git a/apps/funding/templates/funding/offer_list.html b/src/funding/templates/funding/offer_list.html similarity index 100% rename from apps/funding/templates/funding/offer_list.html rename to src/funding/templates/funding/offer_list.html diff --git a/apps/funding/templates/funding/snippets/any_remaining.html b/src/funding/templates/funding/snippets/any_remaining.html similarity index 100% rename from apps/funding/templates/funding/snippets/any_remaining.html rename to src/funding/templates/funding/snippets/any_remaining.html diff --git a/apps/funding/templates/funding/thanks.html b/src/funding/templates/funding/thanks.html similarity index 100% rename from apps/funding/templates/funding/thanks.html rename to src/funding/templates/funding/thanks.html diff --git a/apps/funding/templates/funding/widgets/amount.html b/src/funding/templates/funding/widgets/amount.html similarity index 100% rename from apps/funding/templates/funding/widgets/amount.html rename to src/funding/templates/funding/widgets/amount.html diff --git a/apps/funding/templates/funding/wlfund.html b/src/funding/templates/funding/wlfund.html similarity index 100% rename from apps/funding/templates/funding/wlfund.html rename to src/funding/templates/funding/wlfund.html diff --git a/apps/funding/templatetags/__init__.py b/src/funding/templatetags/__init__.py similarity index 100% rename from apps/funding/templatetags/__init__.py rename to src/funding/templatetags/__init__.py diff --git a/apps/funding/templatetags/funding_tags.py b/src/funding/templatetags/funding_tags.py similarity index 100% rename from apps/funding/templatetags/funding_tags.py rename to src/funding/templatetags/funding_tags.py diff --git a/apps/funding/tests.py b/src/funding/tests.py similarity index 100% rename from apps/funding/tests.py rename to src/funding/tests.py diff --git a/apps/funding/urls.py b/src/funding/urls.py similarity index 100% rename from apps/funding/urls.py rename to src/funding/urls.py diff --git a/apps/funding/utils.py b/src/funding/utils.py similarity index 100% rename from apps/funding/utils.py rename to src/funding/utils.py diff --git a/apps/funding/views.py b/src/funding/views.py similarity index 100% rename from apps/funding/views.py rename to src/funding/views.py diff --git a/apps/funding/widgets.py b/src/funding/widgets.py similarity index 100% rename from apps/funding/widgets.py rename to src/funding/widgets.py diff --git a/apps/infopages/__init__.py b/src/infopages/__init__.py similarity index 100% rename from apps/infopages/__init__.py rename to src/infopages/__init__.py diff --git a/apps/infopages/admin.py b/src/infopages/admin.py similarity index 100% rename from apps/infopages/admin.py rename to src/infopages/admin.py diff --git a/apps/infopages/fixtures/infopages.json b/src/infopages/fixtures/infopages.json similarity index 100% rename from apps/infopages/fixtures/infopages.json rename to src/infopages/fixtures/infopages.json diff --git a/apps/infopages/locale/de/LC_MESSAGES/django.mo b/src/infopages/locale/de/LC_MESSAGES/django.mo similarity index 100% rename from apps/infopages/locale/de/LC_MESSAGES/django.mo rename to src/infopages/locale/de/LC_MESSAGES/django.mo diff --git a/apps/infopages/locale/de/LC_MESSAGES/django.po b/src/infopages/locale/de/LC_MESSAGES/django.po similarity index 100% rename from apps/infopages/locale/de/LC_MESSAGES/django.po rename to src/infopages/locale/de/LC_MESSAGES/django.po diff --git a/apps/infopages/locale/es/LC_MESSAGES/django.mo b/src/infopages/locale/es/LC_MESSAGES/django.mo similarity index 100% rename from apps/infopages/locale/es/LC_MESSAGES/django.mo rename to src/infopages/locale/es/LC_MESSAGES/django.mo diff --git a/apps/infopages/locale/es/LC_MESSAGES/django.po b/src/infopages/locale/es/LC_MESSAGES/django.po similarity index 100% rename from apps/infopages/locale/es/LC_MESSAGES/django.po rename to src/infopages/locale/es/LC_MESSAGES/django.po diff --git a/apps/infopages/locale/pl/LC_MESSAGES/django.mo b/src/infopages/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/infopages/locale/pl/LC_MESSAGES/django.mo rename to src/infopages/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/infopages/locale/pl/LC_MESSAGES/django.po b/src/infopages/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/infopages/locale/pl/LC_MESSAGES/django.po rename to src/infopages/locale/pl/LC_MESSAGES/django.po diff --git a/apps/infopages/locale/uk/LC_MESSAGES/django.mo b/src/infopages/locale/uk/LC_MESSAGES/django.mo similarity index 100% rename from apps/infopages/locale/uk/LC_MESSAGES/django.mo rename to src/infopages/locale/uk/LC_MESSAGES/django.mo diff --git a/apps/infopages/locale/uk/LC_MESSAGES/django.po b/src/infopages/locale/uk/LC_MESSAGES/django.po similarity index 100% rename from apps/infopages/locale/uk/LC_MESSAGES/django.po rename to src/infopages/locale/uk/LC_MESSAGES/django.po diff --git a/apps/infopages/migrations/0001_initial.py b/src/infopages/migrations/0001_initial.py similarity index 100% rename from apps/infopages/migrations/0001_initial.py rename to src/infopages/migrations/0001_initial.py diff --git a/apps/infopages/migrations/0002_auto_20151221_1225.py b/src/infopages/migrations/0002_auto_20151221_1225.py similarity index 100% rename from apps/infopages/migrations/0002_auto_20151221_1225.py rename to src/infopages/migrations/0002_auto_20151221_1225.py diff --git a/apps/infopages/migrations/__init__.py b/src/infopages/migrations/__init__.py similarity index 100% rename from apps/infopages/migrations/__init__.py rename to src/infopages/migrations/__init__.py diff --git a/apps/infopages/models.py b/src/infopages/models.py similarity index 100% rename from apps/infopages/models.py rename to src/infopages/models.py diff --git a/apps/infopages/templates/infopages/infopage.html b/src/infopages/templates/infopages/infopage.html similarity index 100% rename from apps/infopages/templates/infopages/infopage.html rename to src/infopages/templates/infopages/infopage.html diff --git a/apps/infopages/templates/infopages/on_main.html b/src/infopages/templates/infopages/on_main.html similarity index 100% rename from apps/infopages/templates/infopages/on_main.html rename to src/infopages/templates/infopages/on_main.html diff --git a/apps/infopages/templatetags/__init__.py b/src/infopages/templatetags/__init__.py similarity index 100% rename from apps/infopages/templatetags/__init__.py rename to src/infopages/templatetags/__init__.py diff --git a/apps/infopages/templatetags/infopages_tags.py b/src/infopages/templatetags/infopages_tags.py similarity index 100% rename from apps/infopages/templatetags/infopages_tags.py rename to src/infopages/templatetags/infopages_tags.py diff --git a/apps/infopages/translation.py b/src/infopages/translation.py similarity index 100% rename from apps/infopages/translation.py rename to src/infopages/translation.py diff --git a/apps/infopages/urls.py b/src/infopages/urls.py similarity index 100% rename from apps/infopages/urls.py rename to src/infopages/urls.py diff --git a/apps/infopages/views.py b/src/infopages/views.py similarity index 100% rename from apps/infopages/views.py rename to src/infopages/views.py diff --git a/apps/lesmianator/__init__.py b/src/lesmianator/__init__.py similarity index 100% rename from apps/lesmianator/__init__.py rename to src/lesmianator/__init__.py diff --git a/apps/lesmianator/locale/pl/LC_MESSAGES/django.mo b/src/lesmianator/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/lesmianator/locale/pl/LC_MESSAGES/django.mo rename to src/lesmianator/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/lesmianator/locale/pl/LC_MESSAGES/django.po b/src/lesmianator/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/lesmianator/locale/pl/LC_MESSAGES/django.po rename to src/lesmianator/locale/pl/LC_MESSAGES/django.po diff --git a/apps/lesmianator/management/__init__.py b/src/lesmianator/management/__init__.py similarity index 100% rename from apps/lesmianator/management/__init__.py rename to src/lesmianator/management/__init__.py diff --git a/apps/lesmianator/management/commands/__init__.py b/src/lesmianator/management/commands/__init__.py similarity index 100% rename from apps/lesmianator/management/commands/__init__.py rename to src/lesmianator/management/commands/__init__.py diff --git a/apps/lesmianator/management/commands/lesmianator.py b/src/lesmianator/management/commands/lesmianator.py similarity index 100% rename from apps/lesmianator/management/commands/lesmianator.py rename to src/lesmianator/management/commands/lesmianator.py diff --git a/apps/lesmianator/migrations/0001_initial.py b/src/lesmianator/migrations/0001_initial.py similarity index 100% rename from apps/lesmianator/migrations/0001_initial.py rename to src/lesmianator/migrations/0001_initial.py diff --git a/apps/lesmianator/migrations/0002_auto_20151221_1225.py b/src/lesmianator/migrations/0002_auto_20151221_1225.py similarity index 100% rename from apps/lesmianator/migrations/0002_auto_20151221_1225.py rename to src/lesmianator/migrations/0002_auto_20151221_1225.py diff --git a/apps/lesmianator/migrations/__init__.py b/src/lesmianator/migrations/__init__.py similarity index 100% rename from apps/lesmianator/migrations/__init__.py rename to src/lesmianator/migrations/__init__.py diff --git a/apps/lesmianator/models.py b/src/lesmianator/models.py similarity index 100% rename from apps/lesmianator/models.py rename to src/lesmianator/models.py diff --git a/apps/lesmianator/templates/lesmianator/lesmianator.html b/src/lesmianator/templates/lesmianator/lesmianator.html similarity index 100% rename from apps/lesmianator/templates/lesmianator/lesmianator.html rename to src/lesmianator/templates/lesmianator/lesmianator.html diff --git a/apps/lesmianator/templates/lesmianator/poem.html b/src/lesmianator/templates/lesmianator/poem.html similarity index 100% rename from apps/lesmianator/templates/lesmianator/poem.html rename to src/lesmianator/templates/lesmianator/poem.html diff --git a/apps/lesmianator/urls.py b/src/lesmianator/urls.py similarity index 100% rename from apps/lesmianator/urls.py rename to src/lesmianator/urls.py diff --git a/apps/lesmianator/views.py b/src/lesmianator/views.py similarity index 100% rename from apps/lesmianator/views.py rename to src/lesmianator/views.py diff --git a/apps/libraries/__init__.py b/src/libraries/__init__.py similarity index 100% rename from apps/libraries/__init__.py rename to src/libraries/__init__.py diff --git a/apps/libraries/admin.py b/src/libraries/admin.py similarity index 100% rename from apps/libraries/admin.py rename to src/libraries/admin.py diff --git a/apps/libraries/locale/pl/LC_MESSAGES/django.mo b/src/libraries/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/libraries/locale/pl/LC_MESSAGES/django.mo rename to src/libraries/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/libraries/locale/pl/LC_MESSAGES/django.po b/src/libraries/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/libraries/locale/pl/LC_MESSAGES/django.po rename to src/libraries/locale/pl/LC_MESSAGES/django.po diff --git a/apps/libraries/migrations/0001_initial.py b/src/libraries/migrations/0001_initial.py similarity index 100% rename from apps/libraries/migrations/0001_initial.py rename to src/libraries/migrations/0001_initial.py diff --git a/apps/libraries/migrations/0002_auto_20151221_1225.py b/src/libraries/migrations/0002_auto_20151221_1225.py similarity index 100% rename from apps/libraries/migrations/0002_auto_20151221_1225.py rename to src/libraries/migrations/0002_auto_20151221_1225.py diff --git a/apps/libraries/migrations/__init__.py b/src/libraries/migrations/__init__.py similarity index 100% rename from apps/libraries/migrations/__init__.py rename to src/libraries/migrations/__init__.py diff --git a/apps/libraries/models.py b/src/libraries/models.py similarity index 100% rename from apps/libraries/models.py rename to src/libraries/models.py diff --git a/apps/libraries/templates/libraries/catalog_view.html b/src/libraries/templates/libraries/catalog_view.html similarity index 100% rename from apps/libraries/templates/libraries/catalog_view.html rename to src/libraries/templates/libraries/catalog_view.html diff --git a/apps/libraries/templates/libraries/library_view.html b/src/libraries/templates/libraries/library_view.html similarity index 100% rename from apps/libraries/templates/libraries/library_view.html rename to src/libraries/templates/libraries/library_view.html diff --git a/apps/libraries/templates/libraries/main_view.html b/src/libraries/templates/libraries/main_view.html similarity index 100% rename from apps/libraries/templates/libraries/main_view.html rename to src/libraries/templates/libraries/main_view.html diff --git a/apps/libraries/urls.py b/src/libraries/urls.py similarity index 100% rename from apps/libraries/urls.py rename to src/libraries/urls.py diff --git a/apps/libraries/views.py b/src/libraries/views.py similarity index 100% rename from apps/libraries/views.py rename to src/libraries/views.py diff --git a/manage.py b/src/manage.py similarity index 76% rename from manage.py rename to src/manage.py index a03a13a7c..c1c055b1e 100755 --- a/manage.py +++ b/src/manage.py @@ -4,9 +4,7 @@ import sys ROOT = os.path.dirname(os.path.abspath(__file__)) sys.path = [ - os.path.join(ROOT, 'apps'), - os.path.join(ROOT, 'lib'), - os.path.join(ROOT, 'lib/librarian'), + os.path.join(ROOT, '../lib/librarian'), ] + sys.path if __name__ == "__main__": diff --git a/apps/newtagging/__init__.py b/src/newtagging/__init__.py similarity index 100% rename from apps/newtagging/__init__.py rename to src/newtagging/__init__.py diff --git a/apps/newtagging/admin.py b/src/newtagging/admin.py similarity index 100% rename from apps/newtagging/admin.py rename to src/newtagging/admin.py diff --git a/apps/newtagging/locale/de/LC_MESSAGES/django.mo b/src/newtagging/locale/de/LC_MESSAGES/django.mo similarity index 100% rename from apps/newtagging/locale/de/LC_MESSAGES/django.mo rename to src/newtagging/locale/de/LC_MESSAGES/django.mo diff --git a/apps/newtagging/locale/de/LC_MESSAGES/django.po b/src/newtagging/locale/de/LC_MESSAGES/django.po similarity index 100% rename from apps/newtagging/locale/de/LC_MESSAGES/django.po rename to src/newtagging/locale/de/LC_MESSAGES/django.po diff --git a/apps/newtagging/locale/en/LC_MESSAGES/django.mo b/src/newtagging/locale/en/LC_MESSAGES/django.mo similarity index 100% rename from apps/newtagging/locale/en/LC_MESSAGES/django.mo rename to src/newtagging/locale/en/LC_MESSAGES/django.mo diff --git a/apps/newtagging/locale/en/LC_MESSAGES/django.po b/src/newtagging/locale/en/LC_MESSAGES/django.po similarity index 100% rename from apps/newtagging/locale/en/LC_MESSAGES/django.po rename to src/newtagging/locale/en/LC_MESSAGES/django.po diff --git a/apps/newtagging/locale/es/LC_MESSAGES/django.mo b/src/newtagging/locale/es/LC_MESSAGES/django.mo similarity index 100% rename from apps/newtagging/locale/es/LC_MESSAGES/django.mo rename to src/newtagging/locale/es/LC_MESSAGES/django.mo diff --git a/apps/newtagging/locale/es/LC_MESSAGES/django.po b/src/newtagging/locale/es/LC_MESSAGES/django.po similarity index 100% rename from apps/newtagging/locale/es/LC_MESSAGES/django.po rename to src/newtagging/locale/es/LC_MESSAGES/django.po diff --git a/apps/newtagging/locale/fr/LC_MESSAGES/django.mo b/src/newtagging/locale/fr/LC_MESSAGES/django.mo similarity index 100% rename from apps/newtagging/locale/fr/LC_MESSAGES/django.mo rename to src/newtagging/locale/fr/LC_MESSAGES/django.mo diff --git a/apps/newtagging/locale/fr/LC_MESSAGES/django.po b/src/newtagging/locale/fr/LC_MESSAGES/django.po similarity index 100% rename from apps/newtagging/locale/fr/LC_MESSAGES/django.po rename to src/newtagging/locale/fr/LC_MESSAGES/django.po diff --git a/apps/newtagging/locale/it/LC_MESSAGES/django.mo b/src/newtagging/locale/it/LC_MESSAGES/django.mo similarity index 100% rename from apps/newtagging/locale/it/LC_MESSAGES/django.mo rename to src/newtagging/locale/it/LC_MESSAGES/django.mo diff --git a/apps/newtagging/locale/it/LC_MESSAGES/django.po b/src/newtagging/locale/it/LC_MESSAGES/django.po similarity index 100% rename from apps/newtagging/locale/it/LC_MESSAGES/django.po rename to src/newtagging/locale/it/LC_MESSAGES/django.po diff --git a/apps/newtagging/locale/jp/LC_MESSAGES/django.mo b/src/newtagging/locale/jp/LC_MESSAGES/django.mo similarity index 100% rename from apps/newtagging/locale/jp/LC_MESSAGES/django.mo rename to src/newtagging/locale/jp/LC_MESSAGES/django.mo diff --git a/apps/newtagging/locale/jp/LC_MESSAGES/django.po b/src/newtagging/locale/jp/LC_MESSAGES/django.po similarity index 100% rename from apps/newtagging/locale/jp/LC_MESSAGES/django.po rename to src/newtagging/locale/jp/LC_MESSAGES/django.po diff --git a/apps/newtagging/locale/lt/LC_MESSAGES/django.mo b/src/newtagging/locale/lt/LC_MESSAGES/django.mo similarity index 100% rename from apps/newtagging/locale/lt/LC_MESSAGES/django.mo rename to src/newtagging/locale/lt/LC_MESSAGES/django.mo diff --git a/apps/newtagging/locale/lt/LC_MESSAGES/django.po b/src/newtagging/locale/lt/LC_MESSAGES/django.po similarity index 100% rename from apps/newtagging/locale/lt/LC_MESSAGES/django.po rename to src/newtagging/locale/lt/LC_MESSAGES/django.po diff --git a/apps/newtagging/locale/pl/LC_MESSAGES/django.mo b/src/newtagging/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/newtagging/locale/pl/LC_MESSAGES/django.mo rename to src/newtagging/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/newtagging/locale/pl/LC_MESSAGES/django.po b/src/newtagging/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/newtagging/locale/pl/LC_MESSAGES/django.po rename to src/newtagging/locale/pl/LC_MESSAGES/django.po diff --git a/apps/newtagging/locale/ru/LC_MESSAGES/django.mo b/src/newtagging/locale/ru/LC_MESSAGES/django.mo similarity index 100% rename from apps/newtagging/locale/ru/LC_MESSAGES/django.mo rename to src/newtagging/locale/ru/LC_MESSAGES/django.mo diff --git a/apps/newtagging/locale/ru/LC_MESSAGES/django.po b/src/newtagging/locale/ru/LC_MESSAGES/django.po similarity index 100% rename from apps/newtagging/locale/ru/LC_MESSAGES/django.po rename to src/newtagging/locale/ru/LC_MESSAGES/django.po diff --git a/apps/newtagging/locale/uk/LC_MESSAGES/django.mo b/src/newtagging/locale/uk/LC_MESSAGES/django.mo similarity index 100% rename from apps/newtagging/locale/uk/LC_MESSAGES/django.mo rename to src/newtagging/locale/uk/LC_MESSAGES/django.mo diff --git a/apps/newtagging/locale/uk/LC_MESSAGES/django.po b/src/newtagging/locale/uk/LC_MESSAGES/django.po similarity index 100% rename from apps/newtagging/locale/uk/LC_MESSAGES/django.po rename to src/newtagging/locale/uk/LC_MESSAGES/django.po diff --git a/apps/newtagging/managers.py b/src/newtagging/managers.py similarity index 100% rename from apps/newtagging/managers.py rename to src/newtagging/managers.py diff --git a/apps/newtagging/models.py b/src/newtagging/models.py similarity index 100% rename from apps/newtagging/models.py rename to src/newtagging/models.py diff --git a/apps/newtagging/views.py b/src/newtagging/views.py similarity index 100% rename from apps/newtagging/views.py rename to src/newtagging/views.py diff --git a/apps/oai/__init__.py b/src/oai/__init__.py similarity index 100% rename from apps/oai/__init__.py rename to src/oai/__init__.py diff --git a/apps/oai/handlers.py b/src/oai/handlers.py similarity index 100% rename from apps/oai/handlers.py rename to src/oai/handlers.py diff --git a/apps/oai/tests/__init__.py b/src/oai/tests/__init__.py similarity index 100% rename from apps/oai/tests/__init__.py rename to src/oai/tests/__init__.py diff --git a/apps/oai/tests/files/antygona.xml b/src/oai/tests/files/antygona.xml similarity index 100% rename from apps/oai/tests/files/antygona.xml rename to src/oai/tests/files/antygona.xml diff --git a/apps/oai/tests/files/lubie-kiedy-kobieta.xml b/src/oai/tests/files/lubie-kiedy-kobieta.xml similarity index 100% rename from apps/oai/tests/files/lubie-kiedy-kobieta.xml rename to src/oai/tests/files/lubie-kiedy-kobieta.xml diff --git a/apps/oai/tests/oaipmhapi.py b/src/oai/tests/oaipmhapi.py similarity index 100% rename from apps/oai/tests/oaipmhapi.py rename to src/oai/tests/oaipmhapi.py diff --git a/apps/oai/urls.py b/src/oai/urls.py similarity index 100% rename from apps/oai/urls.py rename to src/oai/urls.py diff --git a/apps/oai/views.py b/src/oai/views.py similarity index 100% rename from apps/oai/views.py rename to src/oai/views.py diff --git a/apps/opds/__init__.py b/src/opds/__init__.py similarity index 100% rename from apps/opds/__init__.py rename to src/opds/__init__.py diff --git a/apps/opds/tests/__init__.py b/src/opds/tests/__init__.py similarity index 100% rename from apps/opds/tests/__init__.py rename to src/opds/tests/__init__.py diff --git a/apps/opds/tests/files/do-doktora.xml b/src/opds/tests/files/do-doktora.xml similarity index 100% rename from apps/opds/tests/files/do-doktora.xml rename to src/opds/tests/files/do-doktora.xml diff --git a/apps/opds/urls.py b/src/opds/urls.py similarity index 100% rename from apps/opds/urls.py rename to src/opds/urls.py diff --git a/apps/opds/views.py b/src/opds/views.py similarity index 100% rename from apps/opds/views.py rename to src/opds/views.py diff --git a/apps/pdcounter/__init__.py b/src/pdcounter/__init__.py similarity index 100% rename from apps/pdcounter/__init__.py rename to src/pdcounter/__init__.py diff --git a/apps/pdcounter/admin.py b/src/pdcounter/admin.py similarity index 100% rename from apps/pdcounter/admin.py rename to src/pdcounter/admin.py diff --git a/apps/pdcounter/fixtures/lista.json b/src/pdcounter/fixtures/lista.json similarity index 100% rename from apps/pdcounter/fixtures/lista.json rename to src/pdcounter/fixtures/lista.json diff --git a/apps/pdcounter/locale/de/LC_MESSAGES/django.mo b/src/pdcounter/locale/de/LC_MESSAGES/django.mo similarity index 100% rename from apps/pdcounter/locale/de/LC_MESSAGES/django.mo rename to src/pdcounter/locale/de/LC_MESSAGES/django.mo diff --git a/apps/pdcounter/locale/de/LC_MESSAGES/django.po b/src/pdcounter/locale/de/LC_MESSAGES/django.po similarity index 100% rename from apps/pdcounter/locale/de/LC_MESSAGES/django.po rename to src/pdcounter/locale/de/LC_MESSAGES/django.po diff --git a/apps/pdcounter/locale/en/LC_MESSAGES/django.mo b/src/pdcounter/locale/en/LC_MESSAGES/django.mo similarity index 100% rename from apps/pdcounter/locale/en/LC_MESSAGES/django.mo rename to src/pdcounter/locale/en/LC_MESSAGES/django.mo diff --git a/apps/pdcounter/locale/en/LC_MESSAGES/django.po b/src/pdcounter/locale/en/LC_MESSAGES/django.po similarity index 100% rename from apps/pdcounter/locale/en/LC_MESSAGES/django.po rename to src/pdcounter/locale/en/LC_MESSAGES/django.po diff --git a/apps/pdcounter/locale/es/LC_MESSAGES/django.mo b/src/pdcounter/locale/es/LC_MESSAGES/django.mo similarity index 100% rename from apps/pdcounter/locale/es/LC_MESSAGES/django.mo rename to src/pdcounter/locale/es/LC_MESSAGES/django.mo diff --git a/apps/pdcounter/locale/es/LC_MESSAGES/django.po b/src/pdcounter/locale/es/LC_MESSAGES/django.po similarity index 100% rename from apps/pdcounter/locale/es/LC_MESSAGES/django.po rename to src/pdcounter/locale/es/LC_MESSAGES/django.po diff --git a/apps/pdcounter/locale/fr/LC_MESSAGES/django.mo b/src/pdcounter/locale/fr/LC_MESSAGES/django.mo similarity index 100% rename from apps/pdcounter/locale/fr/LC_MESSAGES/django.mo rename to src/pdcounter/locale/fr/LC_MESSAGES/django.mo diff --git a/apps/pdcounter/locale/fr/LC_MESSAGES/django.po b/src/pdcounter/locale/fr/LC_MESSAGES/django.po similarity index 100% rename from apps/pdcounter/locale/fr/LC_MESSAGES/django.po rename to src/pdcounter/locale/fr/LC_MESSAGES/django.po diff --git a/apps/pdcounter/locale/it/LC_MESSAGES/django.mo b/src/pdcounter/locale/it/LC_MESSAGES/django.mo similarity index 100% rename from apps/pdcounter/locale/it/LC_MESSAGES/django.mo rename to src/pdcounter/locale/it/LC_MESSAGES/django.mo diff --git a/apps/pdcounter/locale/it/LC_MESSAGES/django.po b/src/pdcounter/locale/it/LC_MESSAGES/django.po similarity index 100% rename from apps/pdcounter/locale/it/LC_MESSAGES/django.po rename to src/pdcounter/locale/it/LC_MESSAGES/django.po diff --git a/apps/pdcounter/locale/jp/LC_MESSAGES/django.mo b/src/pdcounter/locale/jp/LC_MESSAGES/django.mo similarity index 100% rename from apps/pdcounter/locale/jp/LC_MESSAGES/django.mo rename to src/pdcounter/locale/jp/LC_MESSAGES/django.mo diff --git a/apps/pdcounter/locale/jp/LC_MESSAGES/django.po b/src/pdcounter/locale/jp/LC_MESSAGES/django.po similarity index 100% rename from apps/pdcounter/locale/jp/LC_MESSAGES/django.po rename to src/pdcounter/locale/jp/LC_MESSAGES/django.po diff --git a/apps/pdcounter/locale/lt/LC_MESSAGES/django.mo b/src/pdcounter/locale/lt/LC_MESSAGES/django.mo similarity index 100% rename from apps/pdcounter/locale/lt/LC_MESSAGES/django.mo rename to src/pdcounter/locale/lt/LC_MESSAGES/django.mo diff --git a/apps/pdcounter/locale/lt/LC_MESSAGES/django.po b/src/pdcounter/locale/lt/LC_MESSAGES/django.po similarity index 100% rename from apps/pdcounter/locale/lt/LC_MESSAGES/django.po rename to src/pdcounter/locale/lt/LC_MESSAGES/django.po diff --git a/apps/pdcounter/locale/pl/LC_MESSAGES/django.mo b/src/pdcounter/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/pdcounter/locale/pl/LC_MESSAGES/django.mo rename to src/pdcounter/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/pdcounter/locale/pl/LC_MESSAGES/django.po b/src/pdcounter/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/pdcounter/locale/pl/LC_MESSAGES/django.po rename to src/pdcounter/locale/pl/LC_MESSAGES/django.po diff --git a/apps/pdcounter/locale/ru/LC_MESSAGES/django.mo b/src/pdcounter/locale/ru/LC_MESSAGES/django.mo similarity index 100% rename from apps/pdcounter/locale/ru/LC_MESSAGES/django.mo rename to src/pdcounter/locale/ru/LC_MESSAGES/django.mo diff --git a/apps/pdcounter/locale/ru/LC_MESSAGES/django.po b/src/pdcounter/locale/ru/LC_MESSAGES/django.po similarity index 100% rename from apps/pdcounter/locale/ru/LC_MESSAGES/django.po rename to src/pdcounter/locale/ru/LC_MESSAGES/django.po diff --git a/apps/pdcounter/locale/uk/LC_MESSAGES/django.mo b/src/pdcounter/locale/uk/LC_MESSAGES/django.mo similarity index 100% rename from apps/pdcounter/locale/uk/LC_MESSAGES/django.mo rename to src/pdcounter/locale/uk/LC_MESSAGES/django.mo diff --git a/apps/pdcounter/locale/uk/LC_MESSAGES/django.po b/src/pdcounter/locale/uk/LC_MESSAGES/django.po similarity index 100% rename from apps/pdcounter/locale/uk/LC_MESSAGES/django.po rename to src/pdcounter/locale/uk/LC_MESSAGES/django.po diff --git a/apps/pdcounter/migrations/0001_initial.py b/src/pdcounter/migrations/0001_initial.py similarity index 100% rename from apps/pdcounter/migrations/0001_initial.py rename to src/pdcounter/migrations/0001_initial.py diff --git a/apps/pdcounter/migrations/0002_auto_20151221_1225.py b/src/pdcounter/migrations/0002_auto_20151221_1225.py similarity index 100% rename from apps/pdcounter/migrations/0002_auto_20151221_1225.py rename to src/pdcounter/migrations/0002_auto_20151221_1225.py diff --git a/apps/pdcounter/migrations/__init__.py b/src/pdcounter/migrations/__init__.py similarity index 100% rename from apps/pdcounter/migrations/__init__.py rename to src/pdcounter/migrations/__init__.py diff --git a/apps/pdcounter/models.py b/src/pdcounter/models.py similarity index 100% rename from apps/pdcounter/models.py rename to src/pdcounter/models.py diff --git a/apps/pdcounter/static/pdcounter/pdcounter.js b/src/pdcounter/static/pdcounter/pdcounter.js similarity index 100% rename from apps/pdcounter/static/pdcounter/pdcounter.js rename to src/pdcounter/static/pdcounter/pdcounter.js diff --git a/apps/pdcounter/templates/pdcounter/author_detail.html b/src/pdcounter/templates/pdcounter/author_detail.html similarity index 100% rename from apps/pdcounter/templates/pdcounter/author_detail.html rename to src/pdcounter/templates/pdcounter/author_detail.html diff --git a/apps/pdcounter/templates/pdcounter/book_stub_detail.html b/src/pdcounter/templates/pdcounter/book_stub_detail.html similarity index 100% rename from apps/pdcounter/templates/pdcounter/book_stub_detail.html rename to src/pdcounter/templates/pdcounter/book_stub_detail.html diff --git a/apps/pdcounter/templatetags/__init__.py b/src/pdcounter/templatetags/__init__.py similarity index 100% rename from apps/pdcounter/templatetags/__init__.py rename to src/pdcounter/templatetags/__init__.py diff --git a/apps/pdcounter/templatetags/time_tags.py b/src/pdcounter/templatetags/time_tags.py similarity index 100% rename from apps/pdcounter/templatetags/time_tags.py rename to src/pdcounter/templatetags/time_tags.py diff --git a/apps/pdcounter/views.py b/src/pdcounter/views.py similarity index 100% rename from apps/pdcounter/views.py rename to src/pdcounter/views.py diff --git a/apps/picture/__init__.py b/src/picture/__init__.py similarity index 100% rename from apps/picture/__init__.py rename to src/picture/__init__.py diff --git a/apps/picture/admin.py b/src/picture/admin.py similarity index 100% rename from apps/picture/admin.py rename to src/picture/admin.py diff --git a/apps/picture/engine.py b/src/picture/engine.py similarity index 100% rename from apps/picture/engine.py rename to src/picture/engine.py diff --git a/apps/picture/forms.py b/src/picture/forms.py similarity index 100% rename from apps/picture/forms.py rename to src/picture/forms.py diff --git a/apps/picture/locale/de/LC_MESSAGES/django.mo b/src/picture/locale/de/LC_MESSAGES/django.mo similarity index 100% rename from apps/picture/locale/de/LC_MESSAGES/django.mo rename to src/picture/locale/de/LC_MESSAGES/django.mo diff --git a/apps/picture/locale/de/LC_MESSAGES/django.po b/src/picture/locale/de/LC_MESSAGES/django.po similarity index 100% rename from apps/picture/locale/de/LC_MESSAGES/django.po rename to src/picture/locale/de/LC_MESSAGES/django.po diff --git a/apps/picture/locale/en/LC_MESSAGES/django.mo b/src/picture/locale/en/LC_MESSAGES/django.mo similarity index 100% rename from apps/picture/locale/en/LC_MESSAGES/django.mo rename to src/picture/locale/en/LC_MESSAGES/django.mo diff --git a/apps/picture/locale/en/LC_MESSAGES/django.po b/src/picture/locale/en/LC_MESSAGES/django.po similarity index 100% rename from apps/picture/locale/en/LC_MESSAGES/django.po rename to src/picture/locale/en/LC_MESSAGES/django.po diff --git a/apps/picture/locale/es/LC_MESSAGES/django.mo b/src/picture/locale/es/LC_MESSAGES/django.mo similarity index 100% rename from apps/picture/locale/es/LC_MESSAGES/django.mo rename to src/picture/locale/es/LC_MESSAGES/django.mo diff --git a/apps/picture/locale/es/LC_MESSAGES/django.po b/src/picture/locale/es/LC_MESSAGES/django.po similarity index 100% rename from apps/picture/locale/es/LC_MESSAGES/django.po rename to src/picture/locale/es/LC_MESSAGES/django.po diff --git a/apps/picture/locale/fr/LC_MESSAGES/django.mo b/src/picture/locale/fr/LC_MESSAGES/django.mo similarity index 100% rename from apps/picture/locale/fr/LC_MESSAGES/django.mo rename to src/picture/locale/fr/LC_MESSAGES/django.mo diff --git a/apps/picture/locale/fr/LC_MESSAGES/django.po b/src/picture/locale/fr/LC_MESSAGES/django.po similarity index 100% rename from apps/picture/locale/fr/LC_MESSAGES/django.po rename to src/picture/locale/fr/LC_MESSAGES/django.po diff --git a/apps/picture/locale/it/LC_MESSAGES/django.mo b/src/picture/locale/it/LC_MESSAGES/django.mo similarity index 100% rename from apps/picture/locale/it/LC_MESSAGES/django.mo rename to src/picture/locale/it/LC_MESSAGES/django.mo diff --git a/apps/picture/locale/it/LC_MESSAGES/django.po b/src/picture/locale/it/LC_MESSAGES/django.po similarity index 100% rename from apps/picture/locale/it/LC_MESSAGES/django.po rename to src/picture/locale/it/LC_MESSAGES/django.po diff --git a/apps/picture/locale/jp/LC_MESSAGES/django.mo b/src/picture/locale/jp/LC_MESSAGES/django.mo similarity index 100% rename from apps/picture/locale/jp/LC_MESSAGES/django.mo rename to src/picture/locale/jp/LC_MESSAGES/django.mo diff --git a/apps/picture/locale/jp/LC_MESSAGES/django.po b/src/picture/locale/jp/LC_MESSAGES/django.po similarity index 100% rename from apps/picture/locale/jp/LC_MESSAGES/django.po rename to src/picture/locale/jp/LC_MESSAGES/django.po diff --git a/apps/picture/locale/lt/LC_MESSAGES/django.mo b/src/picture/locale/lt/LC_MESSAGES/django.mo similarity index 100% rename from apps/picture/locale/lt/LC_MESSAGES/django.mo rename to src/picture/locale/lt/LC_MESSAGES/django.mo diff --git a/apps/picture/locale/lt/LC_MESSAGES/django.po b/src/picture/locale/lt/LC_MESSAGES/django.po similarity index 100% rename from apps/picture/locale/lt/LC_MESSAGES/django.po rename to src/picture/locale/lt/LC_MESSAGES/django.po diff --git a/apps/picture/locale/pl/LC_MESSAGES/django.mo b/src/picture/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/picture/locale/pl/LC_MESSAGES/django.mo rename to src/picture/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/picture/locale/pl/LC_MESSAGES/django.po b/src/picture/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/picture/locale/pl/LC_MESSAGES/django.po rename to src/picture/locale/pl/LC_MESSAGES/django.po diff --git a/apps/picture/locale/ru/LC_MESSAGES/django.mo b/src/picture/locale/ru/LC_MESSAGES/django.mo similarity index 100% rename from apps/picture/locale/ru/LC_MESSAGES/django.mo rename to src/picture/locale/ru/LC_MESSAGES/django.mo diff --git a/apps/picture/locale/ru/LC_MESSAGES/django.po b/src/picture/locale/ru/LC_MESSAGES/django.po similarity index 100% rename from apps/picture/locale/ru/LC_MESSAGES/django.po rename to src/picture/locale/ru/LC_MESSAGES/django.po diff --git a/apps/picture/locale/uk/LC_MESSAGES/django.mo b/src/picture/locale/uk/LC_MESSAGES/django.mo similarity index 100% rename from apps/picture/locale/uk/LC_MESSAGES/django.mo rename to src/picture/locale/uk/LC_MESSAGES/django.mo diff --git a/apps/picture/locale/uk/LC_MESSAGES/django.po b/src/picture/locale/uk/LC_MESSAGES/django.po similarity index 100% rename from apps/picture/locale/uk/LC_MESSAGES/django.po rename to src/picture/locale/uk/LC_MESSAGES/django.po diff --git a/apps/picture/migrations/0001_initial.py b/src/picture/migrations/0001_initial.py similarity index 100% rename from apps/picture/migrations/0001_initial.py rename to src/picture/migrations/0001_initial.py diff --git a/apps/picture/migrations/0002_remove_picture__related_info.py b/src/picture/migrations/0002_remove_picture__related_info.py similarity index 100% rename from apps/picture/migrations/0002_remove_picture__related_info.py rename to src/picture/migrations/0002_remove_picture__related_info.py diff --git a/apps/picture/migrations/0003_auto_20140924_1559.py b/src/picture/migrations/0003_auto_20140924_1559.py similarity index 100% rename from apps/picture/migrations/0003_auto_20140924_1559.py rename to src/picture/migrations/0003_auto_20140924_1559.py diff --git a/apps/picture/migrations/0004_auto_20141016_1337.py b/src/picture/migrations/0004_auto_20141016_1337.py similarity index 100% rename from apps/picture/migrations/0004_auto_20141016_1337.py rename to src/picture/migrations/0004_auto_20141016_1337.py diff --git a/apps/picture/migrations/0005_auto_20141022_1001.py b/src/picture/migrations/0005_auto_20141022_1001.py similarity index 100% rename from apps/picture/migrations/0005_auto_20141022_1001.py rename to src/picture/migrations/0005_auto_20141022_1001.py diff --git a/apps/picture/migrations/0006_auto_20151221_1225.py b/src/picture/migrations/0006_auto_20151221_1225.py similarity index 100% rename from apps/picture/migrations/0006_auto_20151221_1225.py rename to src/picture/migrations/0006_auto_20151221_1225.py diff --git a/apps/picture/migrations/__init__.py b/src/picture/migrations/__init__.py similarity index 100% rename from apps/picture/migrations/__init__.py rename to src/picture/migrations/__init__.py diff --git a/apps/picture/models.py b/src/picture/models.py similarity index 100% rename from apps/picture/models.py rename to src/picture/models.py diff --git a/apps/picture/tasks.py b/src/picture/tasks.py similarity index 100% rename from apps/picture/tasks.py rename to src/picture/tasks.py diff --git a/apps/picture/templates/admin/picture/picture/change_list.html b/src/picture/templates/admin/picture/picture/change_list.html similarity index 100% rename from apps/picture/templates/admin/picture/picture/change_list.html rename to src/picture/templates/admin/picture/picture/change_list.html diff --git a/apps/picture/templates/picture/collection.html b/src/picture/templates/picture/collection.html similarity index 100% rename from apps/picture/templates/picture/collection.html rename to src/picture/templates/picture/collection.html diff --git a/apps/picture/templates/picture/picture_detail.html b/src/picture/templates/picture/picture_detail.html similarity index 100% rename from apps/picture/templates/picture/picture_detail.html rename to src/picture/templates/picture/picture_detail.html diff --git a/apps/picture/templates/picture/picture_info.html b/src/picture/templates/picture/picture_info.html similarity index 100% rename from apps/picture/templates/picture/picture_info.html rename to src/picture/templates/picture/picture_info.html diff --git a/apps/picture/templates/picture/picture_list_thumb.html b/src/picture/templates/picture/picture_list_thumb.html similarity index 100% rename from apps/picture/templates/picture/picture_list_thumb.html rename to src/picture/templates/picture/picture_list_thumb.html diff --git a/apps/picture/templates/picture/picture_mini_box.html b/src/picture/templates/picture/picture_mini_box.html similarity index 100% rename from apps/picture/templates/picture/picture_mini_box.html rename to src/picture/templates/picture/picture_mini_box.html diff --git a/apps/picture/templates/picture/picture_short.html b/src/picture/templates/picture/picture_short.html similarity index 100% rename from apps/picture/templates/picture/picture_short.html rename to src/picture/templates/picture/picture_short.html diff --git a/apps/picture/templates/picture/picture_viewer.html b/src/picture/templates/picture/picture_viewer.html similarity index 100% rename from apps/picture/templates/picture/picture_viewer.html rename to src/picture/templates/picture/picture_viewer.html diff --git a/apps/picture/templates/picture/picture_wide.html b/src/picture/templates/picture/picture_wide.html similarity index 100% rename from apps/picture/templates/picture/picture_wide.html rename to src/picture/templates/picture/picture_wide.html diff --git a/apps/picture/templates/picture/picturearea_short.html b/src/picture/templates/picture/picturearea_short.html similarity index 100% rename from apps/picture/templates/picture/picturearea_short.html rename to src/picture/templates/picture/picturearea_short.html diff --git a/apps/picture/templatetags/__init__.py b/src/picture/templatetags/__init__.py similarity index 100% rename from apps/picture/templatetags/__init__.py rename to src/picture/templatetags/__init__.py diff --git a/apps/picture/templatetags/picture_tags.py b/src/picture/templatetags/picture_tags.py similarity index 100% rename from apps/picture/templatetags/picture_tags.py rename to src/picture/templatetags/picture_tags.py diff --git a/apps/picture/tests/__init__.py b/src/picture/tests/__init__.py similarity index 100% rename from apps/picture/tests/__init__.py rename to src/picture/tests/__init__.py diff --git a/apps/picture/tests/files/kandinsky-composition-viii.png b/src/picture/tests/files/kandinsky-composition-viii.png similarity index 100% rename from apps/picture/tests/files/kandinsky-composition-viii.png rename to src/picture/tests/files/kandinsky-composition-viii.png diff --git a/apps/picture/tests/files/kandinsky-composition-viii.xml b/src/picture/tests/files/kandinsky-composition-viii.xml similarity index 100% rename from apps/picture/tests/files/kandinsky-composition-viii.xml rename to src/picture/tests/files/kandinsky-composition-viii.xml diff --git a/apps/picture/tests/picture_import.py b/src/picture/tests/picture_import.py similarity index 100% rename from apps/picture/tests/picture_import.py rename to src/picture/tests/picture_import.py diff --git a/apps/picture/views.py b/src/picture/views.py similarity index 100% rename from apps/picture/views.py rename to src/picture/views.py diff --git a/apps/polls/__init__.py b/src/polls/__init__.py similarity index 100% rename from apps/polls/__init__.py rename to src/polls/__init__.py diff --git a/apps/polls/admin.py b/src/polls/admin.py similarity index 100% rename from apps/polls/admin.py rename to src/polls/admin.py diff --git a/apps/polls/forms.py b/src/polls/forms.py similarity index 100% rename from apps/polls/forms.py rename to src/polls/forms.py diff --git a/apps/polls/locale/pl/LC_MESSAGES/django.mo b/src/polls/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/polls/locale/pl/LC_MESSAGES/django.mo rename to src/polls/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/polls/locale/pl/LC_MESSAGES/django.po b/src/polls/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/polls/locale/pl/LC_MESSAGES/django.po rename to src/polls/locale/pl/LC_MESSAGES/django.po diff --git a/apps/polls/migrations/0001_initial.py b/src/polls/migrations/0001_initial.py similarity index 100% rename from apps/polls/migrations/0001_initial.py rename to src/polls/migrations/0001_initial.py diff --git a/apps/polls/migrations/0002_auto_20151221_1225.py b/src/polls/migrations/0002_auto_20151221_1225.py similarity index 100% rename from apps/polls/migrations/0002_auto_20151221_1225.py rename to src/polls/migrations/0002_auto_20151221_1225.py diff --git a/apps/polls/migrations/__init__.py b/src/polls/migrations/__init__.py similarity index 100% rename from apps/polls/migrations/__init__.py rename to src/polls/migrations/__init__.py diff --git a/apps/polls/models.py b/src/polls/models.py similarity index 100% rename from apps/polls/models.py rename to src/polls/models.py diff --git a/apps/polls/templates/polls/poll.html b/src/polls/templates/polls/poll.html similarity index 100% rename from apps/polls/templates/polls/poll.html rename to src/polls/templates/polls/poll.html diff --git a/apps/polls/templates/polls/tags/poll.html b/src/polls/templates/polls/tags/poll.html similarity index 100% rename from apps/polls/templates/polls/tags/poll.html rename to src/polls/templates/polls/tags/poll.html diff --git a/apps/polls/templatetags/__init__.py b/src/polls/templatetags/__init__.py similarity index 100% rename from apps/polls/templatetags/__init__.py rename to src/polls/templatetags/__init__.py diff --git a/apps/polls/templatetags/polls_tags.py b/src/polls/templatetags/polls_tags.py similarity index 100% rename from apps/polls/templatetags/polls_tags.py rename to src/polls/templatetags/polls_tags.py diff --git a/apps/polls/urls.py b/src/polls/urls.py similarity index 100% rename from apps/polls/urls.py rename to src/polls/urls.py diff --git a/apps/polls/views.py b/src/polls/views.py similarity index 100% rename from apps/polls/views.py rename to src/polls/views.py diff --git a/apps/reporting/__init__.py b/src/reporting/__init__.py similarity index 100% rename from apps/reporting/__init__.py rename to src/reporting/__init__.py diff --git a/apps/reporting/locale/pl/LC_MESSAGES/django.mo b/src/reporting/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/reporting/locale/pl/LC_MESSAGES/django.mo rename to src/reporting/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/reporting/locale/pl/LC_MESSAGES/django.po b/src/reporting/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/reporting/locale/pl/LC_MESSAGES/django.po rename to src/reporting/locale/pl/LC_MESSAGES/django.po diff --git a/apps/reporting/models.py b/src/reporting/models.py similarity index 100% rename from apps/reporting/models.py rename to src/reporting/models.py diff --git a/apps/reporting/templates/reporting/catalogue.csv b/src/reporting/templates/reporting/catalogue.csv similarity index 100% rename from apps/reporting/templates/reporting/catalogue.csv rename to src/reporting/templates/reporting/catalogue.csv diff --git a/apps/reporting/templates/reporting/catalogue.texml b/src/reporting/templates/reporting/catalogue.texml similarity index 100% rename from apps/reporting/templates/reporting/catalogue.texml rename to src/reporting/templates/reporting/catalogue.texml diff --git a/apps/reporting/templates/reporting/main.html b/src/reporting/templates/reporting/main.html similarity index 100% rename from apps/reporting/templates/reporting/main.html rename to src/reporting/templates/reporting/main.html diff --git a/apps/reporting/templatetags/__init__.py b/src/reporting/templatetags/__init__.py similarity index 100% rename from apps/reporting/templatetags/__init__.py rename to src/reporting/templatetags/__init__.py diff --git a/apps/reporting/templatetags/reporting_stats.py b/src/reporting/templatetags/reporting_stats.py similarity index 100% rename from apps/reporting/templatetags/reporting_stats.py rename to src/reporting/templatetags/reporting_stats.py diff --git a/apps/reporting/urls.py b/src/reporting/urls.py similarity index 100% rename from apps/reporting/urls.py rename to src/reporting/urls.py diff --git a/apps/reporting/utils.py b/src/reporting/utils.py similarity index 100% rename from apps/reporting/utils.py rename to src/reporting/utils.py diff --git a/apps/reporting/views.py b/src/reporting/views.py similarity index 100% rename from apps/reporting/views.py rename to src/reporting/views.py diff --git a/apps/search/__init__.py b/src/search/__init__.py similarity index 100% rename from apps/search/__init__.py rename to src/search/__init__.py diff --git a/apps/search/context_processors.py b/src/search/context_processors.py similarity index 100% rename from apps/search/context_processors.py rename to src/search/context_processors.py diff --git a/apps/search/custom.py b/src/search/custom.py similarity index 100% rename from apps/search/custom.py rename to src/search/custom.py diff --git a/apps/search/fields.py b/src/search/fields.py similarity index 100% rename from apps/search/fields.py rename to src/search/fields.py diff --git a/apps/search/forms.py b/src/search/forms.py similarity index 100% rename from apps/search/forms.py rename to src/search/forms.py diff --git a/apps/search/index.py b/src/search/index.py similarity index 100% rename from apps/search/index.py rename to src/search/index.py diff --git a/apps/search/locale/de/LC_MESSAGES/django.mo b/src/search/locale/de/LC_MESSAGES/django.mo similarity index 100% rename from apps/search/locale/de/LC_MESSAGES/django.mo rename to src/search/locale/de/LC_MESSAGES/django.mo diff --git a/apps/search/locale/de/LC_MESSAGES/django.po b/src/search/locale/de/LC_MESSAGES/django.po similarity index 100% rename from apps/search/locale/de/LC_MESSAGES/django.po rename to src/search/locale/de/LC_MESSAGES/django.po diff --git a/apps/search/locale/en/LC_MESSAGES/django.mo b/src/search/locale/en/LC_MESSAGES/django.mo similarity index 100% rename from apps/search/locale/en/LC_MESSAGES/django.mo rename to src/search/locale/en/LC_MESSAGES/django.mo diff --git a/apps/search/locale/en/LC_MESSAGES/django.po b/src/search/locale/en/LC_MESSAGES/django.po similarity index 100% rename from apps/search/locale/en/LC_MESSAGES/django.po rename to src/search/locale/en/LC_MESSAGES/django.po diff --git a/apps/search/locale/es/LC_MESSAGES/django.mo b/src/search/locale/es/LC_MESSAGES/django.mo similarity index 100% rename from apps/search/locale/es/LC_MESSAGES/django.mo rename to src/search/locale/es/LC_MESSAGES/django.mo diff --git a/apps/search/locale/es/LC_MESSAGES/django.po b/src/search/locale/es/LC_MESSAGES/django.po similarity index 100% rename from apps/search/locale/es/LC_MESSAGES/django.po rename to src/search/locale/es/LC_MESSAGES/django.po diff --git a/apps/search/locale/fr/LC_MESSAGES/django.mo b/src/search/locale/fr/LC_MESSAGES/django.mo similarity index 100% rename from apps/search/locale/fr/LC_MESSAGES/django.mo rename to src/search/locale/fr/LC_MESSAGES/django.mo diff --git a/apps/search/locale/fr/LC_MESSAGES/django.po b/src/search/locale/fr/LC_MESSAGES/django.po similarity index 100% rename from apps/search/locale/fr/LC_MESSAGES/django.po rename to src/search/locale/fr/LC_MESSAGES/django.po diff --git a/apps/search/locale/it/LC_MESSAGES/django.mo b/src/search/locale/it/LC_MESSAGES/django.mo similarity index 100% rename from apps/search/locale/it/LC_MESSAGES/django.mo rename to src/search/locale/it/LC_MESSAGES/django.mo diff --git a/apps/search/locale/it/LC_MESSAGES/django.po b/src/search/locale/it/LC_MESSAGES/django.po similarity index 100% rename from apps/search/locale/it/LC_MESSAGES/django.po rename to src/search/locale/it/LC_MESSAGES/django.po diff --git a/apps/search/locale/jp/LC_MESSAGES/django.mo b/src/search/locale/jp/LC_MESSAGES/django.mo similarity index 100% rename from apps/search/locale/jp/LC_MESSAGES/django.mo rename to src/search/locale/jp/LC_MESSAGES/django.mo diff --git a/apps/search/locale/jp/LC_MESSAGES/django.po b/src/search/locale/jp/LC_MESSAGES/django.po similarity index 100% rename from apps/search/locale/jp/LC_MESSAGES/django.po rename to src/search/locale/jp/LC_MESSAGES/django.po diff --git a/apps/search/locale/lt/LC_MESSAGES/django.mo b/src/search/locale/lt/LC_MESSAGES/django.mo similarity index 100% rename from apps/search/locale/lt/LC_MESSAGES/django.mo rename to src/search/locale/lt/LC_MESSAGES/django.mo diff --git a/apps/search/locale/lt/LC_MESSAGES/django.po b/src/search/locale/lt/LC_MESSAGES/django.po similarity index 100% rename from apps/search/locale/lt/LC_MESSAGES/django.po rename to src/search/locale/lt/LC_MESSAGES/django.po diff --git a/apps/search/locale/pl/LC_MESSAGES/django.mo b/src/search/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/search/locale/pl/LC_MESSAGES/django.mo rename to src/search/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/search/locale/pl/LC_MESSAGES/django.po b/src/search/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/search/locale/pl/LC_MESSAGES/django.po rename to src/search/locale/pl/LC_MESSAGES/django.po diff --git a/apps/search/locale/ru/LC_MESSAGES/django.mo b/src/search/locale/ru/LC_MESSAGES/django.mo similarity index 100% rename from apps/search/locale/ru/LC_MESSAGES/django.mo rename to src/search/locale/ru/LC_MESSAGES/django.mo diff --git a/apps/search/locale/ru/LC_MESSAGES/django.po b/src/search/locale/ru/LC_MESSAGES/django.po similarity index 100% rename from apps/search/locale/ru/LC_MESSAGES/django.po rename to src/search/locale/ru/LC_MESSAGES/django.po diff --git a/apps/search/locale/uk/LC_MESSAGES/django.mo b/src/search/locale/uk/LC_MESSAGES/django.mo similarity index 100% rename from apps/search/locale/uk/LC_MESSAGES/django.mo rename to src/search/locale/uk/LC_MESSAGES/django.mo diff --git a/apps/search/locale/uk/LC_MESSAGES/django.po b/src/search/locale/uk/LC_MESSAGES/django.po similarity index 100% rename from apps/search/locale/uk/LC_MESSAGES/django.po rename to src/search/locale/uk/LC_MESSAGES/django.po diff --git a/apps/search/management/__init__.py b/src/search/management/__init__.py similarity index 100% rename from apps/search/management/__init__.py rename to src/search/management/__init__.py diff --git a/apps/search/management/commands/__init__.py b/src/search/management/commands/__init__.py similarity index 100% rename from apps/search/management/commands/__init__.py rename to src/search/management/commands/__init__.py diff --git a/apps/search/management/commands/reindex.py b/src/search/management/commands/reindex.py similarity index 100% rename from apps/search/management/commands/reindex.py rename to src/search/management/commands/reindex.py diff --git a/apps/search/management/commands/snippets.py b/src/search/management/commands/snippets.py similarity index 100% rename from apps/search/management/commands/snippets.py rename to src/search/management/commands/snippets.py diff --git a/apps/search/mock_search.py b/src/search/mock_search.py similarity index 100% rename from apps/search/mock_search.py rename to src/search/mock_search.py diff --git a/apps/search/templates/newsearch/search.html b/src/search/templates/newsearch/search.html similarity index 100% rename from apps/search/templates/newsearch/search.html rename to src/search/templates/newsearch/search.html diff --git a/apps/search/templatetags/__init__.py b/src/search/templatetags/__init__.py similarity index 100% rename from apps/search/templatetags/__init__.py rename to src/search/templatetags/__init__.py diff --git a/apps/search/templatetags/search_tags.py b/src/search/templatetags/search_tags.py similarity index 100% rename from apps/search/templatetags/search_tags.py rename to src/search/templatetags/search_tags.py diff --git a/apps/search/tests/__init__.py b/src/search/tests/__init__.py similarity index 100% rename from apps/search/tests/__init__.py rename to src/search/tests/__init__.py diff --git a/apps/search/tests/index.py b/src/search/tests/index.py similarity index 100% rename from apps/search/tests/index.py rename to src/search/tests/index.py diff --git a/apps/search/urls.py b/src/search/urls.py similarity index 100% rename from apps/search/urls.py rename to src/search/urls.py diff --git a/apps/search/views.py b/src/search/views.py similarity index 100% rename from apps/search/views.py rename to src/search/views.py diff --git a/apps/social/__init__.py b/src/social/__init__.py similarity index 100% rename from apps/social/__init__.py rename to src/social/__init__.py diff --git a/apps/social/admin.py b/src/social/admin.py similarity index 100% rename from apps/social/admin.py rename to src/social/admin.py diff --git a/apps/social/forms.py b/src/social/forms.py similarity index 100% rename from apps/social/forms.py rename to src/social/forms.py diff --git a/apps/social/locale/pl/LC_MESSAGES/django.mo b/src/social/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/social/locale/pl/LC_MESSAGES/django.mo rename to src/social/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/social/locale/pl/LC_MESSAGES/django.po b/src/social/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/social/locale/pl/LC_MESSAGES/django.po rename to src/social/locale/pl/LC_MESSAGES/django.po diff --git a/apps/social/migrations/0001_initial.py b/src/social/migrations/0001_initial.py similarity index 100% rename from apps/social/migrations/0001_initial.py rename to src/social/migrations/0001_initial.py diff --git a/apps/social/migrations/0002_auto_20151221_1225.py b/src/social/migrations/0002_auto_20151221_1225.py similarity index 100% rename from apps/social/migrations/0002_auto_20151221_1225.py rename to src/social/migrations/0002_auto_20151221_1225.py diff --git a/apps/social/migrations/__init__.py b/src/social/migrations/__init__.py similarity index 100% rename from apps/social/migrations/__init__.py rename to src/social/migrations/__init__.py diff --git a/apps/social/models.py b/src/social/models.py similarity index 100% rename from apps/social/models.py rename to src/social/models.py diff --git a/apps/social/templates/social/cite_info.html b/src/social/templates/social/cite_info.html similarity index 100% rename from apps/social/templates/social/cite_info.html rename to src/social/templates/social/cite_info.html diff --git a/apps/social/templates/social/cite_promo.html b/src/social/templates/social/cite_promo.html similarity index 100% rename from apps/social/templates/social/cite_promo.html rename to src/social/templates/social/cite_promo.html diff --git a/apps/social/templates/social/my_shelf.html b/src/social/templates/social/my_shelf.html similarity index 100% rename from apps/social/templates/social/my_shelf.html rename to src/social/templates/social/my_shelf.html diff --git a/apps/social/templates/social/sets_form.html b/src/social/templates/social/sets_form.html similarity index 100% rename from apps/social/templates/social/sets_form.html rename to src/social/templates/social/sets_form.html diff --git a/apps/social/templates/social/shelf_tags.html b/src/social/templates/social/shelf_tags.html similarity index 100% rename from apps/social/templates/social/shelf_tags.html rename to src/social/templates/social/shelf_tags.html diff --git a/apps/social/templatetags/__init__.py b/src/social/templatetags/__init__.py similarity index 100% rename from apps/social/templatetags/__init__.py rename to src/social/templatetags/__init__.py diff --git a/apps/social/templatetags/social_tags.py b/src/social/templatetags/social_tags.py similarity index 100% rename from apps/social/templatetags/social_tags.py rename to src/social/templatetags/social_tags.py diff --git a/apps/social/urls.py b/src/social/urls.py similarity index 100% rename from apps/social/urls.py rename to src/social/urls.py diff --git a/apps/social/utils.py b/src/social/utils.py similarity index 100% rename from apps/social/utils.py rename to src/social/utils.py diff --git a/apps/social/views.py b/src/social/views.py similarity index 100% rename from apps/social/views.py rename to src/social/views.py diff --git a/lib/sortify.py b/src/sortify.py similarity index 100% rename from lib/sortify.py rename to src/sortify.py diff --git a/apps/sponsors/__init__.py b/src/sponsors/__init__.py similarity index 100% rename from apps/sponsors/__init__.py rename to src/sponsors/__init__.py diff --git a/apps/sponsors/admin.py b/src/sponsors/admin.py similarity index 100% rename from apps/sponsors/admin.py rename to src/sponsors/admin.py diff --git a/apps/sponsors/locale/de/LC_MESSAGES/django.mo b/src/sponsors/locale/de/LC_MESSAGES/django.mo similarity index 100% rename from apps/sponsors/locale/de/LC_MESSAGES/django.mo rename to src/sponsors/locale/de/LC_MESSAGES/django.mo diff --git a/apps/sponsors/locale/de/LC_MESSAGES/django.po b/src/sponsors/locale/de/LC_MESSAGES/django.po similarity index 100% rename from apps/sponsors/locale/de/LC_MESSAGES/django.po rename to src/sponsors/locale/de/LC_MESSAGES/django.po diff --git a/apps/sponsors/locale/en/LC_MESSAGES/django.mo b/src/sponsors/locale/en/LC_MESSAGES/django.mo similarity index 100% rename from apps/sponsors/locale/en/LC_MESSAGES/django.mo rename to src/sponsors/locale/en/LC_MESSAGES/django.mo diff --git a/apps/sponsors/locale/en/LC_MESSAGES/django.po b/src/sponsors/locale/en/LC_MESSAGES/django.po similarity index 100% rename from apps/sponsors/locale/en/LC_MESSAGES/django.po rename to src/sponsors/locale/en/LC_MESSAGES/django.po diff --git a/apps/sponsors/locale/es/LC_MESSAGES/django.mo b/src/sponsors/locale/es/LC_MESSAGES/django.mo similarity index 100% rename from apps/sponsors/locale/es/LC_MESSAGES/django.mo rename to src/sponsors/locale/es/LC_MESSAGES/django.mo diff --git a/apps/sponsors/locale/es/LC_MESSAGES/django.po b/src/sponsors/locale/es/LC_MESSAGES/django.po similarity index 100% rename from apps/sponsors/locale/es/LC_MESSAGES/django.po rename to src/sponsors/locale/es/LC_MESSAGES/django.po diff --git a/apps/sponsors/locale/fr/LC_MESSAGES/django.mo b/src/sponsors/locale/fr/LC_MESSAGES/django.mo similarity index 100% rename from apps/sponsors/locale/fr/LC_MESSAGES/django.mo rename to src/sponsors/locale/fr/LC_MESSAGES/django.mo diff --git a/apps/sponsors/locale/fr/LC_MESSAGES/django.po b/src/sponsors/locale/fr/LC_MESSAGES/django.po similarity index 100% rename from apps/sponsors/locale/fr/LC_MESSAGES/django.po rename to src/sponsors/locale/fr/LC_MESSAGES/django.po diff --git a/apps/sponsors/locale/it/LC_MESSAGES/django.mo b/src/sponsors/locale/it/LC_MESSAGES/django.mo similarity index 100% rename from apps/sponsors/locale/it/LC_MESSAGES/django.mo rename to src/sponsors/locale/it/LC_MESSAGES/django.mo diff --git a/apps/sponsors/locale/it/LC_MESSAGES/django.po b/src/sponsors/locale/it/LC_MESSAGES/django.po similarity index 100% rename from apps/sponsors/locale/it/LC_MESSAGES/django.po rename to src/sponsors/locale/it/LC_MESSAGES/django.po diff --git a/apps/sponsors/locale/jp/LC_MESSAGES/django.mo b/src/sponsors/locale/jp/LC_MESSAGES/django.mo similarity index 100% rename from apps/sponsors/locale/jp/LC_MESSAGES/django.mo rename to src/sponsors/locale/jp/LC_MESSAGES/django.mo diff --git a/apps/sponsors/locale/jp/LC_MESSAGES/django.po b/src/sponsors/locale/jp/LC_MESSAGES/django.po similarity index 100% rename from apps/sponsors/locale/jp/LC_MESSAGES/django.po rename to src/sponsors/locale/jp/LC_MESSAGES/django.po diff --git a/apps/sponsors/locale/lt/LC_MESSAGES/django.mo b/src/sponsors/locale/lt/LC_MESSAGES/django.mo similarity index 100% rename from apps/sponsors/locale/lt/LC_MESSAGES/django.mo rename to src/sponsors/locale/lt/LC_MESSAGES/django.mo diff --git a/apps/sponsors/locale/lt/LC_MESSAGES/django.po b/src/sponsors/locale/lt/LC_MESSAGES/django.po similarity index 100% rename from apps/sponsors/locale/lt/LC_MESSAGES/django.po rename to src/sponsors/locale/lt/LC_MESSAGES/django.po diff --git a/apps/sponsors/locale/pl/LC_MESSAGES/django.mo b/src/sponsors/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/sponsors/locale/pl/LC_MESSAGES/django.mo rename to src/sponsors/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/sponsors/locale/pl/LC_MESSAGES/django.po b/src/sponsors/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/sponsors/locale/pl/LC_MESSAGES/django.po rename to src/sponsors/locale/pl/LC_MESSAGES/django.po diff --git a/apps/sponsors/locale/ru/LC_MESSAGES/django.mo b/src/sponsors/locale/ru/LC_MESSAGES/django.mo similarity index 100% rename from apps/sponsors/locale/ru/LC_MESSAGES/django.mo rename to src/sponsors/locale/ru/LC_MESSAGES/django.mo diff --git a/apps/sponsors/locale/ru/LC_MESSAGES/django.po b/src/sponsors/locale/ru/LC_MESSAGES/django.po similarity index 100% rename from apps/sponsors/locale/ru/LC_MESSAGES/django.po rename to src/sponsors/locale/ru/LC_MESSAGES/django.po diff --git a/apps/sponsors/locale/uk/LC_MESSAGES/django.mo b/src/sponsors/locale/uk/LC_MESSAGES/django.mo similarity index 100% rename from apps/sponsors/locale/uk/LC_MESSAGES/django.mo rename to src/sponsors/locale/uk/LC_MESSAGES/django.mo diff --git a/apps/sponsors/locale/uk/LC_MESSAGES/django.po b/src/sponsors/locale/uk/LC_MESSAGES/django.po similarity index 100% rename from apps/sponsors/locale/uk/LC_MESSAGES/django.po rename to src/sponsors/locale/uk/LC_MESSAGES/django.po diff --git a/apps/sponsors/migrations/0001_initial.py b/src/sponsors/migrations/0001_initial.py similarity index 100% rename from apps/sponsors/migrations/0001_initial.py rename to src/sponsors/migrations/0001_initial.py diff --git a/apps/sponsors/migrations/0002_auto_20151221_1225.py b/src/sponsors/migrations/0002_auto_20151221_1225.py similarity index 100% rename from apps/sponsors/migrations/0002_auto_20151221_1225.py rename to src/sponsors/migrations/0002_auto_20151221_1225.py diff --git a/apps/sponsors/migrations/__init__.py b/src/sponsors/migrations/__init__.py similarity index 100% rename from apps/sponsors/migrations/__init__.py rename to src/sponsors/migrations/__init__.py diff --git a/apps/sponsors/models.py b/src/sponsors/models.py similarity index 100% rename from apps/sponsors/models.py rename to src/sponsors/models.py diff --git a/apps/sponsors/static/sponsors/css/footer_admin.css b/src/sponsors/static/sponsors/css/footer_admin.css similarity index 100% rename from apps/sponsors/static/sponsors/css/footer_admin.css rename to src/sponsors/static/sponsors/css/footer_admin.css diff --git a/apps/sponsors/static/sponsors/css/sponsors.css b/src/sponsors/static/sponsors/css/sponsors.css similarity index 100% rename from apps/sponsors/static/sponsors/css/sponsors.css rename to src/sponsors/static/sponsors/css/sponsors.css diff --git a/apps/sponsors/static/sponsors/js/footer_admin.js b/src/sponsors/static/sponsors/js/footer_admin.js similarity index 100% rename from apps/sponsors/static/sponsors/js/footer_admin.js rename to src/sponsors/static/sponsors/js/footer_admin.js diff --git a/apps/sponsors/static/sponsors/js/jquery.json.min.js b/src/sponsors/static/sponsors/js/jquery.json.min.js similarity index 100% rename from apps/sponsors/static/sponsors/js/jquery.json.min.js rename to src/sponsors/static/sponsors/js/jquery.json.min.js diff --git a/apps/sponsors/static/sponsors/js/sponsors.js b/src/sponsors/static/sponsors/js/sponsors.js similarity index 100% rename from apps/sponsors/static/sponsors/js/sponsors.js rename to src/sponsors/static/sponsors/js/sponsors.js diff --git a/apps/sponsors/templates/sponsors/page.html b/src/sponsors/templates/sponsors/page.html similarity index 100% rename from apps/sponsors/templates/sponsors/page.html rename to src/sponsors/templates/sponsors/page.html diff --git a/apps/sponsors/urls.py b/src/sponsors/urls.py similarity index 100% rename from apps/sponsors/urls.py rename to src/sponsors/urls.py diff --git a/apps/sponsors/views.py b/src/sponsors/views.py similarity index 100% rename from apps/sponsors/views.py rename to src/sponsors/views.py diff --git a/apps/sponsors/widgets.py b/src/sponsors/widgets.py similarity index 100% rename from apps/sponsors/widgets.py rename to src/sponsors/widgets.py diff --git a/apps/stats/__init__.py b/src/stats/__init__.py similarity index 100% rename from apps/stats/__init__.py rename to src/stats/__init__.py diff --git a/apps/stats/models.py b/src/stats/models.py similarity index 100% rename from apps/stats/models.py rename to src/stats/models.py diff --git a/apps/stats/tasks.py b/src/stats/tasks.py similarity index 100% rename from apps/stats/tasks.py rename to src/stats/tasks.py diff --git a/apps/stats/utils.py b/src/stats/utils.py similarity index 100% rename from apps/stats/utils.py rename to src/stats/utils.py diff --git a/apps/suggest/__init__.py b/src/suggest/__init__.py similarity index 100% rename from apps/suggest/__init__.py rename to src/suggest/__init__.py diff --git a/apps/suggest/admin.py b/src/suggest/admin.py similarity index 100% rename from apps/suggest/admin.py rename to src/suggest/admin.py diff --git a/apps/suggest/forms.py b/src/suggest/forms.py similarity index 100% rename from apps/suggest/forms.py rename to src/suggest/forms.py diff --git a/apps/suggest/locale/de/LC_MESSAGES/django.mo b/src/suggest/locale/de/LC_MESSAGES/django.mo similarity index 100% rename from apps/suggest/locale/de/LC_MESSAGES/django.mo rename to src/suggest/locale/de/LC_MESSAGES/django.mo diff --git a/apps/suggest/locale/de/LC_MESSAGES/django.po b/src/suggest/locale/de/LC_MESSAGES/django.po similarity index 100% rename from apps/suggest/locale/de/LC_MESSAGES/django.po rename to src/suggest/locale/de/LC_MESSAGES/django.po diff --git a/apps/suggest/locale/en/LC_MESSAGES/django.mo b/src/suggest/locale/en/LC_MESSAGES/django.mo similarity index 100% rename from apps/suggest/locale/en/LC_MESSAGES/django.mo rename to src/suggest/locale/en/LC_MESSAGES/django.mo diff --git a/apps/suggest/locale/en/LC_MESSAGES/django.po b/src/suggest/locale/en/LC_MESSAGES/django.po similarity index 100% rename from apps/suggest/locale/en/LC_MESSAGES/django.po rename to src/suggest/locale/en/LC_MESSAGES/django.po diff --git a/apps/suggest/locale/es/LC_MESSAGES/django.mo b/src/suggest/locale/es/LC_MESSAGES/django.mo similarity index 100% rename from apps/suggest/locale/es/LC_MESSAGES/django.mo rename to src/suggest/locale/es/LC_MESSAGES/django.mo diff --git a/apps/suggest/locale/es/LC_MESSAGES/django.po b/src/suggest/locale/es/LC_MESSAGES/django.po similarity index 100% rename from apps/suggest/locale/es/LC_MESSAGES/django.po rename to src/suggest/locale/es/LC_MESSAGES/django.po diff --git a/apps/suggest/locale/fr/LC_MESSAGES/django.mo b/src/suggest/locale/fr/LC_MESSAGES/django.mo similarity index 100% rename from apps/suggest/locale/fr/LC_MESSAGES/django.mo rename to src/suggest/locale/fr/LC_MESSAGES/django.mo diff --git a/apps/suggest/locale/fr/LC_MESSAGES/django.po b/src/suggest/locale/fr/LC_MESSAGES/django.po similarity index 100% rename from apps/suggest/locale/fr/LC_MESSAGES/django.po rename to src/suggest/locale/fr/LC_MESSAGES/django.po diff --git a/apps/suggest/locale/it/LC_MESSAGES/django.mo b/src/suggest/locale/it/LC_MESSAGES/django.mo similarity index 100% rename from apps/suggest/locale/it/LC_MESSAGES/django.mo rename to src/suggest/locale/it/LC_MESSAGES/django.mo diff --git a/apps/suggest/locale/it/LC_MESSAGES/django.po b/src/suggest/locale/it/LC_MESSAGES/django.po similarity index 100% rename from apps/suggest/locale/it/LC_MESSAGES/django.po rename to src/suggest/locale/it/LC_MESSAGES/django.po diff --git a/apps/suggest/locale/jp/LC_MESSAGES/django.mo b/src/suggest/locale/jp/LC_MESSAGES/django.mo similarity index 100% rename from apps/suggest/locale/jp/LC_MESSAGES/django.mo rename to src/suggest/locale/jp/LC_MESSAGES/django.mo diff --git a/apps/suggest/locale/jp/LC_MESSAGES/django.po b/src/suggest/locale/jp/LC_MESSAGES/django.po similarity index 100% rename from apps/suggest/locale/jp/LC_MESSAGES/django.po rename to src/suggest/locale/jp/LC_MESSAGES/django.po diff --git a/apps/suggest/locale/lt/LC_MESSAGES/django.mo b/src/suggest/locale/lt/LC_MESSAGES/django.mo similarity index 100% rename from apps/suggest/locale/lt/LC_MESSAGES/django.mo rename to src/suggest/locale/lt/LC_MESSAGES/django.mo diff --git a/apps/suggest/locale/lt/LC_MESSAGES/django.po b/src/suggest/locale/lt/LC_MESSAGES/django.po similarity index 100% rename from apps/suggest/locale/lt/LC_MESSAGES/django.po rename to src/suggest/locale/lt/LC_MESSAGES/django.po diff --git a/apps/suggest/locale/pl/LC_MESSAGES/django.mo b/src/suggest/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/suggest/locale/pl/LC_MESSAGES/django.mo rename to src/suggest/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/suggest/locale/pl/LC_MESSAGES/django.po b/src/suggest/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/suggest/locale/pl/LC_MESSAGES/django.po rename to src/suggest/locale/pl/LC_MESSAGES/django.po diff --git a/apps/suggest/locale/ru/LC_MESSAGES/django.mo b/src/suggest/locale/ru/LC_MESSAGES/django.mo similarity index 100% rename from apps/suggest/locale/ru/LC_MESSAGES/django.mo rename to src/suggest/locale/ru/LC_MESSAGES/django.mo diff --git a/apps/suggest/locale/ru/LC_MESSAGES/django.po b/src/suggest/locale/ru/LC_MESSAGES/django.po similarity index 100% rename from apps/suggest/locale/ru/LC_MESSAGES/django.po rename to src/suggest/locale/ru/LC_MESSAGES/django.po diff --git a/apps/suggest/locale/uk/LC_MESSAGES/django.mo b/src/suggest/locale/uk/LC_MESSAGES/django.mo similarity index 100% rename from apps/suggest/locale/uk/LC_MESSAGES/django.mo rename to src/suggest/locale/uk/LC_MESSAGES/django.mo diff --git a/apps/suggest/locale/uk/LC_MESSAGES/django.po b/src/suggest/locale/uk/LC_MESSAGES/django.po similarity index 100% rename from apps/suggest/locale/uk/LC_MESSAGES/django.po rename to src/suggest/locale/uk/LC_MESSAGES/django.po diff --git a/apps/suggest/migrations/0001_initial.py b/src/suggest/migrations/0001_initial.py similarity index 100% rename from apps/suggest/migrations/0001_initial.py rename to src/suggest/migrations/0001_initial.py diff --git a/apps/suggest/migrations/0002_auto_20151221_1225.py b/src/suggest/migrations/0002_auto_20151221_1225.py similarity index 100% rename from apps/suggest/migrations/0002_auto_20151221_1225.py rename to src/suggest/migrations/0002_auto_20151221_1225.py diff --git a/apps/suggest/migrations/__init__.py b/src/suggest/migrations/__init__.py similarity index 100% rename from apps/suggest/migrations/__init__.py rename to src/suggest/migrations/__init__.py diff --git a/apps/suggest/models.py b/src/suggest/models.py similarity index 100% rename from apps/suggest/models.py rename to src/suggest/models.py diff --git a/apps/suggest/templates/publishing_suggest.html b/src/suggest/templates/publishing_suggest.html similarity index 100% rename from apps/suggest/templates/publishing_suggest.html rename to src/suggest/templates/publishing_suggest.html diff --git a/apps/suggest/urls.py b/src/suggest/urls.py similarity index 100% rename from apps/suggest/urls.py rename to src/suggest/urls.py diff --git a/apps/suggest/views.py b/src/suggest/views.py similarity index 100% rename from apps/suggest/views.py rename to src/suggest/views.py diff --git a/apps/waiter/__init__.py b/src/waiter/__init__.py similarity index 100% rename from apps/waiter/__init__.py rename to src/waiter/__init__.py diff --git a/apps/waiter/locale/pl/LC_MESSAGES/django.mo b/src/waiter/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/waiter/locale/pl/LC_MESSAGES/django.mo rename to src/waiter/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/waiter/locale/pl/LC_MESSAGES/django.po b/src/waiter/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/waiter/locale/pl/LC_MESSAGES/django.po rename to src/waiter/locale/pl/LC_MESSAGES/django.po diff --git a/apps/waiter/migrations/0001_initial.py b/src/waiter/migrations/0001_initial.py similarity index 100% rename from apps/waiter/migrations/0001_initial.py rename to src/waiter/migrations/0001_initial.py diff --git a/apps/waiter/migrations/__init__.py b/src/waiter/migrations/__init__.py similarity index 100% rename from apps/waiter/migrations/__init__.py rename to src/waiter/migrations/__init__.py diff --git a/apps/waiter/models.py b/src/waiter/models.py similarity index 100% rename from apps/waiter/models.py rename to src/waiter/models.py diff --git a/apps/waiter/settings.py b/src/waiter/settings.py similarity index 100% rename from apps/waiter/settings.py rename to src/waiter/settings.py diff --git a/apps/waiter/tasks.py b/src/waiter/tasks.py similarity index 100% rename from apps/waiter/tasks.py rename to src/waiter/tasks.py diff --git a/apps/waiter/templates/waiter/wait.html b/src/waiter/templates/waiter/wait.html similarity index 100% rename from apps/waiter/templates/waiter/wait.html rename to src/waiter/templates/waiter/wait.html diff --git a/apps/waiter/urls.py b/src/waiter/urls.py similarity index 100% rename from apps/waiter/urls.py rename to src/waiter/urls.py diff --git a/apps/waiter/utils.py b/src/waiter/utils.py similarity index 100% rename from apps/waiter/utils.py rename to src/waiter/utils.py diff --git a/apps/waiter/views.py b/src/waiter/views.py similarity index 100% rename from apps/waiter/views.py rename to src/waiter/views.py diff --git a/src/wolnelektury/__init__.py b/src/wolnelektury/__init__.py new file mode 100644 index 000000000..c6098f4e9 --- /dev/null +++ b/src/wolnelektury/__init__.py @@ -0,0 +1,7 @@ +# -*- 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 .celery import app as celery_app + +default_app_config = 'wolnelektury.apps.WLCoreConfig' diff --git a/apps/wolnelektury_core/apps.py b/src/wolnelektury/apps.py similarity index 90% rename from apps/wolnelektury_core/apps.py rename to src/wolnelektury/apps.py index 996ccaec6..a45bfe24f 100644 --- a/apps/wolnelektury_core/apps.py +++ b/src/wolnelektury/apps.py @@ -5,7 +5,7 @@ from django.apps import AppConfig class WLCoreConfig(AppConfig): - name = 'wolnelektury_core' + name = 'wolnelektury' def ready(self): from . import signals diff --git a/wolnelektury/celery.py b/src/wolnelektury/celery.py similarity index 100% rename from wolnelektury/celery.py rename to src/wolnelektury/celery.py diff --git a/apps/wolnelektury_core/context_processors.py b/src/wolnelektury/context_processors.py similarity index 100% rename from apps/wolnelektury_core/context_processors.py rename to src/wolnelektury/context_processors.py diff --git a/wolnelektury/locale-contrib/de/LC_MESSAGES/django.mo b/src/wolnelektury/locale-contrib/de/LC_MESSAGES/django.mo similarity index 100% rename from wolnelektury/locale-contrib/de/LC_MESSAGES/django.mo rename to src/wolnelektury/locale-contrib/de/LC_MESSAGES/django.mo diff --git a/wolnelektury/locale-contrib/de/LC_MESSAGES/django.po b/src/wolnelektury/locale-contrib/de/LC_MESSAGES/django.po similarity index 100% rename from wolnelektury/locale-contrib/de/LC_MESSAGES/django.po rename to src/wolnelektury/locale-contrib/de/LC_MESSAGES/django.po diff --git a/wolnelektury/locale-contrib/django.pot b/src/wolnelektury/locale-contrib/django.pot similarity index 100% rename from wolnelektury/locale-contrib/django.pot rename to src/wolnelektury/locale-contrib/django.pot diff --git a/wolnelektury/locale-contrib/en/LC_MESSAGES/django.mo b/src/wolnelektury/locale-contrib/en/LC_MESSAGES/django.mo similarity index 100% rename from wolnelektury/locale-contrib/en/LC_MESSAGES/django.mo rename to src/wolnelektury/locale-contrib/en/LC_MESSAGES/django.mo diff --git a/wolnelektury/locale-contrib/en/LC_MESSAGES/django.po b/src/wolnelektury/locale-contrib/en/LC_MESSAGES/django.po similarity index 100% rename from wolnelektury/locale-contrib/en/LC_MESSAGES/django.po rename to src/wolnelektury/locale-contrib/en/LC_MESSAGES/django.po diff --git a/wolnelektury/locale-contrib/es/LC_MESSAGES/django.mo b/src/wolnelektury/locale-contrib/es/LC_MESSAGES/django.mo similarity index 100% rename from wolnelektury/locale-contrib/es/LC_MESSAGES/django.mo rename to src/wolnelektury/locale-contrib/es/LC_MESSAGES/django.mo diff --git a/wolnelektury/locale-contrib/es/LC_MESSAGES/django.po b/src/wolnelektury/locale-contrib/es/LC_MESSAGES/django.po similarity index 100% rename from wolnelektury/locale-contrib/es/LC_MESSAGES/django.po rename to src/wolnelektury/locale-contrib/es/LC_MESSAGES/django.po diff --git a/wolnelektury/locale-contrib/fr/LC_MESSAGES/django.mo b/src/wolnelektury/locale-contrib/fr/LC_MESSAGES/django.mo similarity index 100% rename from wolnelektury/locale-contrib/fr/LC_MESSAGES/django.mo rename to src/wolnelektury/locale-contrib/fr/LC_MESSAGES/django.mo diff --git a/wolnelektury/locale-contrib/fr/LC_MESSAGES/django.po b/src/wolnelektury/locale-contrib/fr/LC_MESSAGES/django.po similarity index 100% rename from wolnelektury/locale-contrib/fr/LC_MESSAGES/django.po rename to src/wolnelektury/locale-contrib/fr/LC_MESSAGES/django.po diff --git a/wolnelektury/locale-contrib/it/LC_MESSAGES/django.mo b/src/wolnelektury/locale-contrib/it/LC_MESSAGES/django.mo similarity index 100% rename from wolnelektury/locale-contrib/it/LC_MESSAGES/django.mo rename to src/wolnelektury/locale-contrib/it/LC_MESSAGES/django.mo diff --git a/wolnelektury/locale-contrib/it/LC_MESSAGES/django.po b/src/wolnelektury/locale-contrib/it/LC_MESSAGES/django.po similarity index 100% rename from wolnelektury/locale-contrib/it/LC_MESSAGES/django.po rename to src/wolnelektury/locale-contrib/it/LC_MESSAGES/django.po diff --git a/wolnelektury/locale-contrib/lt/LC_MESSAGES/django.mo b/src/wolnelektury/locale-contrib/lt/LC_MESSAGES/django.mo similarity index 100% rename from wolnelektury/locale-contrib/lt/LC_MESSAGES/django.mo rename to src/wolnelektury/locale-contrib/lt/LC_MESSAGES/django.mo diff --git a/wolnelektury/locale-contrib/lt/LC_MESSAGES/django.po b/src/wolnelektury/locale-contrib/lt/LC_MESSAGES/django.po similarity index 100% rename from wolnelektury/locale-contrib/lt/LC_MESSAGES/django.po rename to src/wolnelektury/locale-contrib/lt/LC_MESSAGES/django.po diff --git a/wolnelektury/locale-contrib/pl/LC_MESSAGES/django.mo b/src/wolnelektury/locale-contrib/pl/LC_MESSAGES/django.mo similarity index 100% rename from wolnelektury/locale-contrib/pl/LC_MESSAGES/django.mo rename to src/wolnelektury/locale-contrib/pl/LC_MESSAGES/django.mo diff --git a/wolnelektury/locale-contrib/pl/LC_MESSAGES/django.po b/src/wolnelektury/locale-contrib/pl/LC_MESSAGES/django.po similarity index 100% rename from wolnelektury/locale-contrib/pl/LC_MESSAGES/django.po rename to src/wolnelektury/locale-contrib/pl/LC_MESSAGES/django.po diff --git a/wolnelektury/locale-contrib/ru/LC_MESSAGES/django.mo b/src/wolnelektury/locale-contrib/ru/LC_MESSAGES/django.mo similarity index 100% rename from wolnelektury/locale-contrib/ru/LC_MESSAGES/django.mo rename to src/wolnelektury/locale-contrib/ru/LC_MESSAGES/django.mo diff --git a/wolnelektury/locale-contrib/ru/LC_MESSAGES/django.po b/src/wolnelektury/locale-contrib/ru/LC_MESSAGES/django.po similarity index 100% rename from wolnelektury/locale-contrib/ru/LC_MESSAGES/django.po rename to src/wolnelektury/locale-contrib/ru/LC_MESSAGES/django.po diff --git a/wolnelektury/locale-contrib/uk/LC_MESSAGES/django.mo b/src/wolnelektury/locale-contrib/uk/LC_MESSAGES/django.mo similarity index 100% rename from wolnelektury/locale-contrib/uk/LC_MESSAGES/django.mo rename to src/wolnelektury/locale-contrib/uk/LC_MESSAGES/django.mo diff --git a/wolnelektury/locale-contrib/uk/LC_MESSAGES/django.po b/src/wolnelektury/locale-contrib/uk/LC_MESSAGES/django.po similarity index 100% rename from wolnelektury/locale-contrib/uk/LC_MESSAGES/django.po rename to src/wolnelektury/locale-contrib/uk/LC_MESSAGES/django.po diff --git a/apps/wolnelektury_core/locale/de/LC_MESSAGES/django.mo b/src/wolnelektury/locale/de/LC_MESSAGES/django.mo similarity index 100% rename from apps/wolnelektury_core/locale/de/LC_MESSAGES/django.mo rename to src/wolnelektury/locale/de/LC_MESSAGES/django.mo diff --git a/apps/wolnelektury_core/locale/de/LC_MESSAGES/django.po b/src/wolnelektury/locale/de/LC_MESSAGES/django.po similarity index 100% rename from apps/wolnelektury_core/locale/de/LC_MESSAGES/django.po rename to src/wolnelektury/locale/de/LC_MESSAGES/django.po diff --git a/apps/wolnelektury_core/locale/en/LC_MESSAGES/django.mo b/src/wolnelektury/locale/en/LC_MESSAGES/django.mo similarity index 100% rename from apps/wolnelektury_core/locale/en/LC_MESSAGES/django.mo rename to src/wolnelektury/locale/en/LC_MESSAGES/django.mo diff --git a/apps/wolnelektury_core/locale/en/LC_MESSAGES/django.po b/src/wolnelektury/locale/en/LC_MESSAGES/django.po similarity index 100% rename from apps/wolnelektury_core/locale/en/LC_MESSAGES/django.po rename to src/wolnelektury/locale/en/LC_MESSAGES/django.po diff --git a/apps/wolnelektury_core/locale/es/LC_MESSAGES/django.mo b/src/wolnelektury/locale/es/LC_MESSAGES/django.mo similarity index 100% rename from apps/wolnelektury_core/locale/es/LC_MESSAGES/django.mo rename to src/wolnelektury/locale/es/LC_MESSAGES/django.mo diff --git a/apps/wolnelektury_core/locale/es/LC_MESSAGES/django.po b/src/wolnelektury/locale/es/LC_MESSAGES/django.po similarity index 100% rename from apps/wolnelektury_core/locale/es/LC_MESSAGES/django.po rename to src/wolnelektury/locale/es/LC_MESSAGES/django.po diff --git a/apps/wolnelektury_core/locale/fr/LC_MESSAGES/django.mo b/src/wolnelektury/locale/fr/LC_MESSAGES/django.mo similarity index 100% rename from apps/wolnelektury_core/locale/fr/LC_MESSAGES/django.mo rename to src/wolnelektury/locale/fr/LC_MESSAGES/django.mo diff --git a/apps/wolnelektury_core/locale/fr/LC_MESSAGES/django.po b/src/wolnelektury/locale/fr/LC_MESSAGES/django.po similarity index 100% rename from apps/wolnelektury_core/locale/fr/LC_MESSAGES/django.po rename to src/wolnelektury/locale/fr/LC_MESSAGES/django.po diff --git a/apps/wolnelektury_core/locale/it/LC_MESSAGES/django.mo b/src/wolnelektury/locale/it/LC_MESSAGES/django.mo similarity index 100% rename from apps/wolnelektury_core/locale/it/LC_MESSAGES/django.mo rename to src/wolnelektury/locale/it/LC_MESSAGES/django.mo diff --git a/apps/wolnelektury_core/locale/it/LC_MESSAGES/django.po b/src/wolnelektury/locale/it/LC_MESSAGES/django.po similarity index 100% rename from apps/wolnelektury_core/locale/it/LC_MESSAGES/django.po rename to src/wolnelektury/locale/it/LC_MESSAGES/django.po diff --git a/apps/wolnelektury_core/locale/jp/LC_MESSAGES/django.mo b/src/wolnelektury/locale/jp/LC_MESSAGES/django.mo similarity index 100% rename from apps/wolnelektury_core/locale/jp/LC_MESSAGES/django.mo rename to src/wolnelektury/locale/jp/LC_MESSAGES/django.mo diff --git a/apps/wolnelektury_core/locale/jp/LC_MESSAGES/django.po b/src/wolnelektury/locale/jp/LC_MESSAGES/django.po similarity index 100% rename from apps/wolnelektury_core/locale/jp/LC_MESSAGES/django.po rename to src/wolnelektury/locale/jp/LC_MESSAGES/django.po diff --git a/apps/wolnelektury_core/locale/lt/LC_MESSAGES/django.mo b/src/wolnelektury/locale/lt/LC_MESSAGES/django.mo similarity index 100% rename from apps/wolnelektury_core/locale/lt/LC_MESSAGES/django.mo rename to src/wolnelektury/locale/lt/LC_MESSAGES/django.mo diff --git a/apps/wolnelektury_core/locale/lt/LC_MESSAGES/django.po b/src/wolnelektury/locale/lt/LC_MESSAGES/django.po similarity index 100% rename from apps/wolnelektury_core/locale/lt/LC_MESSAGES/django.po rename to src/wolnelektury/locale/lt/LC_MESSAGES/django.po diff --git a/apps/wolnelektury_core/locale/pl/LC_MESSAGES/django.mo b/src/wolnelektury/locale/pl/LC_MESSAGES/django.mo similarity index 100% rename from apps/wolnelektury_core/locale/pl/LC_MESSAGES/django.mo rename to src/wolnelektury/locale/pl/LC_MESSAGES/django.mo diff --git a/apps/wolnelektury_core/locale/pl/LC_MESSAGES/django.po b/src/wolnelektury/locale/pl/LC_MESSAGES/django.po similarity index 100% rename from apps/wolnelektury_core/locale/pl/LC_MESSAGES/django.po rename to src/wolnelektury/locale/pl/LC_MESSAGES/django.po diff --git a/apps/wolnelektury_core/locale/ru/LC_MESSAGES/django.mo b/src/wolnelektury/locale/ru/LC_MESSAGES/django.mo similarity index 100% rename from apps/wolnelektury_core/locale/ru/LC_MESSAGES/django.mo rename to src/wolnelektury/locale/ru/LC_MESSAGES/django.mo diff --git a/apps/wolnelektury_core/locale/ru/LC_MESSAGES/django.po b/src/wolnelektury/locale/ru/LC_MESSAGES/django.po similarity index 100% rename from apps/wolnelektury_core/locale/ru/LC_MESSAGES/django.po rename to src/wolnelektury/locale/ru/LC_MESSAGES/django.po diff --git a/apps/wolnelektury_core/locale/uk/LC_MESSAGES/django.mo b/src/wolnelektury/locale/uk/LC_MESSAGES/django.mo similarity index 100% rename from apps/wolnelektury_core/locale/uk/LC_MESSAGES/django.mo rename to src/wolnelektury/locale/uk/LC_MESSAGES/django.mo diff --git a/apps/wolnelektury_core/locale/uk/LC_MESSAGES/django.po b/src/wolnelektury/locale/uk/LC_MESSAGES/django.po similarity index 100% rename from apps/wolnelektury_core/locale/uk/LC_MESSAGES/django.po rename to src/wolnelektury/locale/uk/LC_MESSAGES/django.po diff --git a/apps/wolnelektury_core/management/__init__.py b/src/wolnelektury/management/__init__.py similarity index 100% rename from apps/wolnelektury_core/management/__init__.py rename to src/wolnelektury/management/__init__.py diff --git a/apps/wolnelektury_core/management/commands/__init__.py b/src/wolnelektury/management/commands/__init__.py similarity index 100% rename from apps/wolnelektury_core/management/commands/__init__.py rename to src/wolnelektury/management/commands/__init__.py diff --git a/apps/wolnelektury_core/management/commands/localepack.py b/src/wolnelektury/management/commands/localepack.py similarity index 100% rename from apps/wolnelektury_core/management/commands/localepack.py rename to src/wolnelektury/management/commands/localepack.py diff --git a/apps/wolnelektury_core/management/commands/translation2po.py b/src/wolnelektury/management/commands/translation2po.py similarity index 100% rename from apps/wolnelektury_core/management/commands/translation2po.py rename to src/wolnelektury/management/commands/translation2po.py diff --git a/apps/wolnelektury_core/management/profile.py b/src/wolnelektury/management/profile.py similarity index 100% rename from apps/wolnelektury_core/management/profile.py rename to src/wolnelektury/management/profile.py diff --git a/wolnelektury/middleware.py b/src/wolnelektury/middleware.py similarity index 100% rename from wolnelektury/middleware.py rename to src/wolnelektury/middleware.py diff --git a/apps/wolnelektury_core/templatetags/__init__.py b/src/wolnelektury/migrations/__init__.py similarity index 100% rename from apps/wolnelektury_core/templatetags/__init__.py rename to src/wolnelektury/migrations/__init__.py diff --git a/wolnelektury/migrations/getpaid/0001_initial.py b/src/wolnelektury/migrations/getpaid/0001_initial.py similarity index 100% rename from wolnelektury/migrations/getpaid/0001_initial.py rename to src/wolnelektury/migrations/getpaid/0001_initial.py diff --git a/wolnelektury/migrations/getpaid/0002_auto_20151221_1225.py b/src/wolnelektury/migrations/getpaid/0002_auto_20151221_1225.py similarity index 100% rename from wolnelektury/migrations/getpaid/0002_auto_20151221_1225.py rename to src/wolnelektury/migrations/getpaid/0002_auto_20151221_1225.py diff --git a/wolnelektury/migrations/__init__.py b/src/wolnelektury/migrations/getpaid/__init__.py similarity index 100% rename from wolnelektury/migrations/__init__.py rename to src/wolnelektury/migrations/getpaid/__init__.py diff --git a/wolnelektury/migrations/piston/0001_initial.py b/src/wolnelektury/migrations/piston/0001_initial.py similarity index 100% rename from wolnelektury/migrations/piston/0001_initial.py rename to src/wolnelektury/migrations/piston/0001_initial.py diff --git a/wolnelektury/migrations/getpaid/__init__.py b/src/wolnelektury/migrations/piston/__init__.py similarity index 100% rename from wolnelektury/migrations/getpaid/__init__.py rename to src/wolnelektury/migrations/piston/__init__.py diff --git a/wolnelektury/settings/__init__.py b/src/wolnelektury/settings/__init__.py similarity index 97% rename from wolnelektury/settings/__init__.py rename to src/wolnelektury/settings/__init__.py index 9224484de..411202d6a 100644 --- a/wolnelektury/settings/__init__.py +++ b/src/wolnelektury/settings/__init__.py @@ -18,7 +18,7 @@ TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.request', - 'wolnelektury_core.context_processors.extra_settings', + 'wolnelektury.context_processors.extra_settings', 'search.context_processors.search_form', ) @@ -44,7 +44,7 @@ ROOT_URLCONF = 'wolnelektury.urls' # These are the ones we should test. INSTALLED_APPS_OUR = [ - 'wolnelektury_core', + 'wolnelektury', # our 'ajaxable', 'api', diff --git a/wolnelektury/settings/auth.py b/src/wolnelektury/settings/auth.py similarity index 100% rename from wolnelektury/settings/auth.py rename to src/wolnelektury/settings/auth.py diff --git a/wolnelektury/settings/basic.py b/src/wolnelektury/settings/basic.py similarity index 100% rename from wolnelektury/settings/basic.py rename to src/wolnelektury/settings/basic.py diff --git a/wolnelektury/settings/cache.py b/src/wolnelektury/settings/cache.py similarity index 100% rename from wolnelektury/settings/cache.py rename to src/wolnelektury/settings/cache.py diff --git a/wolnelektury/settings/celery.py b/src/wolnelektury/settings/celery.py similarity index 100% rename from wolnelektury/settings/celery.py rename to src/wolnelektury/settings/celery.py diff --git a/wolnelektury/settings/contrib.py b/src/wolnelektury/settings/contrib.py similarity index 100% rename from wolnelektury/settings/contrib.py rename to src/wolnelektury/settings/contrib.py diff --git a/wolnelektury/settings/custom.py b/src/wolnelektury/settings/custom.py similarity index 100% rename from wolnelektury/settings/custom.py rename to src/wolnelektury/settings/custom.py diff --git a/wolnelektury/settings/locale.py b/src/wolnelektury/settings/locale.py similarity index 100% rename from wolnelektury/settings/locale.py rename to src/wolnelektury/settings/locale.py diff --git a/src/wolnelektury/settings/paths.py b/src/wolnelektury/settings/paths.py new file mode 100644 index 000000000..dfb99de04 --- /dev/null +++ b/src/wolnelektury/settings/paths.py @@ -0,0 +1,6 @@ +from os import path + +PROJECT_DIR = path.dirname(path.dirname(path.abspath(__file__))) +ROOT_DIR = path.dirname(path.dirname(PROJECT_DIR)) +VAR_DIR = path.join(ROOT_DIR, 'var') + diff --git a/wolnelektury/settings/static.py b/src/wolnelektury/settings/static.py similarity index 96% rename from wolnelektury/settings/static.py rename to src/wolnelektury/settings/static.py index a5d7bb7c4..027879a33 100644 --- a/wolnelektury/settings/static.py +++ b/src/wolnelektury/settings/static.py @@ -1,11 +1,11 @@ from os import path -from .paths import PROJECT_DIR +from .paths import VAR_DIR # Absolute path to the directory that holds media. # Example: "/home/media/media.lawrence.com/" -MEDIA_ROOT = path.join(PROJECT_DIR, '../media/') -STATIC_ROOT = path.join(PROJECT_DIR, '../static/') -SEARCH_INDEX = path.join(PROJECT_DIR, '../search_index/') +MEDIA_ROOT = path.join(VAR_DIR, 'media/') +STATIC_ROOT = path.join(VAR_DIR, 'static/') +SEARCH_INDEX = path.join(VAR_DIR, 'search_index/') # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash if there is a path component (optional in other cases). diff --git a/apps/wolnelektury_core/signals.py b/src/wolnelektury/signals.py similarity index 100% rename from apps/wolnelektury_core/signals.py rename to src/wolnelektury/signals.py diff --git a/apps/wolnelektury_core/static/css/annoy.css b/src/wolnelektury/static/css/annoy.css similarity index 100% rename from apps/wolnelektury_core/static/css/annoy.css rename to src/wolnelektury/static/css/annoy.css diff --git a/apps/wolnelektury_core/static/css/jquery.countdown.css b/src/wolnelektury/static/css/jquery.countdown.css similarity index 100% rename from apps/wolnelektury_core/static/css/jquery.countdown.css rename to src/wolnelektury/static/css/jquery.countdown.css diff --git a/apps/wolnelektury_core/static/css/master.book.css b/src/wolnelektury/static/css/master.book.css similarity index 100% rename from apps/wolnelektury_core/static/css/master.book.css rename to src/wolnelektury/static/css/master.book.css diff --git a/apps/wolnelektury_core/static/css/master.picture.css b/src/wolnelektury/static/css/master.picture.css similarity index 100% rename from apps/wolnelektury_core/static/css/master.picture.css rename to src/wolnelektury/static/css/master.picture.css diff --git a/apps/wolnelektury_core/static/css/new.book.css b/src/wolnelektury/static/css/new.book.css similarity index 100% rename from apps/wolnelektury_core/static/css/new.book.css rename to src/wolnelektury/static/css/new.book.css diff --git a/apps/wolnelektury_core/static/css/picture_box.css b/src/wolnelektury/static/css/picture_box.css similarity index 100% rename from apps/wolnelektury_core/static/css/picture_box.css rename to src/wolnelektury/static/css/picture_box.css diff --git a/apps/wolnelektury_core/static/css/simple.css b/src/wolnelektury/static/css/simple.css similarity index 100% rename from apps/wolnelektury_core/static/css/simple.css rename to src/wolnelektury/static/css/simple.css diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/src/wolnelektury/static/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png b/src/wolnelektury/static/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png b/src/wolnelektury/static/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png b/src/wolnelektury/static/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png b/src/wolnelektury/static/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png b/src/wolnelektury/static/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png b/src/wolnelektury/static/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/src/wolnelektury/static/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png b/src/wolnelektury/static/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-icons_222222_256x240.png b/src/wolnelektury/static/css/ui-lightness/images/ui-icons_222222_256x240.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-icons_222222_256x240.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-icons_222222_256x240.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-icons_228ef1_256x240.png b/src/wolnelektury/static/css/ui-lightness/images/ui-icons_228ef1_256x240.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-icons_228ef1_256x240.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-icons_228ef1_256x240.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-icons_ef8c08_256x240.png b/src/wolnelektury/static/css/ui-lightness/images/ui-icons_ef8c08_256x240.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-icons_ef8c08_256x240.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-icons_ef8c08_256x240.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-icons_ffd27a_256x240.png b/src/wolnelektury/static/css/ui-lightness/images/ui-icons_ffd27a_256x240.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-icons_ffd27a_256x240.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-icons_ffd27a_256x240.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/images/ui-icons_ffffff_256x240.png b/src/wolnelektury/static/css/ui-lightness/images/ui-icons_ffffff_256x240.png similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/images/ui-icons_ffffff_256x240.png rename to src/wolnelektury/static/css/ui-lightness/images/ui-icons_ffffff_256x240.png diff --git a/apps/wolnelektury_core/static/css/ui-lightness/jquery-ui-1.8.16.custom.css b/src/wolnelektury/static/css/ui-lightness/jquery-ui-1.8.16.custom.css similarity index 100% rename from apps/wolnelektury_core/static/css/ui-lightness/jquery-ui-1.8.16.custom.css rename to src/wolnelektury/static/css/ui-lightness/jquery-ui-1.8.16.custom.css diff --git a/apps/wolnelektury_core/static/img/1percent-big.png b/src/wolnelektury/static/img/1percent-big.png similarity index 100% rename from apps/wolnelektury_core/static/img/1percent-big.png rename to src/wolnelektury/static/img/1percent-big.png diff --git a/apps/wolnelektury_core/static/img/android-poster.png b/src/wolnelektury/static/img/android-poster.png similarity index 100% rename from apps/wolnelektury_core/static/img/android-poster.png rename to src/wolnelektury/static/img/android-poster.png diff --git a/apps/wolnelektury_core/static/img/arrow-down.png b/src/wolnelektury/static/img/arrow-down.png similarity index 100% rename from apps/wolnelektury_core/static/img/arrow-down.png rename to src/wolnelektury/static/img/arrow-down.png diff --git a/apps/wolnelektury_core/static/img/arrow-gray.png b/src/wolnelektury/static/img/arrow-gray.png similarity index 100% rename from apps/wolnelektury_core/static/img/arrow-gray.png rename to src/wolnelektury/static/img/arrow-gray.png diff --git a/apps/wolnelektury_core/static/img/arrow-gray.svg b/src/wolnelektury/static/img/arrow-gray.svg similarity index 100% rename from apps/wolnelektury_core/static/img/arrow-gray.svg rename to src/wolnelektury/static/img/arrow-gray.svg diff --git a/apps/wolnelektury_core/static/img/arrow-teal.png b/src/wolnelektury/static/img/arrow-teal.png similarity index 100% rename from apps/wolnelektury_core/static/img/arrow-teal.png rename to src/wolnelektury/static/img/arrow-teal.png diff --git a/apps/wolnelektury_core/static/img/arrow-teal.svg b/src/wolnelektury/static/img/arrow-teal.svg similarity index 100% rename from apps/wolnelektury_core/static/img/arrow-teal.svg rename to src/wolnelektury/static/img/arrow-teal.svg diff --git a/apps/wolnelektury_core/static/img/arrow-up.png b/src/wolnelektury/static/img/arrow-up.png similarity index 100% rename from apps/wolnelektury_core/static/img/arrow-up.png rename to src/wolnelektury/static/img/arrow-up.png diff --git a/apps/wolnelektury_core/static/img/auth/facebook.png b/src/wolnelektury/static/img/auth/facebook.png similarity index 100% rename from apps/wolnelektury_core/static/img/auth/facebook.png rename to src/wolnelektury/static/img/auth/facebook.png diff --git a/apps/wolnelektury_core/static/img/auth/google.png b/src/wolnelektury/static/img/auth/google.png similarity index 100% rename from apps/wolnelektury_core/static/img/auth/google.png rename to src/wolnelektury/static/img/auth/google.png diff --git a/apps/wolnelektury_core/static/img/auth/openid.png b/src/wolnelektury/static/img/auth/openid.png similarity index 100% rename from apps/wolnelektury_core/static/img/auth/openid.png rename to src/wolnelektury/static/img/auth/openid.png diff --git a/apps/wolnelektury_core/static/img/auth/twitter.png b/src/wolnelektury/static/img/auth/twitter.png similarity index 100% rename from apps/wolnelektury_core/static/img/auth/twitter.png rename to src/wolnelektury/static/img/auth/twitter.png diff --git a/apps/wolnelektury_core/static/img/backdrop/boltron-3212284622.jpg b/src/wolnelektury/static/img/backdrop/boltron-3212284622.jpg similarity index 100% rename from apps/wolnelektury_core/static/img/backdrop/boltron-3212284622.jpg rename to src/wolnelektury/static/img/backdrop/boltron-3212284622.jpg diff --git a/apps/wolnelektury_core/static/img/backdrop/book-drawer2.jpg b/src/wolnelektury/static/img/backdrop/book-drawer2.jpg similarity index 100% rename from apps/wolnelektury_core/static/img/backdrop/book-drawer2.jpg rename to src/wolnelektury/static/img/backdrop/book-drawer2.jpg diff --git a/apps/wolnelektury_core/static/img/backdrop/horiavarlan-4268896468.jpg b/src/wolnelektury/static/img/backdrop/horiavarlan-4268896468.jpg similarity index 100% rename from apps/wolnelektury_core/static/img/backdrop/horiavarlan-4268896468.jpg rename to src/wolnelektury/static/img/backdrop/horiavarlan-4268896468.jpg diff --git a/apps/wolnelektury_core/static/img/bg-header.png b/src/wolnelektury/static/img/bg-header.png similarity index 100% rename from apps/wolnelektury_core/static/img/bg-header.png rename to src/wolnelektury/static/img/bg-header.png diff --git a/apps/wolnelektury_core/static/img/bg.png b/src/wolnelektury/static/img/bg.png similarity index 100% rename from apps/wolnelektury_core/static/img/bg.png rename to src/wolnelektury/static/img/bg.png diff --git a/apps/wolnelektury_core/static/img/book-parent.png b/src/wolnelektury/static/img/book-parent.png similarity index 100% rename from apps/wolnelektury_core/static/img/book-parent.png rename to src/wolnelektury/static/img/book-parent.png diff --git a/apps/wolnelektury_core/static/img/book.png b/src/wolnelektury/static/img/book.png similarity index 100% rename from apps/wolnelektury_core/static/img/book.png rename to src/wolnelektury/static/img/book.png diff --git a/apps/wolnelektury_core/static/img/doodle/20110908-android.png b/src/wolnelektury/static/img/doodle/20110908-android.png similarity index 100% rename from apps/wolnelektury_core/static/img/doodle/20110908-android.png rename to src/wolnelektury/static/img/doodle/20110908-android.png diff --git a/apps/wolnelektury_core/static/img/doodle/20110908-logo.png b/src/wolnelektury/static/img/doodle/20110908-logo.png similarity index 100% rename from apps/wolnelektury_core/static/img/doodle/20110908-logo.png rename to src/wolnelektury/static/img/doodle/20110908-logo.png diff --git a/apps/wolnelektury_core/static/img/download.png b/src/wolnelektury/static/img/download.png similarity index 100% rename from apps/wolnelektury_core/static/img/download.png rename to src/wolnelektury/static/img/download.png diff --git a/apps/wolnelektury_core/static/img/download.svg b/src/wolnelektury/static/img/download.svg similarity index 100% rename from apps/wolnelektury_core/static/img/download.svg rename to src/wolnelektury/static/img/download.svg diff --git a/apps/wolnelektury_core/static/img/epub-www.jpg b/src/wolnelektury/static/img/epub-www.jpg similarity index 100% rename from apps/wolnelektury_core/static/img/epub-www.jpg rename to src/wolnelektury/static/img/epub-www.jpg diff --git a/apps/wolnelektury_core/static/img/epub.png b/src/wolnelektury/static/img/epub.png similarity index 100% rename from apps/wolnelektury_core/static/img/epub.png rename to src/wolnelektury/static/img/epub.png diff --git a/apps/wolnelektury_core/static/img/favicon.ico b/src/wolnelektury/static/img/favicon.ico similarity index 100% rename from apps/wolnelektury_core/static/img/favicon.ico rename to src/wolnelektury/static/img/favicon.ico diff --git a/apps/wolnelektury_core/static/img/favicon.png b/src/wolnelektury/static/img/favicon.png similarity index 100% rename from apps/wolnelektury_core/static/img/favicon.png rename to src/wolnelektury/static/img/favicon.png diff --git a/apps/wolnelektury_core/static/img/indicator.gif b/src/wolnelektury/static/img/indicator.gif similarity index 100% rename from apps/wolnelektury_core/static/img/indicator.gif rename to src/wolnelektury/static/img/indicator.gif diff --git a/apps/wolnelektury_core/static/img/kindle-poster-260.png b/src/wolnelektury/static/img/kindle-poster-260.png similarity index 100% rename from apps/wolnelektury_core/static/img/kindle-poster-260.png rename to src/wolnelektury/static/img/kindle-poster-260.png diff --git a/apps/wolnelektury_core/static/img/kindle-poster.png b/src/wolnelektury/static/img/kindle-poster.png similarity index 100% rename from apps/wolnelektury_core/static/img/kindle-poster.png rename to src/wolnelektury/static/img/kindle-poster.png diff --git a/apps/wolnelektury_core/static/img/licenses/cc-by-sa.png b/src/wolnelektury/static/img/licenses/cc-by-sa.png similarity index 100% rename from apps/wolnelektury_core/static/img/licenses/cc-by-sa.png rename to src/wolnelektury/static/img/licenses/cc-by-sa.png diff --git a/apps/wolnelektury_core/static/img/licenses/cc-by-sa.svg b/src/wolnelektury/static/img/licenses/cc-by-sa.svg similarity index 100% rename from apps/wolnelektury_core/static/img/licenses/cc-by-sa.svg rename to src/wolnelektury/static/img/licenses/cc-by-sa.svg diff --git a/apps/wolnelektury_core/static/img/listen.png b/src/wolnelektury/static/img/listen.png similarity index 100% rename from apps/wolnelektury_core/static/img/listen.png rename to src/wolnelektury/static/img/listen.png diff --git a/apps/wolnelektury_core/static/img/listen.svg b/src/wolnelektury/static/img/listen.svg similarity index 100% rename from apps/wolnelektury_core/static/img/listen.svg rename to src/wolnelektury/static/img/listen.svg diff --git a/apps/wolnelektury_core/static/img/logo-220.png b/src/wolnelektury/static/img/logo-220.png similarity index 100% rename from apps/wolnelektury_core/static/img/logo-220.png rename to src/wolnelektury/static/img/logo-220.png diff --git a/apps/wolnelektury_core/static/img/logo-bez.png b/src/wolnelektury/static/img/logo-bez.png similarity index 100% rename from apps/wolnelektury_core/static/img/logo-bez.png rename to src/wolnelektury/static/img/logo-bez.png diff --git a/apps/wolnelektury_core/static/img/logo-big.png b/src/wolnelektury/static/img/logo-big.png similarity index 100% rename from apps/wolnelektury_core/static/img/logo-big.png rename to src/wolnelektury/static/img/logo-big.png diff --git a/apps/wolnelektury_core/static/img/logo-fbc.png b/src/wolnelektury/static/img/logo-fbc.png similarity index 100% rename from apps/wolnelektury_core/static/img/logo-fbc.png rename to src/wolnelektury/static/img/logo-fbc.png diff --git a/apps/wolnelektury_core/static/img/logo-neon.png b/src/wolnelektury/static/img/logo-neon.png similarity index 100% rename from apps/wolnelektury_core/static/img/logo-neon.png rename to src/wolnelektury/static/img/logo-neon.png diff --git a/apps/wolnelektury_core/static/img/logo.png b/src/wolnelektury/static/img/logo.png similarity index 100% rename from apps/wolnelektury_core/static/img/logo.png rename to src/wolnelektury/static/img/logo.png diff --git a/apps/wolnelektury_core/static/img/logo_nck.jpg b/src/wolnelektury/static/img/logo_nck.jpg similarity index 100% rename from apps/wolnelektury_core/static/img/logo_nck.jpg rename to src/wolnelektury/static/img/logo_nck.jpg diff --git a/apps/wolnelektury_core/static/img/logo_nck_200horiz_trans.png b/src/wolnelektury/static/img/logo_nck_200horiz_trans.png similarity index 100% rename from apps/wolnelektury_core/static/img/logo_nck_200horiz_trans.png rename to src/wolnelektury/static/img/logo_nck_200horiz_trans.png diff --git a/apps/wolnelektury_core/static/img/logo_nck_200trans.png b/src/wolnelektury/static/img/logo_nck_200trans.png similarity index 100% rename from apps/wolnelektury_core/static/img/logo_nck_200trans.png rename to src/wolnelektury/static/img/logo_nck_200trans.png diff --git a/apps/wolnelektury_core/static/img/mobi.png b/src/wolnelektury/static/img/mobi.png similarity index 100% rename from apps/wolnelektury_core/static/img/mobi.png rename to src/wolnelektury/static/img/mobi.png diff --git a/apps/wolnelektury_core/static/img/odt.png b/src/wolnelektury/static/img/odt.png similarity index 100% rename from apps/wolnelektury_core/static/img/odt.png rename to src/wolnelektury/static/img/odt.png diff --git a/apps/wolnelektury_core/static/img/payu.png b/src/wolnelektury/static/img/payu.png similarity index 100% rename from apps/wolnelektury_core/static/img/payu.png rename to src/wolnelektury/static/img/payu.png diff --git a/apps/wolnelektury_core/static/img/pdf.png b/src/wolnelektury/static/img/pdf.png similarity index 100% rename from apps/wolnelektury_core/static/img/pdf.png rename to src/wolnelektury/static/img/pdf.png diff --git a/apps/wolnelektury_core/static/img/procent.png b/src/wolnelektury/static/img/procent.png similarity index 100% rename from apps/wolnelektury_core/static/img/procent.png rename to src/wolnelektury/static/img/procent.png diff --git a/apps/wolnelektury_core/static/img/progress-pixel.png b/src/wolnelektury/static/img/progress-pixel.png similarity index 100% rename from apps/wolnelektury_core/static/img/progress-pixel.png rename to src/wolnelektury/static/img/progress-pixel.png diff --git a/apps/wolnelektury_core/static/img/read.png b/src/wolnelektury/static/img/read.png similarity index 100% rename from apps/wolnelektury_core/static/img/read.png rename to src/wolnelektury/static/img/read.png diff --git a/apps/wolnelektury_core/static/img/read.svg b/src/wolnelektury/static/img/read.svg similarity index 100% rename from apps/wolnelektury_core/static/img/read.svg rename to src/wolnelektury/static/img/read.svg diff --git a/apps/wolnelektury_core/static/img/s5/blank.gif b/src/wolnelektury/static/img/s5/blank.gif similarity index 100% rename from apps/wolnelektury_core/static/img/s5/blank.gif rename to src/wolnelektury/static/img/s5/blank.gif diff --git a/apps/wolnelektury_core/static/img/s5/bodybg.gif b/src/wolnelektury/static/img/s5/bodybg.gif similarity index 100% rename from apps/wolnelektury_core/static/img/s5/bodybg.gif rename to src/wolnelektury/static/img/s5/bodybg.gif diff --git a/apps/wolnelektury_core/static/img/s5/iepngfix.htc b/src/wolnelektury/static/img/s5/iepngfix.htc similarity index 100% rename from apps/wolnelektury_core/static/img/s5/iepngfix.htc rename to src/wolnelektury/static/img/s5/iepngfix.htc diff --git a/apps/wolnelektury_core/static/img/search.png b/src/wolnelektury/static/img/search.png similarity index 100% rename from apps/wolnelektury_core/static/img/search.png rename to src/wolnelektury/static/img/search.png diff --git a/apps/wolnelektury_core/static/img/social/bigfacebook.png b/src/wolnelektury/static/img/social/bigfacebook.png similarity index 100% rename from apps/wolnelektury_core/static/img/social/bigfacebook.png rename to src/wolnelektury/static/img/social/bigfacebook.png diff --git a/apps/wolnelektury_core/static/img/social/biggoogle.png b/src/wolnelektury/static/img/social/biggoogle.png similarity index 100% rename from apps/wolnelektury_core/static/img/social/biggoogle.png rename to src/wolnelektury/static/img/social/biggoogle.png diff --git a/apps/wolnelektury_core/static/img/social/bignk.png b/src/wolnelektury/static/img/social/bignk.png similarity index 100% rename from apps/wolnelektury_core/static/img/social/bignk.png rename to src/wolnelektury/static/img/social/bignk.png diff --git a/apps/wolnelektury_core/static/img/social/bigtwitter.png b/src/wolnelektury/static/img/social/bigtwitter.png similarity index 100% rename from apps/wolnelektury_core/static/img/social/bigtwitter.png rename to src/wolnelektury/static/img/social/bigtwitter.png diff --git a/apps/wolnelektury_core/static/img/social/f.png b/src/wolnelektury/static/img/social/f.png similarity index 100% rename from apps/wolnelektury_core/static/img/social/f.png rename to src/wolnelektury/static/img/social/f.png diff --git a/apps/wolnelektury_core/static/img/social/f.svg b/src/wolnelektury/static/img/social/f.svg similarity index 100% rename from apps/wolnelektury_core/static/img/social/f.svg rename to src/wolnelektury/static/img/social/f.svg diff --git a/apps/wolnelektury_core/static/img/social/gplus.png b/src/wolnelektury/static/img/social/gplus.png similarity index 100% rename from apps/wolnelektury_core/static/img/social/gplus.png rename to src/wolnelektury/static/img/social/gplus.png diff --git a/apps/wolnelektury_core/static/img/social/gplus.svg b/src/wolnelektury/static/img/social/gplus.svg similarity index 100% rename from apps/wolnelektury_core/static/img/social/gplus.svg rename to src/wolnelektury/static/img/social/gplus.svg diff --git a/apps/wolnelektury_core/static/img/social/nk.png b/src/wolnelektury/static/img/social/nk.png similarity index 100% rename from apps/wolnelektury_core/static/img/social/nk.png rename to src/wolnelektury/static/img/social/nk.png diff --git a/apps/wolnelektury_core/static/img/social/nk.svg b/src/wolnelektury/static/img/social/nk.svg similarity index 100% rename from apps/wolnelektury_core/static/img/social/nk.svg rename to src/wolnelektury/static/img/social/nk.svg diff --git a/apps/wolnelektury_core/static/img/speaker.png b/src/wolnelektury/static/img/speaker.png similarity index 100% rename from apps/wolnelektury_core/static/img/speaker.png rename to src/wolnelektury/static/img/speaker.png diff --git a/apps/wolnelektury_core/static/img/turniej-maly.png b/src/wolnelektury/static/img/turniej-maly.png similarity index 100% rename from apps/wolnelektury_core/static/img/turniej-maly.png rename to src/wolnelektury/static/img/turniej-maly.png diff --git a/apps/wolnelektury_core/static/img/txt.png b/src/wolnelektury/static/img/txt.png similarity index 100% rename from apps/wolnelektury_core/static/img/txt.png rename to src/wolnelektury/static/img/txt.png diff --git a/apps/wolnelektury_core/static/img/wiatrak.png b/src/wolnelektury/static/img/wiatrak.png similarity index 100% rename from apps/wolnelektury_core/static/img/wiatrak.png rename to src/wolnelektury/static/img/wiatrak.png diff --git a/apps/wolnelektury_core/static/img/wl_icon_64.png b/src/wolnelektury/static/img/wl_icon_64.png similarity index 100% rename from apps/wolnelektury_core/static/img/wl_icon_64.png rename to src/wolnelektury/static/img/wl_icon_64.png diff --git a/apps/wolnelektury_core/static/img/zabawnik.png b/src/wolnelektury/static/img/zabawnik.png similarity index 100% rename from apps/wolnelektury_core/static/img/zabawnik.png rename to src/wolnelektury/static/img/zabawnik.png diff --git a/apps/wolnelektury_core/static/js/annoy.js b/src/wolnelektury/static/js/annoy.js similarity index 100% rename from apps/wolnelektury_core/static/js/annoy.js rename to src/wolnelektury/static/js/annoy.js diff --git a/apps/wolnelektury_core/static/js/base.js b/src/wolnelektury/static/js/base.js similarity index 100% rename from apps/wolnelektury_core/static/js/base.js rename to src/wolnelektury/static/js/base.js diff --git a/apps/wolnelektury_core/static/js/book.js b/src/wolnelektury/static/js/book.js similarity index 100% rename from apps/wolnelektury_core/static/js/book.js rename to src/wolnelektury/static/js/book.js diff --git a/apps/wolnelektury_core/static/js/book_text/info.js b/src/wolnelektury/static/js/book_text/info.js similarity index 100% rename from apps/wolnelektury_core/static/js/book_text/info.js rename to src/wolnelektury/static/js/book_text/info.js diff --git a/apps/wolnelektury_core/static/js/book_text/menu.js b/src/wolnelektury/static/js/book_text/menu.js similarity index 100% rename from apps/wolnelektury_core/static/js/book_text/menu.js rename to src/wolnelektury/static/js/book_text/menu.js diff --git a/apps/wolnelektury_core/static/js/book_text/note.js b/src/wolnelektury/static/js/book_text/note.js similarity index 100% rename from apps/wolnelektury_core/static/js/book_text/note.js rename to src/wolnelektury/static/js/book_text/note.js diff --git a/apps/wolnelektury_core/static/js/book_text/settings.js b/src/wolnelektury/static/js/book_text/settings.js similarity index 100% rename from apps/wolnelektury_core/static/js/book_text/settings.js rename to src/wolnelektury/static/js/book_text/settings.js diff --git a/apps/wolnelektury_core/static/js/book_text/toc.js b/src/wolnelektury/static/js/book_text/toc.js similarity index 100% rename from apps/wolnelektury_core/static/js/book_text/toc.js rename to src/wolnelektury/static/js/book_text/toc.js diff --git a/apps/wolnelektury_core/static/js/contrib/ierange-m2.js b/src/wolnelektury/static/js/contrib/ierange-m2.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/ierange-m2.js rename to src/wolnelektury/static/js/contrib/ierange-m2.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery-ui-1.8.16.custom.min.js b/src/wolnelektury/static/js/contrib/jquery-ui-1.8.16.custom.min.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery-ui-1.8.16.custom.min.js rename to src/wolnelektury/static/js/contrib/jquery-ui-1.8.16.custom.min.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.autocomplete.js b/src/wolnelektury/static/js/contrib/jquery.autocomplete.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.autocomplete.js rename to src/wolnelektury/static/js/contrib/jquery.autocomplete.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.countdown-de.js b/src/wolnelektury/static/js/contrib/jquery.countdown-de.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.countdown-de.js rename to src/wolnelektury/static/js/contrib/jquery.countdown-de.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.countdown-es.js b/src/wolnelektury/static/js/contrib/jquery.countdown-es.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.countdown-es.js rename to src/wolnelektury/static/js/contrib/jquery.countdown-es.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.countdown-fr.js b/src/wolnelektury/static/js/contrib/jquery.countdown-fr.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.countdown-fr.js rename to src/wolnelektury/static/js/contrib/jquery.countdown-fr.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.countdown-lt.js b/src/wolnelektury/static/js/contrib/jquery.countdown-lt.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.countdown-lt.js rename to src/wolnelektury/static/js/contrib/jquery.countdown-lt.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.countdown-pl.js b/src/wolnelektury/static/js/contrib/jquery.countdown-pl.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.countdown-pl.js rename to src/wolnelektury/static/js/contrib/jquery.countdown-pl.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.countdown-ru.js b/src/wolnelektury/static/js/contrib/jquery.countdown-ru.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.countdown-ru.js rename to src/wolnelektury/static/js/contrib/jquery.countdown-ru.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.countdown-uk.js b/src/wolnelektury/static/js/contrib/jquery.countdown-uk.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.countdown-uk.js rename to src/wolnelektury/static/js/contrib/jquery.countdown-uk.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.countdown.js b/src/wolnelektury/static/js/contrib/jquery.countdown.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.countdown.js rename to src/wolnelektury/static/js/contrib/jquery.countdown.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.cycle.min.js b/src/wolnelektury/static/js/contrib/jquery.cycle.min.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.cycle.min.js rename to src/wolnelektury/static/js/contrib/jquery.cycle.min.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.eventdelegation.js b/src/wolnelektury/static/js/contrib/jquery.eventdelegation.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.eventdelegation.js rename to src/wolnelektury/static/js/contrib/jquery.eventdelegation.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.form.js b/src/wolnelektury/static/js/contrib/jquery.form.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.form.js rename to src/wolnelektury/static/js/contrib/jquery.form.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.highlightfade.js b/src/wolnelektury/static/js/contrib/jquery.highlightfade.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.highlightfade.js rename to src/wolnelektury/static/js/contrib/jquery.highlightfade.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.jqmodal.js b/src/wolnelektury/static/js/contrib/jquery.jqmodal.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.jqmodal.js rename to src/wolnelektury/static/js/contrib/jquery.jqmodal.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.js b/src/wolnelektury/static/js/contrib/jquery.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.js rename to src/wolnelektury/static/js/contrib/jquery.js diff --git a/apps/wolnelektury_core/static/js/contrib/jquery.scrollto.js b/src/wolnelektury/static/js/contrib/jquery.scrollto.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/jquery.scrollto.js rename to src/wolnelektury/static/js/contrib/jquery.scrollto.js diff --git a/apps/wolnelektury_core/static/js/contrib/modernizr.custom.19652.js b/src/wolnelektury/static/js/contrib/modernizr.custom.19652.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/modernizr.custom.19652.js rename to src/wolnelektury/static/js/contrib/modernizr.custom.19652.js diff --git a/apps/wolnelektury_core/static/js/contrib/progressSpin.min.js b/src/wolnelektury/static/js/contrib/progressSpin.min.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/progressSpin.min.js rename to src/wolnelektury/static/js/contrib/progressSpin.min.js diff --git a/apps/wolnelektury_core/static/js/contrib/raphael-min.js b/src/wolnelektury/static/js/contrib/raphael-min.js similarity index 100% rename from apps/wolnelektury_core/static/js/contrib/raphael-min.js rename to src/wolnelektury/static/js/contrib/raphael-min.js diff --git a/apps/wolnelektury_core/static/js/dialogs.js b/src/wolnelektury/static/js/dialogs.js similarity index 100% rename from apps/wolnelektury_core/static/js/dialogs.js rename to src/wolnelektury/static/js/dialogs.js diff --git a/apps/wolnelektury_core/static/js/locale.js b/src/wolnelektury/static/js/locale.js similarity index 100% rename from apps/wolnelektury_core/static/js/locale.js rename to src/wolnelektury/static/js/locale.js diff --git a/apps/wolnelektury_core/static/js/picture.js b/src/wolnelektury/static/js/picture.js similarity index 100% rename from apps/wolnelektury_core/static/js/picture.js rename to src/wolnelektury/static/js/picture.js diff --git a/apps/wolnelektury_core/static/js/search.js b/src/wolnelektury/static/js/search.js similarity index 100% rename from apps/wolnelektury_core/static/js/search.js rename to src/wolnelektury/static/js/search.js diff --git a/apps/wolnelektury_core/static/js/widget.js b/src/wolnelektury/static/js/widget.js similarity index 100% rename from apps/wolnelektury_core/static/js/widget.js rename to src/wolnelektury/static/js/widget.js diff --git a/apps/wolnelektury_core/static/js/widget_run.js b/src/wolnelektury/static/js/widget_run.js similarity index 100% rename from apps/wolnelektury_core/static/js/widget_run.js rename to src/wolnelektury/static/js/widget_run.js diff --git a/apps/wolnelektury_core/static/opensearch.xml b/src/wolnelektury/static/opensearch.xml similarity index 100% rename from apps/wolnelektury_core/static/opensearch.xml rename to src/wolnelektury/static/opensearch.xml diff --git a/apps/wolnelektury_core/static/scss/book_text.scss b/src/wolnelektury/static/scss/book_text.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text.scss rename to src/wolnelektury/static/scss/book_text.scss diff --git a/apps/wolnelektury_core/static/scss/book_text/body.scss b/src/wolnelektury/static/scss/book_text/body.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text/body.scss rename to src/wolnelektury/static/scss/book_text/body.scss diff --git a/apps/wolnelektury_core/static/scss/book_text/book_box.scss b/src/wolnelektury/static/scss/book_text/book_box.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text/book_box.scss rename to src/wolnelektury/static/scss/book_text/book_box.scss diff --git a/apps/wolnelektury_core/static/scss/book_text/box.scss b/src/wolnelektury/static/scss/book_text/box.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text/box.scss rename to src/wolnelektury/static/scss/book_text/box.scss diff --git a/apps/wolnelektury_core/static/scss/book_text/const.scss b/src/wolnelektury/static/scss/book_text/const.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text/const.scss rename to src/wolnelektury/static/scss/book_text/const.scss diff --git a/apps/wolnelektury_core/static/scss/book_text/info.scss b/src/wolnelektury/static/scss/book_text/info.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text/info.scss rename to src/wolnelektury/static/scss/book_text/info.scss diff --git a/apps/wolnelektury_core/static/scss/book_text/menu.scss b/src/wolnelektury/static/scss/book_text/menu.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text/menu.scss rename to src/wolnelektury/static/scss/book_text/menu.scss diff --git a/apps/wolnelektury_core/static/scss/book_text/note.scss b/src/wolnelektury/static/scss/book_text/note.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text/note.scss rename to src/wolnelektury/static/scss/book_text/note.scss diff --git a/apps/wolnelektury_core/static/scss/book_text/numbering.scss b/src/wolnelektury/static/scss/book_text/numbering.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text/numbering.scss rename to src/wolnelektury/static/scss/book_text/numbering.scss diff --git a/apps/wolnelektury_core/static/scss/book_text/other.scss b/src/wolnelektury/static/scss/book_text/other.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text/other.scss rename to src/wolnelektury/static/scss/book_text/other.scss diff --git a/apps/wolnelektury_core/static/scss/book_text/settings.scss b/src/wolnelektury/static/scss/book_text/settings.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text/settings.scss rename to src/wolnelektury/static/scss/book_text/settings.scss diff --git a/apps/wolnelektury_core/static/scss/book_text/themes.scss b/src/wolnelektury/static/scss/book_text/themes.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text/themes.scss rename to src/wolnelektury/static/scss/book_text/themes.scss diff --git a/apps/wolnelektury_core/static/scss/book_text/toc.scss b/src/wolnelektury/static/scss/book_text/toc.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/book_text/toc.scss rename to src/wolnelektury/static/scss/book_text/toc.scss diff --git a/apps/wolnelektury_core/static/scss/dictionary/dictionary.scss b/src/wolnelektury/static/scss/dictionary/dictionary.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/dictionary/dictionary.scss rename to src/wolnelektury/static/scss/dictionary/dictionary.scss diff --git a/apps/wolnelektury_core/static/scss/funding/funding.scss b/src/wolnelektury/static/scss/funding/funding.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/funding/funding.scss rename to src/wolnelektury/static/scss/funding/funding.scss diff --git a/apps/wolnelektury_core/static/scss/main.scss b/src/wolnelektury/static/scss/main.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main.scss rename to src/wolnelektury/static/scss/main.scss diff --git a/apps/wolnelektury_core/static/scss/main/auth.scss b/src/wolnelektury/static/scss/main/auth.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/auth.scss rename to src/wolnelektury/static/scss/main/auth.scss diff --git a/apps/wolnelektury_core/static/scss/main/base.scss b/src/wolnelektury/static/scss/main/base.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/base.scss rename to src/wolnelektury/static/scss/main/base.scss diff --git a/apps/wolnelektury_core/static/scss/main/book_box.scss b/src/wolnelektury/static/scss/main/book_box.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/book_box.scss rename to src/wolnelektury/static/scss/main/book_box.scss diff --git a/apps/wolnelektury_core/static/scss/main/book_list.scss b/src/wolnelektury/static/scss/main/book_list.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/book_list.scss rename to src/wolnelektury/static/scss/main/book_list.scss diff --git a/apps/wolnelektury_core/static/scss/main/catalogue.scss b/src/wolnelektury/static/scss/main/catalogue.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/catalogue.scss rename to src/wolnelektury/static/scss/main/catalogue.scss diff --git a/apps/wolnelektury_core/static/scss/main/cite.scss b/src/wolnelektury/static/scss/main/cite.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/cite.scss rename to src/wolnelektury/static/scss/main/cite.scss diff --git a/apps/wolnelektury_core/static/scss/main/const.scss b/src/wolnelektury/static/scss/main/const.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/const.scss rename to src/wolnelektury/static/scss/main/const.scss diff --git a/apps/wolnelektury_core/static/scss/main/dialogs.scss b/src/wolnelektury/static/scss/main/dialogs.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/dialogs.scss rename to src/wolnelektury/static/scss/main/dialogs.scss diff --git a/apps/wolnelektury_core/static/scss/main/footer.scss b/src/wolnelektury/static/scss/main/footer.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/footer.scss rename to src/wolnelektury/static/scss/main/footer.scss diff --git a/apps/wolnelektury_core/static/scss/main/form.scss b/src/wolnelektury/static/scss/main/form.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/form.scss rename to src/wolnelektury/static/scss/main/form.scss diff --git a/apps/wolnelektury_core/static/scss/main/fragment.scss b/src/wolnelektury/static/scss/main/fragment.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/fragment.scss rename to src/wolnelektury/static/scss/main/fragment.scss diff --git a/apps/wolnelektury_core/static/scss/main/header.scss b/src/wolnelektury/static/scss/main/header.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/header.scss rename to src/wolnelektury/static/scss/main/header.scss diff --git a/apps/wolnelektury_core/static/scss/main/hidden.scss b/src/wolnelektury/static/scss/main/hidden.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/hidden.scss rename to src/wolnelektury/static/scss/main/hidden.scss diff --git a/apps/wolnelektury_core/static/scss/main/main_content.scss b/src/wolnelektury/static/scss/main/main_content.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/main_content.scss rename to src/wolnelektury/static/scss/main/main_content.scss diff --git a/apps/wolnelektury_core/static/scss/main/main_page.scss b/src/wolnelektury/static/scss/main/main_page.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/main_page.scss rename to src/wolnelektury/static/scss/main/main_page.scss diff --git a/apps/wolnelektury_core/static/scss/main/menu.scss b/src/wolnelektury/static/scss/main/menu.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/menu.scss rename to src/wolnelektury/static/scss/main/menu.scss diff --git a/apps/wolnelektury_core/static/scss/main/picture_box.scss b/src/wolnelektury/static/scss/main/picture_box.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/picture_box.scss rename to src/wolnelektury/static/scss/main/picture_box.scss diff --git a/apps/wolnelektury_core/static/scss/main/search.scss b/src/wolnelektury/static/scss/main/search.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/search.scss rename to src/wolnelektury/static/scss/main/search.scss diff --git a/apps/wolnelektury_core/static/scss/main/tag.scss b/src/wolnelektury/static/scss/main/tag.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/main/tag.scss rename to src/wolnelektury/static/scss/main/tag.scss diff --git a/apps/wolnelektury_core/static/scss/polls/polls.scss b/src/wolnelektury/static/scss/polls/polls.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/polls/polls.scss rename to src/wolnelektury/static/scss/polls/polls.scss diff --git a/apps/wolnelektury_core/static/scss/social/shelf_tags.scss b/src/wolnelektury/static/scss/social/shelf_tags.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/social/shelf_tags.scss rename to src/wolnelektury/static/scss/social/shelf_tags.scss diff --git a/apps/wolnelektury_core/static/scss/tools.scss b/src/wolnelektury/static/scss/tools.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/tools.scss rename to src/wolnelektury/static/scss/tools.scss diff --git a/apps/wolnelektury_core/static/scss/widget.scss b/src/wolnelektury/static/scss/widget.scss similarity index 100% rename from apps/wolnelektury_core/static/scss/widget.scss rename to src/wolnelektury/static/scss/widget.scss diff --git a/apps/wolnelektury_core/templates/404.html b/src/wolnelektury/templates/404.html similarity index 100% rename from apps/wolnelektury_core/templates/404.html rename to src/wolnelektury/templates/404.html diff --git a/apps/wolnelektury_core/templates/500.html b/src/wolnelektury/templates/500.html similarity index 100% rename from apps/wolnelektury_core/templates/500.html rename to src/wolnelektury/templates/500.html diff --git a/apps/wolnelektury_core/templates/503.html b/src/wolnelektury/templates/503.html similarity index 100% rename from apps/wolnelektury_core/templates/503.html rename to src/wolnelektury/templates/503.html diff --git a/apps/wolnelektury_core/templates/account/base.html b/src/wolnelektury/templates/account/base.html similarity index 100% rename from apps/wolnelektury_core/templates/account/base.html rename to src/wolnelektury/templates/account/base.html diff --git a/apps/wolnelektury_core/templates/admin/base_site.html b/src/wolnelektury/templates/admin/base_site.html similarity index 100% rename from apps/wolnelektury_core/templates/admin/base_site.html rename to src/wolnelektury/templates/admin/base_site.html diff --git a/apps/wolnelektury_core/templates/admin/catalogue/book/change_form.html b/src/wolnelektury/templates/admin/catalogue/book/change_form.html similarity index 100% rename from apps/wolnelektury_core/templates/admin/catalogue/book/change_form.html rename to src/wolnelektury/templates/admin/catalogue/book/change_form.html diff --git a/apps/wolnelektury_core/templates/admin/catalogue/book/change_list.html b/src/wolnelektury/templates/admin/catalogue/book/change_list.html similarity index 100% rename from apps/wolnelektury_core/templates/admin/catalogue/book/change_list.html rename to src/wolnelektury/templates/admin/catalogue/book/change_list.html diff --git a/apps/wolnelektury_core/templates/annoy.html b/src/wolnelektury/templates/annoy.html similarity index 100% rename from apps/wolnelektury_core/templates/annoy.html rename to src/wolnelektury/templates/annoy.html diff --git a/apps/wolnelektury_core/templates/auth/login.html b/src/wolnelektury/templates/auth/login.html similarity index 100% rename from apps/wolnelektury_core/templates/auth/login.html rename to src/wolnelektury/templates/auth/login.html diff --git a/apps/wolnelektury_core/templates/auth/login_register.html b/src/wolnelektury/templates/auth/login_register.html similarity index 100% rename from apps/wolnelektury_core/templates/auth/login_register.html rename to src/wolnelektury/templates/auth/login_register.html diff --git a/apps/wolnelektury_core/templates/auth/register.html b/src/wolnelektury/templates/auth/register.html similarity index 100% rename from apps/wolnelektury_core/templates/auth/register.html rename to src/wolnelektury/templates/auth/register.html diff --git a/apps/wolnelektury_core/templates/base.html b/src/wolnelektury/templates/base.html similarity index 100% rename from apps/wolnelektury_core/templates/base.html rename to src/wolnelektury/templates/base.html diff --git a/apps/wolnelektury_core/templates/info/join_us.html b/src/wolnelektury/templates/info/join_us.html similarity index 100% rename from apps/wolnelektury_core/templates/info/join_us.html rename to src/wolnelektury/templates/info/join_us.html diff --git a/apps/wolnelektury_core/templates/latest_blog_posts.html b/src/wolnelektury/templates/latest_blog_posts.html similarity index 100% rename from apps/wolnelektury_core/templates/latest_blog_posts.html rename to src/wolnelektury/templates/latest_blog_posts.html diff --git a/apps/wolnelektury_core/templates/main_page.html b/src/wolnelektury/templates/main_page.html similarity index 100% rename from apps/wolnelektury_core/templates/main_page.html rename to src/wolnelektury/templates/main_page.html diff --git a/apps/wolnelektury_core/templates/openid/login.html b/src/wolnelektury/templates/openid/login.html similarity index 100% rename from apps/wolnelektury_core/templates/openid/login.html rename to src/wolnelektury/templates/openid/login.html diff --git a/apps/wolnelektury_core/templates/pagination/pagination.html b/src/wolnelektury/templates/pagination/pagination.html similarity index 100% rename from apps/wolnelektury_core/templates/pagination/pagination.html rename to src/wolnelektury/templates/pagination/pagination.html diff --git a/apps/wolnelektury_core/templates/piston/authorize_token.html b/src/wolnelektury/templates/piston/authorize_token.html similarity index 100% rename from apps/wolnelektury_core/templates/piston/authorize_token.html rename to src/wolnelektury/templates/piston/authorize_token.html diff --git a/apps/wolnelektury_core/templates/publish_plan.html b/src/wolnelektury/templates/publish_plan.html similarity index 100% rename from apps/wolnelektury_core/templates/publish_plan.html rename to src/wolnelektury/templates/publish_plan.html diff --git a/apps/wolnelektury_core/templates/site_base.html b/src/wolnelektury/templates/site_base.html similarity index 100% rename from apps/wolnelektury_core/templates/site_base.html rename to src/wolnelektury/templates/site_base.html diff --git a/apps/wolnelektury_core/templates/socialaccount/connections.html b/src/wolnelektury/templates/socialaccount/connections.html similarity index 100% rename from apps/wolnelektury_core/templates/socialaccount/connections.html rename to src/wolnelektury/templates/socialaccount/connections.html diff --git a/apps/wolnelektury_core/templates/socialaccount/login_cancelled.html b/src/wolnelektury/templates/socialaccount/login_cancelled.html similarity index 100% rename from apps/wolnelektury_core/templates/socialaccount/login_cancelled.html rename to src/wolnelektury/templates/socialaccount/login_cancelled.html diff --git a/apps/wolnelektury_core/templates/socialaccount/snippets/login_extra.html b/src/wolnelektury/templates/socialaccount/snippets/login_extra.html similarity index 100% rename from apps/wolnelektury_core/templates/socialaccount/snippets/login_extra.html rename to src/wolnelektury/templates/socialaccount/snippets/login_extra.html diff --git a/apps/wolnelektury_core/templates/socialaccount/snippets/provider_list.html b/src/wolnelektury/templates/socialaccount/snippets/provider_list.html similarity index 100% rename from apps/wolnelektury_core/templates/socialaccount/snippets/provider_list.html rename to src/wolnelektury/templates/socialaccount/snippets/provider_list.html diff --git a/apps/wolnelektury_core/templates/superbase.html b/src/wolnelektury/templates/superbase.html similarity index 100% rename from apps/wolnelektury_core/templates/superbase.html rename to src/wolnelektury/templates/superbase.html diff --git a/apps/wolnelektury_core/templates/user.html b/src/wolnelektury/templates/user.html similarity index 100% rename from apps/wolnelektury_core/templates/user.html rename to src/wolnelektury/templates/user.html diff --git a/apps/wolnelektury_core/templates/widget.html b/src/wolnelektury/templates/widget.html similarity index 100% rename from apps/wolnelektury_core/templates/widget.html rename to src/wolnelektury/templates/widget.html diff --git a/wolnelektury/migrations/piston/__init__.py b/src/wolnelektury/templatetags/__init__.py similarity index 100% rename from wolnelektury/migrations/piston/__init__.py rename to src/wolnelektury/templatetags/__init__.py diff --git a/apps/wolnelektury_core/templatetags/common_tags.py b/src/wolnelektury/templatetags/common_tags.py similarity index 100% rename from apps/wolnelektury_core/templatetags/common_tags.py rename to src/wolnelektury/templatetags/common_tags.py diff --git a/apps/wolnelektury_core/templatetags/switch_tag.py b/src/wolnelektury/templatetags/switch_tag.py similarity index 100% rename from apps/wolnelektury_core/templatetags/switch_tag.py rename to src/wolnelektury/templatetags/switch_tag.py diff --git a/wolnelektury/urls.py b/src/wolnelektury/urls.py similarity index 87% rename from wolnelektury/urls.py rename to src/wolnelektury/urls.py index a77a3d1b4..58e45ddb2 100644 --- a/wolnelektury/urls.py +++ b/src/wolnelektury/urls.py @@ -6,10 +6,10 @@ from django.conf.urls import include, patterns, url from django.conf import settings from django.contrib import admin from django.views.generic import RedirectView -import wolnelektury_core.views +import wolnelektury.views -urlpatterns = patterns('wolnelektury_core.views', +urlpatterns = patterns('wolnelektury.views', url(r'^$', 'main_page', name='main_page'), url(r'^planowane/$', 'publish_plan', name='publish_plan'), url(r'^widget\.html$', 'widget', name='widget'), @@ -18,14 +18,14 @@ urlpatterns = patterns('wolnelektury_core.views', # Authentication url(r'^uzytkownik/$', 'user_settings', name='user_settings'), - url(r'^uzytkownik/login/$', wolnelektury_core.views.LoginFormView(), name='login'), - url(r'^uzytkownik/signup/$', wolnelektury_core.views.RegisterFormView(), name='register'), + url(r'^uzytkownik/login/$', wolnelektury.views.LoginFormView(), name='login'), + url(r'^uzytkownik/signup/$', wolnelektury.views.RegisterFormView(), name='register'), url(r'^uzytkownik/logout/$', 'logout_then_redirect', name='logout'), - url(r'^uzytkownik/zaloguj-utworz/$', wolnelektury_core.views.LoginRegisterFormView(), name='login_register'), + url(r'^uzytkownik/zaloguj-utworz/$', wolnelektury.views.LoginRegisterFormView(), name='login_register'), # Includes. url(r'^latests_blog_posts.html$', - wolnelektury_core.views.latest_blog_posts, + wolnelektury.views.latest_blog_posts, name='latest_blog_posts'), ) diff --git a/wolnelektury/utils.py b/src/wolnelektury/utils.py similarity index 100% rename from wolnelektury/utils.py rename to src/wolnelektury/utils.py diff --git a/apps/wolnelektury_core/views.py b/src/wolnelektury/views.py similarity index 100% rename from apps/wolnelektury_core/views.py rename to src/wolnelektury/views.py diff --git a/wolnelektury/wsgi.py b/src/wolnelektury/wsgi.py similarity index 80% rename from wolnelektury/wsgi.py rename to src/wolnelektury/wsgi.py index d688df00f..01a8e1747 100644 --- a/wolnelektury/wsgi.py +++ b/src/wolnelektury/wsgi.py @@ -6,10 +6,7 @@ ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Add apps and lib directories to PYTHONPATH sys.path = [ - ROOT, - os.path.join(ROOT, 'apps'), - os.path.join(ROOT, 'lib'), - os.path.join(ROOT, 'lib/librarian'), + os.path.join(ROOT, '../lib/librarian'), ] + sys.path diff --git a/wolnelektury/__init__.py b/wolnelektury/__init__.py deleted file mode 100644 index cf2e85f6d..000000000 --- a/wolnelektury/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .celery import app as celery_app diff --git a/wolnelektury/settings/paths.py b/wolnelektury/settings/paths.py deleted file mode 100644 index b3ef30438..000000000 --- a/wolnelektury/settings/paths.py +++ /dev/null @@ -1,3 +0,0 @@ -from os import path - -PROJECT_DIR = path.dirname(path.abspath(path.dirname(__file__))) -- 2.20.1 From 87e084d47c335cd6f0b3e91d614999f55d148044 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Thu, 31 Dec 2015 22:07:56 +0100 Subject: [PATCH 02/16] Generally working version. --- fabfile.py | 8 + src/ajaxable/templates/ajaxable/form.html | 4 +- .../templates/ajaxable/form_on_page.html | 4 + src/catalogue/constants.py | 10 + src/catalogue/helpers.py | 112 +++-- src/catalogue/locale/pl/LC_MESSAGES/django.mo | Bin 11408 -> 11446 bytes src/catalogue/locale/pl/LC_MESSAGES/django.po | 462 ++++++++++-------- .../management/commands/importbooks.py | 125 ++--- src/catalogue/models/book.py | 12 +- src/catalogue/models/collection.py | 11 + src/catalogue/models/tag.py | 15 +- .../static/jplayer/jplayer.blue.monday.css | 30 +- src/catalogue/static/player/player.js | 45 +- src/catalogue/tasks.py | 6 + .../templates/catalogue/audiobook_list.html | 24 +- .../templates/catalogue/book_detail.html | 42 +- .../templates/catalogue/book_short.html | 158 ++++-- .../templates/catalogue/book_wide.html | 49 -- .../templates/catalogue/catalogue.html | 23 +- .../templates/catalogue/collection.html | 17 +- .../templates/catalogue/collection_box.html | 21 + .../templates/catalogue/collections.html | 22 + .../templates/catalogue/inline_tag_list.html | 36 +- src/catalogue/templates/catalogue/menu.html | 41 -- .../templates/catalogue/plain_list.html | 19 + src/catalogue/templates/catalogue/player.html | 8 +- .../catalogue/search_multiple_hits.html | 42 +- .../snippets/custom_pdf_link_li.html | 5 +- .../templates/catalogue/tag_box.html | 13 + .../templates/catalogue/tag_catalogue.html | 23 + .../catalogue/tagged_object_list.html | 220 ++++----- src/catalogue/templatetags/catalogue_tags.py | 80 ++- src/catalogue/urls.py | 14 +- src/catalogue/utils.py | 12 - src/catalogue/views.py | 271 +++++----- src/picture/models.py | 22 + .../templates/picture/picture_short.html | 10 +- .../templates/picture/picture_viewer.html | 16 +- .../templates/picture/picture_wide.html | 15 - src/search/templatetags/search_tags.py | 7 +- src/wolnelektury/celery.py | 4 +- .../locale/pl/LC_MESSAGES/django.mo | Bin 8707 -> 7526 bytes .../locale/pl/LC_MESSAGES/django.po | 436 +++++++++-------- src/wolnelektury/settings/custom.py | 5 + src/wolnelektury/settings/static.py | 7 + src/wolnelektury/static/js/base.js | 75 ++- .../static/js/contrib/jquery.paging.min.js | 14 + .../static/scss/book_text/menu.scss | 2 + src/wolnelektury/static/scss/main/base.scss | 54 +- .../static/scss/main/book_box.scss | 129 ++--- .../static/scss/main/dialogs.scss | 6 +- src/wolnelektury/static/scss/main/header.scss | 213 +++++--- .../static/scss/main/main_page.scss | 123 ++--- src/wolnelektury/static/scss/main/menu.scss | 251 +++++----- .../static/scss/main/picture_box.scss | 11 +- src/wolnelektury/static/scss/main/tag.scss | 85 +++- .../static/scss/social/shelf_tags.scss | 22 +- src/wolnelektury/templates/account/base.html | 2 + src/wolnelektury/templates/main_page.html | 74 ++- .../templates/socialaccount/connections.html | 3 +- .../socialaccount/login_cancelled.html | 4 +- src/wolnelektury/templates/superbase.html | 89 ++-- src/wolnelektury/templates/user.html | 3 +- src/wolnelektury/views.py | 40 +- 64 files changed, 2196 insertions(+), 1510 deletions(-) create mode 100644 src/catalogue/templates/catalogue/collection_box.html create mode 100644 src/catalogue/templates/catalogue/collections.html delete mode 100644 src/catalogue/templates/catalogue/menu.html create mode 100644 src/catalogue/templates/catalogue/plain_list.html create mode 100644 src/catalogue/templates/catalogue/tag_box.html create mode 100644 src/catalogue/templates/catalogue/tag_catalogue.html create mode 100644 src/wolnelektury/static/js/contrib/jquery.paging.min.js diff --git a/fabfile.py b/fabfile.py index a7bc768ab..e614e9ce5 100644 --- a/fabfile.py +++ b/fabfile.py @@ -19,6 +19,14 @@ def production(): ] +@task +def beta(): + env.hosts = ['giewont.icm.edu.pl'] + env.user = 'lektury' + env.app_path = '/srv/wolnelektury.pl/beta' + env.services = [] + + @task def staging(): env.hosts = ['san.nowoczesnapolska.org.pl:2223'] diff --git a/src/ajaxable/templates/ajaxable/form.html b/src/ajaxable/templates/ajaxable/form.html index 13586ac9d..963f411f7 100755 --- a/src/ajaxable/templates/ajaxable/form.html +++ b/src/ajaxable/templates/ajaxable/form.html @@ -17,4 +17,6 @@ -{% block extra %}{% endblock %} \ No newline at end of file +
+{% block extra %}{% endblock %} +
diff --git a/src/ajaxable/templates/ajaxable/form_on_page.html b/src/ajaxable/templates/ajaxable/form_on_page.html index 61175d507..8e495234a 100755 --- a/src/ajaxable/templates/ajaxable/form_on_page.html +++ b/src/ajaxable/templates/ajaxable/form_on_page.html @@ -5,10 +5,14 @@ {% block body %} +
+ {% include ajax_template %} {% if response_data.message %}

{{ response_data.message }}

{% endif %} +
+ {% endblock %} diff --git a/src/catalogue/constants.py b/src/catalogue/constants.py index 36f4f5dd3..d1a5ddee3 100644 --- a/src/catalogue/constants.py +++ b/src/catalogue/constants.py @@ -36,3 +36,13 @@ LANGUAGES_3TO2 = { 'rus': 'ru', 'ukr': 'uk', } + +CATEGORIES_NAME_PLURAL = { + 'author': _('authors'), + 'epoch': _('epochs'), + 'kind': _('kinds'), + 'genre': _('genres'), + 'theme': _('themes'), + 'set': _('sets'), + 'thing': _('things'), +} diff --git a/src/catalogue/helpers.py b/src/catalogue/helpers.py index 7ca2cbd3a..b48c483ea 100644 --- a/src/catalogue/helpers.py +++ b/src/catalogue/helpers.py @@ -2,57 +2,91 @@ # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # +from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.db.models import Count from .models import Tag, Book +from os.path import getmtime +import cPickle +from collections import defaultdict + BOOK_CATEGORIES = ('author', 'epoch', 'genre', 'kind') -def get_top_level_related_tags(tags=None, categories=BOOK_CATEGORIES): +_COUNTERS = None +_COUNTER_TIME = None +def get_top_level_related_tags(tags, categories=None): """ Finds tags related to given tags through books, and counts their usage. Takes ancestry into account: if a tag is applied to a book, its usage on the book's descendants is ignored. + """ + global _COUNTERS, _COUNTER_TIME + # First, check that we have a valid and recent version of the counters. + if getmtime(settings.CATALOGUE_COUNTERS_FILE) > _COUNTER_TIME: + with open(settings.CATALOGUE_COUNTERS_FILE) as f: + _COUNTERS = cPickle.load(f) - This is tested for PostgreSQL 9.1+, and might not work elsewhere. - It particular, it uses raw SQL using WITH clause, which is - supported in SQLite from v. 3.8.3, and is missing in MySQL. - http://bugs.mysql.com/bug.php?id=16244 + tagids = tuple(sorted(t.pk for t in tags)) + try: + related_ids = _COUNTERS['next'][tagids] + except KeyError: + return - """ - # First, find all tag relations of relevant books. - bct = ContentType.objects.get_for_model(Book) - relations = Tag.intermediary_table_model.objects.filter( - content_type=bct) - if tags is not None: - tagged_books = Book.tagged.with_all(tags).only('pk') - relations = relations.filter( - object_id__in=tagged_books).exclude( - tag_id__in=[tag.pk for tag in tags]) - - rel_sql, rel_params = relations.query.sql_with_params() - - # Exclude those relations between a book and a tag, - # for which there is a relation between the book's ancestor - # and the tag and - - return Tag.objects.raw(''' - WITH AllTagged AS (''' + rel_sql + ''') - SELECT catalogue_tag.*, COUNT(catalogue_tag.id) AS count - FROM catalogue_tag, AllTagged - WHERE catalogue_tag.id=AllTagged.tag_id - AND catalogue_tag.category IN %s - AND NOT EXISTS ( - SELECT AncestorTagged.id - FROM catalogue_book_ancestor Ancestor, - AllTagged AncestorTagged - WHERE Ancestor.from_book_id=AllTagged.object_id - AND AncestorTagged.content_type_id=%s - AND AncestorTagged.object_id=Ancestor.to_book_id - AND AncestorTagged.tag_id=AllTagged.tag_id - ) - GROUP BY catalogue_tag.id - ORDER BY sort_key''', rel_params + (categories, bct.pk)) + related = Tag.objects.filter(pk__in=related_ids) + + # TODO: do we really need that? + if categories is not None: + related = related.filter(category__in=categories) + + for tag in related: + tag.count = _COUNTERS['count'][tuple(sorted(tagids + (tag.pk,)))] + yield tag + + #~ return related + + +def update_counters(): + def combinations(things): + if len(things): + for c in combinations(things[1:]): + yield c + yield (things[0],) + c + else: + yield () + + def count_for_book(book, count_by_combination=None, parent_combinations=None): + if not parent_combinations: + parent_combinations = set() + tags = sorted(tuple(t.pk for t in book.tags.filter(category__in=('author', 'genre', 'epoch', 'kind')))) + combs = list(combinations(tags)) + for c in combs: + if c not in parent_combinations: + count_by_combination[c] += 1 + combs_for_child = set(list(parent_combinations) + combs) + for child in book.children.all(): + count_for_book(child, count_by_combination, combs_for_child) + + count_by_combination = defaultdict(lambda: 0) + for b in Book.objects.filter(parent=None): + count_for_book(b, count_by_combination) + + next_combinations = defaultdict(set) + # Now build an index of all combinations. + for c in count_by_combination.keys(): + if not c: + continue + for n in c: + rest = tuple(x for x in c if x != n) + next_combinations[rest].add(n) + + counters = { + "count": dict(count_by_combination), + "next": dict(next_combinations), + } + + with open(settings.CATALOGUE_COUNTERS_FILE, 'w') as f: + cPickle.dump(counters, f) diff --git a/src/catalogue/locale/pl/LC_MESSAGES/django.mo b/src/catalogue/locale/pl/LC_MESSAGES/django.mo index 739f69b2dc8f80c2682a68903642c812357744f6..b45c14e211736437b73786eeb1a37f5d99f7b3b5 100644 GIT binary patch delta 4399 zcmYk833OD|8OLuRtYHa+lqEn0NFX7sh9HZ|S_Ncnltn5qnLNm3nK#S=CejXztVIew z5Rk1EutJNL2EkMC^iV>}Dabk1+DcViDn$=;q1IC9Y3c7jb2)Gi|M}f}-@V`cmiu1V zJm>hF#O3zs+YIe>)D>-QV$7GYRR%w_pSCfk6Fdr=!Qa5P@EzD5eg<2>uVDea1DnDE z7PW)};UqW$4u`8@G5iH&UBY}tM}}`h8ETYiOmo-@Hip@-Gwck%0gGWioCLeUFzf<1 zLD@M3<@-@6dv8HG^lM0L<|6C}e+OG~zPV0E8*V~;Fpb+8GX!Qq8Ju7_9kyaT8_Gck z^3R0$=>V5Qf;Zb>7Cd0*--HU_ZTtKx)c$|LY|b}#=*WR=@~MqIpdu`RO5t3n5-hai z1Z0cZ02R@0s0d$%T6YL4kY7S&;2kK(KZFYCOQ?M}U_u*j(rFF<2fM>oc%g+wP^m43 z>2NC4#!{#V=0K&g3~GHH)cTcB5$}P@%n7JKE6zj`~u4GHAorFEvVbwhPr8g4wSt-sQrad>j&ET zhoLe(HaVvLrF0a*Z2O=bYC{~#;3}vO(MBl4n=QB5=PyAyxF0HmhoRR03~K#xC`V30 ztvhYU=QP&)f6-372esh?D2G0Q=cw^@*pu-a6j}$o4|O>|fr{iS%XHq|0>;@;2R;H- z!tro2oCXKO-LN0L2oqZPA38FemYYg_3#gQ4K|S|D?u+RS$+j5{eQ+++2WJ`7CEEs7 zx+72-JOO3*tmWI5??LXj`6!qAE5-k0Li{h3p{Bl+$K9bKsDd)Q1S<07P#N-|?!Z1M zgU6trpN9(IGSscV24(j))cW>4QjYcMkw`@_kO^&=0QEXP3Gu}Qp$=XTRRRyn&~c~( zFG6MLisdz!&-eyZX*#k=4is2E2$hjXEvHVmotbvQJg9?fpdx=B%HthSm*)tSfn#=j z3KlUw1GWBd-p*zt6UxnoUa4HX2<7r2sM~eg&i@K(-6hK_cK!xbEzS724Xx1o7u zqBq@TefZmu#;XN+YPJ-nww{10*99maEW zK2|58%5>h&|FJI@Qwu(4Ldp26fmRg4q5@VejU^SFWC7# zQ2P!*Iq)i^!pWP`AF2fr@u&U*mP38Dwxc0PckDs*Fe*iABT_JZ;5-ztV`V@s1L*^% zQt_AC)FHJgXd9Y{UP5X=L2LN)kR0eob-usp`=FBCZS!qs6?`5YLcLMMYu7r<^R-S- z%w(iC1C2&}uam8U-yLWa+JmT3^3{44s?A2PqAjQpsf|N?T+C7pXg^5)@*e~kM=ek# zdJ(BnyM%d^jy}{+BNgYnNNsuw$wH{B!n}rdqL)TW|^$sX^PrBH*y zXee5a_99!#)Gg3(B>JH`v>ze8cz4@6I&;u0H0Wf+-ADWEH&>$2;!_hP7FlvN$qgtf)N(#w8 z>c#Yzp#f+kit6p?NoOBY`yT3!(lxN{09=f6&>~cYzK@!FC2b0O2i)pvClCv|p{N;C zUG1y!#{w0>&?4VbH&T_FqF3*4(=@Hcm?i#TwZE*|@fNmyt4W0$bwb{V%tCK=W~p~H z^Y`A7cE`M$_6xd93@vmc7{aK}U*^VRzF38mH0WJuKfvpsmEn!bdbYK%+=&Jv!LZg1 z@J?j)^FGR&)Yu=1dHEgs)X(j(GOhm8?7?aEc^%(q)HPJ@%P$BNMtwDI#4-MOtip|0 zM7_(MYrBTsKtM2_jT#gbdeK^I8pD-E@PWi1w-Xg?^c)mF(Eb> zcVW`OGS{s#xID|P4mrNbPE{-(sWoAL#0kZGp?FQ16EWe4vn1%oqbBOaq^LJCXJALC z#)+Dk(w6#V5R7r`vYZ8(CH)6K(7$-FZ}89&LrRJU4fd|*bZT|~WPN7Wv1w_;ywYyN zJ6E~YPF0}NG1L9gcxA)tfa8nD$bW79if$BOyc>-*>Mf~(jbNi(E zy-04@`y%&q?`z-t-lZPlEL#MO`P`I|I`6Tb<6BM)#hgfWFckEAw|Z{L7#s0d`P^_Y z8Xw@T@6|7TVhD@JdW~v6uC8I{*h!*yl$4b+#N! zgAF?aPNhnbDu^4YtMv}{UDLz~yH!E2Z&8j{SCrFikv|p>G2U8K+AQLh*ZC_Q@6SaA zQ$qe!NPd$HG;WqA^IsdNuodtJDh$bYB0g;k2K*-Mh9h-OIT4ufnfkLUtL~E1`i&^5 mabvYhshif+1l`!ZUag7M#^PsJg0T5)%@*IHGxgjSdglLun_Qg$ delta 4310 zcmY+G3vg7`8OKi`2q6$42@ewvRRVs#@)L>QgAUK zRuBrkV5zN&MQLeeN}Jj$Wu{n4wRRY%t##0;DB2O}XkXSkQ2O}&vxkRg=D)x5{LXj2 z@7y!{lbXFXsq?v+2MpyX8i+z&jCmhE*PS2Aq#R=gz{#*HTne+`N;ndR;4N@B)RO&h zK70yJhJS|RVR5hYycJM(*1&GYq)eDfXF8hUt_Ph!#6xoy_JMD}eE1>c zQ06}{5B6YC{SMRtCP0lZhFZTG_Jv`n18sqF=rGJ4BDErBw;7Ahi*PzTunb--;<>vut|-v?7YsT`y-7#@L|cm`&|vrr3u z2X&HjP$9hlb)w5qccvF%(7Mr3hO3}bH5Do%%b_CF40XVVpyuz*BmNx@(7|EN5vb6; z0CfjmhC11KsCj>}<5!_J$i}K1DS=uy&2juHE~t$TLEYk`P#d(vPVhyj4NgMMe--MMzXP@IBd85Ng_?K8 zw!4vEMYt!FA_l)zNSv)Vvlb2UAdy zc-Z#uhh)t>4he$!F?8T-Q18ayU`m%FYe+iOL!m-e24!$ERBEbi`!2|RH1|QBFafoG zGn9k-p&YsZ<@iOY6#fIs&Q+*L^m5XvD|Cpz3|7#g33H%MuoCK)hM_jt0F~=KP>vmj zI>Gm$BKAwDbss~0O;;d$nVg|%2gX2!d=iwsd!hDC3{9my-bsf%-wTJs$DmSj63XMV zP!7Fm`5}}epIQFTvMal2UN0yI217++I@Dd72eodAZLb(frHqa>a1`7HE8z1`3qODg z_1}Y+x=u|gMmvY4&+r6P`*|oAU$K1M_P+}ii%)F3YjJvh0n`!8;WW4mD(QP6H`6=` zbz4qAt^WhmQ7#pm+d4MPVzq)d5GpC-E$2d=aTPoQL$;k=5}fF^KBdQD^N93&{3!f5 zgKru#%RJ4|W$I<9JpK{Nr%O=dpFyQ#P$_RY90R++Lof>-fwF%bD*UHx|7(_SmU7V) z#`ozEKeGH3>Q(wLl!4ylA`?1L8w`hXtjzY$fZFg5$kT2X+i?%dZmS*N29@XCusb|Z z#zoV~4$+}^`xwlIuRPkdZKUesSJJJ+|htUJ*4y2-sH5Tc5&>h*#9a(M+@ieF3TH;|X`v z^k0GfYiaO=n|bIi^b8t_79xExx)&-6`9r_nc&UX<^khtcDj-b_X1A;k6P-Ak7zz&=~Q7v74#if%`} zk;-(m3iU%J=vtX(D{Emc+GyK#un6r!U+?JCy`jwL_~mbh7#zzP)wwnnYrmRvOGeP6 z_sRaQ?>5H5NzaL`bNqVGX^hmy-FQoIw)dzYqtD#T>Uqm*f;oN86*e|HZZZ^!vAQAQ ztc%5&9!WTA2Kl)^?;ff1BeCdAHGi918{C;!UgG**!gm%e8GqACvoPJeI2?AC$Kth- zL=epz(8-Gi59VzR`s9xaX5`Nb9?2ixv(a-Cp0m-7`0s5!(*9ij_Kfz?{U&7Ocuiiy zaibx}k2Oc?+E?{|u~V0%UmuGH;|f}W9~JbUk8cYi(NLpjjdcz&?I zaBOZQ8a95!XH!4sG{+-RKX|KfZB-2s<=?~!8a0Q=0$xk-WZ8ST(j&2v~!c|x3`Yy*SU+E^vTch(jCFHvVz4?_ga2JF{jlHxo5UJiDs{E zz1tXVsjD}P*R{6z(MW?$)9Ln&*E4gy(qh7{pNx79!KSih!SBmP3{0QWkQguS#ABh> zNS$k%Pq&|GYjA@(qo<5+j<\n" "Language-Team: Fundacja Nowoczesna Polska \n" @@ -15,13 +15,41 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Translated-Using: django-rosetta 0.5.6\n" -"X-Generator: Poedit 1.5.4\n" +"X-Generator: Poedit 1.8.4\n" #: constants.py:10 msgid "Creative Commons Attribution-ShareAlike 3.0 Unported" msgstr "" "Creative Commons Uznanie autorstwa – Na tych samych warunkach 3.0 Unported" +#: constants.py:41 +msgid "authors" +msgstr "autorzy" + +#: constants.py:42 +msgid "epochs" +msgstr "epoki" + +#: constants.py:43 +msgid "kinds" +msgstr "rodzaje" + +#: constants.py:44 +msgid "genres" +msgstr "gatunki" + +#: constants.py:45 +msgid "themes" +msgstr "motywy" + +#: constants.py:46 +msgid "sets" +msgstr "półki" + +#: constants.py:47 +msgid "things" +msgstr "przedmioty" + #: forms.py:27 msgid "Please supply an XML." msgstr "Proszę podać XML." @@ -74,7 +102,7 @@ msgstr "Duży" msgid "Queue is full. Please try again later." msgstr "Kolejka jest pełna. Proszę spróbować ponownie później." -#: models/book.py:43 models/collection.py:13 +#: models/book.py:43 models/collection.py:14 msgid "title" msgstr "tytuł" @@ -87,8 +115,8 @@ msgstr "klucz sortowania" msgid "sort key by author" msgstr "Znalezieni autorzy" -#: models/book.py:46 models/book.py:48 models/collection.py:14 -#: models/collection.py:17 models/tag.py:34 +#: models/book.py:46 models/book.py:48 models/collection.py:15 +#: models/collection.py:18 models/tag.py:34 msgid "slug" msgstr "slug" @@ -96,8 +124,8 @@ msgstr "slug" msgid "language code" msgstr "Kod języka" -#: models/book.py:51 models/book.py:160 models/collection.py:15 -#: models/tag.py:38 models/tag.py:144 +#: models/book.py:51 models/book.py:169 models/collection.py:16 +#: models/tag.py:38 models/tag.py:154 msgid "description" msgstr "opis" @@ -122,7 +150,7 @@ msgstr "okładka" msgid "cover thumbnail" msgstr "podgląd okładki" -#: models/book.py:92 models/collection.py:20 +#: models/book.py:92 models/collection.py:21 msgid "book" msgstr "książka" @@ -130,21 +158,21 @@ msgstr "książka" msgid "books" msgstr "książki" -#: models/book.py:258 +#: models/book.py:267 #, python-format msgid "Book \"%s\" does not exist." msgstr "Utwór \"%s\" nie istnieje." -#: models/book.py:272 +#: models/book.py:281 #, python-format msgid "Book %s already exists" msgstr "Książka %s już istnieje" -#: models/book.py:519 +#: models/book.py:529 msgid "This work needs modernisation" msgstr "Ten utwór wymaga uwspółcześnienia" -#: models/book.py:546 models/bookmedia.py:27 +#: models/book.py:556 models/bookmedia.py:27 #, python-format msgid "%s file" msgstr "plik %s" @@ -165,19 +193,19 @@ msgstr "plik" msgid "book media" msgstr "media książki" -#: models/collection.py:18 +#: models/collection.py:19 msgid "book slugs" msgstr "slugi utworów" -#: models/collection.py:20 models/tag.py:20 +#: models/collection.py:21 models/tag.py:20 msgid "kind" msgstr "rodzaj" -#: models/collection.py:24 +#: models/collection.py:25 msgid "collection" msgstr "kolekcja" -#: models/collection.py:25 +#: models/collection.py:26 msgid "collections" msgstr "kolekcje" @@ -237,18 +265,20 @@ msgstr "tag" msgid "tags" msgstr "tagi" -#: templates/catalogue/audiobook_list.html:8 -#: templates/catalogue/audiobook_list.html:17 +#: templates/catalogue/audiobook_list.html:6 +#: templates/catalogue/audiobook_list.html:11 +msgid "Audiobooks" +msgstr "Audiobooki" + +#: templates/catalogue/audiobook_list.html:14 msgid "Listing of all audiobooks" msgstr "Spis wszystkich audiobooków" -#: templates/catalogue/audiobook_list.html:13 -msgid "Latest MP3 audiobooks" -msgstr "Ostatnio dodane audiobooki w formacie MP3" - -#: templates/catalogue/audiobook_list.html:14 -msgid "Latest Ogg Vorbis audiobooks" -msgstr "Ostatnio dodane audiobooki w formacie Ogg Vorbis" +#: templates/catalogue/audiobook_list.html:17 +#: templates/catalogue/daisy_list.html:7 +#: templates/catalogue/daisy_list.html:13 +msgid "Listing of all DAISY files" +msgstr "Spis wszystkich plików DAISY" #: templates/catalogue/book_detail.html:23 #: templates/catalogue/book_text.html:20 @@ -256,11 +286,55 @@ msgid "Other versions" msgstr "Inne wersje" #: templates/catalogue/book_detail.html:31 -#: templates/catalogue/tagged_object_list.html:75 -#: templates/catalogue/tagged_object_list.html:118 msgid "See also" msgstr "Zobacz też" +#: templates/catalogue/book_detail.html:40 +#: templates/catalogue/book_text.html:30 +#: templates/catalogue/tagged_object_list.html:24 +msgid "Themes" +msgstr "Motywy" + +#: templates/catalogue/book_detail.html:47 +msgid "Information about the work" +msgstr "Informacje o utworze" + +#: templates/catalogue/book_detail.html:58 +msgid "Source" +msgstr "Źródło" + +#: templates/catalogue/book_detail.html:58 +msgid "of the book" +msgstr "utworu" + +#: templates/catalogue/book_detail.html:59 +msgid "in" +msgstr "w serwisie" + +#: templates/catalogue/book_detail.html:61 +msgid "Source XML file" +msgstr "Źródłowy plik XML" + +#: templates/catalogue/book_detail.html:63 +msgid "Book on" +msgstr "Utwór na" + +#: templates/catalogue/book_detail.html:63 +msgid "Editor's Platform" +msgstr "Platformie Redakcyjnej" + +#: templates/catalogue/book_detail.html:66 +msgid "Book description on Lektury.Gazeta.pl" +msgstr "Opis lektury w Lektury.Gazeta.pl" + +#: templates/catalogue/book_detail.html:69 +msgid "Book description on Wikipedia" +msgstr "Opis lektury w Wikipedii" + +#: templates/catalogue/book_detail.html:71 +msgid "Mix this book" +msgstr "Miksuj treść utworu" + #: templates/catalogue/book_fragments.html:5 #: templates/catalogue/book_fragments.html:11 msgid "Theme" @@ -350,43 +424,34 @@ msgstr "Język" msgid "Read online" msgstr "Czytaj online" -#: templates/catalogue/book_short.html:101 -#: templates/catalogue/book_wide.html:72 views.py:594 +#: templates/catalogue/book_short.html:101 views.py:588 msgid "Download" msgstr "Pobierz" -#: templates/catalogue/book_short.html:104 -msgid "to print" -msgstr "do druku" - -#: templates/catalogue/book_short.html:107 -msgid "for an e-book reader" -msgstr "na czytnik e-booków" +#: templates/catalogue/book_short.html:173 templates/catalogue/player.html:84 +msgid "Artist" +msgstr "Czyta" -#: templates/catalogue/book_short.html:110 -msgid "for Kindle" -msgstr "na Kindle" +#: templates/catalogue/book_short.html:174 templates/catalogue/player.html:85 +msgid "Director" +msgstr "Reżyseruje" -#: templates/catalogue/book_short.html:113 -msgid "FictionBook" -msgstr "FictionBook" +#: templates/catalogue/book_short.html:190 +msgid "previous" +msgstr "poprzednia" -#: templates/catalogue/book_short.html:116 -msgid "for advanced usage" -msgstr "do zadań specjalnych" +#: templates/catalogue/book_short.html:191 +msgid "Part" +msgstr "Część" -#: templates/catalogue/book_short.html:122 -msgid "Listen" -msgstr "Słuchaj" +#: templates/catalogue/book_short.html:192 +msgid "next" +msgstr "następna" #: templates/catalogue/book_text.html:26 msgid "Table of contents" msgstr "Spis treści" -#: templates/catalogue/book_text.html:30 templatetags/catalogue_tags.py:336 -msgid "Themes" -msgstr "Motywy" - #: templates/catalogue/book_text.html:34 templates/catalogue/book_text.html:91 msgid "Settings" msgstr "Ustawienia" @@ -428,104 +493,50 @@ msgstr "Wyświetlaj motywy" msgid "Display footnotes" msgstr "Wyświetlaj przypisy" -#: templates/catalogue/book_wide.html:23 -#: templates/catalogue/tagged_object_list.html:61 -msgid "Motifs and themes" -msgstr "Motywy i tematy" - -#: templates/catalogue/book_wide.html:52 -msgid "See" -msgstr "Zobacz" - -#: templates/catalogue/book_wide.html:55 -msgid "Source" -msgstr "Źródło" - -#: templates/catalogue/book_wide.html:55 -msgid "of the book" -msgstr "utworu" - -#: templates/catalogue/book_wide.html:56 -msgid "in" -msgstr "w serwisie" - -#: templates/catalogue/book_wide.html:58 -msgid "Source XML file" -msgstr "Źródłowy plik XML" - -#: templates/catalogue/book_wide.html:60 -msgid "Book on" -msgstr "Utwór na" - -#: templates/catalogue/book_wide.html:60 -msgid "Editor's Platform" -msgstr "Platformie Redakcyjnej" - -#: templates/catalogue/book_wide.html:63 -msgid "Book description on Lektury.Gazeta.pl" -msgstr "Opis lektury w Lektury.Gazeta.pl" - -#: templates/catalogue/book_wide.html:66 -msgid "Book description on Wikipedia" -msgstr "Opis lektury w Wikipedii" - -#: templates/catalogue/book_wide.html:68 -msgid "Mix this book" -msgstr "Miksuj treść utworu" - -#: templates/catalogue/book_wide.html:76 -msgid "Download all audiobooks for this book" -msgstr "Pobierz wszystkie audiobooki tego utworu" - -#: templates/catalogue/catalogue.html:6 templates/catalogue/catalogue.html:11 -#: templates/catalogue/menu.html:6 +#: templates/catalogue/catalogue.html:6 msgid "Catalogue" msgstr "Katalog" -#: templates/catalogue/catalogue.html:16 +#: templates/catalogue/catalogue.html:11 +msgid "All works" +msgstr "Wszystkie utwory" + +#: templates/catalogue/catalogue.html:17 msgid "Download the catalogue in PDF format." msgstr "Pobierz katalog w formacie PDF." -#: templates/catalogue/catalogue.html:19 -#: templates/catalogue/search_multiple_hits.html:20 -#: templates/catalogue/tagged_object_list.html:27 -#: templatetags/catalogue_tags.py:332 -msgid "Authors" -msgstr "Autorzy" - -#: templates/catalogue/catalogue.html:22 -#: templates/catalogue/search_multiple_hits.html:28 -#: templates/catalogue/tagged_object_list.html:35 -#: templatetags/catalogue_tags.py:334 -msgid "Kinds" -msgstr "Rodzaje" +#: templates/catalogue/catalogue.html:20 +#: templates/catalogue/tag_list_split.html:3 +#: templates/catalogue/tagged_object_list.html:6 +#: templates/catalogue/tagged_object_list.html:14 +msgid "Literature" +msgstr "Literatura" -#: templates/catalogue/catalogue.html:25 -#: templates/catalogue/search_multiple_hits.html:36 -#: templates/catalogue/tagged_object_list.html:43 -#: templatetags/catalogue_tags.py:333 -msgid "Genres" -msgstr "Gatunki" +#: templates/catalogue/catalogue.html:23 +#: templates/catalogue/collections.html:6 +#: templates/catalogue/collections.html:11 +msgid "Collections" +msgstr "Kolekcje" -#: templates/catalogue/catalogue.html:28 -#: templates/catalogue/search_multiple_hits.html:44 -#: templates/catalogue/tagged_object_list.html:51 -#: templatetags/catalogue_tags.py:335 -msgid "Epochs" -msgstr "Epoki" +#: templates/catalogue/catalogue.html:26 +#: templates/catalogue/tag_list_split.html:8 +#: templates/catalogue/tagged_object_list.html:6 +#: templates/catalogue/tagged_object_list.html:14 +msgid "Gallery" +msgstr "Galeria" -#: templates/catalogue/catalogue.html:31 -msgid "Themes and topics" -msgstr "Motywy i tematy" +#: templates/catalogue/collection_box.html:5 +msgid "Collection" +msgstr "Kolekcja" -#: templates/catalogue/catalogue.html:34 templates/catalogue/menu.html:19 -msgid "Collections" -msgstr "Kolekcje" +#: templates/catalogue/collection_box.html:15 +#, python-format +msgid "and %(c)s more" +msgstr "oraz %(c)s więcej" -#: templates/catalogue/daisy_list.html:7 -#: templates/catalogue/daisy_list.html:13 -msgid "Listing of all DAISY files" -msgstr "Spis wszystkich plików DAISY" +#: templates/catalogue/collections.html:17 +msgid "All collections" +msgstr "Wszystkie kolekcje" #: templates/catalogue/daisy_list.html:10 msgid "Latest DAISY audiobooks" @@ -545,34 +556,18 @@ msgstr "Rozwiń fragment" msgid "Hide fragment" msgstr "Zwiń fragment" -#: templates/catalogue/inline_tag_list.html:4 -#: templates/catalogue/tag_list.html:6 -msgid "See full category" -msgstr "Zobacz całą kategorię" - -#: templates/catalogue/menu.html:5 -msgid "Catalogue of the library" -msgstr "Katalog biblioteki" +#: templates/catalogue/inline_tag_list.html:6 +msgid "Chosen" +msgstr "Wybrane" -#: templates/catalogue/menu.html:13 templates/catalogue/menu.html.py:21 -msgid "Please wait…" -msgstr "Proszę czekać…" +#: templates/catalogue/inline_tag_list.html:14 +#: templates/catalogue/inline_tag_list.html:23 +msgid "Available" +msgstr "Dostępne" -#: templates/catalogue/menu.html:26 -msgid "All books" -msgstr "Wszystkie utwory" - -#: templates/catalogue/menu.html:29 -msgid "Audiobooks" -msgstr "Audiobooki" - -#: templates/catalogue/menu.html:32 -msgid "DAISY" -msgstr "DAISY" - -#: templates/catalogue/menu.html:36 templates/catalogue/tag_list_split.html:8 -msgid "Gallery" -msgstr "Galeria" +#: templates/catalogue/inline_tag_list.html:32 +msgid "Other" +msgstr "Inne" #: templates/catalogue/picture_detail.html:29 msgid "Work is licensed under " @@ -622,31 +617,23 @@ msgstr "Strona utworu" msgid "Download as" msgstr "Pobierz jako" -#: templates/catalogue/player.html:88 -msgid "Artist" -msgstr "Czyta" - -#: templates/catalogue/player.html:89 -msgid "Director" -msgstr "Reżyseruje" - -#: templates/catalogue/player.html:108 +#: templates/catalogue/player.html:104 msgid "Audiobooks were prepared as a part of the projects:" msgstr "Audiobooki przygotowane w ramach projektów:" -#: templates/catalogue/player.html:113 +#: templates/catalogue/player.html:109 #, python-format msgid "%(cs)s, funded by %(fb)s" msgstr "%(cs)s, finansowanego przez %(fb)s" -#: templates/catalogue/player.html:125 +#: templates/catalogue/player.html:121 #, python-format msgid "" "Audiobooks were prepared as a part of the %(cs)s project funded by %(fb)s." msgstr "" "Audiobooki przygotowane w ramach projektu %(cs)s finansowanego przez %(fb)s." -#: templates/catalogue/player.html:127 +#: templates/catalogue/player.html:123 #, python-format msgid "Audiobooks were prepared as a part of the %(cs)s project." msgstr "Audiobooki przygotowane w ramach projektu %(cs)s." @@ -688,28 +675,48 @@ msgstr "Szukaj" msgid "Did you mean" msgstr "Czy chodziło Ci o" -#: templates/catalogue/search_multiple_hits.html:55 +#: templates/catalogue/search_multiple_hits.html:20 +#: templates/catalogue/tagged_object_list.html:19 +msgid "Authors" +msgstr "Autorzy" + +#: templates/catalogue/search_multiple_hits.html:30 +#: templates/catalogue/tagged_object_list.html:22 +msgid "Kinds" +msgstr "Rodzaje" + +#: templates/catalogue/search_multiple_hits.html:40 +#: templates/catalogue/tagged_object_list.html:21 +msgid "Genres" +msgstr "Gatunki" + +#: templates/catalogue/search_multiple_hits.html:50 +#: templates/catalogue/tagged_object_list.html:20 +msgid "Epochs" +msgstr "Epoki" + +#: templates/catalogue/search_multiple_hits.html:63 msgid "Results by title" msgstr "Znalezione w tytułach" -#: templates/catalogue/search_multiple_hits.html:70 +#: templates/catalogue/search_multiple_hits.html:78 msgid "Results by authors" msgstr "Znalezieni autorzy" -#: templates/catalogue/search_multiple_hits.html:83 +#: templates/catalogue/search_multiple_hits.html:91 msgid "Results by translators" msgstr "Znalezieni tłumacze" -#: templates/catalogue/search_multiple_hits.html:96 +#: templates/catalogue/search_multiple_hits.html:104 msgid "Results in text" msgstr "Znalezione w treści" -#: templates/catalogue/search_multiple_hits.html:113 +#: templates/catalogue/search_multiple_hits.html:121 msgid "Other results" msgstr "Inne wyniki" #: templates/catalogue/search_no_hits.html:19 -#: templates/catalogue/tagged_object_list.html:162 +#: templates/catalogue/tagged_object_list.html:61 msgid "Sorry! Search cirteria did not match any resources." msgstr "Przepraszamy! Brak wyników spełniających kryteria podane w zapytaniu." @@ -727,7 +734,7 @@ msgstr "" msgid "Sorry! Search query must have at least two characters." msgstr "Przepraszamy! Zapytanie musi zawierać co najmniej dwa znaki." -#: templates/catalogue/snippets/custom_pdf_link_li.html:5 +#: templates/catalogue/snippets/custom_pdf_link_li.html:3 msgid "Download a custom PDF" msgstr "Stwórz własny plik PDF" @@ -736,30 +743,43 @@ msgstr "Stwórz własny plik PDF" msgid "Free license" msgstr "Wolna licencja" -#: templates/catalogue/tag_list_split.html:3 -msgid "Literature" -msgstr "Literatura" +#: templates/catalogue/tag_catalogue.html:11 +msgid "on Wolne Lektury" +msgstr "w Wolnych Lekturach" -#: templates/catalogue/tagged_object_list.html:79 -#: templates/catalogue/tagged_object_list.html:132 -msgid "in Culture.pl" -msgstr "w Culture.pl" +#: templates/catalogue/tag_list.html:6 +msgid "See full category" +msgstr "Zobacz całą kategorię" -#: templates/catalogue/tagged_object_list.html:84 -#: templates/catalogue/tagged_object_list.html:122 +#: templates/catalogue/tagged_object_list.html:58 +msgid "All matching works" +msgstr "Pasujące utwory" + +#: templates/catalogue/tagged_object_list.html:70 +msgid "Motifs and themes" +msgstr "Motywy i tematy" + +#: templates/catalogue/tagged_object_list.html:87 +msgid "No description." +msgstr "Brak opisu." + +#: templates/catalogue/tagged_object_list.html:93 msgid "in Lektury.Gazeta.pl" msgstr "w serwisie Lektury.Gazeta.pl" -#: templates/catalogue/tagged_object_list.html:89 -#: templates/catalogue/tagged_object_list.html:127 +#: templates/catalogue/tagged_object_list.html:99 msgid "in Wikipedia" msgstr "w Wikipedii" +#: templates/catalogue/tagged_object_list.html:105 +msgid "in Culture.pl" +msgstr "w Culture.pl" + #: templates/catalogue/viewer_base.html:55 msgid "Loading" msgstr "Ładowanie" -#: views.py:558 +#: views.py:552 #, python-format msgid "" "An error occurred: %(exception)s\n" @@ -770,19 +790,61 @@ msgstr "" "\n" "%(tb)s" -#: views.py:559 +#: views.py:553 msgid "Book imported successfully" msgstr "Książka zaimportowana" -#: views.py:561 +#: views.py:555 #, python-format msgid "Error importing file: %r" msgstr "Błąd podczas importowania pliku: %r" -#: views.py:593 +#: views.py:587 msgid "Download custom PDF" msgstr "Stwórz własny PDF" +#~ msgid "Latest MP3 audiobooks" +#~ msgstr "Ostatnio dodane audiobooki w formacie MP3" + +#~ msgid "Latest Ogg Vorbis audiobooks" +#~ msgstr "Ostatnio dodane audiobooki w formacie Ogg Vorbis" + +#~ msgid "to print" +#~ msgstr "do druku" + +#~ msgid "for an e-book reader" +#~ msgstr "na czytnik e-booków" + +#~ msgid "for Kindle" +#~ msgstr "na Kindle" + +#~ msgid "FictionBook" +#~ msgstr "FictionBook" + +#~ msgid "for advanced usage" +#~ msgstr "do zadań specjalnych" + +#~ msgid "Listen" +#~ msgstr "Słuchaj" + +#~ msgid "See" +#~ msgstr "Zobacz" + +#~ msgid "Download all audiobooks for this book" +#~ msgstr "Pobierz wszystkie audiobooki tego utworu" + +#~ msgid "Themes and topics" +#~ msgstr "Motywy i tematy" + +#~ msgid "Catalogue of the library" +#~ msgstr "Katalog biblioteki" + +#~ msgid "Please wait…" +#~ msgstr "Proszę czekać…" + +#~ msgid "DAISY" +#~ msgstr "DAISY" + #~ msgid "book count" #~ msgstr "liczba książek" diff --git a/src/catalogue/management/commands/importbooks.py b/src/catalogue/management/commands/importbooks.py index 338fea6aa..559124bdf 100644 --- a/src/catalogue/management/commands/importbooks.py +++ b/src/catalogue/management/commands/importbooks.py @@ -4,13 +4,11 @@ # import os import sys -import time from optparse import make_option from django.conf import settings from django.core.management.base import BaseCommand from django.core.management.color import color_style from django.core.files import File -from catalogue.utils import trim_query_log from librarian.picture import ImageStore from wolnelektury.management.profile import profile @@ -31,8 +29,6 @@ class Command(BaseCommand): help="Skip building specified formats"), make_option('-S', '--no-search-index', action='store_false', dest='search_index', default=True, 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, help='Import pictures'), ) @@ -81,14 +77,6 @@ class Command(BaseCommand): verbose = options.get('verbose') import_picture = options.get('import_picture') - wait_until = None - if options.get('wait_until'): - wait_until = time.mktime(time.strptime(options.get('wait_until'), '%Y-%m-%d %H:%M:%S')) - if verbose > 0: - print "Will wait until %s; it's %f seconds from now" % ( - time.strftime('%Y-%m-%d %H:%M:%S', - time.localtime(wait_until)), wait_until - time.time()) - index = None if options.get('search_index') and not settings.NO_SEARCH_INDEX: index = Index() @@ -100,74 +88,59 @@ class Command(BaseCommand): raise e # Start transaction management. - transaction.commit_unless_managed() - transaction.enter_transaction_management() - transaction.managed(True) - - files_imported = 0 - files_skipped = 0 - - for dir_name in directories: - if not os.path.isdir(dir_name): - print self.style.ERROR("%s: Not a directory. Skipping." % dir_name) - else: - # files queue - files = sorted(os.listdir(dir_name)) - postponed = {} - while files: - trim_query_log(0) - file_name = files.pop(0) - file_path = os.path.join(dir_name, file_name) - file_base, ext = os.path.splitext(file_path) - - # Skip files that are not XML files - if not ext == '.xml': - continue - - if verbose > 0: - print "Parsing '%s'" % file_path - else: - sys.stdout.write('.') - sys.stdout.flush() - - # Import book files - try: - if import_picture: - self.import_picture(file_path, options) + with transaction.atomic(): + files_imported = 0 + files_skipped = 0 + + for dir_name in directories: + if not os.path.isdir(dir_name): + print self.style.ERROR("%s: Not a directory. Skipping." % dir_name) + else: + # files queue + files = sorted(os.listdir(dir_name)) + postponed = {} + while files: + file_name = files.pop(0) + file_path = os.path.join(dir_name, file_name) + file_base, ext = os.path.splitext(file_path) + + # Skip files that are not XML files + if not ext == '.xml': + continue + + if verbose > 0: + print "Parsing '%s'" % file_path else: - self.import_book(file_path, options) - - files_imported += 1 - transaction.commit() - - except (Book.AlreadyExists, Picture.AlreadyExists): - print self.style.ERROR('%s: Book or Picture already imported. Skipping. To overwrite use --force.' % - file_path) - files_skipped += 1 - - except Book.DoesNotExist, e: - if file_name not in postponed or postponed[file_name] < files_imported: - # push it back into the queue, maybe the missing child will show up - if verbose: - print self.style.NOTICE('Waiting for missing children') - files.append(file_name) - postponed[file_name] = files_imported - else: - # we're in a loop, nothing's being imported - some child is really missing - raise e + sys.stdout.write('.') + sys.stdout.flush() + + # Import book files + try: + if import_picture: + self.import_picture(file_path, options) + else: + self.import_book(file_path, options) + + files_imported += 1 + + except (Book.AlreadyExists, Picture.AlreadyExists): + print self.style.ERROR('%s: Book or Picture already imported. Skipping. To overwrite use --force.' % + file_path) + files_skipped += 1 + + except Book.DoesNotExist, e: + if file_name not in postponed or postponed[file_name] < files_imported: + # push it back into the queue, maybe the missing child will show up + if verbose: + print self.style.NOTICE('Waiting for missing children') + files.append(file_name) + postponed[file_name] = files_imported + else: + # we're in a loop, nothing's being imported - some child is really missing + raise e # Print results print print "Results: %d files imported, %d skipped, %d total." % ( files_imported, files_skipped, files_imported + files_skipped) print - - if wait_until: - print 'Waiting...' - try: - time.sleep(wait_until - time.time()) - except IOError: - print "it's already too late" - - transaction.commit() - transaction.leave_transaction_management() diff --git a/src/catalogue/models/book.py b/src/catalogue/models/book.py index 5f68e09ff..1524c3456 100644 --- a/src/catalogue/models/book.py +++ b/src/catalogue/models/book.py @@ -55,8 +55,8 @@ class Book(models.Model): extra_info = jsonfield.JSONField(_('extra information'), default={}) gazeta_link = models.CharField(blank=True, max_length=240) wiki_link = models.CharField(blank=True, max_length=240) - # files generated during publication + # files generated during publication cover = EbookField('cover', _('cover'), null=True, blank=True, upload_to=_cover_upload_to, @@ -96,6 +96,15 @@ class Book(models.Model): def __unicode__(self): return self.title + def get_initial(self): + try: + return re.search(r'\w', self.title, re.U).group(0) + except AttributeError: + return None + + def author_str(self): + return ", ".join(str(t) for t in self.tags.filter(category='author')) + def save(self, force_insert=False, force_update=False, **kwargs): from sortify import sortify @@ -311,6 +320,7 @@ class Book(models.Model): notify_cover_changed.append(child) cls.repopulate_ancestors() + tasks.update_counters.delay() # No saves beyond this point. diff --git a/src/catalogue/models/collection.py b/src/catalogue/models/collection.py index 098501eba..bae1cc418 100644 --- a/src/catalogue/models/collection.py +++ b/src/catalogue/models/collection.py @@ -6,6 +6,7 @@ from django.conf import settings from django.db import models from django.utils.translation import ugettext_lazy as _ from ssify import flush_ssi_includes +import re class Collection(models.Model): @@ -28,6 +29,12 @@ class Collection(models.Model): def __unicode__(self): return self.title + def get_initial(self): + try: + return re.search(r'\w', self.title, re.U).group(0) + except AttributeError: + return None + @models.permalink def get_absolute_url(self): return ("collection", [self.slug]) @@ -39,6 +46,10 @@ class Collection(models.Model): for slug in slugs] return models.Q(slug__in=slugs) + def get_books(self): + from catalogue.models import Book + return Book.objects.filter(self.get_query()) + def flush_includes(self, languages=True): if not languages: return diff --git a/src/catalogue/models/tag.py b/src/catalogue/models/tag.py index 02bf6c07d..5575d6a14 100644 --- a/src/catalogue/models/tag.py +++ b/src/catalogue/models/tag.py @@ -128,9 +128,21 @@ class Tag(TagBase): def __repr__(self): return "Tag(slug=%r)" % self.slug + def get_initial(self): + if self.category == 'author': + return self.sort_key[0] + elif self.name: + return self.name[0] + else: + return None + @permalink def get_absolute_url(self): - return ('catalogue.views.tagged_object_list', [self.url_chunk]) + return ('tagged_object_list', [self.url_chunk]) + + @permalink + def get_absolute_gallery_url(self): + return ('tagged_object_list_gallery', [self.url_chunk]) @classmethod @permalink @@ -147,6 +159,7 @@ class Tag(TagBase): @staticmethod def get_tag_list(tags): if isinstance(tags, basestring): + if not tags: return [] real_tags = [] ambiguous_slugs = [] category = None diff --git a/src/catalogue/static/jplayer/jplayer.blue.monday.css b/src/catalogue/static/jplayer/jplayer.blue.monday.css index f8b314b6e..d1214c554 100644 --- a/src/catalogue/static/jplayer/jplayer.blue.monday.css +++ b/src/catalogue/static/jplayer/jplayer.blue.monday.css @@ -14,6 +14,17 @@ * Date: 1st September 2011 */ +.jp-audio .title { + font-size: 11px; + position: relative; + left: 10px; + top: 5px; + z-index: 100; +} +.play-prev, .play-next { + cursor: pointer; +} + div.jp-audio, div.jp-video { @@ -31,7 +42,7 @@ div.jp-video { position:relative; } div.jp-audio { - width:420px; + width: 340px; } div.jp-video-270p { width:480px; @@ -111,7 +122,7 @@ div.jp-interface ul.jp-controls { } div.jp-audio ul.jp-controls { - width: 380px; + width: 320px; padding:20px 20px 0 20px; } @@ -198,8 +209,8 @@ div.jp-audio div.jp-progress { height:15px; } div.jp-audio div.jp-type-single div.jp-progress { - left:110px; - width:186px; + left:70px; + width:150px; } div.jp-audio div.jp-type-playlist div.jp-progress { left:166px; @@ -243,7 +254,7 @@ a.jp-volume-max { div.jp-audio div.jp-type-single a.jp-mute, div.jp-audio div.jp-type-single a.jp-unmute { - margin-left: 210px; + margin-left: 180px; } div.jp-audio div.jp-type-playlist a.jp-mute, @@ -252,7 +263,7 @@ div.jp-audio div.jp-type-playlist a.jp-unmute { } div.jp-audio a.jp-volume-max { - margin-left: 56px; + margin-left: 56px; } div.jp-video a.jp-mute, @@ -302,7 +313,7 @@ div.jp-volume-bar { } div.jp-audio div.jp-volume-bar { top:37px; - left:330px; + left:260px; } div.jp-video div.jp-volume-bar { top:17px; @@ -323,8 +334,8 @@ div.jp-audio div.jp-time-holder { top:50px; } div.jp-audio div.jp-type-single div.jp-time-holder { - left:110px; - width:186px; + left:70px; + width:150px; } div.jp-audio div.jp-type-playlist div.jp-time-holder { left:166px; @@ -387,6 +398,7 @@ div.jp-title li { font-weight:bold; } div.jp-playlist li { + display: none; padding:5px 0 4px 20px; border-bottom:1px solid #eee; } diff --git a/src/catalogue/static/player/player.js b/src/catalogue/static/player/player.js index 69dceed55..a41d2c0ae 100755 --- a/src/catalogue/static/player/player.js +++ b/src/catalogue/static/player/player.js @@ -1,34 +1,53 @@ (function($) { $(function() { - $("#jplayer").each(function() { + $(".jp-jplayer").each(function() { var $self = $(this); + var $root = $self.parent(); + var $number = $('.number', $root); $self.jPlayer({ swfPath: "/static/jplayer/", solution: "html,flash", supplied: $self.attr('data-supplied'), - + cssSelectorAncestor: "#" + $self.attr("data-player"), + ready: function() { var player = $(this); var setMedia = function(elem) { var li = $(elem).parent(); - $('.jp-playlist-current').removeClass('jp-playlist-current'); - $(li).addClass('jp-playlist-current'); var media = {} - - $('.mp3', li).each(function() {media['mp3'] = $(this).attr('href')}); - $('.ogg', li).each(function() {media['oga'] = $(this).attr('href')}); - + + media['mp3'] = li.attr('data-mp3'); + media['oga'] = li.attr('data-ogg'); + + $(".title", $root).html(li.html()); return player.jPlayer("setMedia", media); }; - setMedia($('.play').first()).jPlayer("play"); - - $('.play').click(function() { - setMedia(this).jPlayer("play"); + + $('.play-next', $root).click(function() { + var next = parseInt($number.text()) + 1; + var p = $('.play:eq(' + next + ')', $root); + if (p.length) { + setMedia(p).jPlayer("play"); + $number.text(next) + } + }); + $('.play-prev', $root).click(function() { + var next = parseInt($number.text()) - 1; + if (next < 1) + return; + var p = $('.play:eq(' + next + ')', $root); + setMedia(p).jPlayer("play"); + $number.text(next) }); + + setMedia($('.play', $root).first()); + } }); }); + + }); -})(jQuery) \ No newline at end of file +})(jQuery) diff --git a/src/catalogue/tasks.py b/src/catalogue/tasks.py index a2b8be088..4807339ba 100644 --- a/src/catalogue/tasks.py +++ b/src/catalogue/tasks.py @@ -57,3 +57,9 @@ def build_custom_pdf(book_id, customizations, file_name, waiter_id=None): finally: if waiter_id is not None: WaitedFile.objects.filter(pk=waiter_id).delete() + + +@task(ignore_result=True) +def update_counters(): + from .helpers import update_counters + update_counters() diff --git a/src/catalogue/templates/catalogue/audiobook_list.html b/src/catalogue/templates/catalogue/audiobook_list.html index 75576f4ad..7eda46e4b 100644 --- a/src/catalogue/templates/catalogue/audiobook_list.html +++ b/src/catalogue/templates/catalogue/audiobook_list.html @@ -1,21 +1,21 @@ -{% extends "catalogue/book_list.html" %} +{% extends "base.html" %} {% load i18n %} -{% load catalogue_tags %} +{% load catalogue_tags switch_tag social_tags %} {% load ssi_include from ssify %} -{% block bodyid %}book-a-list{% endblock %} +{% block titleextra %}{% trans "Audiobooks" %}{% endblock %} -{% block titleextra %}{% trans "Listing of all audiobooks" %}{% endblock %} +{% block bodyid %}audiobooks{% endblock %} -{% block metadescription %}Darmowe audiobooki na wolnej licencji. Lektury czytane przez znanych aktorów.{% endblock %} +{% block body %} +

{% trans "Audiobooks" %}

-{% block extrahead %} - - -{% endblock %} + {% work_list best %} +

{% trans "Listing of all audiobooks" %}

+ {% plain_list books by_author=True %} + +

{% trans "Listing of all DAISY files" %}

+ {% plain_list daisy by_author=True %} -{% block book_list_header %}{% trans "Listing of all audiobooks" %}{% endblock %} -{% block book_list_info %} -{% ssi_include 'chunk' key='audiobook-list' %} {% endblock %} diff --git a/src/catalogue/templates/catalogue/book_detail.html b/src/catalogue/templates/catalogue/book_detail.html index 7e8128fa7..b87e9eb1f 100644 --- a/src/catalogue/templates/catalogue/book_detail.html +++ b/src/catalogue/templates/catalogue/book_detail.html @@ -28,9 +28,49 @@ {% endif %}
-

{% trans "See also" %}:

+

{% trans "See also" %}:

{% related_books book taken=book.other_versions|length %}
{% endspaceless %} + + +{% with book.related_themes as themes %} +{% if themes %} +

{% trans "Themes" %}

+ {% plain_list themes book=book %} +{% endif %} +{% endwith %} + + + +

{% trans "Information about the work" %}

+{% for tag in tags %} + +{% endfor %} + + + {% if extra_info.source_url %} +
{% trans "Source" %} {% trans "of the book" %} + {% trans "in" %} {% source_name extra_info.source_url %}
+ {% endif %} + + {% if extra_info.about and not hide_about %} +
{% trans "Book on" %} {% trans "Editor's Platform" %}
+ {% endif %} + {% if book.gazeta_link %} + + {% endif %} + {% if book.wiki_link %} + + {% endif %} + + + + + {% endblock %} diff --git a/src/catalogue/templates/catalogue/book_short.html b/src/catalogue/templates/catalogue/book_short.html index b069cb585..a2b0a5c41 100644 --- a/src/catalogue/templates/catalogue/book_short.html +++ b/src/catalogue/templates/catalogue/book_short.html @@ -12,40 +12,40 @@
-{% likes_book book.pk as likes %} -
-
- ★ -
-
-
- {% ssi_csrf_token %} - -
+ {% likes_book book.pk as likes %} +
+
+ ★ +
+
+
+ {% ssi_csrf_token %} + +
+
-
- -
-
- {% for tag in tags.author %} - {{ tag.name }}{% if not forloop.last %}, - {% endif %}{% endfor %}{% for parent in parents %}, - {{ parent.title }}{% endfor %} -
-
- {% if main_link %}{% endif %}{{ book.title }}{% if main_link %}{% endif %} -
+
+
+ {% for tag in tags.author %} + {{ tag.name }}{% if not forloop.last %}, + {% endif %}{% endfor %}{% for parent in parents %}, + {{ parent.title }}{% endfor %} +
+
+ {% if main_link %}{% endif %}{{ book.title }}{% if main_link %}{% endif %}
+
+ +
+ {% if book.cover_thumb %} + {% if main_link %}{% endif %} + Cover + {% if main_link %}{% endif %} + {% endif %} + {% block cover-area-extra %}{% endblock %} +
-
- {% if book.cover_thumb %} - {% if main_link %}{% endif %} - Cover - {% if main_link %}{% endif %} - {% endif %} - {% block cover-area-extra %}{% endblock %} -
{% spaceless %} @@ -97,39 +97,107 @@ {% trans "Read online" %} {% endif %} -
  • - {% trans "Download" %} +
  • + {% trans "Download" %}:
    {% if book.pdf_file %} - PDF {% trans "to print" %} + PDF {% endif %} - {% if book.epub_file %} - EPUB {% trans "for an e-book reader" %} + {% custom_pdf_link_li book %} + {% if book.epub_file %} + EPUB {% endif %} - {% if book.mobi_file %} - MOBI {% trans "for Kindle" %} + {% if book.mobi_file %} + MOBI {% endif %} {% if book.fb2_file %} - FB2 {% trans "FictionBook" %} + FB2 {% endif %} {% if book.txt_file %} - TXT {% trans "for advanced usage" %} + TXT {% endif %} + {% download_audio book %}
    -
  • -
  • - {% if has_audio %} - {% trans "Listen" %} - {% endif %} + +
  • {% block book-box-extra-info %}{% endblock %} {% block box-append %} {% endblock %}
    + + + + + + {% block right-column %} {% endblock %} + + +{% if audiobooks %} + + + +{% endif %} + +
    -{% endspaceless %} \ No newline at end of file +{% endspaceless %} diff --git a/src/catalogue/templates/catalogue/book_wide.html b/src/catalogue/templates/catalogue/book_wide.html index b84acdb53..4d5617566 100644 --- a/src/catalogue/templates/catalogue/book_wide.html +++ b/src/catalogue/templates/catalogue/book_wide.html @@ -16,23 +16,6 @@ -{% block book-box-extra-info %} -{% if themes %} -
    -

    {% trans "Motifs and themes" %}

    -
    - -
    -
    -{% else %} -

     

    -{% endif %} -{% endblock %} {% block right-column %} @@ -48,37 +31,5 @@ {{ fragment_promo.endif }}
    -
    -

    {% trans "See" %}

    - -
    -
    -

    {% trans "Download" %}

    -
      -
    • - {% if related.media.mp3 or related.media.ogg or related.media.daisy %} - {% trans "Download all audiobooks for this book" %}: - {% download_audio book %}. - {% endif %} -
    • - {% custom_pdf_link_li book %} -
    -
    {% endblock %} diff --git a/src/catalogue/templates/catalogue/catalogue.html b/src/catalogue/templates/catalogue/catalogue.html index c7cee4096..6b6957852 100644 --- a/src/catalogue/templates/catalogue/catalogue.html +++ b/src/catalogue/templates/catalogue/catalogue.html @@ -8,7 +8,8 @@ {% block bodyid %}catalogue-catalogue{% endblock %} {% block body %} -

    {% trans "Catalogue" %}

    +

    {% trans "All works" %}

    +
    @@ -16,23 +17,15 @@ {% trans "Download the catalogue in PDF format." %}

    -

    {% trans "Authors" %}

    -
    {{ output.author }}
    - -

    {% trans "Kinds" %}

    -
    {{ output.kind }}
    - -

    {% trans "Genres" %}

    -
    {{ output.genre }}
    +

    {% trans "Literature" %}

    + {% plain_list books by_author=True paged=False %} -

    {% trans "Epochs" %}

    -
    {{ output.epoch }}
    +

    {% trans "Collections" %}

    + {% plain_list collections paged=False %} -

    {% trans "Themes and topics" %}

    -
    {{ output.theme }}
    +

    {% trans "Gallery" %}

    + {% plain_list pictures by_author=True paged=False %} -

    {% trans "Collections" %}

    -
    {{ output.collections }}
    {% endblock %} diff --git a/src/catalogue/templates/catalogue/collection.html b/src/catalogue/templates/catalogue/collection.html index 4bb12c938..cf43ef36b 100755 --- a/src/catalogue/templates/catalogue/collection.html +++ b/src/catalogue/templates/catalogue/collection.html @@ -1,10 +1,17 @@ -{% extends "catalogue/book_list.html" %} +{% extends "base.html" %} {% load i18n %} +{% load catalogue_tags %} -{% block titleextra %}{{ context.collection.title }}{% endblock %} +{% block titleextra %}{{ collection.title }}{% endblock %} + +{% block bodyid %}collection{% endblock %} + +{% block body %} +

    {{ collection.title }}

    + + {{ collection.description|safe }} + + {% plain_list collection.get_books by_author=True %} -{% block book_list_header %}{{ context.collection.title }}{% endblock %} -{% block book_list_info %} -{{ context.collection.description|safe }} {% endblock %} diff --git a/src/catalogue/templates/catalogue/collection_box.html b/src/catalogue/templates/catalogue/collection_box.html new file mode 100644 index 000000000..7c092943c --- /dev/null +++ b/src/catalogue/templates/catalogue/collection_box.html @@ -0,0 +1,21 @@ +{% spaceless %} +{% load i18n %} +{% load ssi_include from ssify %} +
    +

    {% trans "Collection" %}: {{ obj }}

    + {% if obj.description %} + {{ obj.description|safe|truncatewords_html:40 }} + {% endif %} + {% for b in obj.get_books|slice:":5" %} + {% ssi_include 'catalogue_book_mini' pk=b.pk %} + {% endfor %} + {% with obj.get_books.count|add:-5 as more %} + {% if more > 0 %} + + {% blocktrans with c=more %}and {{ c }} more{% endblocktrans %} + + {% endif %} + {% endwith %} + +
    +{% endspaceless %} diff --git a/src/catalogue/templates/catalogue/collections.html b/src/catalogue/templates/catalogue/collections.html new file mode 100644 index 000000000..1c6987278 --- /dev/null +++ b/src/catalogue/templates/catalogue/collections.html @@ -0,0 +1,22 @@ +{% extends "base.html" %} +{% load i18n %} +{% load catalogue_tags %} +{% load ssi_include from ssify %} + +{% block titleextra %}{% trans "Collections" %}{% endblock %} + +{% block bodyid %}collections{% endblock %} + +{% block body %} +

    {% trans "Collections" %}

    + + {% for obj in best %} + {% ssi_include 'catalogue_collection_box' pk=obj.pk %} + {% endfor %} + +

    {% trans "All collections" %}

    + {% plain_list objects %} + + + +{% endblock %} diff --git a/src/catalogue/templates/catalogue/inline_tag_list.html b/src/catalogue/templates/catalogue/inline_tag_list.html index 59b1acce9..920b55500 100755 --- a/src/catalogue/templates/catalogue/inline_tag_list.html +++ b/src/catalogue/templates/catalogue/inline_tag_list.html @@ -1,17 +1,37 @@ {% load i18n %} {% load catalogue_tags %} -{% if one_tag %} - {% trans "See full category" %} {{ one_tag }} -{% else %} -
      {% if choices %} + {% if category_choices %} +
        +
      • {% trans "Chosen" %}:
      • + {% for tag in category_choices %} +
      • {{ tag }} X
      • + {% endfor %} +
      + {% endif %} + {% if tags %} + + {% endif %} + {% else %} + {% if tags %} + + {% endif %} {% endif %} + {% if other %} +
        +
      • {% trans "Other" %}:
      • + {% for tag in other %} +
      • {{ tag }}
      • + {% endfor %}
      -{% endif %} + {% endif %} diff --git a/src/catalogue/templates/catalogue/menu.html b/src/catalogue/templates/catalogue/menu.html deleted file mode 100644 index 5ddbd3b23..000000000 --- a/src/catalogue/templates/catalogue/menu.html +++ /dev/null @@ -1,41 +0,0 @@ -{% spaceless %} -{% load i18n static %} - - - {% trans "Catalogue of the library" %} - {% trans "Catalogue" %} - - - -{% endspaceless %} \ No newline at end of file diff --git a/src/catalogue/templates/catalogue/plain_list.html b/src/catalogue/templates/catalogue/plain_list.html new file mode 100644 index 000000000..276e55e42 --- /dev/null +++ b/src/catalogue/templates/catalogue/plain_list.html @@ -0,0 +1,19 @@ +{% spaceless %} +{% load catalogue_tags %} + + +
      +
      +{% for initial, object_list in names %} + {% if initial %} +

      {{ initial }}

      + {% endif %} + {% for item in object_list %} +

      {{ item }}{% if item.count %} ({{ item.count}}){% endif %}

      + {% endfor %} +{% endfor %} +
      +
      +
      + +{% endspaceless %} diff --git a/src/catalogue/templates/catalogue/player.html b/src/catalogue/templates/catalogue/player.html index 701fbe850..5ddb91306 100755 --- a/src/catalogue/templates/catalogue/player.html +++ b/src/catalogue/templates/catalogue/player.html @@ -6,7 +6,7 @@ {% load thumbnail %} - {% trans "Wolne Lektury" %} :: {{ book.title }} - {{ audiobook }} @@ -26,7 +26,7 @@ {% endthumbnail %} " alt="Cover" style="float: left; margin: .5em 1em 1em 1em;" /> {% endif %} - +

      {% book_title book %}

      @@ -79,10 +79,6 @@ {% for i in audiobooks %}
    • -
      {{ i.mp3.name }}
      {% trans "Artist" %}: {{ i.mp3.extra_info.artist_name }}, diff --git a/src/catalogue/templates/catalogue/search_multiple_hits.html b/src/catalogue/templates/catalogue/search_multiple_hits.html index d1e1dedf7..24a7a7930 100644 --- a/src/catalogue/templates/catalogue/search_multiple_hits.html +++ b/src/catalogue/templates/catalogue/search_multiple_hits.html @@ -17,34 +17,42 @@
      {% if tags.author %}
      -
      {% trans "Authors" %}:
      -
      - {% inline_tag_list tags.author %} -
      +

      {% trans "Authors" %}:

      + {% for tag in tags.author %} + + {% ssi_include "catalogue_tag_box" pk=tag.pk %} + + {% endfor %}
      {% endif %} {% if tags.kind %}
      -
      {% trans "Kinds" %}:
      -
      - {% inline_tag_list tags.kind %} -
      +

      {% trans "Kinds" %}:

      + {% for tag in tags.kind %} + + {% ssi_include "catalogue_tag_box" pk=tag.pk %} + + {% endfor %}
      {% endif %} {% if tags.genre %}
      -
      {% trans "Genres" %}:
      -
      - {% inline_tag_list tags.genre %} -
      +

      {% trans "Genres" %}:

      + {% for tag in tags.genre %} + + {% ssi_include "catalogue_tag_box" pk=tag.pk %} + + {% endfor %}
      {% endif %} {% if tags.epoch %}
      -
      {% trans "Epochs" %}:
      -
      - {% inline_tag_list tags.epoch %} -
      +

      {% trans "Epochs" %}:

      + {% for tag in tags.epoch %} + + {% ssi_include "catalogue_tag_box" pk=tag.pk %} + + {% endfor %}
      {% endif %}
      @@ -63,7 +71,7 @@
      {% endif %} - + {% if results.author %}
      diff --git a/src/catalogue/templates/catalogue/snippets/custom_pdf_link_li.html b/src/catalogue/templates/catalogue/snippets/custom_pdf_link_li.html index 353ad8bdf..1528f3a30 100644 --- a/src/catalogue/templates/catalogue/snippets/custom_pdf_link_li.html +++ b/src/catalogue/templates/catalogue/snippets/custom_pdf_link_li.html @@ -1,7 +1,4 @@ {% load i18n %} {% if not NO_CUSTOM_PDF %} -
    • - {% trans "Download a custom PDF" %} -
    • + {% trans "Download a custom PDF" %} {% endif %} diff --git a/src/catalogue/templates/catalogue/tag_box.html b/src/catalogue/templates/catalogue/tag_box.html new file mode 100644 index 000000000..122b67057 --- /dev/null +++ b/src/catalogue/templates/catalogue/tag_box.html @@ -0,0 +1,13 @@ +{% spaceless %} +{% load i18n %} +{% load catalogue_tags %} +
      +

      {% trans tag.category as c %}{{ c|capfirst }}: {{ tag }}

      + {% if tag.description %} + {{ tag.description|safe|truncatewords_html:40 }} + {% else %} + No description + {% endif %} + +
      +{% endspaceless %} diff --git a/src/catalogue/templates/catalogue/tag_catalogue.html b/src/catalogue/templates/catalogue/tag_catalogue.html new file mode 100644 index 000000000..0279a0e64 --- /dev/null +++ b/src/catalogue/templates/catalogue/tag_catalogue.html @@ -0,0 +1,23 @@ +{% extends "base.html" %} +{% load i18n %} +{% load plain_list from catalogue_tags %} +{% load ssi_include from ssify %} + +{% block titleextra %}{{ title }}{% endblock %} + +{% block bodyid %}tag-catalogue{% endblock %} + +{% block body %} +

      {{ title|title }} {% trans "on Wolne Lektury" %}

      + +{% for tag in best %} + + {% ssi_include "catalogue_tag_box" pk=tag.pk %} + +{% endfor %} + +

      All {{ title }}

      + +{% plain_list tags %} + +{% endblock %} diff --git a/src/catalogue/templates/catalogue/tagged_object_list.html b/src/catalogue/templates/catalogue/tagged_object_list.html index 3df560a6f..033cf9a5a 100644 --- a/src/catalogue/templates/catalogue/tagged_object_list.html +++ b/src/catalogue/templates/catalogue/tagged_object_list.html @@ -3,165 +3,113 @@ {% load catalogue_tags switch_tag social_tags %} {% load ssi_include from ssify %} -{% block titleextra %}{% title_from_tags tags %}{% endblock %} +{% block titleextra %}{% if tags %}{% title_from_tags tags %}{% elif gallery %}{% trans "Gallery" %}{% else %}{% trans "Literature" %}{% endif %}{% endblock %} {% block bodyid %}tagged-object-list{% endblock %} {% block body %} -
      -
      -

      {% html_title_from_tags tags %}

      - - {% with tags|last as last_tag %} - {% if last_tag.has_description %} -
      - -
      {{ last_tag.description|safe|truncatewords_html:40 }}
      +
      +

      {% if tags %} + {% html_title_from_tags tags %} + {% elif gallery %}{% trans "Gallery" %}{% else %}{% trans "Literature" %} + {% endif %} +

      + + - {% endif %} -
      -
      - {% if categories.author %} -
      -
      {% trans "Authors" %}:
      -
      - {% inline_tag_list categories.author tags %} -
      -
      - {% endif %} - {% if categories.kind %} -
      -
      {% trans "Kinds" %}:
      -
      - {% inline_tag_list categories.kind tags %} -
      -
      - {% endif %} - {% if categories.genre %} -
      -
      {% trans "Genres" %}:
      -
      - {% inline_tag_list categories.genre tags %} -
      -
      - {% endif %} - {% if categories.epoch %} -
      -
      {% trans "Epochs" %}:
      -
      - {% inline_tag_list categories.epoch tags %} -
      -
      - {% endif %} - - {% if categories.theme %} -
      -

      - {% trans "Motifs and themes" %}

      -
      - {% tag_list categories.theme tags %} -
      -
      - {% endif %} +
      +
      +
      + {% inline_tag_list categories.author tags 'author' gallery=gallery %} +
      +
      + {% inline_tag_list categories.epoch tags 'epoch' gallery=gallery %}
      +
      + {% inline_tag_list categories.genre tags 'genre' gallery=gallery %} +
      +
      + {% inline_tag_list categories.kind tags 'kind' gallery=gallery %} +
      + {% if theme_is_set %} +
      + {% inline_tag_list categories.theme tags 'theme' gallery=gallery %} +
      + {% endif %} +
      -
      - {% if theme_is_set %} -
      - {% if last_tag.gazeta_link or last_tag.wiki_link %} -

      {% trans "See also" %}:

      -
        - {% if last_tag.culturepl_link %} -
      • - {% trans "in Culture.pl" %} -
      • - {% endif %} - {% if last_tag.gazeta_link %} -
      • - {% trans "in Lektury.Gazeta.pl" %} -
      • - {% endif %} - {% if last_tag.wiki_link %} -
      • - {% trans "in Wikipedia" %} -
      • + + {% if theme_is_set %} + {% work_list object_list %} + {% else %} +
        + {% if object_list %} + {% work_list best %} +

        {% trans "All matching works" %}

        + {% plain_list object_list by_author=True gallery=gallery %} + {% else %} + {% trans "Sorry! Search cirteria did not match any resources." %} + {% include "info/join_us.html" %} {% endif %} -
      - {% endif %} -
      - {% endif %} +
      -
      -
      -
      - {% if theme_is_set %} - {% work_list object_list %} - {% else %} +{% if categories.theme %} +

      {% trans "Motifs and themes" %}

      + {% plain_list categories.theme choice=tags gallery=gallery %} +{% endif %} - {% choose_cite tag_ids=tag_ids as cite_promo_pk %} - {% choose_fragment tag_ids=tag_ids unless=cite_promo_pk as fragment_promo_pk %} - {{ cite_promo_pk.if }} - {% ssi_include 'social_cite' pk=cite_promo_pk %} - {{ cite_promo_pk.endif }} - {{ fragment_promo_pk.if }} - {% ssi_include 'catalogue_fragment_promo' pk=fragment_promo_pk %} - {{ fragment_promo_pk.endif }} - -
      - {% if last_tag.gazeta_link or last_tag.wiki_link %} -

      {% trans "See also" %}:

      - - {% endif %}
      -
      - {% comment %} -

      {% trans "Download" %}:

      - - {% endcomment %} -
      + {% if tag.gazeta_link %} + {% endif %} + {% if tag.wiki_link %} + + {% endif %} + {% if tag.culturepl_link %} + + {% endif %} + {% endif %} + {% endfor %} -
      -
      - {% if not theme_is_set %} -
      - {% if object_list %} - {% work_list object_list %} - {% else %} - {% trans "Sorry! Search cirteria did not match any resources." %} - {% include "info/join_us.html" %} - {% endif %} -
      - {% endif %} - {% endwith %} {% endblock %} diff --git a/src/catalogue/templatetags/catalogue_tags.py b/src/catalogue/templatetags/catalogue_tags.py index 6e81caec2..fd914e321 100644 --- a/src/catalogue/templatetags/catalogue_tags.py +++ b/src/catalogue/templatetags/catalogue_tags.py @@ -4,6 +4,7 @@ # from random import randint, random from urlparse import urlparse +from django.contrib.contenttypes.models import ContentType from django.conf import settings from django import template @@ -242,10 +243,26 @@ def catalogue_url(parser, token): return CatalogueURLNode(tags_to_add, tags_to_remove) +@register.tag +def catalogue_url_gallery(parser, token): + bits = token.split_contents() + + tags_to_add = [] + tags_to_remove = [] + for bit in bits[1:]: + if bit[0] == '-': + tags_to_remove.append(bit[1:]) + else: + tags_to_add.append(bit) + + return CatalogueURLNode(tags_to_add, tags_to_remove, gallery=True) + + class CatalogueURLNode(Node): - def __init__(self, tags_to_add, tags_to_remove): + def __init__(self, tags_to_add, tags_to_remove, gallery=False): self.tags_to_add = [Variable(tag) for tag in tags_to_add] self.tags_to_remove = [Variable(tag) for tag in tags_to_remove] + self.gallery = gallery def render(self, context): tags_to_add = [] @@ -273,23 +290,40 @@ class CatalogueURLNode(Node): pass if len(tag_slugs) > 0: - return reverse('tagged_object_list', kwargs={'tags': '/'.join(tag_slugs)}) + if self.gallery: + return reverse('tagged_object_list_gallery', kwargs={'tags': '/'.join(tag_slugs)}) + else: + return reverse('tagged_object_list', kwargs={'tags': '/'.join(tag_slugs)}) else: - return reverse('main_page') + return reverse('book_list') @register.inclusion_tag('catalogue/tag_list.html') -def tag_list(tags, choices=None): +def tag_list(tags, choices=None, category=None, gallery=False): + print(tags, choices, category) if choices is None: choices = [] - if len(tags) == 1 and tags[0].category not in [t.category for t in choices]: + + if category is None and tags: + category = tags[0].category + + category_choices = [tag for tag in choices if tag.category == category] + + if len(tags) == 1 and category not in [t.category for t in choices]: one_tag = tags[0] + + if category is not None: + other = Tag.objects.filter(category=category).exclude(pk__in=[t.pk for t in tags]).exclude(pk__in=[t.pk for t in category_choices]) + # Filter out empty tags. + ct = ContentType.objects.get_for_model(Picture if gallery else Book) + other = other.filter(items__content_type=ct).distinct() + return locals() @register.inclusion_tag('catalogue/inline_tag_list.html') -def inline_tag_list(tags, choices=None): - return tag_list(tags, choices) +def inline_tag_list(tags, choices=None, category=None, gallery=False): + return tag_list(tags, choices, category, gallery) @register.inclusion_tag('catalogue/collection_list.html') @@ -311,6 +345,25 @@ def work_list(context, object_list): return locals() + +@register.inclusion_tag('catalogue/plain_list.html', takes_context=True) +def plain_list(context, object_list, with_initials=True, by_author=False, choice=None, book=None, gallery=False, paged=True): + names = [(None, [])] + last_initial = None + for obj in object_list: + if with_initials: + if by_author: + initial = obj.sort_key_author + else: + initial = obj.get_initial().upper() + if initial != last_initial: + last_initial = initial + names.append((obj.author_str() if by_author else initial, [])) + names[-1][1].append(obj) + return locals() + + + # TODO: These are no longer just books. @register.inclusion_tag('catalogue/related_books.html', takes_context=True) def related_books(context, instance, limit=6, random=1, taken=0): @@ -347,17 +400,6 @@ def related_books(context, instance, limit=6, random=1, taken=0): } -@register.inclusion_tag('catalogue/menu.html') -def catalogue_menu(): - return {'categories': [ - ('author', _('Authors'), 'autorzy'), - ('genre', _('Genres'), 'gatunki'), - ('kind', _('Kinds'), 'rodzaje'), - ('epoch', _('Epochs'), 'epoki'), - ('theme', _('Themes'), 'motywy'), - ]} - - @register.simple_tag def download_audio(book, daisy=True): links = [] @@ -373,7 +415,7 @@ def download_audio(book, daisy=True): for dsy in book.get_media('daisy'): links.append("%s" % (dsy.file.url, BookMedia.formats['daisy'].name)) - return ", ".join(links) + return "".join(links) @register.inclusion_tag("catalogue/snippets/custom_pdf_link_li.html") diff --git a/src/catalogue/urls.py b/src/catalogue/urls.py index b7c59a055..35a08e11d 100644 --- a/src/catalogue/urls.py +++ b/src/catalogue/urls.py @@ -32,7 +32,16 @@ urlpatterns += patterns('', urlpatterns += patterns('catalogue.views', url(r'^$', 'catalogue', name='catalogue'), - url(r'^lektury/$', 'book_list', name='book_list'), + url(r'^autor/$', 'tag_catalogue', {'category': 'author'}, name='author_catalogue'), + url(r'^epoka/$', 'tag_catalogue', {'category': 'epoch'}, name='epoch_catalogue'), + url(r'^gatunek/$', 'tag_catalogue', {'category': 'genre'}, name='genre_catalogue'), + url(r'^rodzaj/$', 'tag_catalogue', {'category': 'kind'}, name='kind_catalogue'), + url(r'^motyw/$', 'tag_catalogue', {'category': 'theme'}, name='theme_catalogue'), + + url(r'^galeria/$', 'tagged_object_list', {'gallery': True}, name='gallery'), + url(r'^kolekcje/$', 'collections', name='catalogue_collections'), + + url(r'^lektury/$', 'tagged_object_list', name='book_list'), url(r'^lektury/(?P[a-zA-Z0-9-]+)/$', 'collection', name='collection'), url(r'^audiobooki/$', 'audiobook_list', name='audiobook_list'), url(r'^daisy/$', 'daisy_list', name='daisy_list'), @@ -75,7 +84,10 @@ urlpatterns += patterns('catalogue.views', url(r'^b/(?P\d+)/wide\.(?P.+)\.html', 'book_wide', name='catalogue_book_wide'), url(r'^f/(?P\d+)/promo\.(?P.+)\.html', 'fragment_promo', name='catalogue_fragment_promo'), url(r'^f/(?P\d+)/short\.(?P.+)\.html', 'fragment_short', name='catalogue_fragment_short'), + url(r'^t/(?P\d+)/box\.(?P.+)\.html', 'tag_box', name='catalogue_tag_box'), + url(r'^c/(?P.+)/box\.(?P.+)\.html', 'collection_box', name='catalogue_collection_box'), # This should be the last pattern. + url(r'^galeria/(?P[a-zA-Z0-9-/]*)/$', 'tagged_object_list', {'gallery': True}, name='tagged_object_list_gallery'), url(r'^(?P[a-zA-Z0-9-/]*)/$', 'tagged_object_list', name='tagged_object_list'), ) diff --git a/src/catalogue/utils.py b/src/catalogue/utils.py index bcc5a0b33..71cd8907a 100644 --- a/src/catalogue/utils.py +++ b/src/catalogue/utils.py @@ -342,17 +342,5 @@ class AppSettings(object): return value -def trim_query_log(trim_to=25): - """ -connection.queries includes all SQL statements -- INSERTs, UPDATES, SELECTs, etc. Each time your app hits the database, the query will be recorded. -This can sometimes occupy lots of memory, so trim it here a bit. - """ - if settings.DEBUG: - from django.db import connection - connection.queries = trim_to > 0 \ - and connection.queries[-trim_to:] \ - or [] - - def delete_from_cache_by_language(cache, key_template): cache.delete_many([key_template % lc for lc, ln in settings.LANGUAGES]) diff --git a/src/catalogue/views.py b/src/catalogue/views.py index a25a08ffa..5a8277f88 100644 --- a/src/catalogue/views.py +++ b/src/catalogue/views.py @@ -4,11 +4,12 @@ # from collections import OrderedDict import re +import random from django.conf import settings from django.template import RequestContext from django.template.loader import render_to_string -from django.shortcuts import render_to_response, get_object_or_404, render +from django.shortcuts import render_to_response, get_object_or_404, render, redirect from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect, JsonResponse from django.core.urlresolvers import reverse from django.db.models import Q @@ -24,67 +25,21 @@ from picture.models import Picture, PictureArea from picture.views import picture_list_thumb from ssify import ssi_included, ssi_expect, SsiVariable as V from suggest.forms import PublishingSuggestForm +from catalogue import constants from catalogue import forms from catalogue.helpers import get_top_level_related_tags from catalogue import models -from catalogue.utils import split_tags, MultiQuerySet, SortedMultiQuerySet +from catalogue.utils import split_tags from catalogue.templatetags.catalogue_tags import tag_list, collection_list staff_required = user_passes_test(lambda user: user.is_staff) def catalogue(request, as_json=False): - common_categories = ('author',) - split_categories = ('epoch', 'genre', 'kind') - - categories = split_tags( - get_top_level_related_tags(categories=common_categories), - models.Tag.objects.usage_for_model( - models.Fragment, counts=True).filter(category='theme'), - models.Tag.objects.usage_for_model( - Picture, counts=True).filter(category__in=common_categories), - models.Tag.objects.usage_for_model( - PictureArea, counts=True).filter( - category='theme') - ) - book_categories = split_tags( - get_top_level_related_tags(categories=split_categories) - ) - picture_categories = split_tags( - models.Tag.objects.usage_for_model( - Picture, counts=True).filter( - category__in=split_categories), - ) - + books = models.Book.objects.filter(parent=None) + pictures = Picture.objects.all() collections = models.Collection.objects.all() - - def render_tag_list(tags): - return render_to_string('catalogue/tag_list.html', tag_list(tags)) - - def render_split(with_books, with_pictures): - ctx = {} - if with_books: - ctx['books'] = render_tag_list(with_books) - if with_pictures: - ctx['pictures'] = render_tag_list(with_pictures) - return render_to_string('catalogue/tag_list_split.html', ctx) - - output = {} - output['theme'] = render_tag_list(categories.get('theme', [])) - for category in common_categories: - output[category] = render_tag_list(categories.get(category, [])) - for category in split_categories: - output[category] = render_split( - book_categories.get(category, []), - picture_categories.get(category, [])) - - output['collections'] = render_to_string( - 'catalogue/collection_list.html', collection_list(collections)) - if as_json: - return JsonResponse(output) - else: - return render_to_response('catalogue/catalogue.html', locals(), - context_instance=RequestContext(request)) + return render(request, 'catalogue/catalogue.html', locals()) @ssi_included @@ -113,10 +68,20 @@ def book_list(request, filter=None, get_filter=None, def audiobook_list(request): - return book_list(request, Q(media__type='mp3') | Q(media__type='ogg'), - template_name='catalogue/audiobook_list.html', - list_template_name='catalogue/snippets/audiobook_list.html', - ) + books = models.Book.objects.filter(Q(media__type='mp3') | Q(media__type='ogg')).distinct() + books = list(books) + if len(books) > 3: + best = random.sample(books, 3) + else: + best = books + + daisy = models.Book.objects.filter(media__type='daisy').distinct() + + return render(request, 'catalogue/audiobook_list.html', { + 'books': books, + 'best': best, + 'daisy': daisy, + }) def daisy_list(request): @@ -127,17 +92,8 @@ def daisy_list(request): def collection(request, slug): coll = get_object_or_404(models.Collection, slug=slug) - if coll.kind == 'book': - view = book_list - tmpl = "catalogue/collection.html" - elif coll.kind == 'picture': - view = picture_list_thumb - tmpl = "picture/collection.html" - else: - raise ValueError('How do I show this kind of collection? %s' % coll.kind) - return view(request, get_filter=coll.get_query, - template_name=tmpl, - context={'collection': coll}) + return render(request, 'catalogue/collection.html', + {'collection': coll}) def differentiate_tags(request, tags, ambiguous_slugs): @@ -155,7 +111,8 @@ def differentiate_tags(request, tags, ambiguous_slugs): # TODO: Rewrite this hellish piece of code which tries to do everything -def tagged_object_list(request, tags=''): +def tagged_object_list(request, tags='', gallery=False): + raw_tags = tags # preliminary tests and conditions try: tags = models.Tag.get_tag_list(tags) @@ -189,58 +146,87 @@ def tagged_object_list(request, tags=''): objects = None if theme_is_set: + # Only fragments (or pirctureareas) here. shelf_tags = [tag for tag in tags if tag.category == 'set'] fragment_tags = [tag for tag in tags if tag.category != 'set'] - fragments = models.Fragment.tagged.with_all(fragment_tags) - areas = PictureArea.tagged.with_all(fragment_tags) + if gallery: + fragments = PictureArea.tagged.with_all(fragment_tags) + else: + fragments = models.Fragment.tagged.with_all(fragment_tags) if shelf_tags: - books = models.Book.tagged.with_all(shelf_tags).order_by() - fragments = fragments.filter(Q(book__in=books) | Q(book__ancestor__in=books)) - areas = PictureArea.objects.none() + if gallery: + # TODO: Pictures on shelves not supported yet. + raise Http404 + else: + books = models.Book.tagged.with_all(shelf_tags).order_by() + fragments = fragments.filter(Q(book__in=books) | Q(book__ancestor__in=books)) categories = split_tags( models.Tag.objects.usage_for_queryset(fragments, counts=True ).exclude(pk__in=tags_pks), - models.Tag.objects.usage_for_queryset(areas, counts=True - ).exclude(pk__in=tags_pks) ) - # we want the Pictures to go first - objects = MultiQuerySet(areas, fragments) + objects = fragments else: - all_books = models.Book.tagged.with_all(tags) - if shelf_is_set: - books = all_books.order_by('sort_key_author', 'title') - pictures = Picture.objects.none() - related_book_tags = models.Tag.objects.usage_for_queryset( - books, counts=True).exclude( - category='set').exclude(pk__in=tags_pks) + if gallery: + if shelf_is_set: + # TODO: Pictures on shelves not supported yet. + raise Http404 + else: + if tags: + objects = Picture.tagged.with_all(tags).order_by( + 'sort_key_author', 'title') + else: + objects = Picture.objects.all().order_by( + 'sort_key_author', 'title') + areas = PictureArea.objects.filter(picture__in=objects) + categories = split_tags( + models.Tag.objects.usage_for_queryset( + objects, counts=True).exclude(pk__in=tags_pks), + models.Tag.objects.usage_for_queryset( + areas, counts=True).filter( + category__in=('theme', 'thing')).exclude( + pk__in=tags_pks), + ) else: - books = models.Book.tagged_top_level(tags).order_by( - 'sort_key_author', 'title') - pictures = Picture.tagged.with_all(tags).order_by( - 'sort_key_author', 'title') + if tags: + all_books = models.Book.tagged.with_all(tags) + else: + all_books = models.Book.objects.filter(parent=None) + if shelf_is_set: + objects = all_books.order_by('sort_key_author', 'title') + related_book_tags = models.Tag.objects.usage_for_queryset( + objects, counts=True).exclude( + category='set').exclude(pk__in=tags_pks) + else: + if tags: + objects = models.Book.tagged_top_level(tags).order_by( + 'sort_key_author', 'title') + else: + objects = all_books.order_by('sort_key_author', 'title') related_book_tags = get_top_level_related_tags(tags) - fragments = models.Fragment.objects.filter(book__in=all_books) - areas = PictureArea.objects.filter(picture__in=pictures) + fragments = models.Fragment.objects.filter(book__in=all_books) - categories = split_tags( - related_book_tags, - models.Tag.objects.usage_for_queryset( - pictures, counts=True).exclude(pk__in=tags_pks), - models.Tag.objects.usage_for_queryset( - fragments, counts=True).filter( - category='theme').exclude(pk__in=tags_pks), - models.Tag.objects.usage_for_queryset( - areas, counts=True).filter( - category__in=('theme', 'thing')).exclude( - pk__in=tags_pks), - ) + categories = split_tags( + related_book_tags, + models.Tag.objects.usage_for_queryset( + fragments, counts=True).filter( + category='theme').exclude(pk__in=tags_pks), + ) - objects = SortedMultiQuerySet(pictures, books, - order_by=('sort_key_author', 'title')) + objects = list(objects) + if len(objects) > 3: + best = random.sample(objects, 3) + else: + best = objects + + if not gallery and not objects and len(tags) == 1: + tag = tags[0] + if (tag.category in ('theme', 'thing') and PictureArea.tagged.with_any([tag]).exists() or + Picture.tagged.with_any([tag]).exists()): + return redirect('tagged_object_list_gallery', raw_tags, permanent=False) return render_to_response('catalogue/tagged_object_list.html', { @@ -252,6 +238,8 @@ def tagged_object_list(request, tags=''): 'tags': tags, 'tag_ids': tags_pks, 'theme_is_set': theme_is_set, + 'best': best, + 'gallery': gallery, }, context_instance=RequestContext(request)) @@ -272,16 +260,13 @@ def book_detail(request, slug): except models.Book.DoesNotExist: return pdcounter_views.book_stub_detail(request, slug) + tags = book.tags.exclude(category__in=('set', 'theme')) book_children = book.children.all().order_by('parent_number', 'sort_key') return render_to_response('catalogue/book_detail.html', locals(), context_instance=RequestContext(request)) -def player(request, slug): - book = get_object_or_404(models.Book, slug=slug) - if not book.has_media('mp3'): - raise Http404 - +def get_audiobooks(book): ogg_files = {} for m in book.media.filter(type='ogg').order_by().iterator(): ogg_files[m.name] = m @@ -309,6 +294,15 @@ def player(request, slug): audiobooks.append(media) projects = sorted(projects) + return audiobooks, projects, have_oggs + + +def player(request, slug): + book = get_object_or_404(models.Book, slug=slug) + if not book.has_media('mp3'): + raise Http404 + + audiobooks, projects, have_oggs = get_audiobooks(book) extra_info = book.extra_info @@ -636,6 +630,7 @@ def book_mini(request, pk, with_link=True): def book_short(request, pk): book = get_object_or_404(models.Book, pk=pk) stage_note, stage_note_url = book.stage_note() + audiobooks, projects, have_oggs = get_audiobooks(book) return render(request, 'catalogue/book_short.html', { 'book': book, @@ -646,6 +641,8 @@ def book_short(request, pk): 'show_lang': book.language_code() != settings.LANGUAGE_CODE, 'stage_note': stage_note, 'stage_note_url': stage_note_url, + 'audiobooks': audiobooks, + 'have_oggs': have_oggs, }) @@ -659,6 +656,7 @@ def book_wide(request, pk): book = get_object_or_404(models.Book, pk=pk) stage_note, stage_note_url = book.stage_note() extra_info = book.extra_info + audiobooks, projects, have_oggs = get_audiobooks(book) return render(request, 'catalogue/book_wide.html', { 'book': book, @@ -672,7 +670,8 @@ def book_wide(request, pk): 'main_link': reverse('book_text', args=[book.slug]) if book.html_file else None, 'extra_info': extra_info, 'hide_about': extra_info.get('about', '').startswith('http://wiki.wolnepodreczniki.pl'), - 'themes': book.related_themes(), + 'audiobooks': audiobooks, + 'have_oggs': have_oggs, }) @@ -689,3 +688,55 @@ def fragment_promo(request, pk): return render(request, 'catalogue/fragment_promo.html', { 'fragment': fragment }) + + +@ssi_included +def tag_box(request, pk): + tag = get_object_or_404(models.Tag, pk=pk) + assert tag.category != 'set' + + return render(request, 'catalogue/tag_box.html', { + 'tag': tag, + }) + + +@ssi_included +def collection_box(request, pk): + obj = get_object_or_404(models.Collection, pk=pk) + + return render(request, 'catalogue/collection_box.html', { + 'obj': obj, + }) + + +def tag_catalogue(request, category): + if category == 'theme': + tags = models.Tag.objects.usage_for_model( + models.Fragment, counts=True).filter(category='theme') + else: + tags = list(get_top_level_related_tags((), categories=(category,))) + + if len(tags) > 3: + best = random.sample(tags, 3) + else: + best = tags + + return render(request, 'catalogue/tag_catalogue.html', { + 'tags': tags, + 'best': best, + 'title': constants.CATEGORIES_NAME_PLURAL[category], + }) + + +def collections(request): + objects = models.Collection.objects.all() + + if len(objects) > 3: + best = random.sample(objects, 3) + else: + best = objects + + return render(request, 'catalogue/collections.html', { + 'objects': objects, + 'best': best, + }) diff --git a/src/picture/models.py b/src/picture/models.py index 5aabe3c89..bffb63912 100644 --- a/src/picture/models.py +++ b/src/picture/models.py @@ -17,6 +17,7 @@ from StringIO import StringIO import jsonfield import itertools import logging +import re from PIL import Image @@ -123,10 +124,31 @@ class Picture(models.Model): def __unicode__(self): return self.title + def author_str(self): + return ", ".join(str(t) for t in self.tags.filter(category='author')) + @permalink def get_absolute_url(self): return ('picture.views.picture_detail', [self.slug]) + def get_initial(self): + try: + return re.search(r'\w', self.title, re.U).group(0) + except AttributeError: + return '' + + def get_next(self): + try: + return type(self).objects.filter(sort_key__gt=self.sort_key)[0] + except IndexError: + return None + + def get_previous(self): + try: + return type(self).objects.filter(sort_key__lt=self.sort_key).order_by('-sort_key')[0] + except IndexError: + return None + @classmethod def from_xml_file(cls, xml_file, image_file=None, image_store=None, overwrite=False): """ diff --git a/src/picture/templates/picture/picture_short.html b/src/picture/templates/picture/picture_short.html index 1bd70a11b..35fba77b0 100644 --- a/src/picture/templates/picture/picture_short.html +++ b/src/picture/templates/picture/picture_short.html @@ -10,7 +10,7 @@
      {% for tag in tags.author %} - {{ tag }}{% if not forloop.last %}, + {{ tag }}{% if not forloop.last %}, {% endif %}{% endfor %}
      @@ -32,14 +32,14 @@ {% endblock %} {# what about licensing icons here #}
      - +
      {% spaceless %} {% trans "Epoch" %}:  {% for tag in tags.epoch %} - {{ tag }} + {{ tag }} {% if not forloop.last %}, {% endif %} {% endfor %} @@ -47,7 +47,7 @@ {% trans "Kind" %}:  {% for tag in tags.kind %} - {{ tag }} + {{ tag }} {% if not forloop.last %}, {% endif %} {% endfor %} @@ -55,7 +55,7 @@ {% trans "Genre" %}:  {% for tag in tags.genre %} - {{ tag }} + {{ tag }} {% if not forloop.last %}, {% endif %} {% endfor %} diff --git a/src/picture/templates/picture/picture_viewer.html b/src/picture/templates/picture/picture_viewer.html index e169dbe0f..937ef689f 100644 --- a/src/picture/templates/picture/picture_viewer.html +++ b/src/picture/templates/picture/picture_viewer.html @@ -3,6 +3,7 @@ {% load static from staticfiles %} {% load catalogue_tags %} {% load thumbnail %} +{% load ssi_include from ssify %} {% block title %}{{ picture.pretty_title }}{% endblock %} @@ -24,6 +25,17 @@ {% block menu %}
    • +-
    • +{% spaceless %} +
    • + {% with picture.get_previous as prev %} + {% if prev %}<{%endif %} + {% endwith %} + {% with picture.get_next as next %} + {% if next %}>{% endif %} + {% endwith %} +
    • +{% endspaceless %} +
    • {% thumbnail picture.image_file "700x500" as pic %} -
      @@ -82,7 +94,7 @@
      - {{ picture.short_html }} + {% ssi_include 'picture_short' pk=picture.pk %}
      {% endblock %} diff --git a/src/picture/templates/picture/picture_wide.html b/src/picture/templates/picture/picture_wide.html index 9f47c7baa..462e8b0e2 100644 --- a/src/picture/templates/picture/picture_wide.html +++ b/src/picture/templates/picture/picture_wide.html @@ -93,20 +93,5 @@ {% endif %}
    - - {% comment %} -
    -

    {% trans "Download" %}

    -
      -
    • - {% if related.media.mp3 or related.media.ogg or related.media.daisy %} - {% trans "Download all audiobooks for this book" %}: - {% download_audio book %}. - {% endif %} -
    • - {% custom_pdf_link_li book %} -
    -
    - {% endcomment %} {% endblock %} diff --git a/src/search/templatetags/search_tags.py b/src/search/templatetags/search_tags.py index 8dbad9dae..8302379cd 100644 --- a/src/search/templatetags/search_tags.py +++ b/src/search/templatetags/search_tags.py @@ -32,12 +32,15 @@ def book_searched(context, result): # We don't need hits which lead to sections but do not have # snippets. hits = filter(lambda (idx, h): - result.snippets[idx] is not None - or 'fragment' in h, enumerate(result.hits)) + 'fragment' in h or + result.snippets[idx] is not None, + enumerate(result.hits)) # print "[tmpl: from %d hits selected %d]" % (len(result.hits), len(hits)) for (idx, hit) in hits: # currently we generate one snipper per hit though. + if len(result.snippets) <= idx: + break if result.snippets[idx] is None: continue snip = result.snippets[idx] diff --git a/src/wolnelektury/celery.py b/src/wolnelektury/celery.py index ae5ce20ce..094a7a7c2 100644 --- a/src/wolnelektury/celery.py +++ b/src/wolnelektury/celery.py @@ -3,10 +3,8 @@ from __future__ import absolute_import import os import sys -ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path = [ - os.path.join(ROOT, 'apps'), - os.path.join(ROOT, 'lib'), os.path.join(ROOT, 'lib/librarian'), ] + sys.path diff --git a/src/wolnelektury/locale/pl/LC_MESSAGES/django.mo b/src/wolnelektury/locale/pl/LC_MESSAGES/django.mo index b6919642fd37cf4943a3c6f2218b90d18f495192..25437326d65e0db8bbdbce9c483894b8f55a9efd 100644 GIT binary patch delta 1851 zcmaLXTWl0n9LMp0TgsMRC~QkDmX)oFf@Rxntw2kqMH;}SgjG<9a&g#B%G%2`yW5mS z&5{TapHK!&8Xh1q(HI|BjX`)2Z?P{J3=ae~A_>MAjWKGX!OQp89n>dJ_CKF9vuDob zf6nf6{nxwmUxw$LFiJnMgy<#r#e zFn~O=hfovWjmlgSwS{BI$1ZTW4Zpwy-oVYcg~9Ttsk}_(PF&4sTH#JqM=q*k4@rh) zgYOTbQvCw{$eB2f&*0&OW*>2WN?G1jzW-#A8ISCZhT<7HhnmnO)D~Q8Aph#<1`jlW z5GUy(u0&>_HMuTc~H6}6S+ zdEVB~t_tWNlD2U7nl>;Q%RS5XT8udL_G2MCg4_YnGryPs$$v~9|uvZ4|uR?XJTqJjDq-7KrA ztR=dL+7T|=52Z>)sZ=3rv*}j7kLV%R5O)(R36&ON*=&vUqt1=ahDv{tf37iVexf1n zU#X}rOjNvA78*)=q;28A2h#^~BmXYN@lQks7e&2H*2#{ilKYCQ8F7+Nr3#lLXG^NLc-h>P R&0cf<@ui0f@#tqIe*@9E<(~im delta 2901 zcmb7^TWl0n7{||YtKGIx3bd4p94c4Ydt0DOY0E+>Bugm-Qcb*_-96o%?q!;psY5r0 zjgT6NCPXG^+C&3B@ZbYR7mSif5L?5Gh$b2}hQvgQJ|K~3j1P+cZ+BV>l&B~D_IJ*l zneTS~r{lrH+j3W{W*ui3A=tw(*9^v<09$6^2jj$S#=Zwng6}&RJ2;22U$Aa^h_Q=U zuP9~gXRNO~8Cw8;QN~yecnzEj{sq>9<>ibm2fg4Ka1RKVIX0()vEB3nxDtF4L=1Ka ztOSpM@WDoGp0fEKI3Lf?gC*bw?X90N{|)RRte5Ue6|P^%6vuP z0b?6Mda=`9cZ1~k8Iayn?ft_b1$qTs0$TR^G>GEZS&-hp2vUMy+q??mkB#GJ0phdY zF`)pZ_}LEDg5=;?kTOk!=rYql0X`3s!>b^5W*nqMZh&V!e*zKHV1pn;bcA}MfBHDjM* z|1t#d1NM)jEqIlgbwy1a0V%;jZXnO_2zfwfDE6*hy2 z!P-G;VGl?x?gc5qEQsRRkiCA*-aiSF-?Jcz{3Cn+yQSzqwfY(!5O0AL;5JBST8%y~ z0{tMhxYJ&Df#@=efs}v&QbI3*P&IoUq(EqH zF`2QvD4Js+1$q~xR-Ok*8=r%e`M37^21tqg0XjgOTw%~%M-2>;C=4Hdo9#K8S}4j7 zQn8QH{cph}2txsd$|>vhFd9@536KJXU`;USYjPkqbHgaXwXk*=4LS;{mc&fQL}x#B zY_Jyry8m7**1)Jb7i=SpDsO;M>$bpXG#0^HLFy3cgT_i2seEG4u}qAri3wN>dknT2 zwi?z3+l2UR6>KKV10(U#SO+5kO$<&GXDP-mH72zT?^aVH6XV;}flN#oikfk8pU>Uo zZ{$5f(}n5c11S&Rg?Uzt9ZIUEo)mmzqqjN0Q)<$~{edPIH{^ztw^tkp@->0LTE0Hu zcQ^Rl{tZrk&yeo4P*OqOB6vcRy_@STSLy1q`qo~G9_C>0EU zn&fE_lkjvWvxH&v2fbd?G(C}wN7dq<{*<@AbzegAu0o^WCagp>p$(FMS8n=Gbx%?l zs;NX}@%xYxNhzu!(Z#Wm)aVe}NuP5%gvqW6Q6P#Q{pPov`5AUioten-F2sjmZQp- zublJQOzVnsS-!-%$uU=ps|N2Dx^Ajktj&s)xl8$TQq!rs)<{`n{(9Nd4r_14!CIM$ zs%go362e%m^NcjxSdS8mOCx`|V&RO62Dd-p_OIu@=3u~Q-JDlf-r)8%x_!;u?+Z3s z)s;O<-20?R2YGl)SLgmMogKU-9Bxl3bU;?L@>uQT?rv4a6vG`BnfQQ+%OFWy(G%8h zm9d^KOwF zYEj}zgJ_CaR?Q4znw42w>-LQq9lpPg!clSO-lE2n(LTwegS~JgxjC3rGXl4%;A(oo zO%eN~SSgIajZw|fA-K=Ax~Bj3fog{XTkZu1tz4Pj!M~{;ejxW;;o{hyvRuZqGTomN zS{6N0qX{*Z9UY1eMiV?Mc{ZY`+9!FFhq{WFLE)hekMsYFpWXRyW|dd1%b%Mcnw>AH zIpC=7QqWM5Rz`;np=WtQ=wpXOn{{fjx3UMf0R8V99nPZlrnJTvhx5B@&p52gy2I7@ VU)0C8syu_8xH@?iUakAe@eicWSM2}* diff --git a/src/wolnelektury/locale/pl/LC_MESSAGES/django.po b/src/wolnelektury/locale/pl/LC_MESSAGES/django.po index 6a6ad3450..dd6f34fcc 100644 --- a/src/wolnelektury/locale/pl/LC_MESSAGES/django.po +++ b/src/wolnelektury/locale/pl/LC_MESSAGES/django.po @@ -7,35 +7,18 @@ msgid "" msgstr "" "Project-Id-Version: WolneLektury\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-12-16 09:20+0100\n" -"PO-Revision-Date: 2013-04-09 10:43+0100\n" +"POT-Creation-Date: 2015-12-31 16:45+0100\n" +"PO-Revision-Date: 2015-12-31 16:45+0100\n" "Last-Translator: Radek Czajka \n" -"Language-Team: LANGUAGE \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Translated-Using: django-rosetta 0.5.6\n" -"X-Poedit-Language: Polish\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " -"|| n%100>=20) ? 1 : 2)\n" - -#: views.py:34 views.py:35 templates/superbase.html:85 -msgid "Sign in" -msgstr "Zaloguj się" - -#: views.py:41 views.py:62 -#, python-format -msgid "Already logged in as user %(user)s" -msgstr "Zalogowano jako %(user)s" - -#: views.py:53 views.py:54 views.py:82 templates/superbase.html:89 -msgid "Register" -msgstr "Załóż konto" - -#: views.py:77 -msgid "You have to be logged in to continue" -msgstr "Zaloguj się, aby kontynuować" +"|| n%100>=20) ? 1 : 2);\n" +"Language-Team: \n" +"X-Generator: Poedit 1.8.4\n" #: templates/404.html:5 msgid "Page does not exist" @@ -83,175 +66,6 @@ msgstr "" "Serwis Wolnelektury.pl jest obecnie niedostępny z powodu prac " "konserwacyjnych." -#: templates/main_page.html:6 templates/main_page.html.py:7 -msgid "Wolne Lektury internet library" -msgstr "Biblioteka internetowa Wolne Lektury" - -#: templates/main_page.html:23 -msgid "What's new?" -msgstr "Co nowego?" - -#: templates/main_page.html:31 -msgid "Recent publications" -msgstr "Ostatnie publikacje" - -#: templates/main_page.html:41 -msgid "News" -msgstr "Aktualności" - -#: templates/main_page.html:50 -msgid "Utilities" -msgstr "Narzędzia" - -#: templates/main_page.html:53 -msgid "Report a bug or suggestion" -msgstr "Zgłoś błąd lub sugestię" - -#: templates/main_page.html:56 -msgid "Download the catalogue in PDF format." -msgstr "Pobierz katalog w formacie PDF." - -#: templates/main_page.html:58 -msgid "Widget" -msgstr "Widget" - -#: templates/main_page.html:59 -msgid "Missing a book?" -msgstr "Nie znalazłeś/-aś utworu?" - -#: templates/main_page.html:60 templates/publish_plan.html:4 -#: templates/publish_plan.html.py:8 -msgid "Publishing plan" -msgstr "Plan publikacji" - -#: templates/main_page.html:71 -msgid "Information" -msgstr "Informacje" - -#: templates/main_page.html:73 -msgid "Privacy policy" -msgstr "Polityka prywatności" - -#: templates/main_page.html:98 -msgid "Image used:" -msgstr "Użyto obrazu:" - -#: templates/superbase.html:18 -msgid "Wolne Lektury" -msgstr "Wolne Lektury" - -#: templates/superbase.html:55 -#, python-format -msgid "" -"\n" -"
    %(c)s free reading you have right to\n" -" " -msgid_plural "" -"\n" -" %(c)s free readings you have right to\n" -" " -msgstr[0] "" -"\n" -" %(c)s darmowy utwór do której masz prawo\n" -" " -msgstr[1] "" -"\n" -" %(c)s darmowe utwory do których masz prawo\n" -" " -msgstr[2] "" -"\n" -" %(c)s darmowych utworów do których " -"masz prawo\n" -" " - -#: templates/superbase.html:66 -msgid "Welcome" -msgstr "Witaj" - -#: templates/superbase.html:72 templates/user.html:12 -msgid "Password" -msgstr "Hasło" - -#: templates/superbase.html:73 templates/user.html:13 -msgid "E-mail" -msgstr "E-mail" - -#: templates/superbase.html:74 templates/user.html:14 -msgid "Social accounts" -msgstr "Konta społecznościowe" - -#: templates/superbase.html:77 -msgid "My shelf" -msgstr "Moja półka" - -#: templates/superbase.html:79 -msgid "Administration" -msgstr "Administracja" - -#: templates/superbase.html:81 -msgid "Logout" -msgstr "Wyloguj" - -#: templates/superbase.html:111 -msgid "Search" -msgstr "Szukaj" - -#: templates/superbase.html:131 -msgid "Language versions" -msgstr "Wersje językowe" - -#: templates/superbase.html:165 -msgid "" -"\n" -"\t\t\t\tWolne Lektury is a project lead by Modern Poland Foundation.\n" -"\t\t\t\tDigital reproductions are made by The National Library, Biblioteka Śląska and Biblioteka Elbląska, based on TNL, BŚ and BE resources.\n" -"\t\t\t\tHosting: ICM.\n" -"\t\t\t\t" -msgstr "" -"\n" -"Wolne Lektury to projekt prowadzony przez fundację Nowoczesna Polska. \n" -"Reprodukcje cyfrowe wykonane przez Bibliotekę Narodową, Bibliotekę Śląską i Bibliotekę Elbląską z egzemplarzy pochodzących ze zbiorów BN, BŚ i " -"BE.\n" -"Hosting: ICM." - -#: templates/superbase.html:172 -msgid "" -"\n" -"\t\t\t\tModern Poland Foundation, 00-514 Warsaw, ul. Marszałkowska 84/92 " -"lok. 125, tel/fax: (22) 621-30-17\n" -" e-mail: fundacja@nowoczesnapolska.org.pl\n" -"\t\t\t\t" -msgstr "" -"\n" -"Fundacja Nowoczesna Polska, 00-514 Warszawa, ul. Marszałkowska 84/92 lok. " -"125, tel/fax: (22) 621-30-17, e-mail: fundacja@nowoczesnapolska.org.pl" - -#: templates/superbase.html:189 -msgid "Close" -msgstr "Zamknij" - -#: templates/superbase.html:191 -msgid "Loading" -msgstr "Ładowanie" - -#: templates/user.html:5 templates/user.html.py:9 -msgid "User" -msgstr "Użytkownik" - #: templates/admin/base_site.html:4 templates/admin/base_site.html.py:7 msgid "Site administration" msgstr "Administracja stroną" @@ -273,15 +87,15 @@ msgstr "uproszczone" msgid "Import book" msgstr "Importuj książkę" -#: templates/auth/login.html:10 +#: templates/auth/login.html:12 msgid "Forgot Password?" msgstr "Nie pamiętasz hasła?" -#: templates/auth/login.html:15 templates/auth/register.html:7 +#: templates/auth/login.html:17 templates/auth/register.html:7 msgid "Sign in using:" msgstr "Zaloguj się używając:" -#: templates/auth/login_register.html:9 +#: templates/auth/login_register.html:10 msgid "or register" msgstr "albo załóż konto" @@ -332,6 +146,63 @@ msgstr "" msgid "More..." msgstr "Więcej..." +#: templates/main_page.html:7 templates/main_page.html.py:8 +msgid "Wolne Lektury internet library" +msgstr "Biblioteka internetowa Wolne Lektury" + +#: templates/main_page.html:34 +msgid "Theme" +msgstr "Motyw" + +#: templates/main_page.html:85 +msgid "Recent publications" +msgstr "Ostatnie publikacje" + +#: templates/main_page.html:89 +msgid "More recent publications" +msgstr "Więcej ostatnich publikacji" + +#: templates/main_page.html:95 +msgid "News" +msgstr "Aktualności" + +#: templates/main_page.html:101 +msgid "Utilities" +msgstr "Narzędzia" + +#: templates/main_page.html:104 +msgid "Report a bug or suggestion" +msgstr "Zgłoś błąd lub sugestię" + +#: templates/main_page.html:106 +msgid "Download the catalogue in PDF format." +msgstr "Pobierz katalog w formacie PDF." + +#: templates/main_page.html:107 +msgid "Footnotes" +msgstr "Przypisy" + +#: templates/main_page.html:108 +msgid "Missing a book?" +msgstr "Nie znalazłeś/-aś utworu?" + +#: templates/main_page.html:109 templates/publish_plan.html:4 +#: templates/publish_plan.html.py:8 +msgid "Publishing plan" +msgstr "Plan publikacji" + +#: templates/main_page.html:120 +msgid "Information" +msgstr "Informacje" + +#: templates/main_page.html:122 +msgid "Privacy policy" +msgstr "Polityka prywatności" + +#: templates/main_page.html:142 +msgid "Image used:" +msgstr "Użyto obrazu:" + #: templates/openid/login.html:6 templates/openid/login.html.py:10 msgid "OpenID Sign In" msgstr "Logowanie przez OpenID" @@ -364,32 +235,32 @@ msgstr "" "Potwierdź dostęp do Wolnych Lektur jako użytkownik %(user)s." #: templates/socialaccount/connections.html:5 -#: templates/socialaccount/connections.html:8 +#: templates/socialaccount/connections.html:10 msgid "Account Connections" msgstr "Powiązania konta" -#: templates/socialaccount/connections.html:12 +#: templates/socialaccount/connections.html:13 msgid "" "You can sign in to your account using any of the following third party " "accounts:" msgstr "" "Możesz się zalogować na swoje konto używając następujących kont zewnętrznych:" -#: templates/socialaccount/connections.html:36 +#: templates/socialaccount/connections.html:37 msgid "Remove" msgstr "Usuń" -#: templates/socialaccount/connections.html:44 +#: templates/socialaccount/connections.html:45 msgid "" "You currently have no social network accounts connected to this account." msgstr "Aktualnie do Twojego konta nie są podłączone żadne konta zewnętrzne." -#: templates/socialaccount/connections.html:47 +#: templates/socialaccount/connections.html:48 msgid "Add a 3rd Party Account" msgstr "Dodaj konto zewnętrzne" #: templates/socialaccount/login_cancelled.html:5 -#: templates/socialaccount/login_cancelled.html:9 +#: templates/socialaccount/login_cancelled.html:10 msgid "Login Cancelled" msgstr "Anulowano logowanie" @@ -403,6 +274,158 @@ msgstr "" "Logowanie przy użyciu zewnętrznego konta zostało anulowane. Jeśli był to " "błąd, przejdź do strony logowania." +#: templates/superbase.html:21 +msgid "Wolne Lektury" +msgstr "Wolne Lektury" + +#: templates/superbase.html:51 +#, python-format +msgid "" +"\n" +" %(c)s free reading you have right to\n" +" " +msgid_plural "" +"\n" +" %(c)s free readings you have right to\n" +" " +msgstr[0] "" +"\n" +" %(c)s darmowy utwór do której masz prawo\n" +" " +msgstr[1] "" +"\n" +" %(c)s darmowe utwory do których masz prawo\n" +" " +msgstr[2] "" +"\n" +" %(c)s darmowych utworów do których " +"masz prawo\n" +" " + +#: templates/superbase.html:61 +msgid "Language" +msgstr "Język" + +#: templates/superbase.html:85 +msgid "My shelf" +msgstr "Moja półka" + +#: templates/superbase.html:88 +msgid "Administration" +msgstr "Administracja" + +#: templates/superbase.html:90 +msgid "Logout" +msgstr "Wyloguj" + +#: templates/superbase.html:93 views.py:67 views.py:68 +msgid "Sign in" +msgstr "Zaloguj się" + +#: templates/superbase.html:93 views.py:86 views.py:87 views.py:115 +msgid "Register" +msgstr "Załóż konto" + +#: templates/superbase.html:100 +msgid "Literature" +msgstr "Literatura" + +#: templates/superbase.html:101 +msgid "Themes" +msgstr "Motywy" + +#: templates/superbase.html:102 +msgid "Audiobooks" +msgstr "Audiobooki" + +#: templates/superbase.html:103 +msgid "Gallery" +msgstr "Galeria" + +#: templates/superbase.html:114 +msgid "Search" +msgstr "Szukaj" + +#: templates/superbase.html:142 +msgid "Close" +msgstr "Zamknij" + +#: templates/superbase.html:144 +msgid "Loading" +msgstr "Ładowanie" + +#: templates/user.html:5 templates/user.html.py:11 +msgid "User" +msgstr "Użytkownik" + +#: templates/user.html:13 +msgid "Password" +msgstr "Hasło" + +#: templates/user.html:14 +msgid "E-mail" +msgstr "E-mail" + +#: templates/user.html:15 +msgid "Social accounts" +msgstr "Konta społecznościowe" + +#: views.py:74 views.py:95 +#, python-format +msgid "Already logged in as user %(user)s" +msgstr "Zalogowano jako %(user)s" + +#: views.py:110 +msgid "You have to be logged in to continue" +msgstr "Zaloguj się, aby kontynuować" + +#~ msgid "What's new?" +#~ msgstr "Co nowego?" + +#~ msgid "Widget" +#~ msgstr "Widget" + +#~ msgid "Welcome" +#~ msgstr "Witaj" + +#~ msgid "" +#~ "\n" +#~ "\t\t\t\tWolne Lektury is a project lead by Modern Poland Foundation.\n" +#~ "\t\t\t\tDigital reproductions are made by The National Library, Biblioteka Śląska and Biblioteka Elbląska, based on TNL, BŚ and BE resources.\n" +#~ "\t\t\t\tHosting: ICM.\n" +#~ "\t\t\t\t" +#~ msgstr "" +#~ "\n" +#~ "Wolne Lektury to projekt prowadzony przez fundację Nowoczesna Polska. \n" +#~ "Reprodukcje cyfrowe wykonane przez Bibliotekę Narodową, Bibliotekę Śląską i Bibliotekę Elbląską z egzemplarzy pochodzących ze zbiorów BN, BŚ i " +#~ "BE.\n" +#~ "Hosting: ICM." + +#~ msgid "" +#~ "\n" +#~ "\t\t\t\tModern Poland Foundation, 00-514 Warsaw, ul. Marszałkowska 84/92 " +#~ "lok. 125, tel/fax: (22) 621-30-17\n" +#~ " e-mail: fundacja@nowoczesnapolska.org.pl\n" +#~ "\t\t\t\t" +#~ msgstr "" +#~ "\n" +#~ "Fundacja Nowoczesna Polska, 00-514 Warszawa, ul. Marszałkowska 84/92 lok. " +#~ "125, tel/fax: (22) 621-30-17, e-mail: fundacja@nowoczesnapolska.org.pl" + #~ msgid "Listing of all audiobooks" #~ msgstr "Spis wszystkich audiobooków" @@ -424,9 +447,6 @@ msgstr "" #~ msgid "See also" #~ msgstr "Zobacz też" -#~ msgid "Theme" -#~ msgstr "Motyw" - #~ msgid "in work " #~ msgstr "w utworze" @@ -515,9 +535,6 @@ msgstr "" #~ msgid "Table of contents" #~ msgstr "Spis treści" -#~ msgid "Themes" -#~ msgstr "Motywy" - #~ msgid "Edit. note" #~ msgstr "Nota red." @@ -631,9 +648,6 @@ msgstr "" #~ msgid "All books" #~ msgstr "Wszystkie utwory" -#~ msgid "Audiobooks" -#~ msgstr "Audiobooki" - #~ msgid "DAISY" #~ msgstr "DAISY" @@ -685,8 +699,8 @@ msgstr "" #~ msgid "" #~ "Audiobooks were prepared as a part of the %(cs)s project funded by %(fb)s." #~ msgstr "" -#~ "Audiobooki przygotowane w ramach projektu %(cs)s finansowanego przez %(fb)" -#~ "s." +#~ "Audiobooki przygotowane w ramach projektu %(cs)s finansowanego przez " +#~ "%(fb)s." #~ msgid "Audiobooks were prepared as a part of the %(cs)s project." #~ msgstr "Audiobooki przygotowane w ramach projektu %(cs)s." diff --git a/src/wolnelektury/settings/custom.py b/src/wolnelektury/settings/custom.py index 8830ebe6f..fd8a42602 100644 --- a/src/wolnelektury/settings/custom.py +++ b/src/wolnelektury/settings/custom.py @@ -1,3 +1,6 @@ +import os +from .paths import VAR_DIR + # limit number of filtering tags MAX_TAG_LIST = 6 @@ -15,3 +18,5 @@ CATALOGUE_CUSTOMPDF_RATE_LIMIT = '1/m' LIBRARIAN_PDF_MOREFLOATS = None LATEST_BLOG_POSTS = "http://nowoczesnapolska.org.pl/feed/?cat=-135" + +CATALOGUE_COUNTERS_FILE = os.path.join(VAR_DIR, 'catalogue_counters.p') diff --git a/src/wolnelektury/settings/static.py b/src/wolnelektury/settings/static.py index 027879a33..625b4c77f 100644 --- a/src/wolnelektury/settings/static.py +++ b/src/wolnelektury/settings/static.py @@ -16,11 +16,13 @@ STATIC_URL = '/static/' # CSS and JavaScript file groups PIPELINE = { + 'PIPELINE_ENABLED': False, 'STYLESHEETS': { 'main': { # styles both for mobile and for big screen 'source_filenames': [ 'css/jquery.countdown.css', + 'jplayer/jplayer.blue.monday.css', 'sponsors/css/sponsors.css', @@ -77,6 +79,7 @@ PIPELINE = { 'js/contrib/jquery.cycle.min.js', 'js/contrib/jquery.jqmodal.js', 'js/contrib/jquery.form.js', + 'js/contrib/jquery.paging.min.js', 'js/contrib/jquery.countdown.js', 'js/contrib/jquery.countdown-pl.js', 'js/contrib/jquery.countdown-de.js', 'js/contrib/jquery.countdown-uk.js', 'js/contrib/jquery.countdown-es.js', 'js/contrib/jquery.countdown-lt.js', @@ -84,6 +87,10 @@ PIPELINE = { 'js/contrib/jquery-ui-1.8.16.custom.min.js', + 'jplayer/jquery.jplayer.min.js', + 'jplayer/jplayer.playlist.min.js', + 'player/player.js', + 'js/locale.js', 'js/dialogs.js', 'js/base.js', diff --git a/src/wolnelektury/static/js/base.js b/src/wolnelektury/static/js/base.js index f2a8e262a..52834687b 100644 --- a/src/wolnelektury/static/js/base.js +++ b/src/wolnelektury/static/js/base.js @@ -98,7 +98,7 @@ menu_loaded = true; }); } - } + } }); }); /* this kinda breaks the whole page. */ @@ -108,7 +108,7 @@ while (p.length) { if (p == $current) return; - if (p.hasClass('hidden-box-trigger') + if (p.hasClass('hidden-box-trigger') || p.hasClass('simple-toggler') || p.hasClass('mini-search')) return; @@ -118,12 +118,15 @@ $current = null; }); })(); - + $('#show-menu').click(function(event) { event.preventDefault(); - $('#menu').toggle('slow'); + //$('#menu').toggle('slow'); + $('body').toggleClass('menu-on'); }); + + $('#book-list-nav h2').click(function(event) { event.preventDefault(); $('#book-list-nav-index').toggle(); @@ -152,16 +155,76 @@ $('#themes-list-toggle').click(function(event) { $('body').on('click', '.simple-toggler' , function(ev) { ev.preventDefault(); var scope = $(this).closest('.simple-toggler-scope'); - scope.find('.simple-hidden-box').each(function(){ + scope.find('.simple-hidden-box').each(function(){ var $this = $(this); if ($this.is(':hidden')) { $this.show(); - } else { + } else { $this.hide(); } }); }); + + $('.tabbed-filter').each(function() { + var tf = this; + $('.tab').click(function() { + if ($(this).hasClass('active')) { + $(this).removeClass('active'); + $('#' + $(this).attr('data-id')).hide(); + } + else { + var $active = $('.active', tf); + $active.removeClass('active'); + $('#' + $active.attr('data-id')).hide(); + $(this).addClass('active'); + $('#' + $(this).attr('data-id')).show(); + } + }); + }); + + + $('.plain-list-paged').each(function() { + // should change on resize? + var $plc = $(this); + var $pl = $('.plain-list', this); + + var $items = $('p', $pl); + + if ($items.length > 40) { + $items.hide(); + var prev = [0, 0]; + + $('.pager', $plc).paging($items.length, { + format: '[< ncnnn >]', // define how the navigation should look like and in which order onFormat() get's called + perpage: 40, + lapping: 0, // don't overlap pages for the moment + page: 1, // start at page, can also be "null" or negative + onSelect: function (page) { + var data = this.slice; + $items.slice(prev[0], prev[1]).hide(); + $items.slice(data[0], data[1]).show(); + prev = data; + }, + onFormat: function (type) { + switch (type) { + case 'block': // n and c + return ' ' + this.value + ' '; + case 'next': // > + return ' > '; + case 'prev': // < + return ' < '; + case 'first': // [ + return '« '; + case 'last': // ] + return ' »'; + } + } + }); + } + }); + + }); })(jQuery); diff --git a/src/wolnelektury/static/js/contrib/jquery.paging.min.js b/src/wolnelektury/static/js/contrib/jquery.paging.min.js new file mode 100644 index 000000000..da169cb26 --- /dev/null +++ b/src/wolnelektury/static/js/contrib/jquery.paging.min.js @@ -0,0 +1,14 @@ +/* +jQuery paging plugin v1.3.0 23/06/2014 +http://www.xarg.org/2011/09/jquery-pagination-revised/ + +Copyright (c) 2011, Robert Eisele (robert@xarg.org) +Dual licensed under the MIT or GPL Version 2 licenses. +*/ +(function(n,v,r){n.fn.paging=function(z,A){var t=this,b={setOptions:function(a){b.a=n.extend(b.a||{lapping:0,perpage:10,page:1,refresh:{interval:10,url:null},format:"",lock:!1,circular:!1,onClick:null,onFormat:function(){},onSelect:function(){return!0},onRefresh:function(){}},a||{});b.a.lapping|=0;b.a.perpage|=0;null!==b.a.page&&(b.a.page|=0);1>b.a.perpage&&(b.a.perpage=10);b.interval&&v.clearInterval(b.interval);b.a.refresh.url&&(b.interval=v.setInterval(function(){n.ajax({url:b.a.refresh.url,success:function(a){if("string"=== +typeof a)try{a=n.parseJSON(a)}catch(m){return}b.a.onRefresh(a)}})},1E3*b.a.refresh.interval));b.format=function(a){for(var b=0,f=0,h=1,g={g:[],i:0,h:0,b:5,current:3,l:0,m:0},c,p=/[*<>pq\[\]().-]|[nc]+!?/g,n={"[":"first","]":"last","<":"prev",">":"next",q:"left",p:"right","-":"fill",".":"leap"},e={};c=p.exec(a);)c=""+c,r===n[c]?"("===c?f=++b:")"===c?f=0:h&&("*"===c?(g.i=1,g.h=0):(g.i=0,g.h="!"===c.charAt(c.length-1),g.b=c.length-g.h,(g.current=1+c.indexOf("c"))||(g.current=1+g.b>>1)),g.g.push({f:"block", +j:0,c:0}),h=0):(g.g.push({f:n[c],j:f,c:r===e[c]?e[c]=1:++e[c]}),"q"===c?++g.m:"p"===c&&++g.l);return g}(b.a.format);return b},setNumber:function(a){b.s=r===a||0>a?-1:a;return b},setPage:function(a){function w(a,b,c){c=""+a.onFormat.call(b,c);p=b.value?p+c.replace(/m?(c=m=-1,h=Math.max(1,a-e.current+1-q),g=h+e.b):(c=1+Math.ceil((m-f.perpage)/(f.perpage-q)),a=Math.max(1,Math.min(0>a?1+c+a:a,c)),e.i?(h=1,g=1+c,e.current=a,e.b=c):(h=Math.max(1,Math.min(a-e.current,c-e.b)+1),g=e.h?h+e.b:Math.min(h+e.b,1+c)));for(;u--;){k=0;l=e.g[u];switch(l.f){case "left":k=l.c>l.j&1;switch(l.f){case "block":for(;hm,d.first=1===h,d.last=h===c&&0m)?d.value=1+a:(d.value=c,d.active=k&&am)?d.value=1+a:(d.value=Math.min(1+a,c),d.active=k&&a"; - } + .note { + position: absolute; + right: 0; + top: 1px; + width: 139px; + height: 289px - 22px; } } } @@ -254,3 +211,53 @@ } } } + +.more { + display: block; + margin-top: .5em; +} + + +section { + margin-top: 2em; +} + + +.tag-box-section { + @media screen and (min-width: 768px) { + display: inline-block; + width: 48%; + margin-right: 2%; + vertical-align: top; + + .tag-box { + display: block; + width: 100%; + } + } +} + +#main-theme { + .white-box { + position: relative; + + .cite { + display: none; + + @media screen and (min-width: 768px) { + display: block; + position: absolute; + right: 1em; + top: 7em; + background: #F7F7F7; + width: 200px; + padding-left: 20px; + } + + @media screen and (min-width: 1024px) { + width: 340px; + padding-left: 80px; + } + } + } +} diff --git a/src/wolnelektury/static/scss/main/menu.scss b/src/wolnelektury/static/scss/main/menu.scss index 846e4c88c..c2f708a0e 100755 --- a/src/wolnelektury/static/scss/main/menu.scss +++ b/src/wolnelektury/static/scss/main/menu.scss @@ -1,175 +1,146 @@ -#nav-line { - background-color: #e2e2e2; - position: relative; +/* ok */ - @media screen and (min-width: 62.5em) { - @include size(width, 975px); - margin: auto; - } +$menu_width: 200px; - #show-menu { - display: block; - float: left; - @include size(line-height, 13px); - @include size(padding, 18px 13px); - color: #0c7076; - @include size(font-size, 11px); - @include mono; - .long { - display: none; - - &:after { - @include size(padding-left, 10px); - content: url("/static/img/arrow-gray.png"); - vertical-align: top; - } - } +/* This is duplication of code for reader menu button. */ +%menu-toggle { + position: relative; + padding: 0; + &:before { + content: ""; + position: absolute; + top: 8px; + height: 5px; + border-top: 15px double #ddd; + border-bottom: 5px solid #ddd; + } +} - @media screen and (min-width: 20em) { - .long { display: inline; } - .short { display: none; } - } - @media screen and (min-width: 53em) { - display: none; - } +#show-menu { + @extend %menu-toggle; + display: block; + background: #191919; + color: #ddd; + text-align: center; + z-index: 100; + @include size(width, 44px); + @include size(height, 44px); + padding: 0; + position: absolute; + left: 10px; + top: 25px; + + &:before { + left: 8px; + right: 8px; } - ul#menu { - list-style: none; - padding: 0; - margin: 0; - + @media screen and (min-width: 1024px) { display: none; - position: absolute; - @include size(top, 49px); - left: 0; - @include size(right, 10px); - z-index: 400; - - @media screen and (min-width: 24em) { - right: auto; - } - - @media screen and (min-width: 53em) { - display: block !important; - position: static; - @include size(margin-left, 6px); - } - - li.menu { - background-color: #e2e2e2; + } +} - @media screen and (min-width: 53em) { - float: left; - } +body.menu-on { + margin-left: $menu_width; + margin-right: -$menu_width; - a.menu { - display: block; - @include size(line-height, 13px); - @include size(padding, 18px 12px 15px); - @include size(border-bottom, 3px solid #e2e2e2); - color: #0c7076; - @include size(font-size, 11px); - @include mono; - } + @media screen and (min-width: 1024px) { + margin-left: 0; + margin-right: 0; + } - a.hidden-box-trigger:hover { - border-bottom-color: white; - } - } + #menu { + display: block; } +} - #lang-menu { +#menu { + display: none; + position: fixed; + left: 0; + top: 0; + width: $menu_width; + background: #141414; + height: 100%; + overflow-y: auto; + z-index: 90; + + @media screen and (min-width: 1024px) { display: block; - float: right; + width: 975px; + height: 0; + overflow: visible; + margin: auto; + position: absolute; + top: 0; + } - background: #f7f7f7; - @include mono; + ul { + list-style: none; + padding: 0; - @media screen and (min-width: 15em) { - position: relative; + li { + padding: .5em 1em; + + @media screen and (min-width: 1024px) { + padding: 0; + } } + } +} - #lang-button { - @include size(padding-left, 25px); - @include size(padding-right, 20px); - display:block; - @include size(line-height, 17px); - @include size(padding-top, 16px); - @include size(padding-bottom, 16px); - @include size(font-size, 10px); - color: #717171; - .label { - display: none; +@media screen and (min-width: 1024px) { + #user-info { + @include mono; + position: absolute; + right: 150px; + top: 4px; + @include size(font-size, 10px); + list-style: none; - @media screen and (min-width: 62.5em) { - display: inline; - } + li { + display: inline; - &:after { - @include size(padding-left, 10px); - content: url("/static/img/arrow-gray.png"); - vertical-align: top; - } + &:after { + content: " | "; } - - .lang-flag { - @include size(font-size, 13px); - @include size(line-height, 15px); + &:last-child:after { + content: ""; } } + } - #lang-menu-items { - z-index: 9999; + #main-menu { + list-style: none; + padding: 0; + margin: 0; - button { - @include mono; - display: none; - background: #f7f7f7; - color: #6f6f6f; - cursor: pointer; - width: 100%; - margin: 0; - @include size(padding, 10px 0); - - @media screen and (min-width: 62.5em) { - @include size(padding, 5px 0); - } + background-color: #e2e2e2; + position: absolute; + top: 94px; + @include size(width, 975px); - border-width: 0; - @include size(border-bottom, 1px solid #ddd); + li { + display: inline-block; + @include size(width, 20%); - @include size(font-size, 13px); + a { + text-align: center; + display: block; + @include size(line-height, 13px); + @include size(padding, 18px 0 15px); + @include size(border-bottom, 3px solid #e2e2e2); + color: #0c7076; + @include size(font-size, 11px); + @include mono; &.active { - color: #000; - } - } - } - - &:hover, &.hover { - #lang-menu-items { - position: absolute; - padding: 0; - left: 0; - right: 0; - - @media screen and (min-width: 15em) { - left: auto; - @include size(width, 180px); - @include size(top, 49px); - } - @media screen and (min-width: 62.5em) { - width: 100%; - } - - button { - display: block; + border-bottom-color: white; } } } diff --git a/src/wolnelektury/static/scss/main/picture_box.scss b/src/wolnelektury/static/scss/main/picture_box.scss index 69d34a398..037774179 100644 --- a/src/wolnelektury/static/scss/main/picture_box.scss +++ b/src/wolnelektury/static/scss/main/picture_box.scss @@ -17,7 +17,7 @@ margin-left: 0; } - + @media screen and (min-width: 62.5em) { .book-box-head, .tags, .book-box-tools { float: right; @@ -60,12 +60,3 @@ } } - -.work-list { - .Picture-item { - @include min-screen($S_BOOK_SHORT_FULL) { - display: inline-block; - } - vertical-align: top; - } -} diff --git a/src/wolnelektury/static/scss/main/tag.scss b/src/wolnelektury/static/scss/main/tag.scss index d120a3f97..1e1801c13 100755 --- a/src/wolnelektury/static/scss/main/tag.scss +++ b/src/wolnelektury/static/scss/main/tag.scss @@ -1,8 +1,89 @@ -.page-desc { - @include size(margin-left, 15px); +.tabbed-filter { + position: relative; + border-bottom: 1px solid #ddd; + padding-bottom: 4em; + + @media screen and (min-width: 375px) { + padding-bottom: 2em; + } + + @media screen and (min-width: 1024px) { + padding-bottom: 0; + } + + + .tabs { + position: absolute; + right: 0; + bottom: 0; + float: right; + text-align: right; + + .tab { + cursor: pointer; + display: inline-block; + margin-bottom: -1px; + box-shadow: none; + + &.active { + border-bottom-color: white; + } + } + } } +.tabbed-filter-contents { + margin-bottom: 2em; + .tab-content { + display: none; + border-top: none; + + ul { + list-style: none; + margin-left: 0; + padding-left: 10px; + + li { + display: inline-block; + margin-right: 1em; + border-radius: 1em; + padding: .5em; + + &.header { + width: 6em; + } + + &.active { + background: #0D7E85; + color: #ddd; + + a { + display: inline-block; + width: 1.5em; + text-align: center; + margin-left: .5em; + border-radius: 1em; + background: white; + } + } + + &.other { + a { + color: #ddd; + } + } + } + } + } +} + + #tagged-object-list { + + + + + @media screen and (min-width: 62.5em) { .left-column, .right-column { @include size(width, 480px); diff --git a/src/wolnelektury/static/scss/social/shelf_tags.scss b/src/wolnelektury/static/scss/social/shelf_tags.scss index f20fba8b6..9872140bb 100644 --- a/src/wolnelektury/static/scss/social/shelf_tags.scss +++ b/src/wolnelektury/static/scss/social/shelf_tags.scss @@ -1,29 +1,13 @@ .social-shelf-tags { list-style: none; padding: 0; - margin: 10px 0; - @include min-screen($S_BOOK_SHORT_FULL) { - position: absolute; - top: 134px; - left: 152px; - padding: 10px 10px 5px 10px; - margin: 10px 0; - width: 310px; - overflow: hidden; + position: absolute; + top: 10px; + right: 50px; text-overflow: ellipsis; white-space: nowrap; - &:hover { - overflow: visible; - text-overflow: ellipsis; - white-space: normal; - z-index: 1000; - background: #fff; - box-shadow: 0 0 2px #ddd; - } - } - li { display: inline-block; margin-right: .5em; diff --git a/src/wolnelektury/templates/account/base.html b/src/wolnelektury/templates/account/base.html index 6bcdf12cf..ebd628603 100755 --- a/src/wolnelektury/templates/account/base.html +++ b/src/wolnelektury/templates/account/base.html @@ -1,7 +1,9 @@ {% extends "site_base.html" %} {% block body %} +
    {% block content %} {% endblock %} +
    {% endblock %} {% block extrabody %} diff --git a/src/wolnelektury/templates/main_page.html b/src/wolnelektury/templates/main_page.html index f1450cbd6..44f05a8b5 100755 --- a/src/wolnelektury/templates/main_page.html +++ b/src/wolnelektury/templates/main_page.html @@ -14,21 +14,79 @@ {% ssi_include 'social_cite_main' pk=cite_pk %} {{ cite_pk.endif }} +
    +

    W naszej cyfrowej bibliotece znajdziesz

    +
    +
    + {% for b in best %} + {% ssi_include 'catalogue_book_mini' pk=b.pk %} + {% endfor %} +
    +
    + i wiele innych książek, wierszy, obrazów, audiobooków… +
    +
    +
    - -
    -

    {% trans "What's new?" %}

    -
    - {% ssi_include 'chunk' key='promo' %} +
    +

    Motywy i tematy

    +
    +

    {% trans "Theme" %}: {{ theme }}

    +

    Utwory, w których występuje ten motyw:

    + {% for book in theme_books %} + {% ssi_include 'catalogue_book_mini' pk=book.pk %} + {% endfor %} + {% if theme_fragment %} + {% ssi_include 'catalogue_fragment_promo' pk=theme_fragment.pk %} + {% endif %}
    +
    Zobacz katalog motywów +
    + +
    +

    Autorzy

    + + {% ssi_include "catalogue_tag_box" pk=author.pk %} + + Zobacz katalog autorów +
    + +
    +

    Gatunki

    + + {% ssi_include "catalogue_tag_box" pk=genre.pk %} + + Zobacz katalog gatunków +
    + +
    +

    Rodzaje

    + + {% ssi_include "catalogue_tag_box" pk=kind.pk %} + + Zobacz katalog rodzajów
    +
    +

    Epoki

    + + {% ssi_include "catalogue_tag_box" pk=epoch.pk %} + + Zobacz katalog epok +
    -
    -

    {% trans "Recent publications" %}

    +
    +

    Kolekcje

    + {% ssi_include 'catalogue_collection_box' pk=collection.pk %} + Zobacz katalog kolekcji +
    + +
    +

    {% trans "Recent publications" %}

    {% for book in last_published %} {% ssi_include 'catalogue_book_mini' pk=book.pk %} {% endfor %} + {% trans "More recent publications" %}
    @@ -53,7 +111,7 @@
  • OAI-PMH
  • Leśmianator
  • Materiały do nauki j. polskiego
  • - +
    diff --git a/src/wolnelektury/templates/socialaccount/connections.html b/src/wolnelektury/templates/socialaccount/connections.html index 3df16a8c5..0c7316ed4 100644 --- a/src/wolnelektury/templates/socialaccount/connections.html +++ b/src/wolnelektury/templates/socialaccount/connections.html @@ -5,9 +5,10 @@ {% block head_title %}{% trans "Account Connections" %}{% endblock %} {% block body %} +
    +

    {% trans "Account Connections" %}

    -
    {% if form.accounts %}

    {% blocktrans %}You can sign in to your account using any of the following third party accounts:{% endblocktrans %}

    diff --git a/src/wolnelektury/templates/socialaccount/login_cancelled.html b/src/wolnelektury/templates/socialaccount/login_cancelled.html index 7e29b65c7..bee55649a 100644 --- a/src/wolnelektury/templates/socialaccount/login_cancelled.html +++ b/src/wolnelektury/templates/socialaccount/login_cancelled.html @@ -5,10 +5,10 @@ {% block head_title %}{% trans "Login Cancelled" %}{% endblock %} {% block body %} - +
    +

    {% trans "Login Cancelled" %}

    -
    {% url 'socialaccount_login' as login_url %} {{ login_url }} diff --git a/src/wolnelektury/templates/superbase.html b/src/wolnelektury/templates/superbase.html index 08d60a32a..d36f22267 100644 --- a/src/wolnelektury/templates/superbase.html +++ b/src/wolnelektury/templates/superbase.html @@ -36,34 +36,14 @@ {{ current_offer.endif }} {% endif %} +
    + -

    - {% user_username as user_username %} - {% user_is_staff as user_is_staff %} - {{ user_username.if }}{% trans "Welcome" %}, - - {{ user_username }} - - - {% trans "Password" %}
    - {% trans "E-mail" %}
    - {% trans "Social accounts" %}
    -
    -
    | {% trans "My shelf" %} - {{ user_username.endif }} - {{ user_is_staff.if }} | {% trans "Administration" %} - {{ user_is_staff.endif }} - {{ user_username.if }} | {% trans "Logout" %} - {{ user_username.else }} - {% trans "Sign in" %} / {% trans "Register" %} - {{ user_username.endif }} -

    -

    {% url 'book_list' as b %} {% url 'infopage' 'prawa' as r %} @@ -75,24 +55,10 @@ {% endblocktrans %}

    -
    -
    - - {{search_form.q}} -
    -
    - -
    -
    - - - + + + +
    +
    + + {{search_form.q}} +
    +
    + + +
    +
    +
    diff --git a/src/wolnelektury/templates/user.html b/src/wolnelektury/templates/user.html index 0ffdd62a9..fa2f66035 100644 --- a/src/wolnelektury/templates/user.html +++ b/src/wolnelektury/templates/user.html @@ -6,9 +6,10 @@ {% block body %} +
    +

    {% trans "User" %}

    -

    {% trans "Password" %}

    {% trans "E-mail" %}

    {% trans "Social accounts" %}

    diff --git a/src/wolnelektury/views.py b/src/wolnelektury/views.py index 51371735a..0ff2d67fe 100644 --- a/src/wolnelektury/views.py +++ b/src/wolnelektury/views.py @@ -18,16 +18,46 @@ from django.views.decorators.cache import never_cache from ajaxable.utils import AjaxableFormView from ajaxable.utils import placeholdized -from catalogue.models import Book +from catalogue.models import Book, Collection, Tag, Fragment from ssify import ssi_included def main_page(request): - last_published = Book.objects.exclude(cover_thumb='').filter(parent=None).order_by('-created_at')[:4] + ctx = { + 'last_published': Book.objects.exclude(cover_thumb='').filter(parent=None).order_by('-created_at')[:6], + } - return render(request, "main_page.html", { - 'last_published': last_published, - }) + for category in ('author', 'epoch', 'genre', 'kind'): + try: + ctx[category] = Tag.objects.filter(category=category).order_by('?')[:1][0] + except IndexError: + pass + + # FIXME: find this theme and books properly. + ctx['theme_books'] = [] + if Fragment.objects.count(): + while True: + ctx['theme'] = Tag.objects.filter(category='theme').order_by('?')[:1][0] + tf = Fragment.tagged.with_any([ctx['theme']]).order_by('?')[:100] + if not tf: + continue + ctx['theme_fragment'] = tf[0] + for f in tf: + if not f.book in ctx['theme_books']: + ctx['theme_books'].append(f.book) + if len(ctx['theme_books']) == 3: + break + break + + # Choose a collection for main. + try: + ctx['collection'] = Collection.objects.order_by('?')[:1][0] + except IndexError: + pass + + ctx['best'] = Book.objects.order_by('?')[:5] + + return render(request, "main_page.html", ctx) class LoginFormView(AjaxableFormView): -- 2.20.1 From d36673cef5c5f35b1043a03e6c5ddbb7688788ae Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Mon, 4 Jan 2016 13:19:51 +0100 Subject: [PATCH 03/16] Initial not None. --- src/catalogue/models/book.py | 2 +- src/catalogue/models/collection.py | 2 +- src/catalogue/models/tag.py | 2 +- src/catalogue/templatetags/catalogue_tags.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/catalogue/models/book.py b/src/catalogue/models/book.py index 1524c3456..9381afc94 100644 --- a/src/catalogue/models/book.py +++ b/src/catalogue/models/book.py @@ -100,7 +100,7 @@ class Book(models.Model): try: return re.search(r'\w', self.title, re.U).group(0) except AttributeError: - return None + return '' def author_str(self): return ", ".join(str(t) for t in self.tags.filter(category='author')) diff --git a/src/catalogue/models/collection.py b/src/catalogue/models/collection.py index bae1cc418..d51932841 100644 --- a/src/catalogue/models/collection.py +++ b/src/catalogue/models/collection.py @@ -33,7 +33,7 @@ class Collection(models.Model): try: return re.search(r'\w', self.title, re.U).group(0) except AttributeError: - return None + return '' @models.permalink def get_absolute_url(self): diff --git a/src/catalogue/models/tag.py b/src/catalogue/models/tag.py index 5575d6a14..89ca65185 100644 --- a/src/catalogue/models/tag.py +++ b/src/catalogue/models/tag.py @@ -134,7 +134,7 @@ class Tag(TagBase): elif self.name: return self.name[0] else: - return None + return '' @permalink def get_absolute_url(self): diff --git a/src/catalogue/templatetags/catalogue_tags.py b/src/catalogue/templatetags/catalogue_tags.py index fd914e321..ce23e548f 100644 --- a/src/catalogue/templatetags/catalogue_tags.py +++ b/src/catalogue/templatetags/catalogue_tags.py @@ -348,7 +348,7 @@ def work_list(context, object_list): @register.inclusion_tag('catalogue/plain_list.html', takes_context=True) def plain_list(context, object_list, with_initials=True, by_author=False, choice=None, book=None, gallery=False, paged=True): - names = [(None, [])] + names = [('', [])] last_initial = None for obj in object_list: if with_initials: -- 2.20.1 From 274de65ca44c680c6c555c599ec32428c79db356 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Mon, 4 Jan 2016 15:38:01 +0100 Subject: [PATCH 04/16] fix --- fabfile.py | 11 +++++++++-- requirements/requirements-dev.txt | 1 + src/catalogue/tests/tags.py | 9 --------- src/catalogue/tests/visit.py | 1 - src/catalogue/urls.py | 1 - src/catalogue/views.py | 5 ----- 6 files changed, 10 insertions(+), 18 deletions(-) diff --git a/fabfile.py b/fabfile.py index e614e9ce5..bdf0fad40 100644 --- a/fabfile.py +++ b/fabfile.py @@ -1,4 +1,4 @@ -from fnpdjango.deploy import * +from fnpdeploy import * try: from fabfile_local import * except ImportError: @@ -13,6 +13,8 @@ def production(): env.hosts = ['giewont.icm.edu.pl'] env.user = 'lektury' env.app_path = '/srv/wolnelektury.pl' + env.django_root_path = 'src' + env.requirements_file = 'requirements/requirements.txt' env.services = [ Supervisord('wolnelektury'), Supervisord('wolnelektury.celery'), @@ -24,7 +26,12 @@ def beta(): env.hosts = ['giewont.icm.edu.pl'] env.user = 'lektury' env.app_path = '/srv/wolnelektury.pl/beta' - env.services = [] + env.ve = '/srv/wolnelektury.pl/ve' + env.django_root_path = 'src' + env.requirements_file = 'requirements/requirements.txt' + env.services = [ + Supervisord('beta'), + ] @task diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt index 9c428052c..51e044bd0 100644 --- a/requirements/requirements-dev.txt +++ b/requirements/requirements-dev.txt @@ -6,3 +6,4 @@ BabelDjango Fabric sphinx pyinotify +fnpdeploy diff --git a/src/catalogue/tests/tags.py b/src/catalogue/tests/tags.py index 42ea6e245..527775bb8 100644 --- a/src/catalogue/tests/tags.py +++ b/src/catalogue/tests/tags.py @@ -286,12 +286,3 @@ class BookTagsTests(WLTestCase): ['kind']) self.assertEqual([(tag.name, tag.count) for tag in related_themes], [('ChildTheme', 1), ('ParentTheme', 1), ('Theme', 2)]) - - def test_catalogue_tags(self): - """ test main page tags and counts """ - context = self.client.get('/katalog/').context - self.assertEqual([(tag.name, tag.count) for tag in context['categories']['author']], - [('Jim Lazy', 1), ('Common Man', 1)]) - self.assertEqual([(tag.name, tag.count) for tag in context['categories']['theme']], - [('ChildTheme', 1), ('ParentTheme', 1), ('Theme', 2)]) - diff --git a/src/catalogue/tests/visit.py b/src/catalogue/tests/visit.py index cab3c987d..8cfea1290 100644 --- a/src/catalogue/tests/visit.py +++ b/src/catalogue/tests/visit.py @@ -45,7 +45,6 @@ class VisitTest(WLTestCase): 'autor/jane-doe/', 'autor/jane-doe/gatunek/genre/', 'autor/jane-doe/gatunek/genre/motyw/theme/', - 'pl.json', 'b/%d/mini.pl.html' % self.book.pk, 'b/%d/mini_nolink.pl.html' % self.book.pk, 'b/%d/short.pl.html' % self.book.pk, diff --git a/src/catalogue/urls.py b/src/catalogue/urls.py index 35a08e11d..0b33ce96c 100644 --- a/src/catalogue/urls.py +++ b/src/catalogue/urls.py @@ -77,7 +77,6 @@ urlpatterns += patterns('catalogue.views', 'book_fragments', name='book_fragments'), # Includes. - url(r'^(?P[^/]+)\.json$', 'catalogue_json'), url(r'^b/(?P\d+)/mini\.(?P.+)\.html', 'book_mini', name='catalogue_book_mini'), url(r'^b/(?P\d+)/mini_nolink\.(?P.+)\.html', 'book_mini', {'with_link': False}, name='catalogue_book_mini_nolink'), url(r'^b/(?P\d+)/short\.(?P.+)\.html', 'book_short', name='catalogue_book_short'), diff --git a/src/catalogue/views.py b/src/catalogue/views.py index 5a8277f88..a6d6e0023 100644 --- a/src/catalogue/views.py +++ b/src/catalogue/views.py @@ -42,11 +42,6 @@ def catalogue(request, as_json=False): return render(request, 'catalogue/catalogue.html', locals()) -@ssi_included -def catalogue_json(request): - return catalogue(request, True) - - def book_list(request, filter=None, get_filter=None, template_name='catalogue/book_list.html', nav_template_name='catalogue/snippets/book_list_nav.html', -- 2.20.1 From a17eb2013a6d9d0a99352cf1b81a745984756fc3 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Mon, 4 Jan 2016 15:48:32 +0100 Subject: [PATCH 05/16] Specify fnpdeploy version --- requirements/requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt index 51e044bd0..0fe38644e 100644 --- a/requirements/requirements-dev.txt +++ b/requirements/requirements-dev.txt @@ -6,4 +6,4 @@ BabelDjango Fabric sphinx pyinotify -fnpdeploy +fnpdeploy>=0.2.2 -- 2.20.1 From 5221177061d377830cdee4079e57b777b53cb8a7 Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Tue, 5 Jan 2016 15:21:12 +0100 Subject: [PATCH 06/16] django-extensions --- requirements/requirements.txt | 1 + src/wolnelektury/settings/__init__.py | 1 + 2 files changed, 2 insertions(+) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index fcd41c474..b466c0eab 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -12,6 +12,7 @@ jsonfield>=1.0.3,<1.1 django-picklefield django-modeltranslation>=0.10,<0.11 django-allauth>=0.24,<0.25 +django-extensions pytz diff --git a/src/wolnelektury/settings/__init__.py b/src/wolnelektury/settings/__init__.py index 411202d6a..6b0c171da 100644 --- a/src/wolnelektury/settings/__init__.py +++ b/src/wolnelektury/settings/__init__.py @@ -97,6 +97,7 @@ INSTALLED_APPS_CONTRIB = [ 'getpaid', 'getpaid.backends.payu', 'ssify', + 'django_extensions', #allauth stuff 'uni_form', -- 2.20.1 From 2fea31c78fb2dbbbabda91c64aab0760adba517c Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Tue, 5 Jan 2016 15:21:36 +0100 Subject: [PATCH 07/16] fixed when no collections --- src/wolnelektury/templates/main_page.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/wolnelektury/templates/main_page.html b/src/wolnelektury/templates/main_page.html index 44f05a8b5..c037b9f66 100755 --- a/src/wolnelektury/templates/main_page.html +++ b/src/wolnelektury/templates/main_page.html @@ -75,11 +75,13 @@ Zobacz katalog epok
    -
    -

    Kolekcje

    - {% ssi_include 'catalogue_collection_box' pk=collection.pk %} - Zobacz katalog kolekcji -
    + {% if collection %} +
    +

    Kolekcje

    + {% ssi_include 'catalogue_collection_box' pk=collection.pk %} + Zobacz katalog kolekcji +
    + {% endif %}

    {% trans "Recent publications" %}

    -- 2.20.1 From b2d342589a7889a3b096e7192453d53bd28eed7d Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Tue, 12 Jan 2016 10:17:20 +0100 Subject: [PATCH 08/16] pep8 and other code-style changes --- src/ajaxable/utils.py | 11 +- src/api/emitters.py | 23 +- src/api/handlers.py | 47 ++- src/api/helpers.py | 4 +- src/api/management/commands/mobileinit.py | 31 +- src/api/models.py | 5 +- src/api/tests.py | 14 +- src/api/urls.py | 5 +- src/basicauth.py | 7 +- src/catalogue/__init__.py | 11 +- src/catalogue/admin.py | 7 +- src/catalogue/apps.py | 1 + src/catalogue/feeds.py | 7 +- src/catalogue/fields.py | 20 +- src/catalogue/forms.py | 29 +- src/catalogue/helpers.py | 8 +- src/catalogue/import_utils.py | 1 + .../management/commands/checkcovers.py | 9 +- .../management/commands/checkintegrity.py | 9 +- .../management/commands/importbooks.py | 120 +++--- src/catalogue/management/commands/pack.py | 6 +- .../management/commands/report_dead_links.py | 33 +- .../management/commands/savemedia.py | 14 +- src/catalogue/models/book.py | 201 +++++----- src/catalogue/models/bookmedia.py | 34 +- src/catalogue/models/collection.py | 9 +- src/catalogue/models/source.py | 3 +- src/catalogue/models/tag.py | 23 +- src/catalogue/signals.py | 3 +- src/catalogue/templatetags/catalogue_tags.py | 47 ++- src/catalogue/test_utils.py | 2 +- src/catalogue/tests/book_import.py | 184 ++++----- src/catalogue/tests/bookmedia.py | 21 +- src/catalogue/tests/cover.py | 12 +- src/catalogue/tests/search.py | 13 +- src/catalogue/tests/tags.py | 37 +- src/catalogue/tests/templatetags.py | 2 +- src/catalogue/tests/visit.py | 6 +- src/catalogue/translation.py | 3 + src/catalogue/urls.py | 19 +- src/catalogue/utils.py | 25 +- src/catalogue/views.py | 128 +++--- src/chunks/admin.py | 4 + src/chunks/models.py | 8 +- src/chunks/translation.py | 1 + src/chunks/urls.py | 3 +- src/chunks/views.py | 1 + src/dictionary/models.py | 9 +- src/dictionary/tests.py | 5 +- src/dictionary/urls.py | 4 +- src/dictionary/views.py | 19 +- src/funding/admin.py | 7 +- src/funding/forms.py | 14 +- .../management/commands/funding_notify.py | 3 +- src/funding/models.py | 36 +- src/funding/tests.py | 11 +- src/funding/urls.py | 8 +- src/funding/utils.py | 4 +- src/funding/views.py | 32 +- src/funding/widgets.py | 7 +- src/infopages/admin.py | 1 + src/infopages/models.py | 3 +- src/infopages/translation.py | 1 + src/infopages/urls.py | 4 +- src/infopages/views.py | 3 +- .../management/commands/lesmianator.py | 10 +- src/lesmianator/models.py | 7 +- src/lesmianator/urls.py | 4 +- src/lesmianator/views.py | 38 +- src/libraries/models.py | 8 +- src/libraries/urls.py | 3 +- src/libraries/views.py | 4 +- src/newtagging/admin.py | 18 +- src/newtagging/managers.py | 1 - src/newtagging/models.py | 33 +- src/newtagging/views.py | 10 +- src/oai/handlers.py | 379 +++++++++--------- src/oai/tests/oaipmhapi.py | 14 +- src/opds/tests/__init__.py | 16 +- src/opds/urls.py | 3 +- src/opds/views.py | 70 ++-- src/pdcounter/admin.py | 3 +- src/pdcounter/models.py | 7 +- src/pdcounter/templatetags/time_tags.py | 1 + src/pdcounter/views.py | 9 +- src/picture/admin.py | 1 + src/picture/engine.py | 5 +- src/picture/forms.py | 5 +- src/picture/models.py | 80 ++-- src/picture/tasks.py | 1 - src/picture/templatetags/picture_tags.py | 1 + src/picture/tests/picture_import.py | 7 +- src/picture/views.py | 42 +- src/polls/models.py | 4 +- src/polls/templatetags/polls_tags.py | 10 +- src/polls/urls.py | 3 +- src/polls/views.py | 5 +- src/reporting/templatetags/reporting_stats.py | 4 + src/reporting/urls.py | 4 +- src/reporting/utils.py | 14 +- src/reporting/views.py | 23 +- src/search/context_processors.py | 2 +- src/search/custom.py | 51 ++- src/search/fields.py | 14 +- src/search/forms.py | 5 +- src/search/index.py | 125 +++--- src/search/management/commands/reindex.py | 16 +- src/search/management/commands/snippets.py | 19 +- src/search/mock_search.py | 4 +- src/search/templatetags/search_tags.py | 4 +- src/search/tests/index.py | 12 +- src/search/urls.py | 4 +- src/search/views.py | 54 +-- src/social/admin.py | 8 +- src/social/forms.py | 12 +- src/social/models.py | 23 +- src/social/templatetags/social_tags.py | 1 + src/social/urls.py | 15 +- src/social/utils.py | 7 +- src/sortify.py | 4 +- src/sponsors/models.py | 4 +- src/sponsors/urls.py | 3 +- src/sponsors/widgets.py | 3 +- src/stats/models.py | 1 - src/suggest/admin.py | 1 + src/suggest/forms.py | 35 +- src/suggest/models.py | 1 + src/suggest/urls.py | 4 +- src/waiter/settings.py | 1 - src/waiter/urls.py | 3 +- src/wolnelektury/apps.py | 1 + src/wolnelektury/celery.py | 10 +- src/wolnelektury/context_processors.py | 1 + .../management/commands/localepack.py | 40 +- .../management/commands/translation2po.py | 34 +- src/wolnelektury/management/profile.py | 15 +- src/wolnelektury/middleware.py | 43 +- src/wolnelektury/settings/auth.py | 18 +- src/wolnelektury/settings/basic.py | 10 +- src/wolnelektury/settings/cache.py | 4 + src/wolnelektury/settings/celery.py | 4 + src/wolnelektury/settings/contrib.py | 8 +- src/wolnelektury/settings/custom.py | 4 + src/wolnelektury/settings/locale.py | 9 +- src/wolnelektury/settings/paths.py | 5 +- src/wolnelektury/settings/static.py | 280 ++++++------- src/wolnelektury/templatetags/switch_tag.py | 4 + src/wolnelektury/urls.py | 9 +- src/wolnelektury/utils.py | 8 + src/wolnelektury/views.py | 14 +- 150 files changed, 1629 insertions(+), 1557 deletions(-) diff --git a/src/ajaxable/utils.py b/src/ajaxable/utils.py index 89b56228d..c2c368840 100755 --- a/src/ajaxable/utils.py +++ b/src/ajaxable/utils.py @@ -4,8 +4,7 @@ # from functools import wraps -from django.http import (HttpResponse, HttpResponseRedirect, - HttpResponseForbidden) +from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden from django.shortcuts import render_to_response from django.template import RequestContext from django.utils.encoding import force_unicode @@ -44,7 +43,7 @@ def require_login(request): if request.is_ajax(): return HttpResponseForbidden('Not logged in') else: - return HttpResponseRedirect('/uzytkownicy/zaloguj')# next?=request.build_full_path()) + return HttpResponseRedirect('/uzytkownicy/zaloguj') # next?=request.build_full_path()) def placeholdized(form): @@ -119,8 +118,7 @@ class AjaxableFormView(object): if request.is_ajax(): return HttpResponse(LazyEncoder(ensure_ascii=False).encode(response_data)) else: - if (self.POST_login and not request.user.is_authenticated() - and not request.is_ajax()): + if self.POST_login and not request.user.is_authenticated() and not request.is_ajax(): return require_login(request) form = self.form_class(*form_args, **form_kwargs) @@ -148,8 +146,7 @@ class AjaxableFormView(object): "view_kwargs": kwargs, } context.update(self.extra_context(request, obj)) - return render_to_response(template, context, - context_instance=RequestContext(request)) + return render_to_response(template, context, context_instance=RequestContext(request)) def redirect_or_refresh(self, request, path, message=None): """If the form is AJAX, refresh the page. If not, go to `path`.""" diff --git a/src/api/emitters.py b/src/api/emitters.py index 2f6f7e75f..40cc71787 100644 --- a/src/api/emitters.py +++ b/src/api/emitters.py @@ -27,24 +27,24 @@ class SsiQS(object): def get_ssis(self, emitter_format): """Yields SSI include statements for the queryset.""" - url_pattern = reverse('api_include', - kwargs={'model': self.queryset.model.__name__.lower(), - 'pk': '0000', - 'emitter_format': emitter_format, - 'lang': get_language(), - }) + url_pattern = reverse( + 'api_include', + kwargs={ + 'model': self.queryset.model.__name__.lower(), + 'pk': '0000', + 'emitter_format': emitter_format, + 'lang': get_language(), + }) for instance in self.queryset: - yield "" % url_pattern.replace('0000', - str(instance.pk)) + yield "" % url_pattern.replace('0000', str(instance.pk)) class SsiEmitterMixin(object): def construct(self): - if isinstance(self.data, QuerySet) and self.data.model in (Book, - Fragment, Tag): + if isinstance(self.data, QuerySet) and self.data.model in (Book, Fragment, Tag): return SsiQS(self.data) else: - return super(SsiEmitterMixin, self).construct() + return super(SsiEmitterMixin, self).construct() # WTF class SsiJsonEmitter(SsiEmitterMixin, JSONEmitter): @@ -67,4 +67,3 @@ class SsiXmlEmitter(SsiEmitterMixin, XMLEmitter): ''.join(self.construct().get_ssis('xml')) Emitter.register('xml', SsiXmlEmitter, 'text/xml; charset=utf-8') - diff --git a/src/api/handlers.py b/src/api/handlers.py index 5fe931e69..0dc9cd6d6 100644 --- a/src/api/handlers.py +++ b/src/api/handlers.py @@ -18,7 +18,7 @@ from picture.forms import PictureImportForm from stats.utils import piwik_track -from . import emitters # Register our emitters +from . import emitters # Register our emitters API_BASE = WL_BASE = MEDIA_BASE = lazy( lambda: u'http://' + Site.objects.get_current().domain, unicode)() @@ -39,7 +39,6 @@ for k, v in category_singular.items(): book_tag_categories = ['author', 'epoch', 'kind', 'genre'] - def read_tags(tags, allowed): """ Reads a path of filtering tags. @@ -62,7 +61,7 @@ def read_tags(tags, allowed): except KeyError: raise ValueError('Unknown category.') - if not category in allowed: + if category not in allowed: raise ValueError('Category not allowed.') if category == 'book': @@ -137,7 +136,6 @@ class BookDetails(object): book.cover, "139x193").url if book.cover else '' - class BookDetailHandler(BaseHandler, BookDetails): """ Main handler for Book objects. @@ -172,8 +170,7 @@ class AnonymousBooksHandler(AnonymousBaseHandler, BookDetails): return book.tags.filter(category='genre') @piwik_track - def read(self, request, tags=None, top_level=False, - audiobooks=False, daisy=False, pk=None): + def read(self, request, tags=None, top_level=False, audiobooks=False, daisy=False, pk=None): """ Lists all books with given tags. :param tags: filtering tags; should be a path of categories @@ -247,18 +244,27 @@ def _tags_getter(category): def get_tags(cls, book): return book.tags.filter(category=category) return get_tags + + def _tag_getter(category): @classmethod def get_tag(cls, book): return ', '.join(tag.name for tag in book.tags.filter(category=category)) return get_tag -for plural, singular in category_singular.items(): - setattr(BookDetails, plural, _tags_getter(singular)) - setattr(BookDetails, singular, _tag_getter(singular)) + + +def add_tag_getters(): + for plural, singular in category_singular.items(): + setattr(BookDetails, plural, _tags_getter(singular)) + setattr(BookDetails, singular, _tag_getter(singular)) + +add_tag_getters() + # add fields for files in Book -def _file_getter(format): - field = "%s_file" % format +def _file_getter(book_format): + field = "%s_file" % book_format + @classmethod def get_file(cls, book): f = getattr(book, field) @@ -267,8 +273,13 @@ def _file_getter(format): else: return '' return get_file -for format in Book.formats: - setattr(BookDetails, format, _file_getter(format)) + + +def add_file_getters(): + for book_format in Book.formats: + setattr(BookDetails, book_format, _file_getter(book_format)) + +add_file_getters() class CollectionDetails(object): @@ -291,7 +302,6 @@ class CollectionDetails(object): return Book.objects.filter(collection.get_query()) - class CollectionDetailHandler(BaseHandler, CollectionDetails): allowed_methods = ('GET',) fields = ['url', 'title', 'description', 'books'] @@ -343,7 +353,7 @@ class TagDetailHandler(BaseHandler, TagDetails): try: category_sng = category_singular[category] - except KeyError, e: + except KeyError: return rc.NOT_FOUND try: @@ -374,7 +384,7 @@ class TagsHandler(BaseHandler, TagDetails): try: category_sng = category_singular[category] - except KeyError, e: + except KeyError: return rc.NOT_FOUND tags = Tag.objects.filter(category=category_sng).exclude(items=None) @@ -391,8 +401,7 @@ class FragmentDetails(object): def href(cls, fragment): """ Returns URI in the API for the fragment. """ - return API_BASE + reverse("api_fragment", - args=[fragment.book.slug, fragment.anchor]) + return API_BASE + reverse("api_fragment", args=[fragment.book.slug, fragment.anchor]) @classmethod def url(cls, fragment): @@ -430,7 +439,7 @@ class FragmentsHandler(BaseHandler, FragmentDetails): fields = ['book', 'url', 'anchor', 'href'] allowed_methods = ('GET',) - categories = set(['author', 'epoch', 'kind', 'genre', 'book', 'theme']) + categories = {'author', 'epoch', 'kind', 'genre', 'book', 'theme'} @piwik_track def read(self, request, tags): diff --git a/src/api/helpers.py b/src/api/helpers.py index 62578e7c3..03fc18ce6 100644 --- a/src/api/helpers.py +++ b/src/api/helpers.py @@ -5,10 +5,12 @@ from time import mktime from piston.resource import Resource + def timestamp(dtime): - "converts a datetime.datetime object to a timestamp int" + """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): diff --git a/src/api/management/commands/mobileinit.py b/src/api/management/commands/mobileinit.py index 57b41aa46..b89fede9f 100755 --- a/src/api/management/commands/mobileinit.py +++ b/src/api/management/commands/mobileinit.py @@ -3,15 +3,14 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # from datetime import datetime -import os import os.path -import re import sqlite3 from django.core.management.base import BaseCommand from api.helpers import timestamp from api.settings import MOBILE_INIT_DB from catalogue.models import Book, Tag +from wolnelektury.utils import makedirs class Command(BaseCommand): @@ -49,23 +48,20 @@ def pretty_size(size): if size < 10: return "%.1f %s" % (size, unit) return "%d %s" % (size, unit) - - - if not isinstance(value, unicode): - value = unicode(value, 'utf-8') - - # try to replace chars - value = re.sub('[^a-zA-Z0-9\\s\\-]{1}', replace_char, value) - value = value.lower() - value = re.sub(r'[^a-z0-9{|}]+', '~', value) - - return value.encode('ascii', 'ignore') - + # + # if not isinstance(value, unicode): + # value = unicode(value, 'utf-8') + # + # # try to replace chars + # value = re.sub('[^a-zA-Z0-9\\s\\-]{1}', replace_char, value) + # value = value.lower() + # value = re.sub(r'[^a-z0-9{|}]+', '~', value) + # + # return value.encode('ascii', 'ignore') def init_db(last_checked): - if not os.path.isdir(MOBILE_INIT_DB): - os.makedirs(MOBILE_INIT_DB) + makedirs(MOBILE_INIT_DB) db = sqlite3.connect(os.path.join(MOBILE_INIT_DB, 'initial.db-%d' % last_checked)) schema = """ @@ -115,7 +111,6 @@ def current(last_checked): ) - book_sql = """ INSERT INTO book (id, title, cover, html_file, html_file_size, parent, parent_number, sort_key, pretty_size, authors) @@ -138,7 +133,6 @@ categories = {'author': 'autor', def add_book(db, book): - id = book.id title = book.title if book.html_file: html_file = book.html_file.url @@ -158,7 +152,6 @@ def add_book(db, book): def add_tag(db, tag): - id = tag.id category = categories[tag.category] name = tag.name sort_key = tag.sort_key diff --git a/src/api/models.py b/src/api/models.py index 5a3d42440..2f742834f 100644 --- a/src/api/models.py +++ b/src/api/models.py @@ -34,6 +34,7 @@ def _pre_delete_handler(sender, instance, **kwargs): else: category = None content_type = ContentType.objects.get_for_model(sender) - Deleted.objects.create(content_type=content_type, object_id=instance.id, - created_at=instance.created_at, category=category, slug=instance.slug) + Deleted.objects.create( + content_type=content_type, object_id=instance.id, created_at=instance.created_at, category=category, + slug=instance.slug) pre_delete.connect(_pre_delete_handler) diff --git a/src/api/tests.py b/src/api/tests.py index 94abe53b5..1ae143b15 100644 --- a/src/api/tests.py +++ b/src/api/tests.py @@ -50,12 +50,12 @@ class BookTests(ApiTest): books = self.load_json('/api/authors/joe/books/') self.assertEqual([b['title'] for b in books], [self.book_tagged.title], - 'Wrong tagged book list.') + 'Wrong tagged book list.') def test_detail(self): book = self.load_json('/api/books/a-book/') self.assertEqual(book['title'], self.book.title, - 'Wrong book details.') + 'Wrong book details.') class TagTests(ApiTest): @@ -69,19 +69,21 @@ class TagTests(ApiTest): def test_tag_list(self): tags = self.load_json('/api/authors/') self.assertEqual(len(tags), 1, - 'Wrong tag list.') + 'Wrong tag list.') def test_tag_detail(self): tag = self.load_json('/api/authors/joe/') self.assertEqual(tag['name'], self.tag.name, - 'Wrong tag details.') + 'Wrong tag details.') class PictureTests(ApiTest): def test_publish(self): slug = "kandinsky-composition-viii" - xml = SimpleUploadedFile('composition8.xml', open(path.join(picture.tests.__path__[0], "files", slug + ".xml")).read()) - img = SimpleUploadedFile('kompozycja-8.png', open(path.join(picture.tests.__path__[0], "files", slug + ".png")).read()) + xml = SimpleUploadedFile( + 'composition8.xml', open(path.join(picture.tests.__path__[0], "files", slug + ".xml")).read()) + img = SimpleUploadedFile( + 'kompozycja-8.png', open(path.join(picture.tests.__path__[0], "files", slug + ".png")).read()) import_form = PictureImportForm({}, { 'picture_xml_file': xml, diff --git a/src/api/urls.py b/src/api/urls.py index 1c2e656d1..910d362f5 100644 --- a/src/api/urls.py +++ b/src/api/urls.py @@ -15,7 +15,7 @@ auth = OAuthAuthentication(realm="Wolne Lektury") book_list_resource = CsrfExemptResource(handler=handlers.BooksHandler, authentication=auth) ebook_list_resource = Resource(handler=handlers.EBooksHandler) -#book_list_resource = Resource(handler=handlers.BooksHandler) +# book_list_resource = Resource(handler=handlers.BooksHandler) book_resource = Resource(handler=handlers.BookDetailHandler) collection_resource = Resource(handler=handlers.CollectionDetailHandler) @@ -51,7 +51,8 @@ urlpatterns = patterns( url(r'^oauth/authorize/$', 'oauth_user_auth'), url(r'^oauth/access_token/$', csrf_exempt(oauth_access_token)), -) + patterns('', +) + patterns( + '', url(r'^$', TemplateView.as_view(template_name='api/main.html'), name='api'), url(r'^include/(?Pbook|fragment|tag)/(?P\d+)\.(?P.+)\.(?Pxml|json)$', incl, name='api_include'), diff --git a/src/basicauth.py b/src/basicauth.py index befcc6fe7..3635727c4 100644 --- a/src/basicauth.py +++ b/src/basicauth.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- ############################################################################# # from http://djangosnippets.org/snippets/243/ @@ -7,8 +8,8 @@ import base64 from django.http import HttpResponse from django.contrib.auth import authenticate, login -# -def view_or_basicauth(view, request, test_func, realm = "", *args, **kwargs): + +def view_or_basicauth(view, request, test_func, realm="", *args, **kwargs): """ This is a helper function used by 'logged_in_or_basicauth' and 'has_perm_or_basicauth' (deleted) that does the nitty of determining if they @@ -47,7 +48,7 @@ def view_or_basicauth(view, request, test_func, realm = "", *args, **kwargs): # -def logged_in_or_basicauth(realm = ""): +def logged_in_or_basicauth(realm=""): """ A simple decorator that requires a user to be logged in. If they are not logged in the request is examined for a 'authorization' header. diff --git a/src/catalogue/__init__.py b/src/catalogue/__init__.py index eaeb7d468..16c132645 100644 --- a/src/catalogue/__init__.py +++ b/src/catalogue/__init__.py @@ -14,7 +14,7 @@ class Settings(AppSettings): """Default settings for catalogue app.""" DEFAULT_LANGUAGE = u'pol' # PDF needs TeXML + XeLaTeX, MOBI needs Calibre. - DONT_BUILD = set(['pdf', 'mobi']) + DONT_BUILD = {'pdf', 'mobi'} FORMAT_ZIPS = { 'epub': 'wolnelektury_pl_epub', 'pdf': 'wolnelektury_pl_pdf', @@ -23,15 +23,14 @@ class Settings(AppSettings): } REDAKCJA_URL = "http://redakcja.wolnelektury.pl" - GOOD_LICENSES = set([r'CC BY \d\.\d', r'CC BY-SA \d\.\d']) + GOOD_LICENSES = {r'CC BY \d\.\d', r'CC BY-SA \d\.\d'} RELATED_RANDOM_PICTURE_CHANCE = .5 def _more_DONT_BUILD(self, value): for format_ in ['cover', 'pdf', 'epub', 'mobi', 'fb2', 'txt']: attname = 'NO_BUILD_%s' % format_.upper() if hasattr(settings, attname): - logging.warn("%s is deprecated, " - "use CATALOGUE_DONT_BUILD instead", attname) + logging.warn("%s is deprecated, use CATALOGUE_DONT_BUILD instead", attname) if getattr(settings, attname): value.add(format_) else: @@ -42,9 +41,7 @@ class Settings(AppSettings): for format_ in ['epub', 'pdf', 'mobi', 'fb2']: attname = 'ALL_%s_ZIP' % format_.upper() if hasattr(settings, attname): - logging.warn("%s is deprecated, " - "use CATALOGUE_FORMAT_ZIPS[%s] instead", - attname, format_) + logging.warn("%s is deprecated, use CATALOGUE_FORMAT_ZIPS[%s] instead", attname, format_) value[format_] = getattr(settings, attname) return value diff --git a/src/catalogue/admin.py b/src/catalogue/admin.py index 28cf53c37..7cf0f5bf6 100644 --- a/src/catalogue/admin.py +++ b/src/catalogue/admin.py @@ -15,7 +15,7 @@ class TagAdmin(admin.ModelAdmin): search_fields = ('name',) ordering = ('name',) - prepopulated_fields = {'slug': ('name',), 'sort_key': ('name',),} + prepopulated_fields = {'slug': ('name',), 'sort_key': ('name',)} radio_fields = {'category': admin.HORIZONTAL} @@ -35,7 +35,7 @@ class BookAdmin(TaggableModelAdmin): inlines = [MediaInline] def change_view(self, request, object_id, extra_context=None): - if not request.GET.has_key('advanced'): + if 'advanced' not in request.GET: self.form = forms.ModelForm self.fields = ('title', 'description', 'gazeta_link', 'wiki_link') self.readonly_fields = ('title',) @@ -43,8 +43,7 @@ class BookAdmin(TaggableModelAdmin): self.form = TaggableModelForm self.fields = None self.readonly_fields = () - return super(BookAdmin, self).change_view(request, object_id, - extra_context=extra_context) + return super(BookAdmin, self).change_view(request, object_id, extra_context=extra_context) class FragmentAdmin(TaggableModelAdmin): diff --git a/src/catalogue/apps.py b/src/catalogue/apps.py index 54bfc8f8b..5dbc8b37a 100644 --- a/src/catalogue/apps.py +++ b/src/catalogue/apps.py @@ -4,6 +4,7 @@ # from django.apps import AppConfig + class CatalogueConfig(AppConfig): name = 'catalogue' diff --git a/src/catalogue/feeds.py b/src/catalogue/feeds.py index 2411d015a..90088bed8 100644 --- a/src/catalogue/feeds.py +++ b/src/catalogue/feeds.py @@ -8,6 +8,7 @@ from django.core.urlresolvers import reverse from catalogue import models + def absolute_url(url): return "http://%s%s" % (Site.objects.get_current().domain, url) @@ -28,8 +29,8 @@ class AudiobookFeed(Feed): 'daisy': 'WolneLektury.pl - audiobooki w formacie DAISY', } - def get_object(self, request, type): - return {'type': type, 'all': 'all' in request.GET} + def get_object(self, request, obj_type): + return {'type': obj_type, 'all': 'all' in request.GET} def title(self, args): return self.titles[args['type']] @@ -52,7 +53,7 @@ class AudiobookFeed(Feed): def item_categories(self, item): return sorted(set(author.name for author in - item.book.tags.filter(category='author').iterator())) + item.book.tags.filter(category='author').iterator())) def item_description(self, item): lines = [] diff --git a/src/catalogue/fields.py b/src/catalogue/fields.py index 0ff2ca9ef..42612522c 100644 --- a/src/catalogue/fields.py +++ b/src/catalogue/fields.py @@ -117,8 +117,7 @@ class BuildTxt(BuildEbook): class BuildPdf(BuildEbook): @staticmethod def transform(wldoc, fieldfile): - return wldoc.as_pdf(morefloats=settings.LIBRARIAN_PDF_MOREFLOATS, - cover=True) + return wldoc.as_pdf(morefloats=settings.LIBRARIAN_PDF_MOREFLOATS, cover=True) def build(self, fieldfile): BuildEbook.build(self, fieldfile) @@ -161,8 +160,7 @@ class BuildHtml(BuildEbook): if lang not in [ln[0] for ln in settings.LANGUAGES]: lang = None - fieldfile.save(None, ContentFile(html_output.get_string()), - save=False) + fieldfile.save(None, ContentFile(html_output.get_string()), save=False) type(book).objects.filter(pk=book.pk).update(**{ fieldfile.field.attname: fieldfile }) @@ -192,8 +190,7 @@ class BuildHtml(BuildEbook): elif lang is not None: # Don't create unknown themes in non-default languages. try: - tag = Tag.objects.get(category='theme', - **{"name_%s" % lang: theme_name}) + tag = Tag.objects.get(category='theme', **{"name_%s" % lang: theme_name}) except Tag.DoesNotExist: pass else: @@ -205,8 +202,7 @@ class BuildHtml(BuildEbook): short_text = truncate_html_words(text, 15) if text == short_text: short_text = '' - new_fragment = Fragment.objects.create(anchor=fragment.id, - book=book, text=text, short_text=short_text) + new_fragment = Fragment.objects.create(anchor=fragment.id, book=book, text=text, short_text=short_text) new_fragment.save() new_fragment.tags = set(meta_tags + themes) @@ -214,6 +210,7 @@ class BuildHtml(BuildEbook): return True return False + @BuildEbook.register('cover_thumb') @task(ignore_result=True) class BuildCoverThumb(BuildEbook): @@ -223,7 +220,6 @@ class BuildCoverThumb(BuildEbook): return WLCover(wldoc.book_info, height=193).output_file() - class OverwritingFieldFile(FieldFile): """ Deletes the old file before saving the new one. @@ -232,11 +228,9 @@ class OverwritingFieldFile(FieldFile): def save(self, name, content, *args, **kwargs): leave = kwargs.pop('leave', None) # delete if there's a file already and there's a new one coming - if not leave and self and (not hasattr(content, 'path') or - content.path != self.path): + if not leave and self and (not hasattr(content, 'path') or content.path != self.path): self.delete(save=False) - return super(OverwritingFieldFile, self).save( - name, content, *args, **kwargs) + return super(OverwritingFieldFile, self).save(name, content, *args, **kwargs) class OverwritingFileField(models.FileField): diff --git a/src/catalogue/forms.py b/src/catalogue/forms.py index d52310bd3..82a5d1f1a 100644 --- a/src/catalogue/forms.py +++ b/src/catalogue/forms.py @@ -35,8 +35,7 @@ FORMATS = [(f, f.upper()) for f in Book.ebook_formats] class DownloadFormatsForm(forms.Form): - formats = forms.MultipleChoiceField(required=False, choices=FORMATS, - widget=forms.CheckboxSelectMultiple) + formats = forms.MultipleChoiceField(required=False, choices=FORMATS, widget=forms.CheckboxSelectMultiple) def __init__(self, *args, **kwargs): super(DownloadFormatsForm, self).__init__(*args, **kwargs) @@ -53,16 +52,16 @@ CUSTOMIZATION_OPTIONS = ( ('', _('Normal leading')), ('onehalfleading', _('One and a half leading')), ('doubleleading', _('Double leading')), - )), + )), ('fontsize', _("Font size"), ( ('', _('Default')), ('13pt', _('Big')) - )), -# ('pagesize', _("Paper size"), ( -# ('a4paper', _('A4')), -# ('a5paper', _('A5')), -# )), - ) + )), + # ('pagesize', _("Paper size"), ( + # ('a4paper', _('A4')), + # ('a5paper', _('A5')), + # )), +) class CustomPDFForm(forms.Form): @@ -76,8 +75,7 @@ class CustomPDFForm(forms.Form): def clean(self): self.cleaned_data['cust'] = self.customizations - self.cleaned_data['path'] = get_customized_pdf_path(self.book, - self.cleaned_data['cust']) + self.cleaned_data['path'] = get_customized_pdf_path(self.book, self.cleaned_data['cust']) if not WaitedFile.can_order(self.cleaned_data['path']): raise ValidationError(_('Queue is full. Please try again later.')) return self.cleaned_data @@ -99,10 +97,9 @@ class CustomPDFForm(forms.Form): if not self.cleaned_data['cust'] and self.book.pdf_file: # Don't build with default options, just redirect to the standard file. return {"redirect": self.book.pdf_file.url} - url = WaitedFile.order(self.cleaned_data['path'], - lambda p, waiter_id: build_custom_pdf.delay(self.book.id, - self.cleaned_data['cust'], p, waiter_id), + url = WaitedFile.order( + self.cleaned_data['path'], + lambda p, waiter_id: build_custom_pdf.delay(self.book.id, self.cleaned_data['cust'], p, waiter_id), self.book.pretty_title() - ) - #return redirect(url) + ) return {"redirect": url} diff --git a/src/catalogue/helpers.py b/src/catalogue/helpers.py index b48c483ea..38e2a87a1 100644 --- a/src/catalogue/helpers.py +++ b/src/catalogue/helpers.py @@ -3,20 +3,18 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # from django.conf import settings -from django.contrib.contenttypes.models import ContentType -from django.db.models import Count from .models import Tag, Book from os.path import getmtime import cPickle from collections import defaultdict - BOOK_CATEGORIES = ('author', 'epoch', 'genre', 'kind') - _COUNTERS = None _COUNTER_TIME = None + + def get_top_level_related_tags(tags, categories=None): """ Finds tags related to given tags through books, and counts their usage. @@ -46,8 +44,6 @@ def get_top_level_related_tags(tags, categories=None): tag.count = _COUNTERS['count'][tuple(sorted(tagids + (tag.pk,)))] yield tag - #~ return related - def update_counters(): def combinations(things): diff --git a/src/catalogue/import_utils.py b/src/catalogue/import_utils.py index ca0c6efe5..65b71167f 100644 --- a/src/catalogue/import_utils.py +++ b/src/catalogue/import_utils.py @@ -4,6 +4,7 @@ # from librarian import DocProvider + class ORMDocProvider(DocProvider): """Used for getting books' children.""" diff --git a/src/catalogue/management/commands/checkcovers.py b/src/catalogue/management/commands/checkcovers.py index 7535dd474..2466728a9 100644 --- a/src/catalogue/management/commands/checkcovers.py +++ b/src/catalogue/management/commands/checkcovers.py @@ -18,6 +18,8 @@ def ancestor_has_cover(book): current_domain = lazy(lambda: Site.objects.get_current().domain, str)() + + def full_url(obj): return 'http://%s%s' % ( current_domain, @@ -27,7 +29,7 @@ def full_url(obj): class Command(BaseCommand): option_list = BaseCommand.option_list + ( make_option('-q', '--quiet', action='store_false', dest='verbose', default=True, - help='Suppress output'), + help='Suppress output'), ) help = 'Checks cover sources and licenses.' @@ -51,7 +53,7 @@ class Command(BaseCommand): good_license = re.compile("(%s)" % ")|(".join( app_settings.GOOD_LICENSES)) - with transaction.commit_on_success(): + with transaction.atomic(): for book in Book.objects.all().order_by('slug').iterator(): extra_info = book.extra_info if not extra_info.get('cover_url'): @@ -60,8 +62,7 @@ class Command(BaseCommand): else: without_cover.append(book) else: - if not extra_info.get('cover_source', '' - ).startswith(redakcja_url): + if not extra_info.get('cover_source', '').startswith(redakcja_url): not_redakcja.append(book) match = re_license.match(extra_info.get('cover_by', '')) if match: diff --git a/src/catalogue/management/commands/checkintegrity.py b/src/catalogue/management/commands/checkintegrity.py index 6ae2b9a2f..6d8a9559a 100644 --- a/src/catalogue/management/commands/checkintegrity.py +++ b/src/catalogue/management/commands/checkintegrity.py @@ -6,14 +6,15 @@ from optparse import make_option from django.core.management.base import BaseCommand from catalogue.models import Book +from librarian import ParseError class Command(BaseCommand): option_list = BaseCommand.option_list + ( make_option('-q', '--quiet', action='store_false', dest='verbose', default=True, - help='Suppress output'), + 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="Just check for problems, don't fix them"), ) help = 'Checks integrity of catalogue data.' @@ -22,11 +23,11 @@ class Command(BaseCommand): verbose = options['verbose'] - with transaction.commit_on_success(): + with transaction.atomic(): for book in Book.objects.all().iterator(): try: info = book.wldocument().book_info - except: + except ParseError: if verbose: print "ERROR! Bad XML for book:", book.slug print "To resolve: republish." diff --git a/src/catalogue/management/commands/importbooks.py b/src/catalogue/management/commands/importbooks.py index 559124bdf..528077893 100644 --- a/src/catalogue/management/commands/importbooks.py +++ b/src/catalogue/management/commands/importbooks.py @@ -9,8 +9,9 @@ from django.conf import settings from django.core.management.base import BaseCommand from django.core.management.color import color_style from django.core.files import File +from django.db import transaction from librarian.picture import ImageStore -from wolnelektury.management.profile import profile +# from wolnelektury.management.profile import profile from catalogue.models import Book from picture.models import Picture @@ -21,16 +22,16 @@ from search.index import Index class Command(BaseCommand): option_list = BaseCommand.option_list + ( make_option('-q', '--quiet', action='store_false', dest='verbose', default=True, - help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'), + help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'), make_option('-f', '--force', action='store_true', dest='force', default=False, - help='Overwrite works already in the catalogue'), + help='Overwrite works already in the catalogue'), make_option('-D', '--dont-build', dest='dont_build', - metavar="FORMAT,...", - help="Skip building specified formats"), + metavar="FORMAT,...", + help="Skip building specified formats"), make_option('-S', '--no-search-index', action='store_false', dest='search_index', default=True, - help='Skip indexing imported works for search'), + help='Skip indexing imported works for search'), make_option('-p', '--picture', action='store_true', dest='import_picture', default=False, - help='Import pictures'), + help='Import pictures'), ) help = 'Imports books from the specified directories.' args = 'directory [directory ...]' @@ -68,16 +69,14 @@ class Command(BaseCommand): raise ex return picture - # @profile + # @profile + @transaction.atomic def handle(self, *directories, **options): - from django.db import transaction - self.style = color_style() verbose = options.get('verbose') import_picture = options.get('import_picture') - index = None if options.get('search_index') and not settings.NO_SEARCH_INDEX: index = Index() try: @@ -87,57 +86,56 @@ class Command(BaseCommand): index.index.rollback() raise e - # Start transaction management. - with transaction.atomic(): - files_imported = 0 - files_skipped = 0 - - for dir_name in directories: - if not os.path.isdir(dir_name): - print self.style.ERROR("%s: Not a directory. Skipping." % dir_name) - else: - # files queue - files = sorted(os.listdir(dir_name)) - postponed = {} - while files: - file_name = files.pop(0) - file_path = os.path.join(dir_name, file_name) - file_base, ext = os.path.splitext(file_path) - - # Skip files that are not XML files - if not ext == '.xml': - continue - - if verbose > 0: - print "Parsing '%s'" % file_path + files_imported = 0 + files_skipped = 0 + + for dir_name in directories: + if not os.path.isdir(dir_name): + print self.style.ERROR("%s: Not a directory. Skipping." % dir_name) + else: + # files queue + files = sorted(os.listdir(dir_name)) + postponed = {} + while files: + file_name = files.pop(0) + file_path = os.path.join(dir_name, file_name) + file_base, ext = os.path.splitext(file_path) + + # Skip files that are not XML files + if not ext == '.xml': + continue + + if verbose > 0: + print "Parsing '%s'" % file_path + else: + sys.stdout.write('.') + sys.stdout.flush() + + # Import book files + try: + if import_picture: + self.import_picture(file_path, options) + else: + self.import_book(file_path, options) + + files_imported += 1 + + except (Book.AlreadyExists, Picture.AlreadyExists): + print self.style.ERROR( + '%s: Book or Picture already imported. Skipping. To overwrite use --force.' % + file_path) + files_skipped += 1 + + except Book.DoesNotExist, e: + if file_name not in postponed or postponed[file_name] < files_imported: + # push it back into the queue, maybe the missing child will show up + if verbose: + print self.style.NOTICE('Waiting for missing children') + files.append(file_name) + postponed[file_name] = files_imported else: - sys.stdout.write('.') - sys.stdout.flush() - - # Import book files - try: - if import_picture: - self.import_picture(file_path, options) - else: - self.import_book(file_path, options) - - files_imported += 1 - - except (Book.AlreadyExists, Picture.AlreadyExists): - print self.style.ERROR('%s: Book or Picture already imported. Skipping. To overwrite use --force.' % - file_path) - files_skipped += 1 - - except Book.DoesNotExist, e: - if file_name not in postponed or postponed[file_name] < files_imported: - # push it back into the queue, maybe the missing child will show up - if verbose: - print self.style.NOTICE('Waiting for missing children') - files.append(file_name) - postponed[file_name] = files_imported - else: - # we're in a loop, nothing's being imported - some child is really missing - raise e + # we're in a loop, nothing's being imported - some child is really missing + raise e # Print results print diff --git a/src/catalogue/management/commands/pack.py b/src/catalogue/management/commands/pack.py index ba06341b8..98ad7d836 100755 --- a/src/catalogue/management/commands/pack.py +++ b/src/catalogue/management/commands/pack.py @@ -14,11 +14,11 @@ from catalogue.models import Book, Tag class Command(BaseCommand): option_list = BaseCommand.option_list + ( make_option('-t', '--tags', dest='tags', metavar='SLUG,...', - help='Use only books tagged with this tags'), + help='Use only books tagged with this tags'), make_option('-i', '--include', dest='include', metavar='SLUG,...', - help='Include specific books by slug'), + help='Include specific books by slug'), make_option('-e', '--exclude', dest='exclude', metavar='SLUG,...', - help='Exclude specific books by slug') + help='Exclude specific books by slug') ) help = 'Prepare ZIP package with files of given type.' args = '[%s] output_path.zip' % '|'.join(Book.formats) diff --git a/src/catalogue/management/commands/report_dead_links.py b/src/catalogue/management/commands/report_dead_links.py index 34b1e7054..508880e9b 100644 --- a/src/catalogue/management/commands/report_dead_links.py +++ b/src/catalogue/management/commands/report_dead_links.py @@ -16,22 +16,27 @@ class Command(BaseCommand): from urllib2 import urlopen, HTTPError, URLError from django.core.urlresolvers import reverse from django.contrib.sites.models import Site - from django.contrib.sites.shortcuts import get_current_site - domain = get_current_site(None).domain + domain = Site.objects.get_current().domain fields = [ - (Book, [ - ('gazeta_link', lambda b: b.gazeta_link), - ('wiki_link', lambda b: b.wiki_link), - ('źródło', lambda b: b.extra_info.get('source_url')), - ], 'admin:catalogue_book_change' + ( + Book, + [ + ('gazeta_link', lambda b: b.gazeta_link), + ('wiki_link', lambda b: b.wiki_link), + ('źródło', lambda b: b.extra_info.get('source_url')), + ], + 'admin:catalogue_book_change' ), - (Picture, [ - ('gazeta_link', lambda p: p.culturepl_link), - ('wiki_link', lambda p: p.wiki_link), - ('źródło', lambda p: p.extra_info.get('source_url')), - ], 'admin:pictures_picture_change' + ( + Picture, + [ + ('gazeta_link', lambda p: p.culturepl_link), + ('wiki_link', lambda p: p.wiki_link), + ('źródło', lambda p: p.extra_info.get('source_url')), + ], + 'admin:pictures_picture_change' ) ] @@ -48,7 +53,9 @@ class Command(BaseCommand): clean = False print(unicode(obj).encode('utf-8')) print(('Na stronie: https://%s%s' % (domain, obj.get_absolute_url())).encode('utf-8')) - print(('Administracja: https://%s%s' % (domain, reverse(admin_name, args=[obj.pk]))).encode('utf-8')) + print( + ('Administracja: https://%s%s' % (domain, reverse(admin_name, args=[obj.pk]))) + .encode('utf-8')) if obj.extra_info.get('about'): print(('Redakcja: %s' % (obj.extra_info.get('about'),)).encode('utf-8')) print((' %s (%s): %s' % (name, getattr(e, 'code', 'błąd'), url)).encode('utf-8')) diff --git a/src/catalogue/management/commands/savemedia.py b/src/catalogue/management/commands/savemedia.py index 216c5e335..6196bab42 100755 --- a/src/catalogue/management/commands/savemedia.py +++ b/src/catalogue/management/commands/savemedia.py @@ -5,25 +5,21 @@ import os.path from django.core.management.base import BaseCommand +from django.db import transaction from catalogue.models import Book, BookMedia from catalogue.utils import ExistingFile class Command(BaseCommand): - help = "Saves uploaded media with a given book and a given name. If media has a source SHA1 info - matching media is replaced." + help = "Saves uploaded media with a given book and a given name. " \ + "If media has a source SHA1 info - matching media is replaced." args = 'path slug name' + @transaction.atomic def handle(self, *args, **options): - from django.db import transaction - path, slug, name = args - # Start transaction management. - transaction.commit_unless_managed() - transaction.enter_transaction_management() - transaction.managed(True) - book = Book.objects.get(slug=slug) root, ext = os.path.splitext(path) @@ -45,5 +41,3 @@ class Command(BaseCommand): bm.name = name bm.file.save(None, ExistingFile(path)) bm.save() - transaction.commit() - transaction.leave_transaction_management() diff --git a/src/catalogue/models/book.py b/src/catalogue/models/book.py index 9381afc94..5194fe1d6 100644 --- a/src/catalogue/models/book.py +++ b/src/catalogue/models/book.py @@ -26,57 +26,58 @@ from catalogue import tasks bofh_storage = BofhFileSystemStorage() -def _cover_upload_to(i, n): - return 'book/cover/%s.jpg' % i.slug +def _make_upload_to(path): + def _upload_to(i, n): + return path % i.slug + return _upload_to + + +_cover_upload_to = _make_upload_to('book/cover/%s.jpg') +_cover_thumb_upload_to = _make_upload_to('book/cover_thumb/%s.jpg') -def _cover_thumb_upload_to(i, n): - return 'book/cover_thumb/%s.jpg' % i.slug def _ebook_upload_to(upload_path): - def _upload_to(i, n): - return upload_path % i.slug - return _upload_to + return _make_upload_to(upload_path) class Book(models.Model): """Represents a book imported from WL-XML.""" - title = models.CharField(_('title'), max_length=32767) + title = models.CharField(_('title'), max_length=32767) sort_key = models.CharField(_('sort key'), max_length=120, db_index=True, editable=False) - sort_key_author = models.CharField(_('sort key by author'), max_length=120, db_index=True, editable=False, default=u'') - slug = models.SlugField(_('slug'), max_length=120, db_index=True, - unique=True) + sort_key_author = models.CharField( + _('sort key by author'), max_length=120, db_index=True, editable=False, default=u'') + slug = models.SlugField(_('slug'), max_length=120, db_index=True, unique=True) common_slug = models.SlugField(_('slug'), max_length=120, db_index=True) - language = models.CharField(_('language code'), max_length=3, db_index=True, - default=app_settings.DEFAULT_LANGUAGE) - description = models.TextField(_('description'), blank=True) - 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) + language = models.CharField(_('language code'), max_length=3, db_index=True, default=app_settings.DEFAULT_LANGUAGE) + description = models.TextField(_('description'), blank=True) + 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) parent_number = models.IntegerField(_('parent number'), default=0) - extra_info = jsonfield.JSONField(_('extra information'), default={}) - gazeta_link = models.CharField(blank=True, max_length=240) - wiki_link = models.CharField(blank=True, max_length=240) + extra_info = jsonfield.JSONField(_('extra information'), default={}) + gazeta_link = models.CharField(blank=True, max_length=240) + wiki_link = models.CharField(blank=True, max_length=240) # files generated during publication - cover = EbookField('cover', _('cover'), - null=True, blank=True, - upload_to=_cover_upload_to, - storage=bofh_storage, max_length=255) + cover = EbookField( + 'cover', _('cover'), + null=True, blank=True, + upload_to=_cover_upload_to, + storage=bofh_storage, max_length=255) # Cleaner version of cover for thumbs - cover_thumb = EbookField('cover_thumb', _('cover thumbnail'), - null=True, blank=True, - upload_to=_cover_thumb_upload_to, - max_length=255) + cover_thumb = EbookField( + 'cover_thumb', _('cover thumbnail'), + null=True, blank=True, + upload_to=_cover_thumb_upload_to, + max_length=255) ebook_formats = constants.EBOOK_FORMATS formats = ebook_formats + ['html', 'xml'] - parent = models.ForeignKey('self', blank=True, null=True, - related_name='children') - ancestor = models.ManyToManyField('self', blank=True, - editable=False, related_name='descendant', symmetrical=False) + parent = models.ForeignKey('self', blank=True, null=True, related_name='children') + ancestor = models.ManyToManyField('self', blank=True, editable=False, related_name='descendant', symmetrical=False) - objects = models.Manager() - tagged = managers.ModelTaggedItemManager(Tag) - tags = managers.TagDescriptor(Tag) + objects = models.Manager() + tagged = managers.ModelTaggedItemManager(Tag) + tags = managers.TagDescriptor(Tag) tag_relations = GenericRelation(Tag.intermediary_table_model) html_built = django.dispatch.Signal() @@ -109,7 +110,7 @@ class Book(models.Model): from sortify import sortify self.sort_key = sortify(self.title)[:120] - self.title = unicode(self.title) # ??? + self.title = unicode(self.title) # ??? try: author = self.tags.filter(category='author')[0].sort_key @@ -123,12 +124,12 @@ class Book(models.Model): @permalink def get_absolute_url(self): - return ('catalogue.views.book_detail', [self.slug]) + return 'catalogue.views.book_detail', [self.slug] @staticmethod @permalink def create_url(slug): - return ('catalogue.views.book_detail', [slug]) + return 'catalogue.views.book_detail', [slug] @property def name(self): @@ -157,10 +158,13 @@ class Book(models.Model): def get_mp3(self): return self.get_media("mp3") + def get_odt(self): return self.get_media("odt") + def get_ogg(self): return self.get_media("ogg") + def get_daisy(self): return self.get_media("daisy") @@ -194,10 +198,11 @@ class Book(models.Model): else: meta_fallbacks = None - return WLDocument.from_file(self.xml_file.path, - provider=ORMDocProvider(self), - parse_dublincore=parse_dublincore, - meta_fallbacks=meta_fallbacks) + return WLDocument.from_file( + self.xml_file.path, + provider=ORMDocProvider(self), + parse_dublincore=parse_dublincore, + meta_fallbacks=meta_fallbacks) @staticmethod def zip_format(format_): @@ -209,8 +214,7 @@ class Book(models.Model): field_name = "%s_file" % format_ books = Book.objects.filter(parent=None).exclude(**{field_name: ""}) - paths = [(pretty_file_name(b), getattr(b, field_name).path) - for b in books.iterator()] + paths = [(pretty_file_name(b), getattr(b, field_name).path) for b in books.iterator()] return create_zip(paths, app_settings.FORMAT_ZIPS[format_]) def zip_audiobooks(self, format_): @@ -232,7 +236,6 @@ class Book(models.Model): index.index.rollback() raise e - @classmethod def from_xml_file(cls, xml_file, **kwargs): from django.core.files import File @@ -250,9 +253,8 @@ class Book(models.Model): xml_file.close() @classmethod - def from_text_and_meta(cls, raw_file, book_info, overwrite=False, - dont_build=None, search_index=True, - search_index_tags=True): + def from_text_and_meta(cls, raw_file, book_info, overwrite=False, dont_build=None, search_index=True, + search_index_tags=True): if dont_build is None: dont_build = set() dont_build = set.union(set(dont_build), set(app_settings.DONT_BUILD)) @@ -264,8 +266,7 @@ class Book(models.Model): try: children.append(Book.objects.get(slug=part_url.slug)) except Book.DoesNotExist: - raise Book.DoesNotExist(_('Book "%s" does not exist.') % - part_url.slug) + raise Book.DoesNotExist(_('Book "%s" does not exist.') % part_url.slug) # Read book metadata book_slug = book_info.url.slug @@ -278,8 +279,7 @@ class Book(models.Model): old_cover = None else: if not overwrite: - raise Book.AlreadyExists(_('Book %s already exists') % ( - book_slug)) + raise Book.AlreadyExists(_('Book %s already exists') % book_slug) # Save shelves for this book book_shelves = list(book.tags.filter(category='set')) old_cover = book.cover_info() @@ -349,37 +349,37 @@ class Book(models.Model): return book @classmethod + @transaction.atomic def repopulate_ancestors(cls): """Fixes the ancestry cache.""" # TODO: table names - with transaction.atomic(): - cursor = connection.cursor() - if connection.vendor == 'postgres': - cursor.execute("TRUNCATE catalogue_book_ancestor") - cursor.execute(""" - WITH RECURSIVE ancestry AS ( - SELECT book.id, book.parent_id - FROM catalogue_book AS book - WHERE book.parent_id IS NOT NULL - UNION - SELECT ancestor.id, book.parent_id - FROM ancestry AS ancestor, catalogue_book AS book - WHERE ancestor.parent_id = book.id - AND book.parent_id IS NOT NULL - ) - INSERT INTO catalogue_book_ancestor - (from_book_id, to_book_id) - SELECT id, parent_id - FROM ancestry - ORDER BY id; - """) - else: - cursor.execute("DELETE FROM catalogue_book_ancestor") - for b in cls.objects.exclude(parent=None): - parent = b.parent - while parent is not None: - b.ancestor.add(parent) - parent = parent.parent + cursor = connection.cursor() + if connection.vendor == 'postgres': + cursor.execute("TRUNCATE catalogue_book_ancestor") + cursor.execute(""" + WITH RECURSIVE ancestry AS ( + SELECT book.id, book.parent_id + FROM catalogue_book AS book + WHERE book.parent_id IS NOT NULL + UNION + SELECT ancestor.id, book.parent_id + FROM ancestry AS ancestor, catalogue_book AS book + WHERE ancestor.parent_id = book.id + AND book.parent_id IS NOT NULL + ) + INSERT INTO catalogue_book_ancestor + (from_book_id, to_book_id) + SELECT id, parent_id + FROM ancestry + ORDER BY id; + """) + else: + cursor.execute("DELETE FROM catalogue_book_ancestor") + for b in cls.objects.exclude(parent=None): + parent = b.parent + while parent is not None: + b.ancestor.add(parent) + parent = parent.parent def flush_includes(self, languages=True): if not languages: @@ -448,8 +448,7 @@ class Book(models.Model): return books def pretty_title(self, html_links=False): - names = [(tag.name, tag.get_absolute_url()) - for tag in self.tags.filter(category='author')] + names = [(tag.name, tag.get_absolute_url()) for tag in self.tags.filter(category='author')] books = self.parents() + [self] names.extend([(b.title, b.get_absolute_url()) for b in books]) @@ -471,7 +470,7 @@ class Book(models.Model): return objects.exclude(ancestor__in=objects) @classmethod - def book_list(cls, filter=None): + def book_list(cls, book_filter=None): """Generates a hierarchical listing of all books. Books are optionally filtered with a test function. @@ -481,8 +480,8 @@ class Book(models.Model): books_by_parent = {} books = cls.objects.all().order_by('parent_number', 'sort_key').only( 'title', 'parent', 'slug') - if filter: - books = books.filter(filter).distinct() + if book_filter: + books = books.filter(book_filter).distinct() book_ids = set(b['pk'] for b in books.values("pk").iterator()) for book in books.iterator(): @@ -518,6 +517,7 @@ class Book(models.Model): "L": (3, u"liceum"), "LP": (3, u"liceum"), } + def audiences_pl(self): audiences = self.extra_info.get('audiences', []) audiences = sorted(set([self._audiences_pl.get(a, (99, a)) for a in audiences])) @@ -545,18 +545,21 @@ class Book(models.Model): return None -# add the file fields -for format_ in Book.formats: - field_name = "%s_file" % format_ - # This weird globals() assignment makes Django migrations comfortable. - _upload_to = _ebook_upload_to('book/%s/%%s.%s' % (format_, format_)) - _upload_to.__name__ = '_%s_upload_to' % format_ - globals()[_upload_to.__name__] = _upload_to - - EbookField(format_, _("%s file" % format_.upper()), - upload_to=_upload_to, - storage=bofh_storage, - max_length=255, - blank=True, - default='' - ).contribute_to_class(Book, field_name) +def add_file_fields(): + for format_ in Book.formats: + field_name = "%s_file" % format_ + # This weird globals() assignment makes Django migrations comfortable. + _upload_to = _ebook_upload_to('book/%s/%%s.%s' % (format_, format_)) + _upload_to.__name__ = '_%s_upload_to' % format_ + globals()[_upload_to.__name__] = _upload_to + + EbookField( + format_, _("%s file" % format_.upper()), + upload_to=_upload_to, + storage=bofh_storage, + max_length=255, + blank=True, + default='' + ).contribute_to_class(Book, field_name) + +add_file_fields() diff --git a/src/catalogue/models/bookmedia.py b/src/catalogue/models/bookmedia.py index 1ef3fd7b9..1f984a044 100644 --- a/src/catalogue/models/bookmedia.py +++ b/src/catalogue/models/bookmedia.py @@ -9,12 +9,14 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ import jsonfield from fnpdjango.utils.text.slughifi import slughifi +from mutagen import MutagenError + from catalogue.fields import OverwritingFileField def _file_upload_to(i, _n): - return 'book/%(ext)s/%(name)s.%(ext)s' % { - 'ext': i.ext(), 'name': slughifi(i.name)} + return 'book/%(ext)s/%(name)s.%(ext)s' % {'ext': i.ext(), 'name': slughifi(i.name)} + class BookMedia(models.Model): """Represents media attached to a book.""" @@ -24,13 +26,11 @@ class BookMedia(models.Model): ('ogg', FileFormat(name='Ogg Vorbis', ext='ogg')), ('daisy', FileFormat(name='DAISY', ext='daisy.zip')), ]) - format_choices = [(k, _('%s file' % t.name)) - for k, t in formats.items()] + format_choices = [(k, _('%s file' % t.name)) for k, t in formats.items()] type = models.CharField(_('type'), db_index=True, choices=format_choices, max_length=20) name = models.CharField(_('name'), max_length=512) - file = OverwritingFileField(_('file'), max_length=600, - upload_to=_file_upload_to) + file = OverwritingFileField(_('file'), max_length=600, upload_to=_file_upload_to) uploaded_at = models.DateTimeField(_('creation date'), auto_now_add=True, editable=False, db_index=True) extra_info = jsonfield.JSONField(_('extra information'), default={}, editable=False) book = models.ForeignKey('Book', related_name='media') @@ -40,8 +40,8 @@ class BookMedia(models.Model): return "%s (%s)" % (self.name, self.file.name.split("/")[-1]) class Meta: - ordering = ('type', 'name') - verbose_name = _('book media') + ordering = ('type', 'name') + verbose_name = _('book media') verbose_name_plural = _('book media') app_label = 'catalogue' @@ -86,11 +86,13 @@ class BookMedia(models.Model): audio = id3.ID3(self.file.path) artist_name = ', '.join(', '.join(tag.text) for tag in audio.getall('TPE1')) director_name = ', '.join(', '.join(tag.text) for tag in audio.getall('TPE3')) - project = ", ".join([t.data for t in audio.getall('PRIV') - if t.owner == 'wolnelektury.pl?project']) - funded_by = ", ".join([t.data for t in audio.getall('PRIV') - if t.owner == 'wolnelektury.pl?funded_by']) - except: + project = ", ".join([ + t.data for t in audio.getall('PRIV') + if t.owner == 'wolnelektury.pl?project']) + funded_by = ", ".join([ + t.data for t in audio.getall('PRIV') + if t.owner == 'wolnelektury.pl?funded_by']) + except MutagenError: pass elif self.type == 'ogg': try: @@ -99,7 +101,7 @@ class BookMedia(models.Model): director_name = ', '.join(audio.get('conductor', [])) project = ", ".join(audio.get('project', [])) funded_by = ", ".join(audio.get('funded_by', [])) - except: + except (MutagenError, AttributeError): pass else: return {} @@ -122,13 +124,13 @@ class BookMedia(models.Model): audio = id3.ID3(filepath) return [t.data for t in audio.getall('PRIV') if t.owner == 'wolnelektury.pl?flac_sha1'][0] - except: + except MutagenError: return None elif filetype == 'ogg': try: audio = mutagen.File(filepath) return audio.get('flac_sha1', [None])[0] - except: + except (MutagenError, AttributeError): return None else: return None diff --git a/src/catalogue/models/collection.py b/src/catalogue/models/collection.py index d51932841..15a4e2adc 100644 --- a/src/catalogue/models/collection.py +++ b/src/catalogue/models/collection.py @@ -18,7 +18,8 @@ class Collection(models.Model): models.SlugField(_('slug'), max_length=120, unique=True, db_index=True) book_slugs = models.TextField(_('book slugs')) - kind = models.CharField(_('kind'), max_length=10, blank=False, default='book', db_index=True, choices=((('book'), _('book')), (('picture'), ('picture')))) + kind = models.CharField(_('kind'), max_length=10, blank=False, default='book', db_index=True, + choices=(('book', _('book')), ('picture', _('picture')))) class Meta: ordering = ('title',) @@ -37,13 +38,13 @@ class Collection(models.Model): @models.permalink def get_absolute_url(self): - return ("collection", [self.slug]) + return "collection", [self.slug] def get_query(self): slugs = self.book_slugs.split() # allow URIs - slugs = [slug.rstrip('/').rsplit('/', 1)[-1] if '/' in slug else slug - for slug in slugs] + # WTF + slugs = [slug.rstrip('/').rsplit('/', 1)[-1] if '/' in slug else slug for slug in slugs] return models.Q(slug__in=slugs) def get_books(self): diff --git a/src/catalogue/models/source.py b/src/catalogue/models/source.py index 9aff4efec..bcf5254bb 100644 --- a/src/catalogue/models/source.py +++ b/src/catalogue/models/source.py @@ -39,7 +39,6 @@ class Source(models.Model): if old_name != self.name or old_netloc != self.netloc: 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): + if self.netloc in source or (old_netloc != self.netloc and old_netloc in source): book.flush_includes() return ret diff --git a/src/catalogue/models/tag.py b/src/catalogue/models/tag.py index 89ca65185..4a7be0247 100644 --- a/src/catalogue/models/tag.py +++ b/src/catalogue/models/tag.py @@ -21,7 +21,7 @@ TAG_CATEGORIES = ( ('genre', _('genre')), ('theme', _('theme')), ('set', _('set')), - ('thing', _('thing')), # things shown on pictures + ('thing', _('thing')), # things shown on pictures ) @@ -33,8 +33,8 @@ class Tag(TagBase): name = models.CharField(_('name'), max_length=120, db_index=True) slug = models.SlugField(_('slug'), max_length=120, db_index=True) sort_key = models.CharField(_('sort key'), max_length=120, db_index=True) - category = models.CharField(_('category'), max_length=50, blank=False, null=False, - db_index=True, choices=TAG_CATEGORIES) + category = models.CharField( + _('category'), max_length=50, blank=False, null=False, db_index=True, choices=TAG_CATEGORIES) description = models.TextField(_('description'), blank=True) user = models.ForeignKey(User, blank=True, null=True) @@ -138,18 +138,18 @@ class Tag(TagBase): @permalink def get_absolute_url(self): - return ('tagged_object_list', [self.url_chunk]) + return 'tagged_object_list', [self.url_chunk] @permalink def get_absolute_gallery_url(self): - return ('tagged_object_list_gallery', [self.url_chunk]) + return 'tagged_object_list_gallery', [self.url_chunk] @classmethod @permalink def create_url(cls, category, slug): return ('catalogue.views.tagged_object_list', [ - '/'.join((cls.categories_dict[category], slug)) - ]) + '/'.join((cls.categories_dict[category], slug)) + ]) def has_description(self): return len(self.description) > 0 @@ -159,7 +159,8 @@ class Tag(TagBase): @staticmethod def get_tag_list(tags): if isinstance(tags, basestring): - if not tags: return [] + if not tags: + return [] real_tags = [] ambiguous_slugs = [] category = None @@ -175,7 +176,7 @@ class Tag(TagBase): try: real_tags.append(Tag.objects.get(slug=name)) deprecated = True - except Tag.MultipleObjectsReturned, e: + except Tag.MultipleObjectsReturned: ambiguous_slugs.append(name) if category: @@ -208,10 +209,10 @@ class Tag(TagBase): for field_name, category in categories: try: tag_names = getattr(info, field_name) - except: + except KeyError: try: tag_names = [getattr(info, category)] - except: + except KeyError: # For instance, Pictures do not have 'genre' field. continue for tag_name in tag_names: diff --git a/src/catalogue/signals.py b/src/catalogue/signals.py index 660d26493..3adfedbb0 100644 --- a/src/catalogue/signals.py +++ b/src/catalogue/signals.py @@ -92,8 +92,7 @@ def tag_after_change(sender, instance, languages, **kwargs): @receiver(tags_updated) def receive_tags_updated(sender, instance, affected_tags, **kwargs): - categories = set(tag.category for tag in affected_tags - if tag.category not in ('set', 'book')) + categories = set(tag.category for tag in affected_tags if tag.category not in ('set', 'book')) if not categories: return diff --git a/src/catalogue/templatetags/catalogue_tags.py b/src/catalogue/templatetags/catalogue_tags.py index ce23e548f..117abba0c 100644 --- a/src/catalogue/templatetags/catalogue_tags.py +++ b/src/catalogue/templatetags/catalogue_tags.py @@ -24,14 +24,18 @@ register = template.Library() class RegistrationForm(UserCreationForm): def as_ul(self): - "Returns this form rendered as HTML
  • s -- excluding the
      ." - return self._html_output(u'
    • %(errors)s%(label)s %(field)s%(help_text)s
    • ', u'
    • %s
    • ', '', u' %s', False) + """Returns this form rendered as HTML
    • s -- excluding the
        .""" + return self._html_output( + u'
      • %(errors)s%(label)s %(field)s%(help_text)s
      • ', u'
      • %s
      • ', + '', u' %s', False) class LoginForm(AuthenticationForm): def as_ul(self): - "Returns this form rendered as HTML
      • s -- excluding the
          ." - return self._html_output(u'
        • %(errors)s%(label)s %(field)s%(help_text)s
        • ', u'
        • %s
        • ', '', u' %s', False) + """Returns this form rendered as HTML
        • s -- excluding the
            .""" + return self._html_output( + u'
          • %(errors)s%(label)s %(field)s%(help_text)s
          • ', u'
          • %s
          • ', + '', u' %s', False) def iterable(obj): @@ -108,8 +112,8 @@ def title_from_tags(tags): # Specjalny przypadek "Dramat w twórczości Sofoklesa", wtedy gdy podane # są tylko rodzaj literacki i autor if 'kind' in self and 'author' in self and len(self) == 2: - text = u'%s w twórczości %s' % (unicode(self['kind']), - flection.get_case(unicode(self['author']), u'dopełniacz')) + text = u'%s w twórczości %s' % ( + unicode(self['kind']), flection.get_case(unicode(self['author']), u'dopełniacz')) return capfirst(text) # Przypadki ogólniejsze @@ -150,17 +154,20 @@ def book_tree(book_list, books_by_parent): else: return '' + @register.simple_tag def audiobook_tree(book_list, books_by_parent): text = "".join("
          • %s%s
          • " % ( - reverse("book_player", args=[book.slug]), book.title, audiobook_tree(books_by_parent.get(book, ()), books_by_parent) - ) for book in book_list) + reverse("book_player", args=[book.slug]), book.title, + audiobook_tree(books_by_parent.get(book, ()), books_by_parent) + ) for book in book_list) if text: return "
              %s
            " % text else: return '' + @register.simple_tag def book_tree_texml(book_list, books_by_parent, depth=1): return "".join(""" @@ -201,6 +208,7 @@ def book_tree_csv(author, book_list, books_by_parent, depth=1, max_depth=3, deli "children": book_tree_csv(author, books_by_parent.get(book.id, ()), books_by_parent, depth + 1) } for book in book_list) + @register.simple_tag def all_editors(extra_info): editors = [] @@ -313,7 +321,8 @@ def tag_list(tags, choices=None, category=None, gallery=False): one_tag = tags[0] if category is not None: - other = Tag.objects.filter(category=category).exclude(pk__in=[t.pk for t in tags]).exclude(pk__in=[t.pk for t in category_choices]) + other = Tag.objects.filter(category=category).exclude(pk__in=[t.pk for t in tags])\ + .exclude(pk__in=[t.pk for t in category_choices]) # Filter out empty tags. ct = ContentType.objects.get_for_model(Picture if gallery else Book) other = other.filter(items__content_type=ct).distinct() @@ -345,9 +354,9 @@ def work_list(context, object_list): return locals() - @register.inclusion_tag('catalogue/plain_list.html', takes_context=True) -def plain_list(context, object_list, with_initials=True, by_author=False, choice=None, book=None, gallery=False, paged=True): +def plain_list(context, object_list, with_initials=True, by_author=False, choice=None, book=None, gallery=False, + paged=True): names = [('', [])] last_initial = None for obj in object_list: @@ -363,11 +372,10 @@ def plain_list(context, object_list, with_initials=True, by_author=False, choice return locals() - # TODO: These are no longer just books. @register.inclusion_tag('catalogue/related_books.html', takes_context=True) def related_books(context, instance, limit=6, random=1, taken=0): - limit = limit - taken + limit -= taken max_books = limit - random is_picture = isinstance(instance, Picture) @@ -404,17 +412,14 @@ def related_books(context, instance, limit=6, random=1, taken=0): def download_audio(book, daisy=True): links = [] if book.has_media('mp3'): - links.append("%s" % - (reverse('download_zip_mp3', args=[book.slug]), - BookMedia.formats['mp3'].name)) + links.append("%s" % ( + reverse('download_zip_mp3', args=[book.slug]), BookMedia.formats['mp3'].name)) if book.has_media('ogg'): - links.append("%s" % - (reverse('download_zip_ogg', args=[book.slug]), - BookMedia.formats['ogg'].name)) + links.append("%s" % ( + reverse('download_zip_ogg', args=[book.slug]), BookMedia.formats['ogg'].name)) if daisy and book.has_media('daisy'): for dsy in book.get_media('daisy'): - links.append("%s" % - (dsy.file.url, BookMedia.formats['daisy'].name)) + links.append("%s" % (dsy.file.url, BookMedia.formats['daisy'].name)) return "".join(links) diff --git a/src/catalogue/test_utils.py b/src/catalogue/test_utils.py index 9d87311dd..497b99545 100644 --- a/src/catalogue/test_utils.py +++ b/src/catalogue/test_utils.py @@ -14,7 +14,7 @@ from django.conf import settings @override_settings( MEDIA_ROOT=tempfile.mkdtemp(prefix='djangotest_'), - CATALOGUE_DONT_BUILD=set(['pdf', 'mobi', 'epub', 'txt', 'fb2', 'cover']), + CATALOGUE_DONT_BUILD={'pdf', 'mobi', 'epub', 'txt', 'fb2', 'cover'}, NO_SEARCH_INDEX=True, CELERY_ALWAYS_EAGER=True, CACHES={ diff --git a/src/catalogue/tests/book_import.py b/src/catalogue/tests/book_import.py index 775fc2929..e5d5b0c72 100644 --- a/src/catalogue/tests/book_import.py +++ b/src/catalogue/tests/book_import.py @@ -2,8 +2,6 @@ # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # -from django.conf import settings - from django.core.files.base import ContentFile from catalogue.test_utils import * from catalogue import models @@ -12,6 +10,7 @@ from librarian import WLURI from nose.tools import raises from os import path, makedirs + class BookImportLogicTests(WLTestCase): def setUp(self): @@ -36,8 +35,8 @@ class BookImportLogicTests(WLTestCase): self.expected_tags.sort() def test_empty_book(self): - BOOK_TEXT = "" - book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info) + book_text = "" + book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info) self.assertEqual(book.title, "Default Book") self.assertEqual(book.slug, "default-book") @@ -52,7 +51,7 @@ class BookImportLogicTests(WLTestCase): self.assertEqual(book.gazeta_link, '') self.assertEqual(book.description, '') - tags = [ (tag.category, tag.slug) for tag in book.tags ] + tags = [(tag.category, tag.slug) for tag in book.tags] tags.sort() self.assertEqual(tags, self.expected_tags) @@ -63,53 +62,53 @@ class BookImportLogicTests(WLTestCase): Should work like any other non-empty book. """ - BOOK_TEXT = """ + book_text = """ Nic """ - book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info) + book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info) self.assertTrue(book.has_html_file()) def test_book_with_fragment(self): - BOOK_TEXT = """ + book_text = """ LoveAla ma kota """ - book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info) + book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info) self.assertTrue(book.has_html_file()) self.assertEqual(book.fragments.count(), 1) self.assertEqual(book.fragments.all()[0].text, u'

            Ala ma kota

            \n') - self.assert_(('theme', 'love') in [ (tag.category, tag.slug) for tag in book.fragments.all()[0].tags ]) + self.assert_(('theme', 'love') in [(tag.category, tag.slug) for tag in book.fragments.all()[0].tags]) def test_book_with_empty_theme(self): """ empty themes should be ignored """ - BOOK_TEXT = """ + book_text = """ , Love , , Ala ma kota """ - book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info) + book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info) self.assert_([('theme', 'love')], - [ (tag.category, tag.slug) for tag in book.fragments.all()[0].tags.filter(category='theme') ]) + [(tag.category, tag.slug) for tag in book.fragments.all()[0].tags.filter(category='theme')]) def test_book_with_no_theme(self): """ fragments with no themes shouldn't be created at all """ - BOOK_TEXT = """ + book_text = """ Ala ma kota """ - book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info) + book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info) self.assertEqual(book.fragments.count(), 0) self.assertEqual(book.tags.filter(category='theme').count(), 0) @@ -117,27 +116,27 @@ class BookImportLogicTests(WLTestCase): def test_book_with_invalid_slug(self): """ Book with invalid characters in slug shouldn't be imported """ self.book_info.url = WLURI.from_slug(u"default_book") - BOOK_TEXT = "" - models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info) + book_text = "" + models.Book.from_text_and_meta(ContentFile(book_text), self.book_info) def test_book_replace_title(self): - BOOK_TEXT = """""" - book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info) + book_text = """""" + models.Book.from_text_and_meta(ContentFile(book_text), self.book_info) self.book_info.title = u"Extraordinary" - book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info, overwrite=True) + book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info, overwrite=True) - tags = [ (tag.category, tag.slug) for tag in book.tags ] + tags = [(tag.category, tag.slug) for tag in book.tags] tags.sort() self.assertEqual(tags, self.expected_tags) def test_book_replace_author(self): - BOOK_TEXT = """""" - book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info) + book_text = """""" + models.Book.from_text_and_meta(ContentFile(book_text), self.book_info) self.book_info.author = PersonStub(("Hans", "Christian"), "Andersen") - book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info, overwrite=True) + book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info, overwrite=True) - tags = [ (tag.category, tag.slug) for tag in book.tags ] + tags = [(tag.category, tag.slug) for tag in book.tags] tags.sort() self.expected_tags.remove(('author', 'jim-lazy')) @@ -150,7 +149,7 @@ class BookImportLogicTests(WLTestCase): models.Tag.objects.get(slug="jim-lazy", category="author") def test_book_remove_fragment(self): - BOOK_TEXT = """ + book_text = """ LoveAla ma kota @@ -158,7 +157,7 @@ class BookImportLogicTests(WLTestCase): """ - BOOK_TEXT_AFTER = """ + book_text_after = """ LoveAla ma kota @@ -167,13 +166,13 @@ class BookImportLogicTests(WLTestCase): """ - book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info) + book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info) self.assertEqual(book.fragments.count(), 2) - book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT_AFTER), self.book_info, overwrite=True) + book = models.Book.from_text_and_meta(ContentFile(book_text_after), self.book_info, overwrite=True) self.assertEqual(book.fragments.count(), 1) def test_multiple_tags(self): - BOOK_TEXT = """""" + book_text = """""" self.book_info.authors = self.book_info.author, PersonStub(("Joe",), "Dilligent"), self.book_info.kinds = self.book_info.kind, 'Y-Kind', self.book_info.genres = self.book_info.genre, 'Y-Genre', @@ -187,8 +186,8 @@ class BookImportLogicTests(WLTestCase): ]) self.expected_tags.sort() - book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info) - tags = [ (tag.category, tag.slug) for tag in book.tags ] + book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info) + tags = [(tag.category, tag.slug) for tag in book.tags] tags.sort() self.assertEqual(tags, self.expected_tags) @@ -216,32 +215,30 @@ class ChildImportTests(WLTestCase): ) def test_child(self): - TEXT = """""" - child = models.Book.from_text_and_meta(ContentFile(TEXT), self.child_info) - parent = models.Book.from_text_and_meta(ContentFile(TEXT), self.parent_info) + text = """""" + child = models.Book.from_text_and_meta(ContentFile(text), self.child_info) + parent = models.Book.from_text_and_meta(ContentFile(text), self.parent_info) author = parent.tags.get(category='author') books = self.client.get(author.get_absolute_url()).context['object_list'] - self.assertEqual(len(books), 1, - "Only parent book should be visible on author's page") + self.assertEqual(len(books), 1, "Only parent book should be visible on author's page") def test_child_replace(self): - PARENT_TEXT = """""" - CHILD_TEXT = """ + parent_text = """""" + child_text = """ PiesAla ma kota """ - child = models.Book.from_text_and_meta(ContentFile(CHILD_TEXT), self.child_info) - parent = models.Book.from_text_and_meta(ContentFile(PARENT_TEXT), self.parent_info) - CHILD_TEXT = """ + child = models.Book.from_text_and_meta(ContentFile(child_text), self.child_info) + parent = models.Book.from_text_and_meta(ContentFile(parent_text), self.parent_info) + child_text = """ KotAla ma kota """ - child = models.Book.from_text_and_meta(ContentFile(CHILD_TEXT), self.child_info, overwrite=True) + child = models.Book.from_text_and_meta(ContentFile(child_text), self.child_info, overwrite=True) themes = parent.related_themes() - self.assertEqual(['Kot'], [tag.name for tag in themes], - 'wrong related theme list') + self.assertEqual(['Kot'], [tag.name for tag in themes], 'wrong related theme list') class TreeImportTest(WLTestCase): @@ -289,47 +286,38 @@ class TreeImportTest(WLTestCase): def test_ok(self): self.assertEqual( - list(self.client.get('/katalog/gatunek/x-genre/' - ).context['object_list']), + list(self.client.get('/katalog/gatunek/x-genre/').context['object_list']), [self.parent], u"There should be only parent on common tag page." ) - pies = models.Tag.objects.get(slug='pies') + # pies = models.Tag.objects.get(slug='pies') themes = self.parent.related_themes() - self.assertEqual(len(themes), 1, - u"There should be child theme in parent theme counter." - ) + self.assertEqual(len(themes), 1, u"There should be child theme in parent theme counter.") # TODO: book_count is deprecated, update here. - #~ epoch = models.Tag.objects.get(slug='x-epoch') - #~ self.assertEqual(epoch.book_count, 1, - #~ u"There should be only parent in common tag's counter." - #~ ) + # epoch = models.Tag.objects.get(slug='x-epoch') + # self.assertEqual(epoch.book_count, 1, u"There should be only parent in common tag's counter.") def test_child_republish(self): - CHILD_TEXT = """ + child_text = """ Pies, Kot Ala ma kota """ models.Book.from_text_and_meta( - ContentFile(CHILD_TEXT), self.child_info, overwrite=True) + ContentFile(child_text), self.child_info, overwrite=True) self.assertEqual( - list(self.client.get('/katalog/gatunek/x-genre/' - ).context['object_list']), + list(self.client.get('/katalog/gatunek/x-genre/').context['object_list']), [self.parent], u"There should only be parent on common tag page." ) - pies = models.Tag.objects.get(slug='pies') - kot = models.Tag.objects.get(slug='kot') + # pies = models.Tag.objects.get(slug='pies') + # kot = models.Tag.objects.get(slug='kot') self.assertEqual(len(self.parent.related_themes()), 2, - u"There should be child themes in parent theme counter." - ) + u"There should be child themes in parent theme counter.") # TODO: book_count is deprecated, update here. - #~ epoch = models.Tag.objects.get(slug='x-epoch') - #~ self.assertEqual(epoch.book_count, 1, - #~ u"There should only be parent in common tag's counter." - #~ ) + # epoch = models.Tag.objects.get(slug='x-epoch') + # self.assertEqual(epoch.book_count, 1, u"There should only be parent in common tag's counter.") def test_book_change_child(self): second_child_info = BookInfoStub( @@ -339,7 +327,7 @@ class TreeImportTest(WLTestCase): author=PersonStub(("Joe",), "Doe"), **info_args("Second Child") ) - SECOND_CHILD_TEXT = """ + second_child_text = """ Kot Ala ma kota @@ -347,39 +335,34 @@ class TreeImportTest(WLTestCase): """ # Import a second child. second_child = models.Book.from_text_and_meta( - ContentFile(SECOND_CHILD_TEXT), second_child_info) + ContentFile(second_child_text), second_child_info) # The book has only this new child now. self.book_info.parts = [second_child_info.url] self.book = models.Book.from_text_and_meta( ContentFile(self.BOOK_TEXT), self.book_info, overwrite=True) self.assertEqual( - set(self.client.get('/katalog/gatunek/x-genre/' - ).context['object_list']), - set([self.parent, self.child]), - u"There should be parent and old child on common tag page." - ) - kot = models.Tag.objects.get(slug='kot') + set(self.client.get('/katalog/gatunek/x-genre/').context['object_list']), + {self.parent, self.child}, + u"There should be parent and old child on common tag page." + ) + # kot = models.Tag.objects.get(slug='kot') self.assertEqual(len(self.parent.related_themes()), 1, - u"There should only be new child themes in parent theme counter." - ) - epoch = models.Tag.objects.get(slug='x-epoch') - # book_count deprecated, update test. - #~ self.assertEqual(epoch.book_count, 2, - #~ u"There should be parent and old child in common tag's counter." - #~ ) + u"There should only be new child themes in parent theme counter.") + # # book_count deprecated, update test. + # epoch = models.Tag.objects.get(slug='x-epoch') + # self.assertEqual(epoch.book_count, 2, + # u"There should be parent and old child in common tag's counter.") self.assertEqual( - list(self.client.get('/katalog/lektura/parent/motyw/kot/' - ).context['fragments']), - [second_child.fragments.all()[0]], - u"There should be new child's fragments on parent's theme page." - ) + list(self.client.get('/katalog/lektura/parent/motyw/kot/').context['fragments']), + [second_child.fragments.all()[0]], + u"There should be new child's fragments on parent's theme page." + ) self.assertEqual( - list(self.client.get('/katalog/lektura/parent/motyw/pies/' - ).context['fragments']), - [], - u"There should be no old child's fragments on parent's theme page." - ) + list(self.client.get('/katalog/lektura/parent/motyw/pies/').context['fragments']), + [], + u"There should be no old child's fragments on parent's theme page." + ) class MultilingualBookImportTest(WLTestCase): @@ -406,16 +389,16 @@ class MultilingualBookImportTest(WLTestCase): ) def test_multilingual_import(self): - BOOK_TEXT = """A""" + book_text = """A""" - book1 = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.pol_info) - book2 = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.eng_info) + models.Book.from_text_and_meta(ContentFile(book_text), self.pol_info) + models.Book.from_text_and_meta(ContentFile(book_text), self.eng_info) self.assertEqual( - set([b.language for b in models.Book.objects.all()]), - set(['pol', 'eng']), - 'Books imported in wrong languages.' - ) + set([b.language for b in models.Book.objects.all()]), + {'pol', 'eng'}, + 'Books imported in wrong languages.' + ) class BookImportGenerateTest(WLTestCase): @@ -445,6 +428,5 @@ class BookImportGenerateTest(WLTestCase): if not path.exists(path.dirname(absoulute_path)): makedirs(path.dirname(absoulute_path)) - build_custom_pdf(self.book.id, - customizations=['nofootnotes', '13pt', 'a4paper'], file_name=out) + build_custom_pdf(self.book.id, customizations=['nofootnotes', '13pt', 'a4paper'], file_name=out) self.assertTrue(path.exists(absoulute_path)) diff --git a/src/catalogue/tests/bookmedia.py b/src/catalogue/tests/bookmedia.py index 2d3cf539d..9d6a52475 100644 --- a/src/catalogue/tests/bookmedia.py +++ b/src/catalogue/tests/bookmedia.py @@ -2,13 +2,13 @@ # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # -from django.conf import settings -from os.path import basename, exists, join, dirname +from os.path import basename, exists from django.core.files.base import ContentFile from catalogue.test_utils import * from catalogue import models, utils + class BookMediaTests(WLTestCase): def setUp(self): @@ -18,14 +18,14 @@ class BookMediaTests(WLTestCase): self.book = models.Book.objects.create(slug='test-book') def test_diacritics(self): - bm = models.BookMedia(book=self.book, type="ogg", - name=u"Zażółć gęślą jaźń") + bm = models.BookMedia(book=self.book, type="ogg", name=u"Zażółć gęślą jaźń") bm.file.save(None, self.file) self.assertEqual(basename(bm.file.name), 'zazolc-gesla-jazn.ogg') def test_long_name(self): - bm = models.BookMedia(book=self.book, type="ogg", - name="Some very very very very very very very very very very very very very very very very long file name") + bm = models.BookMedia( + book=self.book, type="ogg", + name="Some very very very very very very very very very very very very very very very very long file name") bm.file.save(bm.name, self.file) # reload to see what was really saved @@ -37,8 +37,7 @@ class BookMediaTests(WLTestCase): File gets overwritten with same filename on update. """ - bm = models.BookMedia(book=self.book, type='ogg', - name="Some media") + bm = models.BookMedia(book=self.book, type='ogg', name="Some media") bm.file.save(None, self.file) bm.file.save(None, self.file2) @@ -50,11 +49,9 @@ class BookMediaTests(WLTestCase): File save doesn't clobber some other media with similar name. """ - bm = models.BookMedia(book=self.book, type='ogg', - name=u"Tytul") + bm = models.BookMedia(book=self.book, type='ogg', name=u"Tytul") bm.file.save(None, self.file) - bm2 = models.BookMedia(book=self.book, type='ogg', - name=u"Tytuł") + bm2 = models.BookMedia(book=self.book, type='ogg', name=u"Tytuł") bm2.file.save(None, self.file2) self.assertEqual(basename(bm.file.name), 'tytul.ogg') self.assertNotEqual(basename(bm2.file.name), 'tytul.ogg') diff --git a/src/catalogue/tests/cover.py b/src/catalogue/tests/cover.py index 0e08556b4..8c5d04718 100755 --- a/src/catalogue/tests/cover.py +++ b/src/catalogue/tests/cover.py @@ -39,15 +39,13 @@ class CoverTests(WLTestCase): # Now reimport parent. parent_cover_changed.reset_mock() - parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent, - overwrite=True) + parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent, overwrite=True) self.assertEqual(parent_cover_changed.call_count, 0) # Now change cover in parent. parent_cover_changed.reset_mock() self.parent.cover_url = "http://example.com/other-cover.jpg" - parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent, - overwrite=True) + parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent, overwrite=True) parent_cover_changed.assert_called_with(child) @patch.object(Book, 'parent_cover_changed', autospec=True) @@ -65,13 +63,11 @@ class CoverTests(WLTestCase): # Now import child and reimport parent. child = Book.from_text_and_meta(ContentFile(self.TEXT), self.child) self.parent.parts = parts - parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent, - overwrite=True) + parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent, overwrite=True) parent_cover_changed.assert_called_with(child) # Now remove the child. parent_cover_changed.reset_mock() self.parent.parts = [] - parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent, - overwrite=True) + parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent, overwrite=True) parent_cover_changed.assert_called_with(child) diff --git a/src/catalogue/tests/search.py b/src/catalogue/tests/search.py index 77afae4c3..b6b03d828 100644 --- a/src/catalogue/tests/search.py +++ b/src/catalogue/tests/search.py @@ -7,21 +7,22 @@ from catalogue.test_utils import * from nose.tools import raises + class BasicSearchLogicTests(WLTestCase): def setUp(self): WLTestCase.setUp(self) self.author_tag = models.Tag.objects.create( - name=u'Adam Mickiewicz [SubWord]', - category=u'author', slug="one") + name=u'Adam Mickiewicz [SubWord]', + category=u'author', slug="one") self.unicode_tag = models.Tag.objects.create( - name=u'Tadeusz Żeleński (Boy)', - category=u'author', slug="two") + name=u'Tadeusz Żeleński (Boy)', + category=u'author', slug="two") self.polish_tag = models.Tag.objects.create( - name=u'ĘÓĄŚŁŻŹĆŃęóąśłżźćń', - category=u'author', slug="three") + name=u'ĘÓĄŚŁŻŹĆŃęóąśłżźćń', + category=u'author', slug="three") @raises(ValueError) def test_empty_query(self): diff --git a/src/catalogue/tests/tags.py b/src/catalogue/tests/tags.py index 527775bb8..e6fe17c6d 100644 --- a/src/catalogue/tests/tags.py +++ b/src/catalogue/tests/tags.py @@ -104,8 +104,7 @@ class TagRelatedTagsTests(WLTestCase): """ empty tag should have no related tags """ cats = self.client.get('/katalog/autor/empty/').context['categories'] - self.assertEqual({k: v for (k, v) in cats.items() if v}, {}, - 'tags related to empty tag') + self.assertEqual({k: v for (k, v) in cats.items() if v}, {}, 'tags related to empty tag') def test_has_related(self): """ related own and descendants' tags should be generated """ @@ -116,17 +115,17 @@ class TagRelatedTagsTests(WLTestCase): self.assertTrue('Epoch' in [tag.name for tag in cats['epoch']], 'missing `epoch` related tag') self.assertFalse(cats.get("kind", False), - "There should be no child-only related `kind` tags") + "There should be no child-only related `kind` tags") self.assertTrue("Genre" in [tag.name for tag in cats['genre']], 'missing `genre` related tag') self.assertFalse("ChildGenre" in [tag.name for tag in cats['genre']], - "There should be no child-only related `genre` tags") + "There should be no child-only related `genre` tags") self.assertTrue("GchildGenre" in [tag.name for tag in cats['genre']], "missing grandchild's related tag") self.assertTrue('Theme' in [tag.name for tag in cats['theme']], "missing related theme") self.assertFalse('Child1Theme' in [tag.name for tag in cats['theme']], - "There should be no child-only related `theme` tags") + "There should be no child-only related `theme` tags") self.assertTrue('GChildTheme' in [tag.name for tag in cats['theme']], "missing grandchild's related theme") @@ -149,18 +148,18 @@ class TagRelatedTagsTests(WLTestCase): [('Epoch', 1)], 'wrong related tag epoch tag on tag page') - def test_siblings_tags_count(self): """ if children have tags and parent hasn't, count the children """ cats = self.client.get('/katalog/epoka/epoch/').context['categories'] - self.assertTrue(('ChildKind', 2) in [(tag.name, tag.count) for tag in cats['kind']], - 'wrong related kind tags on tag page, got: ' + - unicode([(tag.name, tag.count) for tag in cats['kind']])) + self.assertTrue( + ('ChildKind', 2) in [(tag.name, tag.count) for tag in cats['kind']], + 'wrong related kind tags on tag page, got: ' + + unicode([(tag.name, tag.count) for tag in cats['kind']])) # all occurencies of theme should be counted self.assertTrue(('Theme', 4) in [(tag.name, tag.count) for tag in cats['theme']], - 'wrong related theme count') + 'wrong related theme count') def test_query_child_tag(self): """ @@ -169,8 +168,8 @@ class TagRelatedTagsTests(WLTestCase): """ cats = self.client.get('/katalog/gatunek/childgenre/').context['categories'] self.assertTrue(('Epoch', 2) in [(tag.name, tag.count) for tag in cats['epoch']], - 'wrong related kind tags on tag page, got: ' + - unicode([(tag.name, tag.count) for tag in cats['epoch']])) + 'wrong related kind tags on tag page, got: ' + + unicode([(tag.name, tag.count) for tag in cats['epoch']])) class CleanTagRelationTests(WLTestCase): @@ -180,8 +179,7 @@ class CleanTagRelationTests(WLTestCase): WLTestCase.setUp(self) author = PersonStub(("Common",), "Man") - book_info = BookInfoStub(author=author, genre="G", epoch='E', kind="K", - **info_args(u"Book")) + book_info = BookInfoStub(author=author, genre="G", epoch='E', kind="K", **info_args(u"Book")) book_text = """ ThemeAla ma kota @@ -215,11 +213,7 @@ class TestIdenticalTag(WLTestCase): WLTestCase.setUp(self) author = PersonStub((), "Tag") - self.book_info = BookInfoStub(author=author, - genre="tag", - epoch='tag', - kind="tag", - **info_args(u"tag")) + self.book_info = BookInfoStub(author=author, genre="tag", epoch='tag', kind="tag", **info_args(u"tag")) self.book_text = """ @@ -229,7 +223,6 @@ class TestIdenticalTag(WLTestCase): """ - def test_book_tags(self): """ there should be all related tags in relevant categories """ book = models.Book.from_text_and_meta(ContentFile(self.book_text), self.book_info) @@ -242,7 +235,7 @@ class TestIdenticalTag(WLTestCase): def test_qualified_url(self): models.Book.from_text_and_meta(ContentFile(self.book_text), self.book_info) - categories = {'author': 'autor', 'theme': 'motyw', 'epoch': 'epoka', 'kind':'rodzaj', 'genre':'gatunek'} + categories = {'author': 'autor', 'theme': 'motyw', 'epoch': 'epoka', 'kind': 'rodzaj', 'genre': 'gatunek'} for cat, localcat in categories.iteritems(): context = self.client.get('/katalog/%s/tag/' % localcat).context self.assertEqual(1, len(context['object_list'])) @@ -259,7 +252,7 @@ class BookTagsTests(WLTestCase): author2 = PersonStub(("Jim",), "Lazy") child_info = BookInfoStub(authors=(author1, author2), genre="ChildGenre", epoch='Epoch', kind="ChildKind", - **info_args(u"Child")) + **info_args(u"Child")) parent_info = BookInfoStub(author=author1, genre="Genre", epoch='Epoch', kind="Kind", parts=[child_info.url], **info_args(u"Parent")) diff --git a/src/catalogue/tests/templatetags.py b/src/catalogue/tests/templatetags.py index a66d604de..c69472fac 100644 --- a/src/catalogue/tests/templatetags.py +++ b/src/catalogue/tests/templatetags.py @@ -16,7 +16,7 @@ class BookDescTests(WLTestCase): authors = PersonStub(("Common",), "Man"), PersonStub(("Jane",), "Doe") child_info = BookInfoStub(authors=authors, genre="Genre", epoch='Epoch', kind="Kind", - **info_args(u"Child")) + **info_args(u"Child")) parent_info = BookInfoStub(authors=authors, genre="Genre", epoch='Epoch', kind="Kind", parts=[child_info.url], **info_args(u"Parent")) diff --git a/src/catalogue/tests/visit.py b/src/catalogue/tests/visit.py index 8cfea1290..0edccd096 100644 --- a/src/catalogue/tests/visit.py +++ b/src/catalogue/tests/visit.py @@ -74,6 +74,6 @@ class VisitTest(WLTestCase): for url in urls: print(url) status = self.client.get(prefix + url).status_code - self.assertEqual(status, expected_status, - "Wrong status code for '%s'. Expected %d, got %d." % ( - prefix + url, expected_status, status)) + self.assertEqual( + status, expected_status, + "Wrong status code for '%s'. Expected %d, got %d." % (prefix + url, expected_status, status)) diff --git a/src/catalogue/translation.py b/src/catalogue/translation.py index 319736515..4946143db 100644 --- a/src/catalogue/translation.py +++ b/src/catalogue/translation.py @@ -6,12 +6,15 @@ from modeltranslation.translator import translator, TranslationOptions from catalogue.models import Collection, Tag, Source + class TagTranslationOptions(TranslationOptions): fields = ('name', 'description', 'wiki_link') + class CollectionTranslationOptions(TranslationOptions): fields = ('title', 'description') + class SourceTranslationOptions(TranslationOptions): fields = ('name',) diff --git a/src/catalogue/urls.py b/src/catalogue/urls.py index 0b33ce96c..a4627e25e 100644 --- a/src/catalogue/urls.py +++ b/src/catalogue/urls.py @@ -12,7 +12,8 @@ from catalogue.models import Book SLUG = r'[a-z0-9-]*' -urlpatterns = patterns('picture.views', +urlpatterns = patterns( + 'picture.views', # pictures - currently pictures are coupled with catalogue, hence the url is here url(r'^obraz/$', 'picture_list_thumb', name='picture_list_thumb'), url(r'^obraz/(?P%s).html$' % SLUG, 'picture_viewer', name='picture_viewer'), @@ -23,13 +24,15 @@ urlpatterns = patterns('picture.views', url(r'^pa/(?P\d+)/short\.(?P.+)\.html', 'picturearea_short', name='picture_area_short'), ) -urlpatterns += patterns('', +urlpatterns += patterns( + '', # old search page - redirected url(r'^szukaj/$', RedirectView.as_view( url='/szukaj/', query_string=True, permanent=True)), ) -urlpatterns += patterns('catalogue.views', +urlpatterns += patterns( + 'catalogue.views', url(r'^$', 'catalogue', name='catalogue'), url(r'^autor/$', 'tag_catalogue', {'category': 'author'}, name='author_catalogue'), @@ -52,10 +55,10 @@ urlpatterns += patterns('catalogue.views', template_name='catalogue/recent_list.html'), name='recent_list'), url(r'^nowe/audiobooki/$', ListView.as_view( queryset=Book.objects.filter(media__type='ogg').annotate(m=Max('media__uploaded_at')).order_by('-m'), - template_name='catalogue/recent_audiobooks_list.html'), name='recent_audiobooks_list'), + template_name='catalogue/recent_audiobooks_list.html'), name='recent_audiobooks_list'), url(r'^nowe/daisy/$', ListView.as_view( queryset=Book.objects.filter(media__type='daisy').annotate(m=Max('media__uploaded_at')).order_by('-m'), - template_name='catalogue/recent_daisy_list.html'), name='recent_daisy_list'), + template_name='catalogue/recent_daisy_list.html'), name='recent_daisy_list'), url(r'^custompdf/(?P%s)/$' % SLUG, CustomPDFFormView(), name='custom_pdf_form'), @@ -78,7 +81,8 @@ urlpatterns += patterns('catalogue.views', # Includes. url(r'^b/(?P\d+)/mini\.(?P.+)\.html', 'book_mini', name='catalogue_book_mini'), - url(r'^b/(?P\d+)/mini_nolink\.(?P.+)\.html', 'book_mini', {'with_link': False}, name='catalogue_book_mini_nolink'), + url(r'^b/(?P\d+)/mini_nolink\.(?P.+)\.html', 'book_mini', {'with_link': False}, + name='catalogue_book_mini_nolink'), url(r'^b/(?P\d+)/short\.(?P.+)\.html', 'book_short', name='catalogue_book_short'), url(r'^b/(?P\d+)/wide\.(?P.+)\.html', 'book_wide', name='catalogue_book_wide'), url(r'^f/(?P\d+)/promo\.(?P.+)\.html', 'fragment_promo', name='catalogue_fragment_promo'), @@ -87,6 +91,7 @@ urlpatterns += patterns('catalogue.views', url(r'^c/(?P.+)/box\.(?P.+)\.html', 'collection_box', name='catalogue_collection_box'), # This should be the last pattern. - url(r'^galeria/(?P[a-zA-Z0-9-/]*)/$', 'tagged_object_list', {'gallery': True}, name='tagged_object_list_gallery'), + url(r'^galeria/(?P[a-zA-Z0-9-/]*)/$', 'tagged_object_list', {'gallery': True}, + name='tagged_object_list_gallery'), url(r'^(?P[a-zA-Z0-9-/]*)/$', 'tagged_object_list', name='tagged_object_list'), ) diff --git a/src/catalogue/utils.py b/src/catalogue/utils.py index 71cd8907a..e79b4392c 100644 --- a/src/catalogue/utils.py +++ b/src/catalogue/utils.py @@ -30,9 +30,9 @@ MAX_SESSION_KEY = 18446744073709551616L # 2 << 63 def get_random_hash(seed): - sha_digest = hashlib.sha1('%s%s%s%s' % - (randrange(0, MAX_SESSION_KEY), time.time(), unicode(seed).encode('utf-8', 'replace'), - settings.SECRET_KEY)).digest() + sha_digest = hashlib.sha1('%s%s%s%s' % ( + randrange(0, MAX_SESSION_KEY), time.time(), unicode(seed).encode('utf-8', 'replace'), settings.SECRET_KEY) + ).digest() return urlsafe_b64encode(sha_digest).replace('=', '').replace('_', '-').lower() @@ -89,7 +89,7 @@ class LockFile(object): self.lock.close() -#@task +# @task def create_zip(paths, zip_slug): """ Creates a zip in MEDIA_ROOT/zip directory containing files from path. @@ -145,6 +145,7 @@ class AttachmentHttpResponse(HttpResponse): for chunk in read_chunks(f): self.write(chunk) + class MultiQuerySet(object): def __init__(self, *args, **kwargs): self.querysets = args @@ -163,7 +164,7 @@ class MultiQuerySet(object): (offset, stop, step) = item.indices(self.count()) except AttributeError: # it's not a slice - make it one - return self[item : item + 1][0] + return self[item:item + 1][0] items = [] total_len = stop - offset for qs in self.querysets: @@ -178,6 +179,7 @@ class MultiQuerySet(object): stop = total_len - len(items) continue + class SortedMultiQuerySet(MultiQuerySet): def __init__(self, *args, **kwargs): self.order_by = kwargs.pop('order_by', None) @@ -193,7 +195,7 @@ class SortedMultiQuerySet(MultiQuerySet): (offset, stop, step) = item.indices(self.count()) except AttributeError: # it's not a slice - make it one - return self[item : item + 1][0] + return self[item:item + 1][0] items = [] total_len = stop - offset skipped = 0 @@ -215,14 +217,14 @@ class SortedMultiQuerySet(MultiQuerySet): candidate = competitor candidate_i = i except IndexError: - continue # continue next sort_head + continue # continue next sort_head # we have no more elements: if candidate is None: break sort_heads[candidate_i] += 1 if skipped < offset: skipped += 1 - continue # continue next item + continue # continue next item items.append(candidate) return items @@ -279,7 +281,8 @@ def truncate_html_words(s, num, end_text='...'): except ValueError: pass else: - # SGML: An end tag closes, back to the matching start tag, all unclosed intervening start tags with omitted end tags + # SGML: An end tag closes, back to the matching start tag, + # all unclosed intervening start tags with omitted end tags open_tags = open_tags[i+1:] else: # Add it to the start of the open tags list @@ -333,9 +336,7 @@ class AppSettings(object): def __getattribute__(self, name): if name.startswith('_'): return object.__getattribute__(self, name) - value = getattr(settings, - "%s_%s" % (self._prefix, name), - object.__getattribute__(self, name)) + value = getattr(settings, "%s_%s" % (self._prefix, name), object.__getattribute__(self, name)) more = "_more_%s" % name if hasattr(self, more): value = getattr(self, more)(value) diff --git a/src/catalogue/views.py b/src/catalogue/views.py index a6d6e0023..084396bd4 100644 --- a/src/catalogue/views.py +++ b/src/catalogue/views.py @@ -22,7 +22,6 @@ from ajaxable.utils import AjaxableFormView from pdcounter import models as pdcounter_models from pdcounter import views as pdcounter_views from picture.models import Picture, PictureArea -from picture.views import picture_list_thumb from ssify import ssi_included, ssi_expect, SsiVariable as V from suggest.forms import PublishingSuggestForm from catalogue import constants @@ -30,7 +29,6 @@ from catalogue import forms from catalogue.helpers import get_top_level_related_tags from catalogue import models from catalogue.utils import split_tags -from catalogue.templatetags.catalogue_tags import tag_list, collection_list staff_required = user_passes_test(lambda user: user.is_staff) @@ -42,12 +40,9 @@ def catalogue(request, as_json=False): return render(request, 'catalogue/catalogue.html', locals()) -def book_list(request, filter=None, get_filter=None, - template_name='catalogue/book_list.html', - nav_template_name='catalogue/snippets/book_list_nav.html', - list_template_name='catalogue/snippets/book_list.html', - context=None, - ): +def book_list(request, filter=None, get_filter=None, template_name='catalogue/book_list.html', + nav_template_name='catalogue/snippets/book_list_nav.html', + list_template_name='catalogue/snippets/book_list.html', context=None): """ generates a listing of all books, optionally filtered with a test function """ if get_filter: filter = get_filter() @@ -58,8 +53,7 @@ def book_list(request, filter=None, get_filter=None, books_nav.setdefault(tag.sort_key[0], []).append(tag) rendered_nav = render_to_string(nav_template_name, locals()) rendered_book_list = render_to_string(list_template_name, locals()) - return render_to_response(template_name, locals(), - context_instance=RequestContext(request)) + return render_to_response(template_name, locals(), context_instance=RequestContext(request)) def audiobook_list(request): @@ -87,8 +81,7 @@ def daisy_list(request): def collection(request, slug): coll = get_object_or_404(models.Collection, slug=slug) - return render(request, 'catalogue/collection.html', - {'collection': coll}) + return render(request, 'catalogue/collection.html', {'collection': coll}) def differentiate_tags(request, tags, ambiguous_slugs): @@ -100,9 +93,9 @@ def differentiate_tags(request, tags, ambiguous_slugs): 'url_args': '/'.join((beginning, tag.url_chunk, unparsed)).strip('/'), 'tags': [tag] }) - return render_to_response('catalogue/differentiate_tags.html', - {'tags': tags, 'options': options, 'unparsed': ambiguous_slugs[1:]}, - context_instance=RequestContext(request)) + return render_to_response( + 'catalogue/differentiate_tags.html', {'tags': tags, 'options': options, 'unparsed': ambiguous_slugs[1:]}, + context_instance=RequestContext(request)) # TODO: Rewrite this hellish piece of code which tries to do everything @@ -123,7 +116,8 @@ def tagged_object_list(request, tags='', gallery=False): # Ask the user to disambiguate return differentiate_tags(request, e.tags, e.ambiguous_slugs) except models.Tag.UrlDeprecationWarning, e: - return HttpResponsePermanentRedirect(reverse('tagged_object_list', args=['/'.join(tag.url_chunk for tag in e.tags)])) + return HttpResponsePermanentRedirect( + reverse('tagged_object_list', args=['/'.join(tag.url_chunk for tag in e.tags)])) try: if len(tags) > settings.MAX_TAG_LIST: @@ -158,9 +152,8 @@ def tagged_object_list(request, tags='', gallery=False): fragments = fragments.filter(Q(book__in=books) | Q(book__ancestor__in=books)) categories = split_tags( - models.Tag.objects.usage_for_queryset(fragments, counts=True - ).exclude(pk__in=tags_pks), - ) + models.Tag.objects.usage_for_queryset(fragments, counts=True).exclude(pk__in=tags_pks), + ) objects = fragments else: @@ -220,10 +213,11 @@ def tagged_object_list(request, tags='', gallery=False): if not gallery and not objects and len(tags) == 1: tag = tags[0] if (tag.category in ('theme', 'thing') and PictureArea.tagged.with_any([tag]).exists() or - Picture.tagged.with_any([tag]).exists()): - return redirect('tagged_object_list_gallery', raw_tags, permanent=False) + Picture.tagged.with_any([tag]).exists()): + return redirect('tagged_object_list_gallery', raw_tags, permanent=False) - return render_to_response('catalogue/tagged_object_list.html', + return render_to_response( + 'catalogue/tagged_object_list.html', { 'object_list': objects, 'categories': categories, @@ -245,8 +239,7 @@ def book_fragments(request, slug, theme_slug): fragments = models.Fragment.tagged.with_all([theme]).filter( Q(book=book) | Q(book__ancestor=book)) - return render_to_response('catalogue/book_fragments.html', locals(), - context_instance=RequestContext(request)) + return render_to_response('catalogue/book_fragments.html', locals(), context_instance=RequestContext(request)) def book_detail(request, slug): @@ -257,8 +250,7 @@ def book_detail(request, slug): tags = book.tags.exclude(category__in=('set', 'theme')) book_children = book.children.all().order_by('parent_number', 'sort_key') - return render_to_response('catalogue/book_detail.html', locals(), - context_instance=RequestContext(request)) + return render_to_response('catalogue/book_detail.html', locals(), context_instance=RequestContext(request)) def get_audiobooks(book): @@ -301,8 +293,7 @@ def player(request, slug): extra_info = book.extra_info - return render_to_response('catalogue/player.html', locals(), - context_instance=RequestContext(request)) + return render_to_response('catalogue/player.html', locals(), context_instance=RequestContext(request)) def book_text(request, slug): @@ -310,8 +301,7 @@ def book_text(request, slug): if not book.has_html_file(): raise Http404 - return render_to_response('catalogue/book_text.html', locals(), - context_instance=RequestContext(request)) + return render_to_response('catalogue/book_text.html', locals(), context_instance=RequestContext(request)) # ========== @@ -323,18 +313,24 @@ def _no_diacritics_regexp(query): should be locale-aware """ names = { - u'a':u'aąĄ', u'c':u'cćĆ', u'e':u'eęĘ', u'l': u'lłŁ', u'n':u'nńŃ', u'o':u'oóÓ', u's':u'sśŚ', u'z':u'zźżŹŻ', - u'ą':u'ąĄ', u'ć':u'ćĆ', u'ę':u'ęĘ', u'ł': u'łŁ', u'ń':u'ńŃ', u'ó':u'óÓ', u'ś':u'śŚ', u'ź':u'źŹ', u'ż':u'żŻ' + u'a': u'aąĄ', u'c': u'cćĆ', u'e': u'eęĘ', u'l': u'lłŁ', u'n': u'nńŃ', u'o': u'oóÓ', u's': u'sśŚ', + u'z': u'zźżŹŻ', + u'ą': u'ąĄ', u'ć': u'ćĆ', u'ę': u'ęĘ', u'ł': u'łŁ', u'ń': u'ńŃ', u'ó': u'óÓ', u'ś': u'śŚ', u'ź': u'źŹ', + u'ż': u'żŻ' } + def repl(m): l = m.group() return u"(%s)" % '|'.join(names[l]) + return re.sub(u'[%s]' % (u''.join(names.keys())), repl, query) + def unicode_re_escape(query): """ Unicode-friendly version of re.escape """ return re.sub(r'(?u)(\W)', r'\\\1', query) + def _word_starts_with(name, prefix): """returns a Q object getting models having `name` contain a word starting with `prefix` @@ -364,8 +360,7 @@ def _sqlite_word_starts_with(name, prefix): SQLite in Django uses Python re module """ - kwargs = {} - kwargs['%s__iregex' % name] = _word_starts_with_regexp(prefix) + kwargs = {'%s__iregex' % name: _word_starts_with_regexp(prefix)} return Q(**kwargs) @@ -376,12 +371,13 @@ elif settings.DATABASE_ENGINE == 'sqlite3': _word_starts_with = _sqlite_word_starts_with -class App(): +class App: def __init__(self, name, view): self.name = name self._view = view self.lower = name.lower() self.category = 'application' + def view(self): return reverse(*self._view) @@ -404,14 +400,14 @@ def _tags_starting_with(prefix, user=None): tags = tags.exclude(category='set') prefix_regexp = re.compile(_word_starts_with_regexp(prefix)) - return list(books) + list(tags) + [app for app in _apps if prefix_regexp.search(app.lower)] + list(book_stubs) + list(authors) + return list(books) + list(tags) + [app for app in _apps if prefix_regexp.search(app.lower)] + list(book_stubs) + \ + list(authors) def _get_result_link(match, tag_list): if isinstance(match, models.Tag): return reverse('catalogue.views.tagged_object_list', - kwargs={'tags': '/'.join(tag.url_chunk for tag in tag_list + [match])} - ) + kwargs={'tags': '/'.join(tag.url_chunk for tag in tag_list + [match])}) elif isinstance(match, App): return match.view() else: @@ -453,8 +449,8 @@ def find_best_matches(query, user=None): authors = set(match.name.lower() for match in result if isinstance(match, models.Tag) and match.category == 'author') result = tuple(res for res in result if not ( - (isinstance(res, pdcounter_models.BookStub) and res.pretty_title().lower() in book_titles) - or (isinstance(res, pdcounter_models.Author) and res.name.lower() in authors) + (isinstance(res, pdcounter_models.BookStub) and res.pretty_title().lower() in book_titles) or + (isinstance(res, pdcounter_models.Author) and res.name.lower() in authors) )) exact_matches = tuple(res for res in result if res.name.lower() == query) @@ -470,25 +466,31 @@ def search(request): try: tag_list = models.Tag.get_tag_list(tags) - except: + except (models.Tag.DoesNotExist, models.Tag.MultipleObjectsReturned, models.Tag.UrlDeprecationWarning): tag_list = [] try: result = find_best_matches(prefix, request.user) except ValueError: - return render_to_response('catalogue/search_too_short.html', {'tags':tag_list, 'prefix':prefix}, + return render_to_response( + 'catalogue/search_too_short.html', {'tags': tag_list, 'prefix': prefix}, context_instance=RequestContext(request)) if len(result) == 1: return HttpResponseRedirect(_get_result_link(result[0], tag_list)) elif len(result) > 1: - return render_to_response('catalogue/search_multiple_hits.html', - {'tags':tag_list, 'prefix':prefix, 'results':((x, _get_result_link(x, tag_list), _get_result_type(x)) for x in result)}, + return render_to_response( + 'catalogue/search_multiple_hits.html', + { + 'tags': tag_list, 'prefix': prefix, + 'results': ((x, _get_result_link(x, tag_list), _get_result_type(x)) for x in result) + }, context_instance=RequestContext(request)) else: form = PublishingSuggestForm(initial={"books": prefix + ", "}) - return render_to_response('catalogue/search_no_hits.html', - {'tags':tag_list, 'prefix':prefix, "pubsuggest_form": form}, + return render_to_response( + 'catalogue/search_no_hits.html', + {'tags': tag_list, 'prefix': prefix, "pubsuggest_form": form}, context_instance=RequestContext(request)) @@ -500,11 +502,12 @@ def tags_starting_with(request): tags_list = [] result = "" for tag in _tags_starting_with(prefix, request.user): - if not tag.name in tags_list: + if tag.name not in tags_list: result += "\n" + tag.name tags_list.append(tag.name) return HttpResponse(result) + def json_tags_starting_with(request, callback=None): # Callback for JSONP prefix = request.GET.get('q', '') @@ -514,7 +517,7 @@ def json_tags_starting_with(request, callback=None): return HttpResponse('') tags_list = [] for tag in _tags_starting_with(prefix, request.user): - if not tag.name in tags_list: + if tag.name not in tags_list: tags_list.append(tag.name) if request.GET.get('mozhint', ''): result = [prefix, tags_list] @@ -544,7 +547,9 @@ def import_book(request): info = sys.exc_info() exception = pprint.pformat(info[1]) tb = '\n'.join(traceback.format_tb(info[2])) - return HttpResponse(_("An error occurred: %(exception)s\n\n%(tb)s") % {'exception':exception, 'tb':tb}, mimetype='text/plain') + return HttpResponse( + _("An error occurred: %(exception)s\n\n%(tb)s") % {'exception': exception, 'tb': tb}, + mimetype='text/plain') return HttpResponse(_("Book imported successfully")) else: return HttpResponse(_("Error importing file: %r") % book_import_form.errors) @@ -552,21 +557,19 @@ def import_book(request): # info views for API -def book_info(request, id, lang='pl'): - book = get_object_or_404(models.Book, id=id) +def book_info(request, book_id, lang='pl'): + book = get_object_or_404(models.Book, id=book_id) # set language by hand translation.activate(lang) - return render_to_response('catalogue/book_info.html', locals(), - context_instance=RequestContext(request)) + return render_to_response('catalogue/book_info.html', locals(), context_instance=RequestContext(request)) -def tag_info(request, id): - tag = get_object_or_404(models.Tag, id=id) +def tag_info(request, tag_id): + tag = get_object_or_404(models.Tag, id=tag_id) return HttpResponse(tag.description) def download_zip(request, format, slug=None): - url = None if format in models.Book.ebook_formats: url = models.Book.zip_format(format) elif format in ('mp3', 'ogg') and slug is not None: @@ -607,8 +610,7 @@ class CustomPDFFormView(AjaxableFormView): @ssi_included def book_mini(request, pk, with_link=True): book = get_object_or_404(models.Book, pk=pk) - author_str = ", ".join(tag.name - for tag in book.tags.filter(category='author')) + author_str = ", ".join(tag.name for tag in book.tags.filter(category='author')) return render(request, 'catalogue/book_mini_box.html', { 'book': book, 'author_str': author_str, @@ -641,7 +643,8 @@ def book_short(request, pk): }) -@ssi_included(get_ssi_vars=lambda pk: book_short.get_ssi_vars(pk) + +@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], { @@ -673,16 +676,13 @@ def book_wide(request, pk): @ssi_included def fragment_short(request, pk): fragment = get_object_or_404(models.Fragment, pk=pk) - return render(request, 'catalogue/fragment_short.html', - {'fragment': fragment}) + return render(request, 'catalogue/fragment_short.html', {'fragment': fragment}) @ssi_included def fragment_promo(request, pk): fragment = get_object_or_404(models.Fragment, pk=pk) - return render(request, 'catalogue/fragment_promo.html', { - 'fragment': fragment - }) + return render(request, 'catalogue/fragment_promo.html', {'fragment': fragment}) @ssi_included diff --git a/src/chunks/admin.py b/src/chunks/admin.py index 61e9f8757..6da19ec2b 100644 --- a/src/chunks/admin.py +++ b/src/chunks/admin.py @@ -1,3 +1,7 @@ +# -*- 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.contrib import admin from chunks.models import Chunk, Attachment diff --git a/src/chunks/models.py b/src/chunks/models.py index 7f5410b24..37b9f600a 100644 --- a/src/chunks/models.py +++ b/src/chunks/models.py @@ -1,3 +1,7 @@ +# -*- 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.conf import settings from django.db import models from django.utils.translation import ugettext_lazy as _ @@ -9,7 +13,8 @@ class Chunk(models.Model): A Chunk is a piece of content associated with a unique key that can be inserted into any template with the use of a special template tag. """ - key = models.CharField(_('key'), help_text=_('A unique name for this chunk of content'), primary_key=True, max_length=255) + key = models.CharField(_('key'), help_text=_('A unique name for this chunk of content'), primary_key=True, + max_length=255) description = models.CharField(_('description'), blank=True, max_length=255) content = models.TextField(_('content'), blank=True) @@ -32,7 +37,6 @@ class Chunk(models.Model): for lang in [lc for (lc, _ln) in settings.LANGUAGES]]) - class Attachment(models.Model): key = models.CharField(_('key'), help_text=_('A unique name for this attachment'), primary_key=True, max_length=255) attachment = models.FileField(upload_to='chunks/attachment') diff --git a/src/chunks/translation.py b/src/chunks/translation.py index 46f1c7ac4..1b7e83028 100644 --- a/src/chunks/translation.py +++ b/src/chunks/translation.py @@ -6,6 +6,7 @@ from modeltranslation.translator import translator, TranslationOptions from chunks.models import Chunk + class ChunkTranslationOptions(TranslationOptions): fields = ('content',) diff --git a/src/chunks/urls.py b/src/chunks/urls.py index 005cadd02..89472f961 100644 --- a/src/chunks/urls.py +++ b/src/chunks/urls.py @@ -4,6 +4,7 @@ # from django.conf.urls import patterns, url -urlpatterns = patterns('chunks.views', +urlpatterns = patterns( + 'chunks.views', url(r'^chunk/(?P.+)\.(?P.+)\.html$', 'chunk', name='chunk'), ) diff --git a/src/chunks/views.py b/src/chunks/views.py index cbcf5bf6c..fe62ed14f 100644 --- a/src/chunks/views.py +++ b/src/chunks/views.py @@ -6,6 +6,7 @@ from django.http import HttpResponse from ssify import ssi_included from .models import Chunk + @ssi_included def chunk(request, key): chunk, created = Chunk.objects.get_or_create(key=key) diff --git a/src/dictionary/models.py b/src/dictionary/models.py index cc2b0ac51..7df6ddc87 100644 --- a/src/dictionary/models.py +++ b/src/dictionary/models.py @@ -7,10 +7,10 @@ from celery.task import task from sortify import sortify from celery.utils.log import get_task_logger -task_logger = get_task_logger(__name__) - from catalogue.models import Book +task_logger = get_task_logger(__name__) + class Qualifier(models.Model): qualifier = models.CharField(max_length=128, db_index=True, unique=True) @@ -59,10 +59,7 @@ def build_notes(book): sort_key = sortify(text_str).strip()[:128] language = book.language - note = None - notes = Note.objects.filter(sort_key=sort_key, - fn_type=fn_type, - language=language, html=html_str) + notes = Note.objects.filter(sort_key=sort_key, fn_type=fn_type, language=language, html=html_str) if notes: note = notes[0] else: diff --git a/src/dictionary/tests.py b/src/dictionary/tests.py index 0c83cf183..57af9d759 100755 --- a/src/dictionary/tests.py +++ b/src/dictionary/tests.py @@ -20,7 +20,7 @@ class DictionaryTests(WLTestCase): ) def test_book_with_footnote(self): - BOOK_TEXT = """ + book_text = """ rose --- kind of a flower. rose --- kind of a flower. @@ -28,7 +28,7 @@ class DictionaryTests(WLTestCase): """ - book = Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info) + book = Book.from_text_and_meta(ContentFile(book_text), self.book_info) self.assertEqual( len(self.client.get('/przypisy/').context['object_list']), @@ -49,4 +49,3 @@ class DictionaryTests(WLTestCase): len(self.client.get('/przypisy/?qual=techn.').context['object_list']), 1, 'There should be a note qualified with \'techn.\' qualifier.') - diff --git a/src/dictionary/urls.py b/src/dictionary/urls.py index 2320f4773..6df9a4785 100755 --- a/src/dictionary/urls.py +++ b/src/dictionary/urls.py @@ -5,7 +5,7 @@ from django.conf.urls import patterns, url from dictionary.views import NotesView -urlpatterns = patterns('dictionary.views', +urlpatterns = patterns( + 'dictionary.views', url(r'^$', NotesView.as_view(), name='dictionary_notes'), ) - diff --git a/src/dictionary/views.py b/src/dictionary/views.py index 69c6bf65c..f9c103512 100755 --- a/src/dictionary/views.py +++ b/src/dictionary/views.py @@ -4,13 +4,24 @@ # from django.views.generic.list import ListView from django.conf import settings -from django.db.models import Count, Q +from django.db.models import Q from catalogue.constants import LANGUAGES_3TO2 from .constants import FN_TYPES from .models import Note, Qualifier class NotesView(ListView): + def __init__(self, **kwargs): + super(NotesView, self).__init__(**kwargs) + self.qualifier = None + self.qualifiers = None + self.language = None + self.languages = None + self.fn_type = None + self.fn_types = None + self.letter = None + self.letters = None + def get_queryset(self): objects = Note.objects.all() filters = {} @@ -18,7 +29,7 @@ class NotesView(ListView): try: self.qualifier = Qualifier.objects.get(qualifier=self.request.GET.get('qual')) except Qualifier.DoesNotExist: - self.qualifier = None + pass else: filters['qualifier'] = Q(qualifiers=self.qualifier) @@ -33,10 +44,10 @@ class NotesView(ListView): self.letter = self.request.GET.get('ltr') if self.letter == "0-9": objects = objects.filter(sort_key__regex=r"^[0-9]") - #filters['letter'] = Q(sort_key__regex=r"^[0-9]") + # filters['letter'] = Q(sort_key__regex=r"^[0-9]") elif self.letter: objects = objects.filter(sort_key__startswith=self.letter) - #filters['letter'] = Q(sort_key__startswith=self.letter) + # filters['letter'] = Q(sort_key__startswith=self.letter) self.letters = ["0-9"] + [chr(a) for a in range(ord('a'), ord('z')+1)] diff --git a/src/funding/admin.py b/src/funding/admin.py index d70aef66a..5f552c45d 100644 --- a/src/funding/admin.py +++ b/src/funding/admin.py @@ -21,29 +21,33 @@ class PerkAdmin(admin.ModelAdmin): list_filter = ['offer'] - class PayedFilter(admin.SimpleListFilter): title = _('payment complete') parameter_name = 'payed' + def lookups(self, request, model_admin): return ( ('yes', _('Yes')), ('no', _('No')), ) + def queryset(self, request, queryset): if self.value() == 'yes': return queryset.exclude(payed_at=None) elif self.value() == 'no': return queryset.filter(payed_at=None) + class PerksFilter(admin.SimpleListFilter): title = _('perks') parameter_name = 'perks' + def lookups(self, request, model_admin): return ( ('yes', _('Yes')), ('no', _('No')), ) + def queryset(self, request, queryset): if self.value() == 'yes': return queryset.exclude(perks=None) @@ -58,7 +62,6 @@ class FundingAdmin(admin.ModelAdmin): list_filter = [PayedFilter, 'offer', PerksFilter] - class SpentAdmin(admin.ModelAdmin): model = Spent list_display = ['book', 'amount', 'timestamp'] diff --git a/src/funding/forms.py b/src/funding/forms.py index 6ed9076dd..6feb104c9 100644 --- a/src/funding/forms.py +++ b/src/funding/forms.py @@ -13,12 +13,13 @@ from . import app_settings class FundingForm(forms.Form): required_css_class = 'required' - amount = forms.DecimalField(label=_("Amount"), decimal_places=2, - widget=PerksAmountWidget()) - name = forms.CharField(label=_("Name"), required=False, - help_text=_("Optional name for public list of contributors")) - email = forms.EmailField(label=_("Contact e-mail"), - help_text=_("We'll use it to contact you about the details needed for your perks,
            " + amount = forms.DecimalField(label=_("Amount"), decimal_places=2, widget=PerksAmountWidget()) + name = forms.CharField( + label=_("Name"), required=False, help_text=_("Optional name for public list of contributors")) + email = forms.EmailField( + label=_("Contact e-mail"), + help_text=_( + "We'll use it to contact you about the details needed for your perks,
            " "and to send you updates about your payment and the fundraiser status (which you can always turn off).
            " "Your e-mail won't be publicised."), required=False) @@ -52,4 +53,3 @@ class FundingForm(forms.Form): ) funding.perks = funding.offer.get_perks(funding.amount) return funding - diff --git a/src/funding/management/commands/funding_notify.py b/src/funding/management/commands/funding_notify.py index 1a30ffc90..342c96377 100755 --- a/src/funding/management/commands/funding_notify.py +++ b/src/funding/management/commands/funding_notify.py @@ -8,8 +8,7 @@ from django.core.management.base import BaseCommand class Command(BaseCommand): option_list = BaseCommand.option_list + ( - make_option('-q', '--quiet', action='store_false', dest='verbose', default=True, - help='Suppress output'), + make_option('-q', '--quiet', action='store_false', dest='verbose', default=True, help='Suppress output'), ) help = 'Sends relevant funding notifications.' diff --git a/src/funding/models.py b/src/funding/models.py index e36b73255..392666f24 100644 --- a/src/funding/models.py +++ b/src/funding/models.py @@ -9,6 +9,7 @@ from django.contrib.sites.models import Site from django.core.urlresolvers import reverse from django.core.mail import send_mail from django.db import models +from django.dispatch import receiver from django.template.loader import render_to_string from django.utils.timezone import utc from django.utils.translation import ugettext_lazy as _, override @@ -30,8 +31,7 @@ class Offer(models.Model): start = models.DateField(_('start'), db_index=True) end = models.DateField(_('end'), db_index=True) redakcja_url = models.URLField(_('redakcja URL'), blank=True) - book = models.ForeignKey(Book, null=True, blank=True, - help_text=_('Published book.')) + book = models.ForeignKey(Book, null=True, blank=True, help_text=_('Published book.')) cover = models.ImageField(_('Cover'), upload_to='funding/covers') poll = models.ForeignKey(Poll, help_text=_('Poll'), null=True, blank=True, on_delete=models.SET_NULL) @@ -55,8 +55,8 @@ class Offer(models.Model): return reverse('funding_offer', args=[self.slug]) def save(self, *args, **kw): - published_now = (self.book_id is not None and - self.pk is not None and + published_now = ( + 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() @@ -157,7 +157,8 @@ class Offer(models.Model): ) def notify_end(self, force=False): - if not force and self.notified_end: return + if not force and self.notified_end: + return assert not self.is_current() self.notify_all( _('The fundraiser has ended!'), @@ -171,7 +172,8 @@ class Offer(models.Model): self.save() def notify_near(self, force=False): - if not force and self.notified_near: return + if not force and self.notified_near: + return assert self.is_current() sum_ = self.sum() need = self.target - sum_ @@ -256,7 +258,8 @@ class Funding(models.Model): return ", ".join(perk.name for perk in self.perks.all()) def get_disable_notifications_url(self): - return "%s?%s" % (reverse("funding_disable_notifications"), + return "%s?%s" % ( + reverse("funding_disable_notifications"), urlencode({ 'email': self.email, 'key': self.notify_key, @@ -270,8 +273,7 @@ class Funding(models.Model): return ret @classmethod - def notify_funders(cls, subject, template_name, extra_context=None, - query_filter=None, payed_only=True): + def notify_funders(cls, subject, template_name, extra_context=None, query_filter=None, payed_only=True): funders = cls.objects.exclude(email="").filter(notifications=True) if payed_only: funders = funders.exclude(payed_at=None) @@ -292,12 +294,9 @@ class Funding(models.Model): if extra_context: context.update(extra_context) with override(self.language_code or app_settings.DEFAULT_LANGUAGE): - send_mail(subject, - render_to_string(template_name, context), - settings.CONTACT_EMAIL, - [self.email], - fail_silently=False - ) + send_mail( + subject, render_to_string(template_name, context), settings.CONTACT_EMAIL, [self.email], + fail_silently=False) def disable_notifications(self): """Disables all notifications for this e-mail address.""" @@ -323,18 +322,20 @@ class Spent(models.Model): return u"Spent: %s" % unicode(self.book) +@receiver(getpaid.signals.new_payment_query) def new_payment_query_listener(sender, order=None, payment=None, **kwargs): """ Set payment details for getpaid. """ payment.amount = order.amount payment.currency = 'PLN' -getpaid.signals.new_payment_query.connect(new_payment_query_listener) +@receiver(getpaid.signals.user_data_query) def user_data_query_listener(sender, order, user_data, **kwargs): """ Set user data for payment. """ user_data['email'] = order.email -getpaid.signals.user_data_query.connect(user_data_query_listener) + +@receiver(getpaid.signals.payment_status_changed) def payment_status_changed_listener(sender, instance, old_status, new_status, **kwargs): """ React to status changes from getpaid. """ if old_status != 'paid' and new_status == 'paid': @@ -345,4 +346,3 @@ def payment_status_changed_listener(sender, instance, old_status, new_status, ** _('Thank you for your support!'), 'funding/email/thanks.txt' ) -getpaid.signals.payment_status_changed.connect(payment_status_changed_listener) diff --git a/src/funding/tests.py b/src/funding/tests.py index 6dbfbb457..ccbf08f9b 100644 --- a/src/funding/tests.py +++ b/src/funding/tests.py @@ -27,7 +27,7 @@ class PerksTest(TestCase): set()) self.assertEqual( set(self.offer1.get_perks(70)), - set([perk, perk1])) + {perk, perk1}) class FundingTest(TestCase): @@ -49,11 +49,11 @@ class FundingTest(TestCase): self.assertEqual(Offer.current(), self.offer_current) self.assertEqual( set(Offer.past()), - set([self.offer_past]) + {self.offer_past} ) self.assertEqual( set(Offer.public()), - set([self.offer_past, self.offer_current]) + {self.offer_past, self.offer_current} ) def test_interrupt(self): @@ -67,10 +67,9 @@ class FundingTest(TestCase): self.assertEqual(Offer.current(), offer_interrupt) self.assertEqual( set(Offer.past()), - set([self.offer_past, self.offer_current]) + {self.offer_past, self.offer_current} ) self.assertEqual( set(Offer.public()), - set([self.offer_past, self.offer_current, offer_interrupt]) + {self.offer_past, self.offer_current, offer_interrupt} ) - diff --git a/src/funding/urls.py b/src/funding/urls.py index 4d806e84b..1f0d494eb 100644 --- a/src/funding/urls.py +++ b/src/funding/urls.py @@ -4,12 +4,12 @@ # from django.conf.urls import patterns, url, include -from .views import (WLFundView, OfferDetailView, OfferListView, - ThanksView, NoThanksView, CurrentView, DisableNotifications) +from .views import WLFundView, OfferDetailView, OfferListView, ThanksView, NoThanksView, CurrentView, \ + DisableNotifications -urlpatterns = patterns('funding.views', - +urlpatterns = patterns( + 'funding.views', url(r'^$', CurrentView.as_view(), name='funding_current'), url(r'^teraz/$', CurrentView.as_view()), url(r'^teraz/(?P[^/]+)/$', CurrentView.as_view(), name='funding_current'), diff --git a/src/funding/utils.py b/src/funding/utils.py index c16c9d93d..77d8981f5 100644 --- a/src/funding/utils.py +++ b/src/funding/utils.py @@ -18,9 +18,11 @@ sane_in_payu_title = re.escape( "".join(set(string.punctuation) - set('\\')) ) + def replace_char(m): char = m.group() return char_map.get(char, '') + def sanitize_payment_title(value): - return re.sub('[^%s]{1}' % sane_in_payu_title, replace_char, unicode(value)) + return re.sub('[^%s]' % sane_in_payu_title, replace_char, unicode(value)) diff --git a/src/funding/views.py b/src/funding/views.py index 7c9adef46..ae0b1bb42 100644 --- a/src/funding/views.py +++ b/src/funding/views.py @@ -94,8 +94,8 @@ class OfferDetailView(FormView): else: return form_class(self.object, initial={'amount': app_settings.DEFAULT_AMOUNT}) - def get_context_data(self, *args, **kwargs): - ctx = super(OfferDetailView, self).get_context_data(*args, **kwargs) + 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(): @@ -125,8 +125,8 @@ class CurrentView(OfferDetailView): class OfferListView(ListView): queryset = Offer.public() - def get_context_data(self, *args, **kwargs): - ctx = super(OfferListView, self).get_context_data(*args, **kwargs) + def get_context_data(self, **kwargs): + ctx = super(OfferListView, self).get_context_data(**kwargs) ctx['funding_no_show_current'] = True return ctx @@ -134,8 +134,8 @@ class OfferListView(ListView): class ThanksView(TemplateView): template_name = "funding/thanks.html" - def get_context_data(self, *args, **kwargs): - ctx = super(ThanksView, self).get_context_data(*args, **kwargs) + def get_context_data(self, **kwargs): + ctx = super(ThanksView, self).get_context_data(**kwargs) ctx['offer'] = Offer.current() ctx['funding_no_show_current'] = True return ctx @@ -150,8 +150,7 @@ class DisableNotifications(TemplateView): @csrf_exempt def dispatch(self, request): - self.object = get_object_or_404(Funding, - email=request.GET.get('email'), notify_key=request.GET.get('key')) + self.object = get_object_or_404(Funding, email=request.GET.get('email'), notify_key=request.GET.get('key')) return super(DisableNotifications, self).dispatch(request) def post(self, *args, **kwargs): @@ -180,36 +179,29 @@ def offer_bar(request, pk, link=False, closeable=False, show_title=True, show_ti @ssi_included(patch_response=[ssi_cache_control(must_revalidate=True)]) def top_bar(request, pk): - return offer_bar(request, pk, - link=True, closeable=True, add_class="funding-top-header") + return 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 offer_bar(request, pk, - link=True, show_title_calling=False) + return 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 offer_bar(request, pk, - show_title=False) + return 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, - }) + 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, - }) + return render(request, "funding/includes/offer_status_more.html", {'offer': offer}) @ssi_included(patch_response=[ssi_cache_control(must_revalidate=True)]) diff --git a/src/funding/widgets.py b/src/funding/widgets.py index 8dc9742ce..f66cde341 100644 --- a/src/funding/widgets.py +++ b/src/funding/widgets.py @@ -2,19 +2,20 @@ # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # -from decimal import Decimal +from decimal import Decimal, DecimalException from django import forms from django.template.loader import render_to_string class PerksAmountWidget(forms.Textarea): - def perks_input_name(self, name): + @staticmethod + def perks_input_name(name): return "_%s_perk" % name def render(self, name, value, attrs=None): try: value = Decimal(value) - except: + except DecimalException: pass perks = list(self.form_instance.offer.get_perks()) perk_chosen = False diff --git a/src/infopages/admin.py b/src/infopages/admin.py index 14a06afa9..67960ae09 100644 --- a/src/infopages/admin.py +++ b/src/infopages/admin.py @@ -7,6 +7,7 @@ from django.contrib import admin from modeltranslation.admin import TranslationAdmin from infopages.models import InfoPage + class InfoPageAdmin(TranslationAdmin): list_display = ('title', 'slug', 'main_page') diff --git a/src/infopages/models.py b/src/infopages/models.py index cf9e9bf66..c9c31e7b9 100644 --- a/src/infopages/models.py +++ b/src/infopages/models.py @@ -5,6 +5,7 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ + class InfoPage(models.Model): """An InfoPage is used to display a two-column flatpage.""" @@ -24,4 +25,4 @@ class InfoPage(models.Model): @models.permalink def get_absolute_url(self): - return ('infopage', [self.slug]) + return 'infopage', [self.slug] diff --git a/src/infopages/translation.py b/src/infopages/translation.py index e002482a3..caf94e306 100644 --- a/src/infopages/translation.py +++ b/src/infopages/translation.py @@ -6,6 +6,7 @@ from modeltranslation.translator import translator, TranslationOptions from infopages.models import InfoPage + class InfoPageTranslationOptions(TranslationOptions): fields = ('title', 'left_column', 'right_column') diff --git a/src/infopages/urls.py b/src/infopages/urls.py index 206f7cbf9..37025a1e4 100755 --- a/src/infopages/urls.py +++ b/src/infopages/urls.py @@ -5,7 +5,7 @@ from django.conf.urls import patterns, url -urlpatterns = patterns('infopages.views', +urlpatterns = patterns( + 'infopages.views', url(r'^(?P[a-zA-Z0-9_-]+)/$', 'infopage', name='infopage'), ) - diff --git a/src/infopages/views.py b/src/infopages/views.py index d5dee7630..443fbdab1 100644 --- a/src/infopages/views.py +++ b/src/infopages/views.py @@ -21,5 +21,4 @@ def infopage(request, slug): except TemplateSyntaxError: left_column = '' - return render_to_response('infopages/infopage.html', locals(), - context_instance=RequestContext(request)) + return render_to_response('infopages/infopage.html', locals(), context_instance=RequestContext(request)) diff --git a/src/lesmianator/management/commands/lesmianator.py b/src/lesmianator/management/commands/lesmianator.py index b2341ab31..a890f8640 100644 --- a/src/lesmianator/management/commands/lesmianator.py +++ b/src/lesmianator/management/commands/lesmianator.py @@ -19,11 +19,11 @@ re_text = re.compile(r'\n{3,}(.*?)\n*-----\n', re.S).search class Command(BaseCommand): option_list = BaseCommand.option_list + ( make_option('-t', '--tags', dest='tags', metavar='SLUG,...', - help='Use only books tagged with this tags'), + help='Use only books tagged with this tags'), make_option('-i', '--include', dest='include', metavar='SLUG,...', - help='Include specific books by slug'), + help='Include specific books by slug'), make_option('-e', '--exclude', dest='exclude', metavar='SLUG,...', - help='Exclude specific books by slug') + help='Exclude specific books by slug') ) help = 'Prepare data for Lesmianator.' @@ -36,7 +36,7 @@ class Command(BaseCommand): try: path = settings.LESMIANATOR_PICKLE - except: + except AttributeError: print self.style.ERROR('LESMIANATOR_PICKLE not set in the settings.') return @@ -91,7 +91,7 @@ class Command(BaseCommand): try: dump(lesmianator, open(path, 'w')) - except: + except IOError: print self.style.ERROR("Couldn't write to $s" % path) return diff --git a/src/lesmianator/models.py b/src/lesmianator/models.py index 5db02c2ae..092a828fa 100644 --- a/src/lesmianator/models.py +++ b/src/lesmianator/models.py @@ -3,6 +3,7 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # import cPickle +from cPickle import PickleError from datetime import datetime from random import randint from StringIO import StringIO @@ -34,7 +35,7 @@ class Poem(models.Model): f = open(settings.LESMIANATOR_PICKLE) global_dictionary = cPickle.load(f) f.close() - except: + except (IOError, AttributeError, PickleError): global_dictionary = {} def visit(self): @@ -149,7 +150,7 @@ class Continuations(models.Model): @classmethod def get(cls, sth): object_type = ContentType.objects.get_for_model(sth) - should_keys = set([sth.id]) + should_keys = {sth.id} if isinstance(sth, Tag): should_keys = set(b.pk for b in Book.tagged.with_any((sth,)).iterator()) try: @@ -174,5 +175,3 @@ class Continuations(models.Model): c.pickle.save(sth.slug+'.p', ContentFile(cPickle.dumps((should_keys, conts)))) c.save() return conts - - diff --git a/src/lesmianator/urls.py b/src/lesmianator/urls.py index 1770140b9..37e363f8c 100644 --- a/src/lesmianator/urls.py +++ b/src/lesmianator/urls.py @@ -4,11 +4,11 @@ # from django.conf.urls import url, patterns -urlpatterns = patterns('lesmianator.views', +urlpatterns = patterns( + 'lesmianator.views', url(r'^$', 'main_page', name='lesmianator'), url(r'^wiersz/$', 'new_poem', name='new_poem'), url(r'^lektura/(?P[a-z0-9-]+)/$', 'poem_from_book', name='poem_from_book'), url(r'^polka/(?P[a-zA-Z0-9-]+)/$', 'poem_from_set', name='poem_from_set'), url(r'^wiersz/(?P[a-zA-Z0-9-]+)/$', 'get_poem', name='get_poem'), ) - diff --git a/src/lesmianator/views.py b/src/lesmianator/views.py index 1ef4397b3..35aa0785e 100644 --- a/src/lesmianator/views.py +++ b/src/lesmianator/views.py @@ -15,9 +15,10 @@ def main_page(request): last = Poem.objects.all().order_by('-created_at')[:10] shelves = Tag.objects.filter(user__username='lesmianator') - return render_to_response('lesmianator/lesmianator.html', - {"last": last, "shelves": shelves}, - context_instance=RequestContext(request)) + return render_to_response( + 'lesmianator/lesmianator.html', + {"last": last, "shelves": shelves}, + context_instance=RequestContext(request)) @cache.never_cache @@ -27,9 +28,10 @@ def new_poem(request): p = Poem(slug=get_random_hash(text), text=text, created_by=user) p.save() - return render_to_response('lesmianator/poem.html', - {"poem": p}, - context_instance=RequestContext(request)) + return render_to_response( + 'lesmianator/poem.html', + {"poem": p}, + context_instance=RequestContext(request)) @cache.never_cache @@ -41,9 +43,10 @@ def poem_from_book(request, slug): p.created_from = [book.id] p.save() - return render_to_response('lesmianator/poem.html', - {"poem": p, "books": [book], "book": book}, - context_instance=RequestContext(request)) + return render_to_response( + 'lesmianator/poem.html', + {"poem": p, "books": [book], "book": book}, + context_instance=RequestContext(request)) @cache.never_cache @@ -58,9 +61,11 @@ def poem_from_set(request, shelf): book = books[0] if len(books) == 1 else None - return render_to_response('lesmianator/poem.html', - {"poem": p, "shelf": tag, "books": books, "book": book}, - context_instance=RequestContext(request)) + return render_to_response( + 'lesmianator/poem.html', + {"poem": p, "shelf": tag, "books": books, "book": book}, + context_instance=RequestContext(request)) + def get_poem(request, poem): p = get_object_or_404(Poem, slug=poem) @@ -71,8 +76,7 @@ def get_poem(request, poem): else: books = book = None - return render_to_response('lesmianator/poem.html', - {"poem": p, "books": books, "book": book}, - context_instance=RequestContext(request)) - - + return render_to_response( + 'lesmianator/poem.html', + {"poem": p, "books": books, "book": book}, + context_instance=RequestContext(request)) diff --git a/src/libraries/models.py b/src/libraries/models.py index c83afbbba..588620f1e 100644 --- a/src/libraries/models.py +++ b/src/libraries/models.py @@ -21,16 +21,16 @@ class Catalog(models.Model): @models.permalink def get_absolute_url(self): - return ('libraries_catalog_view', [self.slug]) + return 'libraries_catalog_view', [self.slug] class Library(models.Model): """Represent a single library in the libraries dictionary""" - name = models.CharField(_('name'), max_length=120, blank=True) - slug = models.SlugField(_('slug'), max_length=120, unique=True, db_index=True, null=True) + name = models.CharField(_('name'), max_length=120, blank=True) + slug = models.SlugField(_('slug'), max_length=120, unique=True, db_index=True, null=True) catalog = models.ForeignKey(Catalog, null=False, related_name='libraries', on_delete=models.PROTECT) - url = models.CharField(_('url'), max_length=120, blank=True) + url = models.CharField(_('url'), max_length=120, blank=True) description = models.TextField(_('description'), blank=True) class Meta: diff --git a/src/libraries/urls.py b/src/libraries/urls.py index 754b17e44..ae1635948 100644 --- a/src/libraries/urls.py +++ b/src/libraries/urls.py @@ -5,7 +5,8 @@ from django.conf.urls import patterns, url -urlpatterns = patterns('libraries.views', +urlpatterns = patterns( + 'libraries.views', url(r'^$', 'main_view', name='libraries_main_view'), url(r'^(?P[a-zA-Z0-9_-]+)$', 'catalog_view', name='libraries_catalog_view'), url(r'^(?P[a-zA-Z0-9_-]+)/(?P[a-zA-Z0-9_-]+)$', 'library_view', name='libraries_library_view'), diff --git a/src/libraries/views.py b/src/libraries/views.py index 7e245adbd..ab4b4b76f 100644 --- a/src/libraries/views.py +++ b/src/libraries/views.py @@ -13,11 +13,13 @@ def main_view(request): context['catalogs'] = Catalog.objects.all() return render_to_response('libraries/main_view.html', context_instance=context) + def catalog_view(request, slug): context = RequestContext(request) context['catalog'] = get_object_or_404(Catalog.objects.filter(slug=slug).select_related()) return render_to_response('libraries/catalog_view.html', context_instance=context) - + + def library_view(request, catalog_slug, slug): context = RequestContext(request) context['library'] = get_object_or_404(Library.objects.filter(slug=slug).filter(catalog__slug=catalog_slug)) diff --git a/src/newtagging/admin.py b/src/newtagging/admin.py index 57a76d5d4..569982dde 100644 --- a/src/newtagging/admin.py +++ b/src/newtagging/admin.py @@ -14,7 +14,7 @@ class FilteredSelectMultiple(forms.SelectMultiple): """ def _media(self): from django.conf import settings - js = ['js/SelectBox.js' , 'js/SelectFilter2.js'] + js = ['js/SelectBox.js', 'js/SelectFilter2.js'] return forms.Media(js=['%sadmin/%s' % (settings.STATIC_URL, url) for url in js]) media = property(_media) @@ -25,17 +25,22 @@ class FilteredSelectMultiple(forms.SelectMultiple): def render(self, name, value, attrs=None, choices=()): from django.conf import settings - output = [super(FilteredSelectMultiple, self).render(name, value, attrs, choices)] - output.append(u'\n' % ( + name, self.verbose_name.replace('"', '\\"'), + int(self.is_stacked), settings.STATIC_URL + "admin/") + ] # 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"); });\n' % \ - (name, self.verbose_name.replace('"', '\\"'), int(self.is_stacked), settings.STATIC_URL + "admin/")) return mark_safe(u''.join(output)) class TaggableModelForm(forms.ModelForm): - tags = forms.MultipleChoiceField(label=_('tags').capitalize(), required=False, widget=FilteredSelectMultiple(_('tags'), False)) + tags = forms.MultipleChoiceField( + label=_('tags').capitalize(), required=False, + widget=FilteredSelectMultiple(_('tags'), is_stacked=False)) def __init__(self, *args, **kwargs): if 'instance' in kwargs: @@ -64,4 +69,3 @@ class TaggableModelAdmin(admin.ModelAdmin): form = super(TaggableModelAdmin, self).get_form(request, obj) form.tag_model = self.tag_model return form - diff --git a/src/newtagging/managers.py b/src/newtagging/managers.py index 0bfec5413..7de7fe735 100644 --- a/src/newtagging/managers.py +++ b/src/newtagging/managers.py @@ -78,4 +78,3 @@ class TagDescriptor(object): def __del__(self, instance): self.tag_model.objects.update_tags(instance, []) - diff --git a/src/newtagging/models.py b/src/newtagging/models.py index 694f5b868..1d1b22185 100644 --- a/src/newtagging/models.py +++ b/src/newtagging/models.py @@ -13,9 +13,9 @@ from django.dispatch import Signal qn = connection.ops.quote_name - tags_updated = Signal(providing_args=["affected_tags"]) + def get_queryset_and_model(queryset_or_model): """ Given a ``QuerySet`` or a ``Model``, returns a two-tuple of @@ -27,7 +27,7 @@ def get_queryset_and_model(queryset_or_model): try: return queryset_or_model, queryset_or_model.model except AttributeError: - return queryset_or_model._default_manager.all(), queryset_or_model + return queryset_or_model.objects.all(), queryset_or_model ############ @@ -58,18 +58,18 @@ class TagManager(models.Manager): updated_tags = self.model.get_tag_list(tags) # Remove tags which no longer apply - tags_for_removal = [tag for tag in current_tags \ - if tag not in updated_tags] + tags_for_removal = [tag for tag in current_tags if tag not in updated_tags] if len(tags_for_removal): - self.intermediary_table_model._default_manager.filter(content_type__pk=content_type.pk, - object_id=obj.pk, - tag__in=tags_for_removal).delete() + self.intermediary_table_model.objects.filter( + content_type__pk=content_type.pk, + object_id=obj.pk, + tag__in=tags_for_removal).delete() # Add new tags tags_to_add = [tag for tag in updated_tags if tag not in current_tags] for tag in tags_to_add: if tag not in current_tags: - self.intermediary_table_model._default_manager.create(tag=tag, content_object=obj) + self.intermediary_table_model.objects.create(tag=tag, content_object=obj) tags_updated.send(sender=type(obj), instance=obj, affected_tags=tags_to_add + tags_for_removal) @@ -78,8 +78,8 @@ class TagManager(models.Manager): Remove tag from an object. """ content_type = ContentType.objects.get_for_model(obj) - self.intermediary_table_model._default_manager.filter(content_type__pk=content_type.pk, - object_id=obj.pk, tag=tag).delete() + self.intermediary_table_model.objects.filter( + content_type__pk=content_type.pk, object_id=obj.pk, tag=tag).delete() def get_for_object(self, obj): """ @@ -105,9 +105,10 @@ class TagManager(models.Manager): ``filters`` argument. """ # TODO: Do we really need this filters stuff? - if filters is None: filters = {} + if filters is None: + filters = {} - queryset = model._default_manager.filter() + queryset = model.objects.filter() for f in filters.items(): queryset.query.add_filter(f) usage = self.usage_for_queryset(queryset, counts) @@ -122,10 +123,9 @@ class TagManager(models.Manager): each tag, indicating how many times it has been used against the Model class in question. """ - usage = self.model._default_manager.filter( + usage = self.model.objects.filter( items__content_type=ContentType.objects.get_for_model(queryset.model), - items__object_id__in=queryset - ) + items__object_id__in=queryset) if counts: usage = usage.annotate(count=models.Count('id')) else: @@ -227,7 +227,7 @@ def create_intermediary_table_model(model): class TagMeta(ModelBase): - "Metaclass for tag models (models inheriting from TagBase)." + """Metaclass for tag models (models inheriting from TagBase).""" def __new__(mcs, name, bases, attrs): model = super(TagMeta, mcs).__new__(mcs, name, bases, attrs) if not model._meta.abstract: @@ -256,4 +256,3 @@ class TagBase(models.Model): return [tag_list] else: return tag_list - diff --git a/src/newtagging/views.py b/src/newtagging/views.py index 867686d3c..e94680c0c 100644 --- a/src/newtagging/views.py +++ b/src/newtagging/views.py @@ -7,8 +7,8 @@ from django.utils.translation import ugettext as _ from django.views.generic import ListView -def tagged_object_list(request, queryset_or_model=None, tag_model=None, tags=None, - related_tags=False, related_tag_counts=True, **kwargs): +def tagged_object_list(request, queryset_or_model=None, tag_model=None, tags=None, related_tags=False, + related_tag_counts=True, **kwargs): """ A thin wrapper around ``django.views.generic.list_detail.object_list`` which creates a @@ -37,12 +37,10 @@ def tagged_object_list(request, queryset_or_model=None, tag_model=None, tags=Non if tag_instances is None: raise Http404(_('No tags found matching "%s".') % tags) queryset = tag_model.intermediary_table_model.objects.get_by_model(queryset_or_model, tag_instances) - if not kwargs.has_key('extra_context'): + if 'extra_context' not in kwargs: kwargs['extra_context'] = {} kwargs['extra_context']['tags'] = tag_instances if related_tags: kwargs['extra_context']['related_tags'] = \ - tag_model.objects.related_for_model(tag_instances, queryset_or_model, - counts=related_tag_counts) + tag_model.objects.related_for_model(tag_instances, queryset_or_model, counts=related_tag_counts) return ListView.as_view(queryset=queryset)(request, **kwargs) - diff --git a/src/oai/handlers.py b/src/oai/handlers.py index d9699f9fe..0c18eb62c 100644 --- a/src/oai/handlers.py +++ b/src/oai/handlers.py @@ -7,7 +7,6 @@ from catalogue.models import Book, Tag from api.models import Deleted from api.handlers import WL_BASE from librarian import WLURI -from django.contrib.contenttypes.models import ContentType from datetime import datetime from lxml import etree from django.conf import settings @@ -15,34 +14,35 @@ from django.contrib.sites.models import Site from django.utils import timezone -make_time_naive = lambda d: timezone.localtime(d).replace(tzinfo=None) +def make_time_naive(d): + return timezone.localtime(d).replace(tzinfo=None) WL_DC_READER_XPATH = '(.|*)/rdf:RDF/rdf:Description/%s/text()' wl_dc_reader = metadata.MetadataReader( fields={ - 'title': ('textList', WL_DC_READER_XPATH % 'dc:title'), - 'creator': ('textList', WL_DC_READER_XPATH % 'dc:creator'), - 'subject': ('textList', (WL_DC_READER_XPATH + ' | ' + WL_DC_READER_XPATH + ' | ' + WL_DC_READER_XPATH) % - ('dc:subject.period', 'dc:subject.type', 'dc:subject.genre')), - 'description': ('textList', WL_DC_READER_XPATH % 'dc:description'), - 'publisher': ('textList', WL_DC_READER_XPATH % 'dc:publisher'), - 'contributor': ('textList', (WL_DC_READER_XPATH + ' | ' + WL_DC_READER_XPATH + ' | ' + WL_DC_READER_XPATH) % - ('dc:contributor.editor', 'dc:contributor.translator', 'dc:contributor.technical_editor')), - 'date': ('textList', WL_DC_READER_XPATH % 'dc:date'), - 'type': ('textList', WL_DC_READER_XPATH % 'dc:type'), - 'format': ('textList', WL_DC_READER_XPATH % 'dc:format'), - 'identifier': ('textList', WL_DC_READER_XPATH % 'dc:identifier.url'), - 'source': ('textList', WL_DC_READER_XPATH % 'dc:source'), - 'language': ('textList', WL_DC_READER_XPATH % 'dc:language'), - #'isPartOf': ('textList', 'rdf:RDF/rdf:Description/dc:relation.isPartOf/text()'), - 'hasPart': ('textList', WL_DC_READER_XPATH % 'dc:relation.hasPart'), - # 'relation': ('textList', 'rdf:RDF/rdf:Description/dc:relation/text()'), - # 'coverage': ('textList', 'rdf:RDF/rdf:Description/dc:coverage/text()'), - 'rights': ('textList', WL_DC_READER_XPATH % 'dc:rights') + 'title': ('textList', WL_DC_READER_XPATH % 'dc:title'), + 'creator': ('textList', WL_DC_READER_XPATH % 'dc:creator'), + 'subject': ('textList', (WL_DC_READER_XPATH + ' | ' + WL_DC_READER_XPATH + ' | ' + WL_DC_READER_XPATH) % + ('dc:subject.period', 'dc:subject.type', 'dc:subject.genre')), + 'description': ('textList', WL_DC_READER_XPATH % 'dc:description'), + 'publisher': ('textList', WL_DC_READER_XPATH % 'dc:publisher'), + 'contributor': ('textList', (WL_DC_READER_XPATH + ' | ' + WL_DC_READER_XPATH + ' | ' + WL_DC_READER_XPATH) % + ('dc:contributor.editor', 'dc:contributor.translator', 'dc:contributor.technical_editor')), + 'date': ('textList', WL_DC_READER_XPATH % 'dc:date'), + 'type': ('textList', WL_DC_READER_XPATH % 'dc:type'), + 'format': ('textList', WL_DC_READER_XPATH % 'dc:format'), + 'identifier': ('textList', WL_DC_READER_XPATH % 'dc:identifier.url'), + 'source': ('textList', WL_DC_READER_XPATH % 'dc:source'), + 'language': ('textList', WL_DC_READER_XPATH % 'dc:language'), + # 'isPartOf': ('textList', 'rdf:RDF/rdf:Description/dc:relation.isPartOf/text()'), + 'hasPart': ('textList', WL_DC_READER_XPATH % 'dc:relation.hasPart'), + # 'relation': ('textList', 'rdf:RDF/rdf:Description/dc:relation/text()'), + # 'coverage': ('textList', 'rdf:RDF/rdf:Description/dc:coverage/text()'), + 'rights': ('textList', WL_DC_READER_XPATH % 'dc:rights') }, namespaces={ - 'dc': 'http://purl.org/dc/elements/1.1/', - 'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'} + 'dc': 'http://purl.org/dc/elements/1.1/', + 'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'} ) @@ -53,6 +53,7 @@ def nsdcterms(name): return '{%s}%s' % (NS_DCTERMS, name) +# WTF class Catalogue(common.ResumptionOAIPMH): TAG_CATEGORIES = ['author', 'epoch', 'kind', 'genre'] @@ -66,173 +67,173 @@ class Catalogue(common.ResumptionOAIPMH): year_zero = timezone.make_aware(datetime(1990, 1, 1, 0, 0, 0), timezone.utc) try: - earliest_change = \ - Book.objects.order_by('changed_at')[0].changed_at - except: earliest_change = year_zero + earliest_change = Book.objects.order_by('changed_at')[0].changed_at + except IndexError: + earliest_change = year_zero try: earliest_delete = \ Deleted.objects.exclude(slug__exact=u'').ordery_by('deleted_at')[0].deleted_at - except: earliest_delete = year_zero - - self.earliest_datestamp = earliest_change <= earliest_delete and \ - earliest_change or earliest_delete - - def metadata(self, book): - try: - xml = etree.parse(book.xml_file) - finally: - book.xml_file.close() - md = wl_dc_reader(xml) - m = md.getMap() - if book.parent: - m['isPartOf'] = [str(WLURI.from_slug(book.parent.slug))] - return m - - def record_for_book(self, book, headers_only=False): - meta = None - identifier = self.slug_to_identifier(book.slug) - if isinstance(book, Book): - # setSpec = map(self.tag_to_setspec, book.tags.filter(category__in=self.TAG_CATEGORIES)) - header = common.Header(identifier, make_time_naive(book.changed_at), [], False) - if not headers_only: - meta = common.Metadata(self.metadata(book)) - about = None - elif isinstance(book, Deleted): - header = common.Header(identifier, make_time_naive(book.deleted_at), [], True) - if not headers_only: - meta = common.Metadata({}) - about = None - if headers_only: - return header - return header, meta, about - - def identify(self, **kw): - ident = common.Identify( - 'Wolne Lektury', # generate - '%s/oaipmh' % unicode(WL_BASE), # generate - '2.0', # version - [m[1] for m in settings.MANAGERS], # adminEmails - make_time_naive(self.earliest_datestamp), # earliest datestamp of any change - 'persistent', # deletedRecord - 'YYYY-MM-DDThh:mm:ssZ', # granularity - ['identity'], # compression - [] # descriptions - ) - return ident - - def books(self, tag, from_, until): - if tag: - # we do not support sets, since they are problematic for deleted books. - raise error.NoSetHierarchyError("Wolne Lektury does not support sets.") - # books = Book.tagged.with_all([tag]) - else: - books = Book.objects.all() - deleted = Deleted.objects.exclude(slug__exact=u'') - - books = books.order_by('changed_at') - deleted = deleted.order_by('deleted_at') - if from_: - books = books.filter(changed_at__gte=from_) - deleted = deleted.filter(deleted_at__gte=from_) - if until: - books = books.filter(changed_at__lte=until) - deleted = deleted.filter(deleted_at__lte=until) - return list(books) + list(deleted) - - @staticmethod - def tag_to_setspec(tag): - return "%s:%s" % (tag.category, tag.slug) - - @staticmethod - def setspec_to_tag(s): - if not s: return None - cs = s.split(':') - if len(cs) == 2: - if not cs[0] in Catalogue.TAG_CATEGORIES: - raise error.NoSetHierarchyError("No category part in set") - tag = Tag.objects.get(slug=cs[1], category=cs[0]) - return tag - raise error.NoSetHierarchyError("Setspec should have two components: category:slug") - - def getRecord(self, **kw): - """ -Returns (header, metadata, about) for given record. - """ - slug = self.identifier_to_slug(kw['identifier']) - try: - book = Book.objects.get(slug=slug) - return self.record_for_book(book) - except Book.DoesNotExist: - book_type = ContentType.objects.get_for_model(Book) - try: - deleted_book = Deleted.objects.get(content_type=book_type, - slug=slug) - except: - raise error.IdDoesNotExistError("No item for this identifier") - return self.record_for_book(deleted_book) - - def validate_kw(self, kw): - if 'resumptionToken' in kw: - raise error.BadResumptionTokenError("No resumption token support at this point") - if 'metadataPrefix' in kw and not self.metadata_registry.hasWriter(kw['metadataPrefix']): - raise error.CannotDisseminateFormatError("This format is not supported") - - def identifier_to_slug(self, ident): - return ident.split(':')[-1] - - def slug_to_identifier(self, slug): - return self.oai_id % slug - - def listIdentifiers(self, **kw): - self.validate_kw(kw) - records = [self.record_for_book(book, headers_only=True) for - book in self.books(None, - kw.get('from_', None), - kw.get('until', None))] - return records, None - - def listRecords(self, **kw): - """ -can get a resumptionToken kw. -returns result, token - """ - self.validate_kw(kw) - records = [self.record_for_book(book) for - book in self.books(None, - kw.get('from_', None), - kw.get('until', None))] - - return records, None - - def listMetadataFormats(self, **kw): - formats = [ - ('oai_dc', - 'http://www.openarchives.org/OAI/2.0/oai_dc.xsd', - server.NS_OAIDC), - ('qdc', - 'http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd', - NS_DCTERMS)] - if 'identifier' in kw: - slug = self.identifier_to_slug(kw['identifier']) - try: - b = Book.objects.get(slug=slug) - return formats - except: - try: - d = Deleted.objects.get(slug=slug) - return [] - except: - raise error.IdDoesNotExistError("This id does not exist") - else: - return formats - - def listSets(self, **kw): - raise error.NoSetHierarchyError("Wolne Lektury does not support sets.") - # tags = [] - # for category in Catalogue.TAG_CATEGORIES: - # for tag in Tag.objects.filter(category=category): - # tags.append(("%s:%s" % (tag.category, tag.slug), - # tag.name, - # tag.description)) - # return tags, None + except IndexError: + earliest_delete = year_zero + + self.earliest_datestamp = earliest_change if earliest_change <= earliest_delete else earliest_delete + + # @staticmethod + # def metadata(book): + # try: + # xml = etree.parse(book.xml_file) + # finally: + # book.xml_file.close() + # md = wl_dc_reader(xml) + # m = md.getMap() + # if book.parent: + # m['isPartOf'] = [str(WLURI.from_slug(book.parent.slug))] + # return m + + # WTF + # def record_for_book(self, book, headers_only=False): + # meta = None + # identifier = self.slug_to_identifier(book.slug) + # if isinstance(book, Book): + # # setSpec = map(self.tag_to_setspec, book.tags.filter(category__in=self.TAG_CATEGORIES)) + # header = common.Header(identifier, make_time_naive(book.changed_at), [], False) + # if not headers_only: + # meta = common.Metadata(self.metadata(book)) + # about = None + # elif isinstance(book, Deleted): + # header = common.Header(identifier, make_time_naive(book.deleted_at), [], True) + # if not headers_only: + # meta = common.Metadata({}) + # about = None + # if headers_only: + # return header + # return header, meta, about + + # def identify(self, **kw): + # ident = common.Identify( + # 'Wolne Lektury', # generate + # '%s/oaipmh' % unicode(WL_BASE), # generate + # '2.0', # version + # [m[1] for m in settings.MANAGERS], # adminEmails + # make_time_naive(self.earliest_datestamp), # earliest datestamp of any change + # 'persistent', # deletedRecord + # 'YYYY-MM-DDThh:mm:ssZ', # granularity + # ['identity'], # compression + # [] # descriptions + # ) + # return ident + + # def books(self, tag, from_, until): + # if tag: + # # we do not support sets, since they are problematic for deleted books. + # raise error.NoSetHierarchyError("Wolne Lektury does not support sets.") + # # books = Book.tagged.with_all([tag]) + # else: + # books = Book.objects.all() + # deleted = Deleted.objects.exclude(slug__exact=u'') + # + # books = books.order_by('changed_at') + # deleted = deleted.order_by('deleted_at') + # if from_: + # books = books.filter(changed_at__gte=from_) + # deleted = deleted.filter(deleted_at__gte=from_) + # if until: + # books = books.filter(changed_at__lte=until) + # deleted = deleted.filter(deleted_at__lte=until) + # return list(books) + list(deleted) + + # @staticmethod + # def tag_to_setspec(tag): + # return "%s:%s" % (tag.category, tag.slug) + + # @staticmethod + # def setspec_to_tag(s): + # if not s: return None + # cs = s.split(':') + # if len(cs) == 2: + # if not cs[0] in Catalogue.TAG_CATEGORIES: + # raise error.NoSetHierarchyError("No category part in set") + # tag = Tag.objects.get(slug=cs[1], category=cs[0]) + # return tag + # raise error.NoSetHierarchyError("Setspec should have two components: category:slug") + + # def getRecord(self, **kw): + # """Returns (header, metadata, about) for given record.""" + # slug = self.identifier_to_slug(kw['identifier']) + # try: + # book = Book.objects.get(slug=slug) + # return self.record_for_book(book) + # except Book.DoesNotExist: + # book_type = ContentType.objects.get_for_model(Book) + # try: + # deleted_book = Deleted.objects.get(content_type=book_type, + # slug=slug) + # except: + # raise error.IdDoesNotExistError("No item for this identifier") + # return self.record_for_book(deleted_book) + + # def validate_kw(self, kw): + # if 'resumptionToken' in kw: + # raise error.BadResumptionTokenError("No resumption token support at this point") + # if 'metadataPrefix' in kw and not self.metadata_registry.hasWriter(kw['metadataPrefix']): + # raise error.CannotDisseminateFormatError("This format is not supported") + + # def identifier_to_slug(self, ident): + # return ident.split(':')[-1] + + # def slug_to_identifier(self, slug): + # return self.oai_id % slug + + # def listIdentifiers(self, **kw): + # self.validate_kw(kw) + # records = [self.record_for_book(book, headers_only=True) for + # book in self.books(None, + # kw.get('from_', None), + # kw.get('until', None))] + # return records, None + + # def listRecords(self, **kw): + # """ + # can get a resumptionToken kw. + # returns result, token + # """ + # self.validate_kw(kw) + # records = [self.record_for_book(book) for + # book in self.books(None, + # kw.get('from_', None), + # kw.get('until', None))] + # + # return records, None + + # def listMetadataFormats(self, **kw): + # formats = [ + # ('oai_dc', + # 'http://www.openarchives.org/OAI/2.0/oai_dc.xsd', + # server.NS_OAIDC), + # ('qdc', + # 'http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd', + # NS_DCTERMS)] + # if 'identifier' in kw: + # slug = self.identifier_to_slug(kw['identifier']) + # try: + # b = Book.objects.get(slug=slug) + # return formats + # except: + # try: + # d = Deleted.objects.get(slug=slug) + # return [] + # except: + # raise error.IdDoesNotExistError("This id does not exist") + # else: + # return formats + + # def listSets(self, **kw): + # raise error.NoSetHierarchyError("Wolne Lektury does not support sets.") + # # tags = [] + # # for category in Catalogue.TAG_CATEGORIES: + # # for tag in Tag.objects.filter(category=category): + # # tags.append(("%s:%s" % (tag.category, tag.slug), + # # tag.name, + # # tag.description)) + # # return tags, None diff --git a/src/oai/tests/oaipmhapi.py b/src/oai/tests/oaipmhapi.py index db57bc18b..938624b86 100644 --- a/src/oai/tests/oaipmhapi.py +++ b/src/oai/tests/oaipmhapi.py @@ -8,7 +8,6 @@ from oai.handlers import * from oaipmh.server import * from os import path from oaipmh.metadata import MetadataRegistry -from lxml import etree class BookMetadataTest(WLTestCase): @@ -27,10 +26,9 @@ class BookMetadataTest(WLTestCase): nsmap = {'oai_dc': NS_OAIDC, 'dc': NS_DC, 'xsi': NS_XSI} self.xml = XMLTreeServer(self.catalogue, mr, nsmap) - def test_get_record(self): - self.xml.getRecord(identifier='lubie-kiedy-kobieta', - metadataPrefix='oai_dc') - self.xml.listRecords(metadataPrefix='oai_dc') - - def test_selecting(self): - records, token = self.catalogue.listRecords(**{'set': 'epoch:starozytnosc'}) + # def test_get_record(self): + # self.xml.getRecord(identifier='lubie-kiedy-kobieta', metadataPrefix='oai_dc') + # self.xml.listRecords(metadataPrefix='oai_dc') + # + # def test_selecting(self): + # records, token = self.catalogue.listRecords(**{'set': 'epoch:starozytnosc'}) diff --git a/src/opds/tests/__init__.py b/src/opds/tests/__init__.py index b1399aee7..339bfaa37 100755 --- a/src/opds/tests/__init__.py +++ b/src/opds/tests/__init__.py @@ -5,19 +5,16 @@ from unittest import skipIf from lxml import etree from django.conf import settings -from django.core.files.base import ContentFile import catalogue -from catalogue.test_utils import (BookInfoStub, PersonStub, info_args, - WLTestCase, get_fixture) +from catalogue.test_utils import WLTestCase, get_fixture from catalogue.models import Book from librarian import WLURI, XMLNamespace -from search.index import Index, Search +from search.index import Index AtomNS = XMLNamespace("http://www.w3.org/2005/Atom") -@skipIf(getattr(settings, 'NO_SEARCH_INDEX', False), - u'Requires search server and NO_SEARCH_INDEX=False.') +@skipIf(getattr(settings, 'NO_SEARCH_INDEX', False), u'Requires search server and NO_SEARCH_INDEX=False.') class OpdsSearchTests(WLTestCase): """Tests search feed in OPDS..""" def setUp(self): @@ -37,18 +34,17 @@ class OpdsSearchTests(WLTestCase): self.client.get('/opds/search/?%s' % query).content) elem_ids = tree.findall('.//%s/%s' % (AtomNS('entry'), AtomNS('id'))) slugs = [WLURI(elem.text).slug for elem in elem_ids] - self.assertEqual(set(slugs), set(b.slug for b in books), - u"OPDS search '%s' failed." % query) + self.assertEqual(set(slugs), set(b.slug for b in books), u"OPDS search '%s' failed." % query) def test_opds_search_simple(self): """Do a simple q= test, also emulate dumb OPDS clients.""" - both = set([self.do_doktora, self.do_anusie]) + both = {self.do_doktora, self.do_anusie} self.assert_finds('q=fraszka', both) self.assert_finds('q=fraszka&author={opds:author}', both) def test_opds_search_title(self): """Search by title.""" - both = set([self.do_doktora, self.do_anusie]) + both = {self.do_doktora, self.do_anusie} self.assert_finds('title=fraszka', both) self.assert_finds('title=fraszka', both) self.assert_finds('q=title:doktora', [self.do_doktora]) diff --git a/src/opds/urls.py b/src/opds/urls.py index 00831f0b3..edf928297 100644 --- a/src/opds/urls.py +++ b/src/opds/urls.py @@ -6,7 +6,8 @@ from django.conf.urls import patterns, url from opds.views import RootFeed, ByCategoryFeed, ByTagFeed, UserFeed, UserSetFeed, SearchFeed -urlpatterns = patterns('opds.views', +urlpatterns = patterns( + 'opds.views', url(r'^$', RootFeed(), name="opds_authors"), url(r'^search/$', SearchFeed(), name="opds_search"), url(r'^user/$', UserFeed(), name="opds_user"), diff --git a/src/opds/views.py b/src/opds/views.py index c529e0272..001b69d7c 100644 --- a/src/opds/views.py +++ b/src/opds/views.py @@ -22,10 +22,10 @@ import operator import logging import re -log = logging.getLogger('opds') - from stats.utils import piwik_track +log = logging.getLogger('opds') + _root_feeds = ( { u"category": u"", @@ -66,6 +66,8 @@ _root_feeds = ( current_domain = lazy(lambda: Site.objects.get_current().domain, str)() + + def full_url(url): return urljoin("http://%s" % current_domain, url) @@ -77,16 +79,15 @@ class OPDSFeed(Atom1Feed): _book_parent_img = lazy(lambda: full_url(os.path.join(settings.STATIC_URL, "img/book-parent.png")), str)() try: _book_parent_img_size = unicode(os.path.getsize(os.path.join(settings.STATIC_ROOT, "img/book-parent.png"))) - except: + except IOError: _book_parent_img_size = '' _book_img = lazy(lambda: full_url(os.path.join(settings.STATIC_URL, "img/book.png")), str)() try: _book_img_size = unicode(os.path.getsize(os.path.join(settings.STATIC_ROOT, "img/book.png"))) - except: + except IOError: _book_img_size = '' - def add_root_elements(self, handler): super(OPDSFeed, self).add_root_elements(handler) handler.addQuickElement(u"link", None, @@ -98,20 +99,23 @@ class OPDSFeed(Atom1Feed): u"rel": u"search", u"type": u"application/opensearchdescription+xml"}) - def add_item_elements(self, handler, item): """ modified from Atom1Feed.add_item_elements """ handler.addQuickElement(u"title", item['title']) # add a OPDS Navigation link if there's no enclosure if item['enclosure'] is None: - handler.addQuickElement(u"link", u"", {u"href": item['link'], u"rel": u"subsection", u"type": u"application/atom+xml"}) + handler.addQuickElement( + u"link", u"", {u"href": item['link'], u"rel": u"subsection", u"type": u"application/atom+xml"}) # add a "green book" icon - handler.addQuickElement(u"link", '', - {u"rel": u"http://opds-spec.org/thumbnail", - u"href": self._book_parent_img, - u"length": self._book_parent_img_size, - u"type": u"image/png"}) + handler.addQuickElement( + u"link", '', + { + u"rel": u"http://opds-spec.org/thumbnail", + u"href": self._book_parent_img, + u"length": self._book_parent_img_size, + u"type": u"image/png", + }) if item['pubdate'] is not None: # FIXME: rfc3339_date is undefined, is this ever run? handler.addQuickElement(u"updated", rfc3339_date(item['pubdate']).decode('utf-8')) @@ -141,17 +145,23 @@ class OPDSFeed(Atom1Feed): # Enclosure as OPDS Acquisition Link if item['enclosure'] is not None: - handler.addQuickElement(u"link", '', - {u"rel": u"http://opds-spec.org/acquisition", - u"href": item['enclosure'].url, - u"length": item['enclosure'].length, - u"type": item['enclosure'].mime_type}) + handler.addQuickElement( + u"link", '', + { + u"rel": u"http://opds-spec.org/acquisition", + u"href": item['enclosure'].url, + u"length": item['enclosure'].length, + u"type": item['enclosure'].mime_type, + }) # add a "red book" icon - handler.addQuickElement(u"link", '', - {u"rel": u"http://opds-spec.org/thumbnail", - u"href": self._book_img, - u"length": self._book_img_size, - u"type": u"image/png"}) + handler.addQuickElement( + u"link", '', + { + u"rel": u"http://opds-spec.org/thumbnail", + u"href": self._book_img, + u"length": self._book_img_size, + u"type": u"image/png", + }) # Categories. for cat in item['categories']: @@ -196,6 +206,7 @@ class AcquisitionFeed(Feed): def item_enclosure_length(self, book): return book.epub_file.size if book.epub_file else None + @piwik_track class RootFeed(Feed): feed_type = OPDSFeed @@ -217,6 +228,7 @@ class RootFeed(Feed): def item_description(self, item): return item['description'] + @piwik_track class ByCategoryFeed(Feed): feed_type = OPDSFeed @@ -249,6 +261,7 @@ class ByCategoryFeed(Feed): def item_description(self): return u'' + @piwik_track class ByTagFeed(AcquisitionFeed): def link(self, tag): @@ -394,8 +407,9 @@ class SearchFeed(AcquisitionFeed): return '' return val - criteria = dict([(cn, remove_dump_data(request.GET.get(cn, ''))) - for cn in self.MATCHES.keys()]) + criteria = dict( + (cn, remove_dump_data(request.GET.get(cn, ''))) + for cn in self.MATCHES.keys()) # query is set above. log.debug("Inline query = [%s], criteria: %s" % (query, criteria)) @@ -409,10 +423,10 @@ class SearchFeed(AcquisitionFeed): if query: q = srch.index.query( - reduce(operator.or_, - [srch.index.Q(**{self.PARAMS_TO_FIELDS.get(cn, cn): query}) - for cn in self.MATCHES.keys()], - srch.index.Q())) + reduce( + operator.or_, + [srch.index.Q(**{self.PARAMS_TO_FIELDS.get(cn, cn): query}) for cn in self.MATCHES.keys()], + srch.index.Q())) else: q = srch.index.query(srch.index.Q()) diff --git a/src/pdcounter/admin.py b/src/pdcounter/admin.py index e2e3fc310..b83756baa 100644 --- a/src/pdcounter/admin.py +++ b/src/pdcounter/admin.py @@ -14,12 +14,13 @@ class BookStubAdmin(admin.ModelAdmin): prepopulated_fields = {'slug': ('title',)} + class AuthorAdmin(admin.ModelAdmin): list_display = ('name', 'slug', 'death') search_fields = ('name',) ordering = ('sort_key', 'name') - prepopulated_fields = {'slug': ('name',), 'sort_key': ('name',),} + prepopulated_fields = {'slug': ('name',), 'sort_key': ('name',)} admin.site.register(BookStub, BookStubAdmin) diff --git a/src/pdcounter/models.py b/src/pdcounter/models.py index 7c10f1e59..69c70c1c0 100644 --- a/src/pdcounter/models.py +++ b/src/pdcounter/models.py @@ -9,6 +9,7 @@ from django.utils.translation import ugettext_lazy as _ from datetime import datetime from django.db.models.signals import post_save, post_delete + class Author(models.Model): name = models.CharField(_('name'), max_length=50, db_index=True) slug = models.SlugField(_('slug'), max_length=120, db_index=True, unique=True) @@ -35,7 +36,7 @@ class Author(models.Model): @permalink def get_absolute_url(self): - return ('catalogue.views.tagged_object_list', [self.url_chunk]) + return 'catalogue.views.tagged_object_list', [self.url_chunk] def has_description(self): return len(self.description) > 0 @@ -75,7 +76,7 @@ class BookStub(models.Model): @permalink def get_absolute_url(self): - return ('catalogue.views.book_detail', [self.slug]) + return 'catalogue.views.book_detail', [self.slug] def in_pd(self): return self.pd is not None and self.pd <= datetime.now().year @@ -92,7 +93,7 @@ if not settings.NO_SEARCH_INDEX: def update_index(sender, instance, **kwargs): from search.index import Index idx = Index() - idx.index_tags(instance, remove_only=not 'created' in kwargs) + idx.index_tags(instance, remove_only='created' not in kwargs) post_delete.connect(update_index, Author) post_delete.connect(update_index, BookStub) diff --git a/src/pdcounter/templatetags/time_tags.py b/src/pdcounter/templatetags/time_tags.py index 7ea5c6055..42427fb60 100755 --- a/src/pdcounter/templatetags/time_tags.py +++ b/src/pdcounter/templatetags/time_tags.py @@ -11,6 +11,7 @@ from django.utils import timezone register = template.Library() + @register.filter def date_to_utc(date, day_end=False): """ Converts a datetime.date to UTC datetime. diff --git a/src/pdcounter/views.py b/src/pdcounter/views.py index e5b4421ce..eee6bfc7d 100644 --- a/src/pdcounter/views.py +++ b/src/pdcounter/views.py @@ -16,11 +16,9 @@ def book_stub_detail(request, slug): if book.pd and not book.in_pd(): pd_counter = datetime(book.pd, 1, 1) - form = PublishingSuggestForm( - initial={"books": u"%s — %s, \n" % (book.author, book.title)}) + form = PublishingSuggestForm(initial={"books": u"%s — %s, \n" % (book.author, book.title)}) - return render_to_response('pdcounter/book_stub_detail.html', locals(), - context_instance=RequestContext(request)) + return render_to_response('pdcounter/book_stub_detail.html', locals(), context_instance=RequestContext(request)) @cache.never_cache @@ -31,5 +29,4 @@ def author_detail(request, slug): form = PublishingSuggestForm(initial={"books": author.name + ", \n"}) - return render_to_response('pdcounter/author_detail.html', locals(), - context_instance=RequestContext(request)) + return render_to_response('pdcounter/author_detail.html', locals(), context_instance=RequestContext(request)) diff --git a/src/picture/admin.py b/src/picture/admin.py index f107d3196..debe11a81 100644 --- a/src/picture/admin.py +++ b/src/picture/admin.py @@ -6,6 +6,7 @@ from django.contrib import admin from picture.models import Picture from sorl.thumbnail.admin import AdminImageMixin + class PictureAdmin(AdminImageMixin, admin.ModelAdmin): pass diff --git a/src/picture/engine.py b/src/picture/engine.py index 574e5a889..83d255df5 100644 --- a/src/picture/engine.py +++ b/src/picture/engine.py @@ -1,6 +1,7 @@ from sorl.thumbnail.engines import pil_engine from sorl.thumbnail import parsers + # # Class developed by # http://timmyomahony.com/blog/custom-cropping-engine-sorl-thumbnail/ @@ -34,7 +35,7 @@ class CustomCroppingEngine(pil_engine.Engine): m = parsers.bgpos_pat.match(crop) if not m: raise parsers.ThumbnailParseError('Unrecognized crop option: %s' % crop) - value = int(m.group('value')) # we only take ints in the regexp + value = int(m.group('value')) # we only take ints in the regexp unit = m.group('unit') if unit == '%': value = epsilon * value / 100.0 @@ -50,7 +51,7 @@ class CustomCroppingEngine(pil_engine.Engine): if not crop or crop == 'noop': return image x_image, y_image = self.get_image_size(image) - x1,y1,x2,y2 = self._crop_parse(crop, (x_image, y_image), geometry) + x1, y1, x2, y2 = self._crop_parse(crop, (x_image, y_image), geometry) return self._crop(image, x1, y1, x2, y2) def _crop(self, image, x1, y1, x2, y2): diff --git a/src/picture/forms.py b/src/picture/forms.py index 2ad47b0b8..14706d9da 100644 --- a/src/picture/forms.py +++ b/src/picture/forms.py @@ -35,5 +35,6 @@ class PictureImportForm(forms.Form): return super(PictureImportForm, self).clean() def save(self, commit=True, **kwargs): - return Picture.from_xml_file(self.cleaned_data['picture_xml_file'], image_file=self.cleaned_data['picture_image_file'], - overwrite=True, **kwargs) + return Picture.from_xml_file( + self.cleaned_data['picture_xml_file'], image_file=self.cleaned_data['picture_image_file'], + overwrite=True, **kwargs) diff --git a/src/picture/models.py b/src/picture/models.py index bffb63912..020d3f565 100644 --- a/src/picture/models.py +++ b/src/picture/models.py @@ -34,14 +34,13 @@ picture_storage = FileSystemStorage(location=path.join( class PictureArea(models.Model): picture = models.ForeignKey('picture.Picture', related_name='areas') area = jsonfield.JSONField(_('area'), default={}, editable=False) - kind = models.CharField(_('kind'), max_length=10, blank=False, - null=False, db_index=True, - choices=(('thing', _('thing')), - ('theme', _('theme')))) - - objects = models.Manager() - tagged = managers.ModelTaggedItemManager(catalogue.models.Tag) - tags = managers.TagDescriptor(catalogue.models.Tag) + kind = models.CharField( + _('kind'), max_length=10, blank=False, null=False, db_index=True, + choices=(('thing', _('thing')), ('theme', _('theme')))) + + objects = models.Manager() + tagged = managers.ModelTaggedItemManager(catalogue.models.Tag) + tags = managers.TagDescriptor(catalogue.models.Tag) tag_relations = GenericRelation(catalogue.models.Tag.intermediary_table_model) short_html_url_name = 'picture_area_short' @@ -73,26 +72,27 @@ class Picture(models.Model): Picture resource. """ - title = models.CharField(_('title'), max_length=32767) - slug = models.SlugField(_('slug'), max_length=120, db_index=True, unique=True) - sort_key = models.CharField(_('sort key'), max_length=120, db_index=True, editable=False) - sort_key_author = models.CharField(_('sort key by author'), max_length=120, db_index=True, editable=False, default=u'') - 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) - xml_file = models.FileField('xml_file', upload_to="xml", storage=picture_storage) - image_file = ImageField(_('image_file'), upload_to="images", storage=picture_storage) - html_file = models.FileField('html_file', upload_to="html", storage=picture_storage) - areas_json = jsonfield.JSONField(_('picture areas JSON'), default={}, editable=False) - extra_info = jsonfield.JSONField(_('extra information'), default={}) - culturepl_link = models.CharField(blank=True, max_length=240) - wiki_link = models.CharField(blank=True, max_length=240) - - width = models.IntegerField(null=True) - height = models.IntegerField(null=True) - - objects = models.Manager() - tagged = managers.ModelTaggedItemManager(catalogue.models.Tag) - tags = managers.TagDescriptor(catalogue.models.Tag) + title = models.CharField(_('title'), max_length=32767) + slug = models.SlugField(_('slug'), max_length=120, db_index=True, unique=True) + sort_key = models.CharField(_('sort key'), max_length=120, db_index=True, editable=False) + sort_key_author = models.CharField( + _('sort key by author'), max_length=120, db_index=True, editable=False, default=u'') + 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) + xml_file = models.FileField('xml_file', upload_to="xml", storage=picture_storage) + image_file = ImageField(_('image_file'), upload_to="images", storage=picture_storage) + html_file = models.FileField('html_file', upload_to="html", storage=picture_storage) + areas_json = jsonfield.JSONField(_('picture areas JSON'), default={}, editable=False) + extra_info = jsonfield.JSONField(_('extra information'), default={}) + culturepl_link = models.CharField(blank=True, max_length=240) + wiki_link = models.CharField(blank=True, max_length=240) + + width = models.IntegerField(null=True) + height = models.IntegerField(null=True) + + objects = models.Manager() + tagged = managers.ModelTaggedItemManager(catalogue.models.Tag) + tags = managers.TagDescriptor(catalogue.models.Tag) tag_relations = GenericRelation(catalogue.models.Tag.intermediary_table_model) short_html_url_name = 'picture_short' @@ -129,7 +129,7 @@ class Picture(models.Model): @permalink def get_absolute_url(self): - return ('picture.views.picture_detail', [self.slug]) + return 'picture.views.picture_detail', [self.slug] def get_initial(self): try: @@ -163,7 +163,6 @@ class Picture(models.Model): close_xml_file = False close_image_file = False - if image_file is not None and not isinstance(image_file, File): image_file = File(open(image_file)) close_image_file = True @@ -190,7 +189,7 @@ class Picture(models.Model): motif_tags = set() thing_tags = set() - area_data = {'themes':{}, 'things':{}} + area_data = {'themes': {}, 'things': {}} # Treat all names in picture XML as in default language. lang = settings.LANGUAGE_CODE @@ -203,13 +202,14 @@ class Picture(models.Model): _tags = set() for objname in part['object'].split(','): objname = objname.strip().capitalize() - tag, created = catalogue.models.Tag.objects.get_or_create(slug=slughifi(objname), category='thing') + tag, created = catalogue.models.Tag.objects.get_or_create( + slug=slughifi(objname), category='thing') if created: tag.name = objname setattr(tag, 'name_%s' % lang, tag.name) tag.sort_key = sortify(tag.name) tag.save() - #thing_tags.add(tag) + # thing_tags.add(tag) area_data['things'][tag.slug] = { 'object': objname, 'coords': part['coords'], @@ -223,12 +223,13 @@ class Picture(models.Model): _tags = set() for motifs in part['themes']: for motif in motifs.split(','): - tag, created = catalogue.models.Tag.objects.get_or_create(slug=slughifi(motif), category='theme') + tag, created = catalogue.models.Tag.objects.get_or_create( + slug=slughifi(motif), category='theme') if created: tag.name = motif tag.sort_key = sortify(tag.name) tag.save() - #motif_tags.add(tag) + # motif_tags.add(tag) _tags.add(tag) area_data['themes'][tag.slug] = { 'theme': motif, @@ -282,10 +283,7 @@ class Picture(models.Model): from PIL import ImageDraw, ImageFont from librarian import get_resource - annotated = Image.new(img.mode, - (img.size[0], img.size[1] + 40), - (255, 255, 255) - ) + annotated = Image.new(img.mode, (img.size[0], img.size[1] + 40), (255, 255, 255)) annotated.paste(img, (0, 0)) annotation = Image.new('RGB', (img.size[0] * 3, 120), (255, 255, 255)) ImageDraw.Draw(annotation).text( @@ -297,14 +295,14 @@ class Picture(models.Model): annotated.paste(annotation.resize((img.size[0], 40), Image.ANTIALIAS), (0, img.size[1])) return annotated + # WTF/unused @classmethod def picture_list(cls, filter=None): """Generates a hierarchical listing of all pictures Pictures are optionally filtered with a test function. """ - pics = cls.objects.all().order_by('sort_key')\ - .only('title', 'slug', 'image_file') + pics = cls.objects.all().order_by('sort_key').only('title', 'slug', 'image_file') if filter: pics = pics.filter(filter).distinct() diff --git a/src/picture/tasks.py b/src/picture/tasks.py index fc9eafa7a..1958d2881 100644 --- a/src/picture/tasks.py +++ b/src/picture/tasks.py @@ -17,4 +17,3 @@ def generate_picture_html(picture_id): 'themes': pic.areas_json['themes'], })) pic.html_file.save("%s.html" % pic.slug, ContentFile(html_text)) - diff --git a/src/picture/templatetags/picture_tags.py b/src/picture/templatetags/picture_tags.py index 02d80b005..b31405b8d 100644 --- a/src/picture/templatetags/picture_tags.py +++ b/src/picture/templatetags/picture_tags.py @@ -18,6 +18,7 @@ register = template.Library() cropper = CustomCroppingEngine() + @register.inclusion_tag('picture/picture_wide.html', takes_context=True) def picture_wide(context, picture): context.update({ diff --git a/src/picture/tests/picture_import.py b/src/picture/tests/picture_import.py index 1e17289c3..022b33c62 100644 --- a/src/picture/tests/picture_import.py +++ b/src/picture/tests/picture_import.py @@ -16,9 +16,10 @@ class PictureTest(WLTestCase): themes = set() for area in picture.areas.all(): - themes.update([(tag.category, tag.name) + themes.update([ + (tag.category, tag.name) for tag in area.tags if tag.category in (u'theme', u'thing')]) - assert themes == set([(u'theme', u'nieporządek'), (u'thing', u'Kosmos')]), \ + assert themes == {(u'theme', u'nieporządek'), (u'thing', u'Kosmos')}, \ 'Bad themes on Picture areas: %s' % themes pic_themes = set([tag.name for tag in picture.tags if tag.category in ('theme', 'thing')]) @@ -32,7 +33,6 @@ class PictureTest(WLTestCase): picture.delete() - def test_import_2(self): picture = Picture.from_xml_file(path.join(path.dirname(__file__), "files/kandinsky-composition-viii.xml"), path.join(path.dirname(__file__), "files/kandinsky-composition-viii.png"), @@ -40,4 +40,3 @@ class PictureTest(WLTestCase): cats = set([t.category for t in picture.tags]) assert 'epoch' in cats assert 'kind' in cats - diff --git a/src/picture/views.py b/src/picture/views.py index 1f8738650..fea5a5eb2 100644 --- a/src/picture/views.py +++ b/src/picture/views.py @@ -2,7 +2,6 @@ # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # -from collections import OrderedDict from django.contrib.auth.decorators import permission_required from django.shortcuts import render_to_response, get_object_or_404, render from django.template import RequestContext @@ -11,23 +10,26 @@ from catalogue.utils import split_tags from ssify import ssi_included from sponsors.models import Sponsor -# was picture/picture_list.html list (without thumbs) -def picture_list(request, filter=None, get_filter=None, template_name='catalogue/picture_list.html', cache_key=None, context=None): - """ generates a listing of all books, optionally filtered with a test function """ - if get_filter: - filt = get_filter() - pictures_by_author, orphans = Picture.picture_list(filt) - books_nav = OrderedDict() - for tag in pictures_by_author: - if pictures_by_author[tag]: - books_nav.setdefault(tag.sort_key[0], []).append(tag) - - return render_to_response(template_name, locals(), - context_instance=RequestContext(request)) +# WTF/unused +# # was picture/picture_list.html list (without thumbs) +# def picture_list(request, filter=None, get_filter=None, template_name='catalogue/picture_list.html', +# cache_key=None, context=None): +# """ generates a listing of all books, optionally filtered with a test function """ +# +# if get_filter: +# filt = get_filter() +# pictures_by_author, orphans = Picture.picture_list(filt) +# books_nav = OrderedDict() +# for tag in pictures_by_author: +# if pictures_by_author[tag]: +# books_nav.setdefault(tag.sort_key[0], []).append(tag) +# +# return render_to_response(template_name, locals(), context_instance=RequestContext(request)) -def picture_list_thumb(request, filter=None, get_filter=None, template_name='picture/picture_list_thumb.html', cache_key=None, context=None): +def picture_list_thumb(request, filter=None, get_filter=None, template_name='picture/picture_list_thumb.html', + cache_key=None, context=None): book_list = Picture.objects.all() if filter: book_list = book_list.filter(filter) @@ -35,8 +37,8 @@ def picture_list_thumb(request, filter=None, get_filter=None, template_name='pic book_list = book_list.filter(get_filter()) book_list = book_list.order_by('sort_key_author') book_list = list(book_list) - return render_to_response(template_name, locals(), - context_instance=RequestContext(request)) + return render_to_response(template_name, locals(), context_instance=RequestContext(request)) + def picture_detail(request, slug): picture = get_object_or_404(Picture, slug=slug) @@ -88,7 +90,8 @@ def import_picture(request): info = sys.exc_info() exception = pprint.pformat(info[1]) tb = '\n'.join(traceback.format_tb(info[2])) - return HttpResponse(_("An error occurred: %(exception)s\n\n%(tb)s") % {'exception':exception, 'tb':tb}, mimetype='text/plain') + return HttpResponse(_("An error occurred: %(exception)s\n\n%(tb)s") % + {'exception': exception, 'tb': tb}, mimetype='text/plain') return HttpResponse(_("Picture imported successfully")) else: return HttpResponse(_("Error importing file: %r") % import_form.errors) @@ -97,8 +100,7 @@ def import_picture(request): @ssi_included def picture_mini(request, pk, with_link=True): picture = get_object_or_404(Picture, pk=pk) - author_str = ", ".join(tag.name - for tag in picture.tags.filter(category='author')) + author_str = ", ".join(tag.name for tag in picture.tags.filter(category='author')) return render(request, 'picture/picture_mini_box.html', { 'picture': picture, 'author_str': author_str, diff --git a/src/polls/models.py b/src/polls/models.py index 8e356683e..bfc36394b 100644 --- a/src/polls/models.py +++ b/src/polls/models.py @@ -49,7 +49,7 @@ class PollItem(models.Model): class Meta: verbose_name = _('vote item') verbose_name_plural = _('vote items') - + def __unicode__(self): return self.content + ' @ ' + unicode(self.poll) @@ -58,7 +58,7 @@ class PollItem(models.Model): return (float(self.vote_count) / self.poll.vote_count) * 100 if self.poll.vote_count else 0 def vote(self, session): - self.vote_count = self.vote_count + 1 + self.vote_count += 1 self.save() session.setdefault(USED_POLLS_KEY, []).append(self.poll.id) session.save() diff --git a/src/polls/templatetags/polls_tags.py b/src/polls/templatetags/polls_tags.py index 38619c108..7124b8603 100644 --- a/src/polls/templatetags/polls_tags.py +++ b/src/polls/templatetags/polls_tags.py @@ -8,16 +8,12 @@ from ..forms import PollForm register = template.Library() + @register.inclusion_tag('polls/tags/poll.html', takes_context=True) def poll(context, poll, show_results=True, redirect_to=''): form = None voted_already = poll.voted(context.get('request').session) if not voted_already: form = PollForm(poll=poll, initial=dict(redirect_to=redirect_to)) - return dict(poll=poll, - form=form, - voted_already=voted_already, - vote_count=poll.vote_count, - show_results=show_results, - request=context.get('request'), - ) + return {'poll': poll, 'form': form, 'voted_already': voted_already, 'vote_count': poll.vote_count, + 'show_results': show_results, 'request': context.get('request')} diff --git a/src/polls/urls.py b/src/polls/urls.py index fcd0ac6b7..0bec684e5 100644 --- a/src/polls/urls.py +++ b/src/polls/urls.py @@ -5,6 +5,7 @@ from django.conf.urls import patterns, url -urlpatterns = patterns('polls.views', +urlpatterns = patterns( + 'polls.views', url(r'^(?P[^/]+)$', 'poll', name='poll'), ) diff --git a/src/polls/views.py b/src/polls/views.py index 79540c66a..0d9590d85 100644 --- a/src/polls/views.py +++ b/src/polls/views.py @@ -15,12 +15,11 @@ from .forms import PollForm @cache.never_cache @require_http_methods(['GET', 'POST']) def poll(request, slug): - poll = get_object_or_404(Poll, slug=slug, open=True) if request.method == 'POST': - redirect_to = reverse('poll', args = [slug]) - form = PollForm(request.POST, poll = poll) + redirect_to = reverse('poll', args=[slug]) + form = PollForm(request.POST, poll=poll) if form.is_valid(): if not poll.voted(request.session): try: diff --git a/src/reporting/templatetags/reporting_stats.py b/src/reporting/templatetags/reporting_stats.py index 7bbe23d03..7a2080425 100755 --- a/src/reporting/templatetags/reporting_stats.py +++ b/src/reporting/templatetags/reporting_stats.py @@ -9,6 +9,7 @@ from catalogue.models import Book register = template.Library() + class StatsNode(template.Node): def __init__(self, value, varname=None): self.value = value @@ -44,14 +45,17 @@ def register_counter(f): def count_books_all(): return Book.objects.all().count() + @register_counter def count_books(): return Book.objects.filter(children=None).count() + @register_counter def count_books_parent(): return Book.objects.exclude(children=None).count() + @register_counter def count_books_root(): return Book.objects.filter(parent=None).count() diff --git a/src/reporting/urls.py b/src/reporting/urls.py index e78f961b2..3b09f1152 100755 --- a/src/reporting/urls.py +++ b/src/reporting/urls.py @@ -5,9 +5,9 @@ from django.conf.urls import patterns, url -urlpatterns = patterns('reporting.views', +urlpatterns = patterns( + 'reporting.views', url(r'^$', 'stats_page', name='reporting_stats'), url(r'^katalog.pdf$', 'catalogue_pdf', name='reporting_catalogue_pdf'), url(r'^katalog.csv$', 'catalogue_csv', name='reporting_catalogue_csv'), ) - diff --git a/src/reporting/utils.py b/src/reporting/utils.py index 8ecb9b045..f5d4c3342 100755 --- a/src/reporting/utils.py +++ b/src/reporting/utils.py @@ -8,6 +8,7 @@ import os.path from django.conf import settings import logging from django.http import HttpResponse +from wolnelektury.utils import makedirs logger = logging.getLogger(__name__) @@ -47,12 +48,10 @@ def render_to_pdf(output_path, template, context=None, add_files=None): cwd = os.getcwd() os.chdir(tempdir) try: - subprocess.check_call(['xelatex', '-interaction=batchmode', tex_path], + subprocess.check_call( + ['xelatex', '-interaction=batchmode', tex_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - try: - os.makedirs(os.path.dirname(output_path)) - except: - pass + makedirs(os.path.dirname(output_path)) shutil.move(os.path.join(tempdir, "doc.pdf"), output_path) finally: os.chdir(cwd) @@ -70,10 +69,7 @@ def render_to_csv(output_path, template, context=None, add_files=None): from django.template.loader import render_to_string - try: - os.makedirs(os.path.dirname(output_path)) - except: - pass + makedirs(os.path.dirname(output_path)) rendered = render_to_string(template, context) with open(output_path, 'w') as csv_file: diff --git a/src/reporting/views.py b/src/reporting/views.py index 8cb2715d5..d17d21281 100644 --- a/src/reporting/views.py +++ b/src/reporting/views.py @@ -17,39 +17,34 @@ from reporting.utils import render_to_pdf, render_to_csv, generated_file_view @staff_member_required def stats_page(request): media = BookMedia.objects.count() - media_types = BookMedia.objects.values('type').\ - annotate(count=Count('type')).\ - order_by('type') + media_types = BookMedia.objects.values('type').annotate(count=Count('type')).order_by('type') for mt in media_types: mt['size'] = sum(b.file.size for b in BookMedia.objects.filter(type=mt['type']).iterator()) if mt['type'] in ('mp3', 'ogg'): - deprecated = BookMedia.objects.filter( - type=mt['type'], source_sha1=None) + deprecated = BookMedia.objects.filter(type=mt['type'], source_sha1=None) mt['deprecated'] = deprecated.count() mt['deprecated_files'] = deprecated.order_by('book', 'name') else: mt['deprecated'] = '-' - licenses = set(((b.extra_info.get('license'), b.extra_info.get('license_description')) + licenses = set(( + (b.extra_info.get('license'), b.extra_info.get('license_description')) for b in Book.objects.all().iterator() if b.extra_info.get('license'))) - return render_to_response('reporting/main.html', - locals(), context_instance=RequestContext(request)) + return render_to_response('reporting/main.html', locals(), context_instance=RequestContext(request)) @generated_file_view('reports/katalog.pdf', 'application/pdf', - send_name=lambda: 'wolnelektury_%s.pdf' % date.today(), - signals=[Book.published]) + send_name=lambda: 'wolnelektury_%s.pdf' % date.today(), signals=[Book.published]) def catalogue_pdf(path): books_by_author, orphans, books_by_parent = Book.book_list() render_to_pdf(path, 'reporting/catalogue.texml', locals(), { - "wl-logo.png": os.path.join(settings.STATIC_ROOT, "img/logo-big.png"), - }) + "wl-logo.png": os.path.join(settings.STATIC_ROOT, "img/logo-big.png"), + }) @generated_file_view('reports/katalog.csv', 'application/csv', - send_name=lambda: 'wolnelektury_%s.csv' % date.today(), - signals=[Book.published]) + send_name=lambda: 'wolnelektury_%s.csv' % date.today(), signals=[Book.published]) def catalogue_csv(path): books_by_author, orphans, books_by_parent = Book.book_list() render_to_csv(path, 'reporting/catalogue.csv', locals()) diff --git a/src/search/context_processors.py b/src/search/context_processors.py index 3cb9256c6..a3f1ea912 100644 --- a/src/search/context_processors.py +++ b/src/search/context_processors.py @@ -7,4 +7,4 @@ from search.forms import SearchForm def search_form(request): - return { 'search_form': SearchForm(reverse('search.views.hint'), request.GET) } + return {'search_form': SearchForm(reverse('search.views.hint'), request.GET)} diff --git a/src/search/custom.py b/src/search/custom.py index b3b704d0b..dfface953 100644 --- a/src/search/custom.py +++ b/src/search/custom.py @@ -51,8 +51,8 @@ class CustomSolrConnection(sunburnt.SolrConnection): qs = urllib.urlencode(params) url = "%s?%s" % (self.analysis_url, qs) if len(url) > self.max_length_get_url: - warnings.warn("Long query URL encountered - POSTing instead of " - "GETting. This query will not be cached at the HTTP layer") + warnings.warn("Long query URL encountered - POSTing instead of GETting. " + "This query will not be cached at the HTTP layer") url = self.analysis_url kwargs = dict( method="POST", @@ -87,7 +87,8 @@ setattr(search.SolrSearch, '_init_common_modules', __patched__init_common_module class CustomSolrInterface(sunburnt.SolrInterface): # just copied from parent and SolrConnection -> CustomSolrConnection - def __init__(self, url, schemadoc=None, http_connection=None, mode='', retry_timeout=-1, max_length_get_url=sunburnt.MAX_LENGTH_GET_URL): + def __init__(self, url, schemadoc=None, http_connection=None, mode='', retry_timeout=-1, + max_length_get_url=sunburnt.MAX_LENGTH_GET_URL): self.conn = CustomSolrConnection(url, http_connection, retry_timeout, max_length_get_url) self.schemadoc = schemadoc if 'w' not in mode: @@ -105,10 +106,14 @@ class CustomSolrInterface(sunburnt.SolrInterface): args = { 'analysis_showmatch': True } - if 'field' in kwargs: args['analysis_fieldname'] = kwargs['field'] - if 'text' in kwargs: args['analysis_fieldvalue'] = kwargs['text'] - if 'q' in kwargs: args['q'] = kwargs['q'] - if 'query' in kwargs: args['q'] = kwargs['q'] + if 'field' in kwargs: + args['analysis_fieldname'] = kwargs['field'] + if 'text' in kwargs: + args['analysis_fieldvalue'] = kwargs['text'] + if 'q' in kwargs: + args['q'] = kwargs['q'] + if 'query' in kwargs: + args['q'] = kwargs['q'] params = map(lambda (k, v): (k.replace('_', '.'), v), sunburnt.params_from_dict(**args)) @@ -126,9 +131,8 @@ class CustomSolrInterface(sunburnt.SolrInterface): matches.add((start, end)) if matches: - return self.substring(kwargs['text'], matches, - margins=kwargs.get('margins', 30), - mark=kwargs.get('mark', ("", ""))) + return self.substring( + kwargs['text'], matches, margins=kwargs.get('margins', 30), mark=kwargs.get('mark', ("", ""))) else: return None @@ -155,36 +159,29 @@ class CustomSolrInterface(sunburnt.SolrInterface): break end += 1 - return (start, end) + return start, end def substring(self, text, matches, margins=30, mark=("", "")): - start = None - end = None totlen = len(text) - matches_margins = map(lambda (s, e): - ((s, e), - (max(0, s - margins), min(totlen, e + margins))), - matches) - matches_margins = map(lambda (m, (s, e)): - (m, self.expand_margins(text, s, e)), - matches_margins) - - # lets start with first match + matches_margins = [ + ((s, e), self.expand_margins(text, max(0, s - margins), min(totlen, e + margins))) for s, e in matches] + + # lets start with first match (start, end) = matches_margins[0][1] - matches = [matches_margins[0][0]] + new_matches = [matches_margins[0][0]] for (m, (s, e)) in matches_margins[1:]: if end < s or start > e: continue start = min(start, s) end = max(end, e) - matches.append(m) + new_matches.append(m) snip = text[start:end] - matches.sort(lambda a, b: cmp(b[0], a[0])) + new_matches.sort(lambda a, b: cmp(b[0], a[0])) - for (s, e) in matches: - off = - start + for (s, e) in new_matches: + off = -start snip = snip[:e + off] + mark[1] + snip[e + off:] snip = snip[:s + off] + mark[0] + snip[s + off:] diff --git a/src/search/fields.py b/src/search/fields.py index 45d8b7ecf..1dc787016 100755 --- a/src/search/fields.py +++ b/src/search/fields.py @@ -22,7 +22,7 @@ class JQueryAutoCompleteWidget(forms.TextInput): if value: final_attrs['value'] = smart_unicode(value) - if not self.attrs.has_key('id'): + if 'id' not in self.attrs: final_attrs['id'] = 'id_%s' % name html = u''' @@ -30,7 +30,7 @@ class JQueryAutoCompleteWidget(forms.TextInput): %(js)s//--> ''' % { 'attrs': flatatt(final_attrs), - 'js' : self.render_js(final_attrs['id'], self.options), + 'js': self.render_js(final_attrs['id'], self.options), } return mark_safe(html) @@ -42,10 +42,12 @@ class JQueryAutoCompleteSearchWidget(JQueryAutoCompleteWidget): def render_js(self, field_id, options): return u"" - + class JQueryAutoCompleteField(forms.CharField): - def __init__(self, source, options={}, *args, **kwargs): + def __init__(self, source, options=None, *args, **kwargs): + if options is None: + options = {} if 'widget' not in kwargs: options['source'] = source kwargs['widget'] = JQueryAutoCompleteWidget(options) @@ -54,7 +56,9 @@ class JQueryAutoCompleteField(forms.CharField): class JQueryAutoCompleteSearchField(forms.CharField): - def __init__(self, options={}, *args, **kwargs): + def __init__(self, options=None, *args, **kwargs): + if options is None: + options = {} if 'widget' not in kwargs: kwargs['widget'] = JQueryAutoCompleteSearchWidget(options) diff --git a/src/search/forms.py b/src/search/forms.py index 9e0a07880..b67ae7773 100755 --- a/src/search/forms.py +++ b/src/search/forms.py @@ -9,7 +9,8 @@ from search.fields import JQueryAutoCompleteSearchField class SearchForm(forms.Form): - q = JQueryAutoCompleteSearchField(label=_('Search')) # {'minChars': 2, 'selectFirst': True, 'cacheLength': 50, 'matchContains': "word"}) + q = JQueryAutoCompleteSearchField(label=_('Search')) + # {'minChars': 2, 'selectFirst': True, 'cacheLength': 50, 'matchContains': "word"}) def __init__(self, source, *args, **kwargs): kwargs['auto_id'] = False @@ -17,5 +18,5 @@ class SearchForm(forms.Form): self.fields['q'].widget.attrs['id'] = 'search' self.fields['q'].widget.attrs['autocomplete'] = 'off' self.fields['q'].widget.attrs['data-source'] = source - if not 'q' in self.data: + if 'q' not in self.data: self.fields['q'].widget.attrs['placeholder'] = _('title, author, theme/topic, epoch, kind, genre, phrase') diff --git a/src/search/index.py b/src/search/index.py index 31417ca87..ffad25788 100644 --- a/src/search/index.py +++ b/src/search/index.py @@ -6,22 +6,21 @@ from django.conf import settings import os import re -import errno from librarian import dcparser from librarian.parser import WLDocument from lxml import etree import catalogue.models from pdcounter.models import Author as PDCounterAuthor, BookStub as PDCounterBook from itertools import chain -import traceback -import logging -log = logging.getLogger('search') import sunburnt import custom import operator +import logging +from wolnelektury.utils import makedirs log = logging.getLogger('search') + class SolrIndex(object): def __init__(self, mode=None): self.index = custom.CustomSolrInterface(settings.SOLR, mode=mode) @@ -36,20 +35,18 @@ class Snippets(object): SNIPPET_DIR = "snippets" def __init__(self, book_id, revision=None): - try: - os.makedirs(os.path.join(settings.SEARCH_INDEX, self.SNIPPET_DIR)) - except OSError as exc: - if exc.errno == errno.EEXIST: - pass - else: raise + makedirs(os.path.join(settings.SEARCH_INDEX, self.SNIPPET_DIR)) self.book_id = book_id self.revision = revision self.file = None + self.position = None @property def path(self): - if self.revision: fn = "%d.%d" % (self.book_id, self.revision) - else: fn = "%d" % self.book_id + if self.revision: + fn = "%d.%d" % (self.book_id, self.revision) + else: + fn = "%d" % self.book_id return os.path.join(settings.SEARCH_INDEX, self.SNIPPET_DIR, fn) @@ -57,7 +54,7 @@ class Snippets(object): """ Open the snippet file. Call .close() afterwards. """ - if not 'b' in mode: + if 'b' not in mode: mode += 'b' if 'w' in mode: @@ -142,6 +139,7 @@ class Index(SolrIndex): else: return False + # WTF def index_tags(self, *tags, **kw): """ Re-index global tag list. @@ -173,8 +171,9 @@ class Index(SolrIndex): if not remove_only: # then add them [all or just one passed] if not tags: - tags = chain(catalogue.models.Tag.objects.exclude(category='set'), \ - PDCounterAuthor.objects.all(), \ + tags = chain( + catalogue.models.Tag.objects.exclude(category='set'), + PDCounterAuthor.objects.all(), PDCounterBook.objects.all()) for tag in tags: @@ -211,11 +210,9 @@ class Index(SolrIndex): """ Create a lucene document referring book id. """ - doc = { - 'book_id': int(book.id), - } + doc = {'book_id': int(book.id)} if book.parent is not None: - doc["parent_id"] = int(book.parent.id) + doc['parent_id'] = int(book.parent.id) return doc def remove_book(self, book_or_id, remove_snippets=True): @@ -284,7 +281,8 @@ class Index(SolrIndex): footnote_tags = ['pa', 'pt', 'pr', 'pe'] - skip_header_tags = ['autor_utworu', 'nazwa_utworu', 'dzielo_nadrzedne', '{http://www.w3.org/1999/02/22-rdf-syntax-ns#}RDF'] + skip_header_tags = ['autor_utworu', 'nazwa_utworu', 'dzielo_nadrzedne', + '{http://www.w3.org/1999/02/22-rdf-syntax-ns#}RDF'] published_date_re = re.compile("([0-9]+)[\]. ]*$") @@ -298,7 +296,7 @@ class Index(SolrIndex): book_info = dcparser.parse(open(book.xml_file.path)) fields['slug'] = book.slug - fields['tags'] = [t.name for t in book.tags] + fields['tags'] = [t.name for t in book.tags] fields['is_book'] = True # validator, name @@ -332,7 +330,8 @@ class Index(SolrIndex): match = self.published_date_re.search(book_info.source_name) if match is not None: pd = str(match.groups()[0]) - if not pd: pd = "" + if not pd: + pd = "" fields["published_date"] = pd return fields @@ -355,7 +354,7 @@ class Index(SolrIndex): if master.tag in self.master_tags: return master - def index_content(self, book, book_fields={}): + def index_content(self, book, book_fields): """ Walks the book XML and extract content from it. Adds parts for each header tag and for each fragment. @@ -367,8 +366,7 @@ class Index(SolrIndex): if master is None: return [] - def walker(node, ignore_tags=[]): - + def walker(node, ignore_tags=()): if node.tag not in ignore_tags: yield node, None, None if node.text is not None: @@ -383,7 +381,7 @@ class Index(SolrIndex): return def fix_format(text): - # separator = [u" ", u"\t", u".", u";", u","] + # separator = [u" ", u"\t", u".", u";", u","] if isinstance(text, list): # need to join it first text = filter(lambda s: s is not None, content) @@ -471,12 +469,13 @@ class Index(SolrIndex): # handle fragments and themes. if start is not None and start.tag == 'begin': fid = start.attrib['id'][1:] - fragments[fid] = {'text': [], 'themes': [], 'start_section': position, 'start_header': header.tag} + fragments[fid] = { + 'text': [], 'themes': [], 'start_section': position, 'start_header': header.tag} # themes for this fragment elif start is not None and start.tag == 'motyw': fid = start.attrib['id'][1:] - handle_text.append(None) + handle_text.append(lambda text: None) if start.text is not None: fragments[fid]['themes'] += map(unicode.strip, map(unicode, (start.text.split(',')))) elif end is not None and end.tag == 'motyw': @@ -487,7 +486,7 @@ class Index(SolrIndex): if fid not in fragments: continue # a broken node, skip it frag = fragments[fid] - if frag['themes'] == []: + if not frag['themes']: continue # empty themes list. del fragments[fid] @@ -504,8 +503,7 @@ class Index(SolrIndex): if text is not None and handle_text is not []: hdl = handle_text[-1] - if hdl is not None: - hdl(text) + hdl(text) # in the end, add a section text. doc = add_part(snippets, header_index=position, @@ -525,6 +523,7 @@ class SearchResult(object): self._processed_hits = None # processed hits self.snippets = [] self.query_terms = query_terms + self._book = None if 'score' in doc: self._score = doc['score'] @@ -561,7 +560,9 @@ class SearchResult(object): def __unicode__(self): return u"" % \ - (self.book_id, len(self._hits), self._processed_hits and len(self._processed_hits) or -1, self._score, len(self.snippets)) + (self.book_id, len(self._hits), + len(self._processed_hits) if self._processed_hits else -1, + self._score, len(self.snippets)) def __str__(self): return unicode(self).encode('utf-8') @@ -579,7 +580,7 @@ class SearchResult(object): return self def get_book(self): - if hasattr(self, '_book'): + if self._book is not None: return self._book self._book = catalogue.models.Book.objects.get(id=self.book_id) return self._book @@ -605,11 +606,8 @@ class SearchResult(object): # sections not covered by fragments sect = filter(lambda s: 0 == len(filter( - lambda f: s[self.POSITION][self.POSITION_INDEX] >= f[self.POSITION][self.POSITION_INDEX] - and s[self.POSITION][self.POSITION_INDEX] < f[self.POSITION][self.POSITION_INDEX] + f[self.POSITION][self.POSITION_SPAN], - frags)), sect) - - hits = [] + lambda f: f[self.POSITION][self.POSITION_INDEX] <= s[self.POSITION][self.POSITION_INDEX] < + f[self.POSITION][self.POSITION_INDEX] + f[self.POSITION][self.POSITION_SPAN], frags)), sect) def remove_duplicates(lst, keyfn, compare): els = {} @@ -713,7 +711,7 @@ class SearchResult(object): def snippet_revision(self, idx=0): try: return self.hits[idx]['snippets_revision'] - except: + except (IndexError, KeyError): return None @@ -724,25 +722,26 @@ class Search(SolrIndex): def __init__(self, default_field="text"): super(Search, self).__init__(mode='r') - def make_term_query(self, query, field='text', modal=operator.or_): """ Returns term queries joined by boolean query. modal - applies to boolean query fuzzy - should the query by fuzzy. """ - if query is None: query = '' + if query is None: + query = '' q = self.index.Q() - q = reduce(modal, map(lambda s: self.index.Q(**{field: s}), - query.split(r" ")), q) + q = reduce(modal, map(lambda s: self.index.Q(**{field: s}), query.split(r" ")), q) return q def search_phrase(self, searched, field='text', book=False, filters=None, snippets=False): - if filters is None: filters = [] - if book: filters.append(self.index.Q(is_book=True)) + if filters is None: + filters = [] + if book: + filters.append(self.index.Q(is_book=True)) q = self.index.query(**{field: searched}) q = self.apply_filters(q, filters).field_limit(score=True, all_fields=True) @@ -752,8 +751,10 @@ class Search(SolrIndex): def search_some(self, searched, fields, book=True, filters=None, snippets=True, query_terms=None): assert isinstance(fields, list) - if filters is None: filters = [] - if book: filters.append(self.index.Q(is_book=True)) + if filters is None: + filters = [] + if book: + filters.append(self.index.Q(is_book=True)) query = self.index.Q() @@ -765,7 +766,6 @@ class Search(SolrIndex): res = query.execute() return [SearchResult(found, how_found='search_some', query_terms=query_terms) for found in res] - def search_everywhere(self, searched, query_terms=None): """ Tries to use search terms to match different fields of book (or its parts). @@ -860,7 +860,8 @@ class Search(SolrIndex): """ Search for Tag objects using query. """ - if not filters: filters = [] + if not filters: + filters = [] if not pdcounter: filters.append(~self.index.Q(is_pdcounter=True)) res = self.apply_filters(query, filters).execute() @@ -872,25 +873,30 @@ class Search(SolrIndex): is_pdcounter = doc.get('is_pdcounter', False) category = doc.get('tag_category') try: - if is_pdcounter == True: + if is_pdcounter: if category == 'pd_author': tag = PDCounterAuthor.objects.get(id=doc.get('tag_id')) elif category == 'pd_book': tag = PDCounterBook.objects.get(id=doc.get('tag_id')) tag.category = 'pd_book' # make it look more lik a tag. else: - print ("Warning. cannot get pdcounter tag_id=%d from db; cat=%s" % (int(doc.get('tag_id')), category)).encode('utf-8') + # WTF + print ("Warning. cannot get pdcounter tag_id=%d from db; cat=%s" % ( + int(doc.get('tag_id')), category)).encode('utf-8') pd_tags.append(tag) else: tag = catalogue.models.Tag.objects.get(id=doc.get("tag_id")) tags.append(tag) - except catalogue.models.Tag.DoesNotExist: pass - except PDCounterAuthor.DoesNotExist: pass - except PDCounterBook.DoesNotExist: pass + except catalogue.models.Tag.DoesNotExist: + pass + except PDCounterAuthor.DoesNotExist: + pass + except PDCounterBook.DoesNotExist: + pass tags_slugs = set(map(lambda t: t.slug, tags)) - tags = tags + filter(lambda t: not t.slug in tags_slugs, pd_tags) + tags = tags + filter(lambda t: t.slug not in tags_slugs, pd_tags) log.debug('search_tags: %s' % tags) @@ -923,19 +929,20 @@ class Search(SolrIndex): for r in res: try: bid = r['book_id'] - if not bid in bks_found: + if bid not in bks_found: bks.append(catalogue.models.Book.objects.get(id=bid)) bks_found.add(bid) - except catalogue.models.Book.DoesNotExist: pass + except catalogue.models.Book.DoesNotExist: + pass return bks - @staticmethod def apply_filters(query, filters): """ Apply filters to a query """ - if filters is None: filters = [] + if filters is None: + filters = [] filters = filter(lambda x: x is not None, filters) for f in filters: query = query.query(f) diff --git a/src/search/management/commands/reindex.py b/src/search/management/commands/reindex.py index 4941354ce..f982b2a3e 100755 --- a/src/search/management/commands/reindex.py +++ b/src/search/management/commands/reindex.py @@ -7,6 +7,7 @@ from django.core.management.base import BaseCommand from optparse import make_option + def query_yes_no(question, default="yes"): """Ask a yes/no question via raw_input() and return their answer. @@ -17,9 +18,9 @@ def query_yes_no(question, default="yes"): The "answer" return value is one of "yes" or "no". """ - valid = {"yes":True, "y":True, "ye":True, - "no":False, "n":False} - if default == None: + valid = {"yes": True, "y": True, "ye": True, + "no": False, "n": False} + if default is None: prompt = " [y/n] " elif default == "yes": prompt = " [Y/n] " @@ -36,8 +37,8 @@ def query_yes_no(question, default="yes"): elif choice in valid: return valid[choice] else: - sys.stdout.write("Please respond with 'yes' or 'no' "\ - "(or 'y' or 'n').\n") + sys.stdout.write("Please respond with 'yes' or 'no' (or 'y' or 'n').\n") + class Command(BaseCommand): help = 'Reindex everything.' @@ -45,10 +46,11 @@ class Command(BaseCommand): option_list = BaseCommand.option_list + ( make_option('-n', '--book-id', action='store_true', dest='book_id', default=False, - help='book id instead of slugs'), + help='book id instead of slugs'), make_option('-t', '--just-tags', action='store_true', dest='just_tags', default=False, - help='just reindex tags'), + help='just reindex tags'), ) + def handle(self, *args, **opts): from catalogue.models import Book from search.index import Index diff --git a/src/search/management/commands/snippets.py b/src/search/management/commands/snippets.py index 40310eda1..a758317bb 100755 --- a/src/search/management/commands/snippets.py +++ b/src/search/management/commands/snippets.py @@ -10,21 +10,20 @@ from os import path from sys import stdout from django.conf import settings + class Command(BaseCommand): help = 'Reindex everything.' args = '' option_list = BaseCommand.option_list + ( make_option('-C', '--check-just-read', action='store_true', dest='check', default=False, - help='Check snippets utf-8'), + help='Check snippets utf-8'), make_option('-c', '--check', action='store_true', dest='check2', default=False, - help='Check snippets utf-8 by walking through index'), + help='Check snippets utf-8 by walking through index'), ) - def handle(self, *args, **opts): - from catalogue.models import Book - from search.index import Search + from search.index import Search, Snippets if opts['check']: sfn = glob(settings.SEARCH_INDEX+'snippets/*') @@ -46,19 +45,19 @@ class Command(BaseCommand): doc = reader.document(did) if doc and doc.get('book_id'): bkid = int(doc.get('book_id')) - #import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() stdout.write("\r%d / %d" % (did, numdocs)) stdout.flush() - ss = doc.get('snippet_position') - sl = doc.get('snippet_length') + ss = doc.get('snippet_position') + sl = doc.get('snippet_length') if ss and sl: + # WTF (nie było zaimportowane) snips = Snippets(bkid) try: - txt = snips.get((ss,sl)) + txt = snips.get((ss, sl)) assert len(txt) == sl except UnicodeDecodeError, ude: stdout.write("\nerror in snippets %d\n" % bkid) raise ude stdout.write("\ndone.\n") - diff --git a/src/search/mock_search.py b/src/search/mock_search.py index 253c277a8..b1c8162b9 100644 --- a/src/search/mock_search.py +++ b/src/search/mock_search.py @@ -52,13 +52,13 @@ class Search(Mock): results.append(res) return results - def search_phrase(self, searched, field='text', book=False, - filters=None, snippets=False): + def search_phrase(self, searched, field='text', book=False, filters=None, snippets=False): return self._find_some_books(snippets) def search_some(self, searched, fields, book=True, filters=None, snippets=True, query_terms=None): return self._find_some_books(snippets, query_terms) + # WTF def search_books(self, query, filters=None, max_results=10): return self._find_some_books(snippets, max_results=max_results) diff --git a/src/search/templatetags/search_tags.py b/src/search/templatetags/search_tags.py index 8302379cd..c135b8096 100644 --- a/src/search/templatetags/search_tags.py +++ b/src/search/templatetags/search_tags.py @@ -35,7 +35,7 @@ def book_searched(context, result): 'fragment' in h or result.snippets[idx] is not None, enumerate(result.hits)) - # print "[tmpl: from %d hits selected %d]" % (len(result.hits), len(hits)) + # print "[tmpl: from %d hits selected %d]" % (len(result.hits), len(hits)) for (idx, hit) in hits: # currently we generate one snipper per hit though. @@ -46,7 +46,7 @@ def book_searched(context, result): snip = result.snippets[idx] # fix some formattting snip = re.subn(r"(^[ \t\n]+|[ \t\n]+$)", u"", - re.subn(r"[ \t\n]*\n[ \t\n]*", u"\n", snip)[0])[0] + re.subn(r"[ \t\n]*\n[ \t\n]*", u"\n", snip)[0])[0] snip = snip.replace("\n", "
            ").replace('---', '—') hit['snippet'] = snip diff --git a/src/search/tests/index.py b/src/search/tests/index.py index b8d44726f..d11ff7b06 100644 --- a/src/search/tests/index.py +++ b/src/search/tests/index.py @@ -6,19 +6,16 @@ from unittest import skipIf from django.conf import settings from django.test.utils import override_settings from catalogue.test_utils import WLTestCase, get_fixture -from os import path import tempfile -from catalogue.models import Book, Tag -from search.index import Index, Search, SearchResult +from catalogue.models import Book +from search.index import Index, Search import catalogue import opds -@override_settings( - SEARCH_INDEX = tempfile.mkdtemp(prefix='djangotest_search_'), -) +@override_settings(SEARCH_INDEX=tempfile.mkdtemp(prefix='djangotest_search_')) @skipIf(getattr(settings, 'NO_SEARCH_INDEX', False), - u'Requires search server and NO_SEARCH_INDEX=False.') + u'Requires search server and NO_SEARCH_INDEX=False.') class BookSearchTests(WLTestCase): def setUp(self): WLTestCase.setUp(self) @@ -53,4 +50,3 @@ class BookSearchTests(WLTestCase): # a = SearchResult.aggregate(books) # # just one fragment hit. # assert len(a[0].hits) == 1 - diff --git a/src/search/urls.py b/src/search/urls.py index d77d7220a..8aae74bae 100644 --- a/src/search/urls.py +++ b/src/search/urls.py @@ -4,8 +4,8 @@ # from django.conf.urls import patterns, url -urlpatterns = patterns('search.views', +urlpatterns = patterns( + 'search.views', url(r'^$', 'main', name='search'), url(r'^hint/$', 'hint', name='search_hint'), ) - diff --git a/src/search/views.py b/src/search/views.py index f7aa77cd9..c6759ea76 100644 --- a/src/search/views.py +++ b/src/search/views.py @@ -3,19 +3,18 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # from django.conf import settings -from django.shortcuts import render_to_response, get_object_or_404 +from django.shortcuts import render_to_response from django.template import RequestContext from django.views.decorators import cache -from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect, JsonResponse +from django.http import HttpResponse, JsonResponse from django.utils.translation import ugettext as _ from catalogue.utils import split_tags -from catalogue.models import Book, Tag, Fragment +from catalogue.models import Book from pdcounter.models import Author as PDCounterAuthor, BookStub as PDCounterBook from search.index import Search, SearchResult from suggest.forms import PublishingSuggestForm import re -#import enchant import json @@ -132,16 +131,11 @@ def hint(request): @cache.never_cache def main(request): - results = {} - - results = None - query = None - query = request.GET.get('q', '') if len(query) < 2: - return render_to_response('catalogue/search_too_short.html', - {'prefix': query}, + return render_to_response( + 'catalogue/search_too_short.html', {'prefix': query}, context_instance=RequestContext(request)) query = remove_query_syntax_chars(query) @@ -151,7 +145,7 @@ def main(request): theme_terms = search.index.analyze(text=query, field="themes_pl") \ + search.index.analyze(text=query, field="themes") - # change hints + # change hints tags = search.hint_tags(query, pdcounter=True, prefix=False) tags = split_tags(tags) @@ -236,20 +230,28 @@ def main(request): # return HttpResponseRedirect(results[0].book.get_absolute_url()) if len(results) == 0: form = PublishingSuggestForm(initial={"books": query + ", "}) - return render_to_response('catalogue/search_no_hits.html', - {'tags': tags, - 'prefix': query, - "form": form, - 'did_you_mean': suggestion}, + return render_to_response( + 'catalogue/search_no_hits.html', + { + 'tags': tags, + 'prefix': query, + 'form': form, + 'did_you_mean': suggestion + }, context_instance=RequestContext(request)) - return render_to_response('catalogue/search_multiple_hits.html', - {'tags': tags, - 'prefix': query, - 'results': {'author': author_results, - 'translator': translator_results, - 'title': title_results, - 'content': text_phrase, - 'other': everywhere}, - 'did_you_mean': suggestion}, + return render_to_response( + 'catalogue/search_multiple_hits.html', + { + 'tags': tags, + 'prefix': query, + 'results': { + 'author': author_results, + 'translator': translator_results, + 'title': title_results, + 'content': text_phrase, + 'other': everywhere + }, + 'did_you_mean': suggestion + }, context_instance=RequestContext(request)) diff --git a/src/social/admin.py b/src/social/admin.py index 3da4ae8c0..a0f3ec92b 100755 --- a/src/social/admin.py +++ b/src/social/admin.py @@ -14,10 +14,10 @@ class CiteAdmin(admin.ModelAdmin): (None, {'fields': ('book', 'text', 'small', 'vip', 'link', 'sticky')}), ( _('Background'), - {'fields': ('image', 'image_shift', 'image_title', 'image_author', - 'image_link', 'image_license', 'image_license_link') - } - ) + {'fields': ( + 'image', 'image_shift', 'image_title', 'image_author', + 'image_link', 'image_license', 'image_license_link')}, + ) ) def nonempty_text(self, cite): diff --git a/src/social/forms.py b/src/social/forms.py index 5834ffa24..389185889 100755 --- a/src/social/forms.py +++ b/src/social/forms.py @@ -14,8 +14,7 @@ class UserSetsForm(forms.Form): def __init__(self, book, user, *args, **kwargs): super(UserSetsForm, self).__init__(*args, **kwargs) self.fields['set_ids'] = forms.ChoiceField( - choices=[(tag.id, tag.name) for tag in - Tag.objects.filter(category='set', user=user).iterator()], + choices=[(tag.id, tag.name) for tag in Tag.objects.filter(category='set', user=user).iterator()], ) @@ -28,13 +27,11 @@ class ObjectSetsForm(forms.Form): self._user = user data = kwargs.setdefault('data', {}) if 'tags' not in data and user.is_authenticated(): - data['tags'] = ', '.join(t.name - for t in obj.tags.filter(category='set', user=user).iterator() if t.name) + data['tags'] = ', '.join(t.name for t in obj.tags.filter(category='set', user=user).iterator() if t.name) super(ObjectSetsForm, self).__init__(*args, **kwargs) def save(self, request): - tags = [get_set(self._user, tag_name.strip()) - for tag_name in self.cleaned_data['tags'].split(',')] + tags = [get_set(self._user, tag_name.strip()) for tag_name in self.cleaned_data['tags'].split(',')] set_sets(self._user, self._obj, tags) return {"like": True} @@ -48,8 +45,7 @@ class NewSetForm(forms.Form): def save(self, user, commit=True): name = self.cleaned_data['name'] - new_set = Tag(name=name, slug=utils.get_random_hash(name), sort_key=name.lower(), - category='set', user=user) + new_set = Tag(name=name, slug=utils.get_random_hash(name), sort_key=name.lower(), category='set', user=user) new_set.save() return new_set diff --git a/src/social/models.py b/src/social/models.py index 890280774..12ad61352 100644 --- a/src/social/models.py +++ b/src/social/models.py @@ -13,25 +13,22 @@ from catalogue.models import Book class Cite(models.Model): book = models.ForeignKey(Book, verbose_name=_('book'), null=True, blank=True) text = models.TextField(_('text')) - small = models.BooleanField(_('small'), default=False, - help_text=_('Make this cite display smaller.')) + small = models.BooleanField(_('small'), default=False, help_text=_('Make this cite display smaller.')) vip = models.CharField(_('VIP'), max_length=128, null=True, blank=True) link = models.URLField(_('link')) sticky = models.BooleanField(_('sticky'), default=False, db_index=True, - help_text=_('Sticky cites will take precedense.')) + help_text=_('Sticky cites will take precedense.')) - image = models.ImageField(_('image'), upload_to='social/cite', - null=True, blank=True, + image = models.ImageField( + _('image'), upload_to='social/cite', null=True, blank=True, help_text=_('Best image is exactly 975px wide and weights under 100kB.')) - image_shift = models.IntegerField(_('shift'), null=True, blank=True, - help_text=_(u'Vertical shift, in percents. 0 means top, 100 is bottom. Default is 50%.')) - image_title = models.CharField(_('title'), max_length=255, - null=True, blank=True) - image_author = models.CharField(_('author'), - max_length=255, blank=True, null=True) + image_shift = models.IntegerField( + _('shift'), null=True, blank=True, + help_text=_(u'Vertical shift, in percents. 0 means top, 100 is bottom. Default is 50%.')) + image_title = models.CharField(_('title'), max_length=255, null=True, blank=True) + image_author = models.CharField(_('author'), max_length=255, blank=True, null=True) image_link = models.URLField(_('link'), blank=True, null=True) - image_license = models.CharField(_('license name'), - max_length=255, blank=True, null=True) + image_license = models.CharField(_('license name'), max_length=255, blank=True, null=True) image_license_link = models.URLField(_('license link'), blank=True, null=True) class Meta: diff --git a/src/social/templatetags/social_tags.py b/src/social/templatetags/social_tags.py index 7065467b4..9ba3acc54 100755 --- a/src/social/templatetags/social_tags.py +++ b/src/social/templatetags/social_tags.py @@ -67,6 +67,7 @@ def book_shelf_tags(request, book_id): return None book = Book.objects.get(pk=book_id) lks = likes(request.user, book, request) + def get_value(): if not lks: return '' diff --git a/src/social/urls.py b/src/social/urls.py index 3642d91da..f9222ce93 100755 --- a/src/social/urls.py +++ b/src/social/urls.py @@ -6,7 +6,8 @@ from django.conf.urls import patterns, url from django.views.decorators.cache import never_cache from social.views import ObjectSetsFormView -urlpatterns = patterns('social.views', +urlpatterns = patterns( + 'social.views', url(r'^lektura/(?P[a-z0-9-]+)/lubie/$', 'like_book', name='social_like_book'), url(r'^lektura/(?P[a-z0-9-]+)/nie_lubie/$', 'unlike_book', name='social_unlike_book'), url(r'^lektura/(?P[a-z0-9-]+)/polki/$', never_cache(ObjectSetsFormView()), name='social_book_sets'), @@ -17,10 +18,10 @@ urlpatterns = patterns('social.views', url(r'^cite_main/(?P\d+)\.(?P.+)\.html$', 'cite', {'main': True}, name='social_cite_main'), url(r'^cite_info/(?P\d+).html$', 'cite_info', name='social_cite_info'), - #~ url(r'^polki/(?P[a-zA-Z0-9-]+)/formaty/$', 'shelf_book_formats', name='shelf_book_formats'), - #~ url(r'^polki/(?P[a-zA-Z0-9-]+)/(?P%s)/usun$' % SLUG, 'remove_from_shelf', name='remove_from_shelf'), - #~ url(r'^polki/$', 'user_shelves', name='user_shelves'), - #~ url(r'^polki/(?P[a-zA-Z0-9-]+)/usun/$', 'delete_shelf', name='delete_shelf'), - #~ url(r'^polki/(?P[a-zA-Z0-9-]+)\.zip$', 'download_shelf', name='download_shelf'), - #~ url(r'^polki/nowa/$', 'new_set', name='new_set'), + # url(r'^polki/(?P[a-zA-Z0-9-]+)/formaty/$', 'shelf_book_formats', name='shelf_book_formats'), + # url(r'^polki/(?P[a-zA-Z0-9-]+)/(?P%s)/usun$' % SLUG, 'remove_from_shelf', name='remove_from_shelf'), + # url(r'^polki/$', 'user_shelves', name='user_shelves'), + # url(r'^polki/(?P[a-zA-Z0-9-]+)/usun/$', 'delete_shelf', name='delete_shelf'), + # url(r'^polki/(?P[a-zA-Z0-9-]+)\.zip$', 'download_shelf', name='download_shelf'), + # url(r'^polki/nowa/$', 'new_set', name='new_set'), ) diff --git a/src/social/utils.py b/src/social/utils.py index bf1c24229..c89878ad4 100755 --- a/src/social/utils.py +++ b/src/social/utils.py @@ -21,7 +21,7 @@ def likes(user, work, request=None): if not hasattr(request, 'social_likes'): # tuple: unchecked, checked, liked - request.social_likes = defaultdict(lambda:(set(), set(), set())) + request.social_likes = defaultdict(lambda: (set(), set(), set())) ct = ContentType.objects.get_for_model(type(work)) likes_t = request.social_likes[ct.pk] @@ -29,6 +29,7 @@ def likes(user, work, request=None): return work.pk in likes_t[2] else: likes_t[0].add(work.pk) + def _likes(): if likes_t[0]: ids = tuple(likes_t[0]) @@ -47,8 +48,8 @@ def get_set(user, name): try: tag = Tag.objects.get(category='set', user=user, name=name) except Tag.DoesNotExist: - tag = Tag.objects.create(category='set', user=user, name=name, - slug=utils.get_random_hash(name), sort_key=name.lower()) + tag = Tag.objects.create( + category='set', user=user, name=name, slug=utils.get_random_hash(name), sort_key=name.lower()) return tag diff --git a/src/sortify.py b/src/sortify.py index 642a5403f..f1e8bcb8b 100644 --- a/src/sortify.py +++ b/src/sortify.py @@ -12,7 +12,7 @@ char_order = { def replace_char(m): char = m.group() - if char_map.has_key(char): + if char in char_map: order = char_order.get(char, 0) return "%s~%d" % (char_map[char], order) else: @@ -37,7 +37,7 @@ def sortify(value): value = unicode(value, 'utf-8') # try to replace chars - value = re.sub('[^a-zA-Z0-9\\s\\-]{1}', replace_char, value) + value = re.sub('[^a-zA-Z0-9\\s\\-]', replace_char, value) value = value.lower() value = re.sub(r'[^a-z0-9~]+', ' ', value) diff --git a/src/sponsors/models.py b/src/sponsors/models.py index 0565b9744..89b06ff2c 100644 --- a/src/sponsors/models.py +++ b/src/sponsors/models.py @@ -80,7 +80,8 @@ class SponsorPage(models.Model): if self.sprite: self.sprite.delete(save=False) - self.sprite.save('sponsorzy/sprite/%s-%d.png' % (self.name, time.time()), ContentFile(imgstr.getvalue()), save=False) + self.sprite.save('sponsorzy/sprite/%s-%d.png' % ( + self.name, time.time()), ContentFile(imgstr.getvalue()), save=False) def html(self): return self._html @@ -104,4 +105,3 @@ class SponsorPage(models.Model): def __unicode__(self): return self.name - diff --git a/src/sponsors/urls.py b/src/sponsors/urls.py index 6da6186c3..7c6bc2ce6 100644 --- a/src/sponsors/urls.py +++ b/src/sponsors/urls.py @@ -4,6 +4,7 @@ # from django.conf.urls import patterns, url -urlpatterns = patterns('sponsors.views', +urlpatterns = patterns( + 'sponsors.views', url(r'^page/(?P.+)\.html$', 'page', name='sponsor_page'), ) diff --git a/src/sponsors/widgets.py b/src/sponsors/widgets.py index 0ddab3809..bc8b453fc 100644 --- a/src/sponsors/widgets.py +++ b/src/sponsors/widgets.py @@ -28,6 +28,5 @@ class SponsorPageWidget(forms.Textarea): output.append(u'\n' % - (name, sponsors_js)) + output.append(u'$("#id_%s").sponsorsFooter({sponsors: [%s]}); });\n' % (name, sponsors_js)) return mark_safe(u''.join(output)) diff --git a/src/stats/models.py b/src/stats/models.py index 8b1378917..e69de29bb 100644 --- a/src/stats/models.py +++ b/src/stats/models.py @@ -1 +0,0 @@ - diff --git a/src/suggest/admin.py b/src/suggest/admin.py index b5fcb5cf2..b76b621d7 100644 --- a/src/suggest/admin.py +++ b/src/suggest/admin.py @@ -6,6 +6,7 @@ from django.contrib import admin from suggest.models import Suggestion, PublishingSuggestion + class SuggestionAdmin(admin.ModelAdmin): list_display = ('created_at', 'contact', 'user', 'description') diff --git a/src/suggest/forms.py b/src/suggest/forms.py index b98e0ae4a..03e1232f7 100644 --- a/src/suggest/forms.py +++ b/src/suggest/forms.py @@ -21,8 +21,7 @@ class SuggestForm(forms.Form): contact = self.cleaned_data['contact'] description = self.cleaned_data['description'] - suggestion = Suggestion(contact=contact, - description=description, ip=request.META['REMOTE_ADDR']) + suggestion = Suggestion(contact=contact, description=description, ip=request.META['REMOTE_ADDR']) if request.user.is_authenticated(): suggestion.user = request.user suggestion.save() @@ -47,16 +46,12 @@ Kontakt: %(contact)s except ValidationError: pass else: - send_mail(u'[WolneLektury] ' + - ugettext(u'Thank you for your suggestion.'), - ugettext(u"""\ + send_mail(u'[WolneLektury] ' + ugettext(u'Thank you for your suggestion.'), + ugettext(u"""\ Thank you for your comment on WolneLektury.pl. The suggestion has been referred to the project coordinator.""") + -u""" - --- -""" + ugettext(u'''Message sent automatically. Please do not reply.'''), - 'no-reply@wolnelektury.pl', [contact], fail_silently=True) + u'\n\n-- \n' + ugettext(u'''Message sent automatically. Please do not reply.'''), + 'no-reply@wolnelektury.pl', [contact], fail_silently=True) class PublishingSuggestForm(forms.Form): @@ -64,19 +59,20 @@ class PublishingSuggestForm(forms.Form): books = forms.CharField(label=_('books'), widget=forms.Textarea, required=False) audiobooks = forms.CharField(label=_('audiobooks'), widget=forms.Textarea, required=False) - def clean(self, *args, **kwargs): + def clean(self): if not self.cleaned_data['books'] and not self.cleaned_data['audiobooks']: msg = ugettext(u"One of these fields is required.") self._errors["books"] = self.error_class([msg]) self._errors["audiobooks"] = self.error_class([msg]) - return super(PublishingSuggestForm, self).clean(*args, **kwargs) + return super(PublishingSuggestForm, self).clean() def save(self, request): contact = self.cleaned_data['contact'] books = self.cleaned_data['books'] audiobooks = self.cleaned_data['audiobooks'] - suggestion = PublishingSuggestion(contact=contact, books=books, + suggestion = PublishingSuggestion( + contact=contact, books=books, audiobooks=audiobooks, ip=request.META['REMOTE_ADDR']) if request.user.is_authenticated(): suggestion.user = request.user @@ -106,13 +102,10 @@ Audiobooki: except ValidationError: pass else: - send_mail(u'[WolneLektury] ' + - ugettext(u'Thank you for your suggestion.'), - ugettext(u"""\ + send_mail( + u'[WolneLektury] ' + ugettext(u'Thank you for your suggestion.'), + ugettext(u"""\ Thank you for your comment on WolneLektury.pl. The suggestion has been referred to the project coordinator.""") + -u""" - --- -""" + ugettext(u'''Message sent automatically. Please do not reply.'''), - 'no-reply@wolnelektury.pl', [contact], fail_silently=True) + u"\n\n-- \n" + ugettext(u'''Message sent automatically. Please do not reply.'''), + 'no-reply@wolnelektury.pl', [contact], fail_silently=True) diff --git a/src/suggest/models.py b/src/suggest/models.py index c0f8658f5..87454a211 100644 --- a/src/suggest/models.py +++ b/src/suggest/models.py @@ -6,6 +6,7 @@ from django.db import models from django.contrib.auth.models import User from django.utils.translation import ugettext_lazy as _ + class Suggestion(models.Model): contact = models.CharField(_('contact'), blank=True, max_length=120) description = models.TextField(_('description'), blank=True) diff --git a/src/suggest/urls.py b/src/suggest/urls.py index 2f7017213..5e721d45e 100644 --- a/src/suggest/urls.py +++ b/src/suggest/urls.py @@ -5,8 +5,8 @@ from django.conf.urls import patterns, url from suggest import views -urlpatterns = patterns('', +urlpatterns = patterns( + '', url(r'^$', views.SuggestionFormView(), name='suggest'), url(r'^plan/$', views.PublishingSuggestionFormView(), name='suggest_publishing'), ) - diff --git a/src/waiter/settings.py b/src/waiter/settings.py index aaa9f03b3..15fb7ef83 100644 --- a/src/waiter/settings.py +++ b/src/waiter/settings.py @@ -19,4 +19,3 @@ try: WAITER_MAX_QUEUE = settings.WAITER_MAX_QUEUE except AttributeError: WAITER_MAX_QUEUE = 20 - diff --git a/src/waiter/urls.py b/src/waiter/urls.py index 21352c786..69ab03a85 100644 --- a/src/waiter/urls.py +++ b/src/waiter/urls.py @@ -4,6 +4,7 @@ # from django.conf.urls import patterns, url -urlpatterns = patterns('waiter.views', +urlpatterns = patterns( + 'waiter.views', url(r'^(?P.*)$', 'wait', name='waiter'), ) diff --git a/src/wolnelektury/apps.py b/src/wolnelektury/apps.py index a45bfe24f..a75fd0ca7 100644 --- a/src/wolnelektury/apps.py +++ b/src/wolnelektury/apps.py @@ -4,6 +4,7 @@ # from django.apps import AppConfig + class WLCoreConfig(AppConfig): name = 'wolnelektury' diff --git a/src/wolnelektury/celery.py b/src/wolnelektury/celery.py index 094a7a7c2..85ecb4a17 100644 --- a/src/wolnelektury/celery.py +++ b/src/wolnelektury/celery.py @@ -1,8 +1,15 @@ +# -*- 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 __future__ import absolute_import import os import sys +from celery import Celery +from django.conf import settings + ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path = [ os.path.join(ROOT, 'lib/librarian'), @@ -10,9 +17,6 @@ sys.path = [ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'wolnelektury.settings') -from celery import Celery -from django.conf import settings - app = Celery('wolnelektury') app.config_from_object('django.conf:settings') diff --git a/src/wolnelektury/context_processors.py b/src/wolnelektury/context_processors.py index 5885e039b..fb5584e4d 100644 --- a/src/wolnelektury/context_processors.py +++ b/src/wolnelektury/context_processors.py @@ -4,6 +4,7 @@ # from django.conf import settings + def extra_settings(request): return { 'STATIC_URL': settings.STATIC_URL, diff --git a/src/wolnelektury/management/commands/localepack.py b/src/wolnelektury/management/commands/localepack.py index bd631928c..5458904db 100644 --- a/src/wolnelektury/management/commands/localepack.py +++ b/src/wolnelektury/management/commands/localepack.py @@ -7,6 +7,7 @@ from django.conf import settings from django.core.management.base import BaseCommand from django.core.management import call_command from .translation2po import get_languages +from wolnelektury.utils import makedirs import os import shutil @@ -29,12 +30,12 @@ class Locale(object): def generate(self, languages): pass + def copy_f(frm, to): - "I can create a necessary dest directiories, yey!" - if not os.path.exists(os.path.dirname(to)): - os.makedirs(os.path.dirname(to)) + makedirs(os.path.dirname(to)) shutil.copyfile(frm, to) + class AppLocale(Locale): def __init__(self, appmod): self.app = appmod @@ -54,17 +55,14 @@ class AppLocale(Locale): lc = lc[0] if os.path.exists(os.path.join(self.path, 'locale', lc)): copy_f(os.path.join(self.path, 'locale', lc, 'LC_MESSAGES', 'django.po'), - os.path.join(output_directory, lc, self.name + '.po')) - + os.path.join(output_directory, lc, self.name + '.po')) def load(self, input_directory, languages): for lc in zip(*languages)[0]: if os.path.exists(os.path.join(input_directory, lc, self.name + '.po')): out = os.path.join(self.path, 'locale', lc, 'LC_MESSAGES', 'django.po') - if not os.path.exists(os.path.dirname(out)): - os.makedirs(os.path.dirname(out)) - copy_f(os.path.join(input_directory, lc, self.name + '.po'), - out) + makedirs(os.path.dirname(out)) + copy_f(os.path.join(input_directory, lc, self.name + '.po'), out) wd = os.getcwd() os.chdir(self.path) @@ -75,7 +73,6 @@ class AppLocale(Locale): finally: os.chdir(wd) - def generate(self, languages): wd = os.getcwd() os.chdir(self.path) @@ -123,12 +120,12 @@ class CustomLocale(Locale): for lc in zip(*languages)[0]: if os.path.exists(self.po_file(lc)): copy_f(self.po_file(lc), - os.path.join(output_directory, lc, self.name + '.po')) + os.path.join(output_directory, lc, self.name + '.po')) def load(self, input_directory, languages): for lc in zip(*languages)[0]: copy_f(os.path.join(input_directory, lc, self.name + '.po'), - self.po_file(lc)) + self.po_file(lc)) os.system('pybabel compile -D django -d %s' % os.path.dirname(self.out_file)) @@ -148,14 +145,15 @@ SOURCES.append(CustomLocale(os.path.dirname(allauth.__file__), name='contrib')) class Command(BaseCommand): option_list = BaseCommand.option_list + ( - make_option('-l', '--load', help='load locales back to source', action='store_true', dest='load', default=False), + make_option('-l', '--load', help='load locales back to source', action='store_true', dest='load', + default=False), make_option('-L', '--lang', help='load just one language', dest='lang', default=None), make_option('-d', '--directory', help='load from this directory', dest='directory', default=None), make_option('-o', '--outfile', help='Resulting zip file', dest='outfile', default='./wl-locale.zip'), - make_option('-m', '--merge', help='Use git to merge. Please use with clean working directory.', action='store_true', dest='merge', default=False), + make_option('-m', '--merge', help='Use git to merge. Please use with clean working directory.', + action='store_true', dest='merge', default=False), make_option('-M', '--message', help='commit message', dest='message', default='New locale'), - - ) + ) help = 'Make a locale pack' args = '' @@ -192,14 +190,14 @@ class Command(BaseCommand): rf.write(rev) rf.close() - cwd = os.getcwd() try: os.chdir(os.path.dirname(out_dir)) self.system('zip -r %s %s' % (os.path.join(cwd, packname_b+'.zip'), os.path.basename(out_dir))) finally: os.chdir(cwd) - # shutil.make_archive(packname_b, fmt, root_dir=os.path.dirname(out_dir), base_dir=os.path.basename(out_dir)) + # shutil.make_archive(packname_b, fmt, root_dir=os.path.dirname(out_dir), + # base_dir=os.path.basename(out_dir)) finally: shutil.rmtree(tmp_dir, ignore_errors=True) @@ -215,9 +213,11 @@ class Command(BaseCommand): print "Directory not provided or does not exist, please use -d" sys.exit(1) - if options['merge']: self.merge_setup(options['directory']) + if options['merge']: + self.merge_setup(options['directory']) self.load(options) - if options['merge']: self.merge_finish(options['message']) + if options['merge']: + self.merge_finish(options['message']) else: self.save(options) diff --git a/src/wolnelektury/management/commands/translation2po.py b/src/wolnelektury/management/commands/translation2po.py index 6220006fe..9fcb8bb09 100644 --- a/src/wolnelektury/management/commands/translation2po.py +++ b/src/wolnelektury/management/commands/translation2po.py @@ -7,16 +7,16 @@ import time from optparse import make_option from django.conf import settings from django.core.management.base import BaseCommand -from django.core.management.color import color_style from django.db import models import polib -import modeltranslation.models from modeltranslation.translator import translator, NotRegistered +from wolnelektury.utils import makedirs + def metadata(language=''): - "get metadata for PO, given language code" + """get metadata for PO, given language code""" t = time.strftime('%Y-%m-%d %H:%M%z') return { @@ -33,14 +33,15 @@ def metadata(language=''): def make_po(language=''): - "Create new POFile object for language code" + """Create new POFile object for language code""" po = polib.POFile() po.metadata = metadata(language) return po def get_languages(langs): - if not langs: return settings.LANGUAGES + if not langs: + return settings.LANGUAGES langs = langs.split(',') lm = dict(settings.LANGUAGES) return map(lambda l: (l, lm.get(l, l)), langs) @@ -48,18 +49,22 @@ def get_languages(langs): class Command(BaseCommand): option_list = BaseCommand.option_list + ( - make_option('-d', '--directory', help='Specify which directory should hold generated PO files', dest='directory', default=''), - make_option('-l', '--load', help='load locales back to source', action='store_true', dest='load', default=False), + make_option('-d', '--directory', help='Specify which directory should hold generated PO files', + dest='directory', default=''), + make_option('-l', '--load', help='load locales back to source', action='store_true', dest='load', + default=False), make_option('-L', '--language', help='locales to load', dest='lang', default=None), make_option('-n', '--poname', help='name of the po file [no extension]', dest='poname', default=None), - make_option('-k', '--keep-running', help='keep running even when missing an input file', dest='keep_running', default=False, action='store_true'), - ) + make_option('-k', '--keep-running', help='keep running even when missing an input file', dest='keep_running', + default=False, action='store_true'), + ) help = 'Export models from app to po files' args = 'app' def get_models(self, app): for mdname in dir(app.models): - if mdname[0] == '_': continue + if mdname[0] == '_': + continue md = getattr(app.models, mdname) try: assert issubclass(md, models.Model) @@ -74,14 +79,15 @@ class Command(BaseCommand): yield (md, opts) def handle(self, appname, **options): - if not options['poname']: options['poname'] = appname + if not options['poname']: + options['poname'] = appname app = __import__(appname) if options['load']: objects = {} modmod = {} for md, opts in self.get_models(app): - if not md.__name__ in objects: + if md.__name__ not in objects: objects[md.__name__] = {} modmod['model'] = md @@ -119,7 +125,7 @@ class Command(BaseCommand): cur_lang = locfld.language try: po = pofiles[cur_lang] - except: + except KeyError: po = make_po(cur_lang) pofiles[cur_lang] = po v = locfld.value_from_object(obj) or '' @@ -131,5 +137,5 @@ class Command(BaseCommand): directory = options['directory'] for lng, po in pofiles.items(): - os.makedirs(os.path.join(directory, lng)) + makedirs(os.path.join(directory, lng)) po.save(os.path.join(directory, lng, '%s.po' % options['poname'])) diff --git a/src/wolnelektury/management/profile.py b/src/wolnelektury/management/profile.py index 90e5ec5f5..6978ea831 100644 --- a/src/wolnelektury/management/profile.py +++ b/src/wolnelektury/management/profile.py @@ -1,17 +1,20 @@ - +# -*- 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. +# import cProfile import functools import os _object = None + def profile(meth): def _wrapper(self, *args, **kwargs): - object = self - setattr(object, "__%s" % meth.__name__, meth) - cProfile.runctx('object.__%s(object, *args, **kwargs)' % (meth.__name__, ), globals(), locals(), - "profile.%d" % os.getpid()) + setattr(self, "__%s" % meth.__name__, meth) + cProfile.runctx( + 'object.__%s(object, *args, **kwargs)' % (meth.__name__, ), globals(), locals(), + 'profile.%d' % os.getpid()) functools.update_wrapper(_wrapper, meth) return _wrapper - diff --git a/src/wolnelektury/middleware.py b/src/wolnelektury/middleware.py index 60b382cd3..652c80c7b 100644 --- a/src/wolnelektury/middleware.py +++ b/src/wolnelektury/middleware.py @@ -1,11 +1,13 @@ -# Orignal version taken from http://www.djangosnippets.org/snippets/186/ +# -*- coding: utf-8 -*- +# Original version taken from http://www.djangosnippets.org/snippets/186/ # Original author: udfalkso # Modified by: Shwagroo Team import sys import os import re -import hotshot, hotshot.stats +import hotshot +import hotshot.stats import tempfile import StringIO import pprint @@ -14,12 +16,12 @@ from django.conf import settings from django.db import connection -words_re = re.compile( r'\s+' ) +words_re = re.compile(r'\s+') group_prefix_re = [ - re.compile( "^.*/django/[^/]+" ), - re.compile( "^(.*)/[^/]+$" ), # extract module path - re.compile( ".*" ), # catch strange entries + re.compile("^.*/django/[^/]+"), + re.compile("^(.*)/[^/]+$"), # extract module path + re.compile(".*"), # catch strange entries ] @@ -36,24 +38,24 @@ class ProfileMiddleware(object): WARNING: It uses hotshot profiler which is not thread safe. """ def process_request(self, request): - if (settings.DEBUG or request.user.is_superuser) and request.GET.has_key('prof'): + if (settings.DEBUG or request.user.is_superuser) and 'prof' in request.GET: connection.queries = [] self.tmpfile = tempfile.mktemp() self.prof = hotshot.Profile(self.tmpfile) def process_view(self, request, callback, callback_args, callback_kwargs): - if (settings.DEBUG or request.user.is_superuser) and request.GET.has_key('prof'): + if (settings.DEBUG or request.user.is_superuser) and 'prof' in request.GET: return self.prof.runcall(callback, request, *callback_args, **callback_kwargs) def get_group(self, file): for g in group_prefix_re: - name = g.findall( file ) + name = g.findall(file) if name: return name[0] def get_summary(self, results_dict, sum): - list = [ (item[1], item[0]) for item in results_dict.items() ] - list.sort( reverse = True ) + list = [(item[1], item[0]) for item in results_dict.items()] + list.sort(reverse=True) list = list[:40] res = " tottime\n" @@ -62,7 +64,7 @@ class ProfileMiddleware(object): foo = 0 else: foo = 100*item[0]/sum - res += "%4.1f%% %7.3f %s\n" % (foo, item[0], item[1] ) + res += "%4.1f%% %7.3f %s\n" % (foo, item[0], item[1]) return res @@ -75,28 +77,28 @@ class ProfileMiddleware(object): sum = 0 for s in stats_str: - fields = words_re.split(s); + fields = words_re.split(s) if len(fields) == 7: time = float(fields[2]) sum += time file = fields[6].split(":")[0] - if not file in mystats: + if file not in mystats: mystats[file] = 0 mystats[file] += time group = self.get_group(file) - if not group in mygroups: - mygroups[ group ] = 0 - mygroups[ group ] += time + if group not in mygroups: + mygroups[group] = 0 + mygroups[group] += time return "
            " + \
            -               " ---- By file ----\n\n" + self.get_summary(mystats,sum) + "\n" + \
            -               " ---- By group ---\n\n" + self.get_summary(mygroups,sum) + \
            +               " ---- By file ----\n\n" + self.get_summary(mystats, sum) + "\n" + \
            +               " ---- By group ---\n\n" + self.get_summary(mygroups, sum) + \
                            "
            " def process_response(self, request, response): - if (settings.DEBUG or request.user.is_superuser) and request.GET.has_key('prof'): + if (settings.DEBUG or request.user.is_superuser) and 'prof' in request.GET: self.prof.close() out = StringIO.StringIO() @@ -123,4 +125,3 @@ class ProfileMiddleware(object): response.content += pprint.pformat(connection.queries) return response - diff --git a/src/wolnelektury/settings/auth.py b/src/wolnelektury/settings/auth.py index 4d3ea224a..d1c6a8f4e 100644 --- a/src/wolnelektury/settings/auth.py +++ b/src/wolnelektury/settings/auth.py @@ -1,3 +1,7 @@ +# -*- 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. +# AUTHENTICATION_BACKENDS = [ 'django.contrib.auth.backends.ModelBackend', 'allauth.account.auth_backends.AuthenticationBackend', @@ -11,9 +15,11 @@ SOCIALACCOUNT_AUTO_SIGNUP = False SOCIALACCOUNT_QUERY_EMAIL = True -SOCIALACCOUNT_PROVIDERS = \ - { 'openid': - { 'SERVERS': - [dict(id='google', - name='Google', - openid_url='https://www.google.com/accounts/o8/id')]}} +SOCIALACCOUNT_PROVIDERS = { + 'openid': { + 'SERVERS': [{ + 'id': 'google', + 'name': 'Google', + 'openid_url': 'https://www.google.com/accounts/o8/id'}], + }, +} diff --git a/src/wolnelektury/settings/basic.py b/src/wolnelektury/settings/basic.py index 30812e516..ef14739e5 100644 --- a/src/wolnelektury/settings/basic.py +++ b/src/wolnelektury/settings/basic.py @@ -1,3 +1,7 @@ +# -*- 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 os import path from .paths import PROJECT_DIR @@ -13,8 +17,8 @@ MANAGERS = ADMINS DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. - 'NAME': path.join(PROJECT_DIR, 'dev.db'), # Or path to database file if using sqlite3. + 'ENGINE': 'django.db.backends.sqlite3', # 'postgresql_psycopg2' + 'NAME': path.join(PROJECT_DIR, 'dev.db'), 'USER': '', # Not used with sqlite3. 'PASSWORD': '', # Not used with sqlite3. 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. @@ -38,5 +42,5 @@ SITE_ID = 1 TEMPLATE_LOADERS = [ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', -# 'django.template.loaders.eggs.Loader', + # 'django.template.loaders.eggs.Loader', ] diff --git a/src/wolnelektury/settings/cache.py b/src/wolnelektury/settings/cache.py index a9cc70f3b..69ce6cb63 100644 --- a/src/wolnelektury/settings/cache.py +++ b/src/wolnelektury/settings/cache.py @@ -1,3 +1,7 @@ +# -*- 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. +# CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', diff --git a/src/wolnelektury/settings/celery.py b/src/wolnelektury/settings/celery.py index 77abfa658..e5c265c2e 100644 --- a/src/wolnelektury/settings/celery.py +++ b/src/wolnelektury/settings/celery.py @@ -1,3 +1,7 @@ +# -*- 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. +# BROKER_URL = 'django://' CELERY_EAGER_PROPAGATES_EXCEPTIONS = True diff --git a/src/wolnelektury/settings/contrib.py b/src/wolnelektury/settings/contrib.py index f0e8430a5..4bb78bcfe 100644 --- a/src/wolnelektury/settings/contrib.py +++ b/src/wolnelektury/settings/contrib.py @@ -1,3 +1,7 @@ +# -*- 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. +# HONEYPOT_FIELD_NAME = 'miut' PAGINATION_INVALID_PAGE_RAISES_404 = True THUMBNAIL_QUALITY = 95 @@ -6,8 +10,8 @@ MODELTRANSLATION_DEFAULT_LANGUAGE = 'pl' MODELTRANSLATION_PREPOPULATE_LANGUAGE = 'pl' MIGRATION_MODULES = { - 'getpaid' : 'wolnelektury.migrations.getpaid', - 'piston' : 'wolnelektury.migrations.piston', + 'getpaid': 'wolnelektury.migrations.getpaid', + 'piston': 'wolnelektury.migrations.piston', } GETPAID_ORDER_DESCRIPTION = "{% load funding_tags %}{{ order|sanitize_payment_title }}" diff --git a/src/wolnelektury/settings/custom.py b/src/wolnelektury/settings/custom.py index fd8a42602..688573270 100644 --- a/src/wolnelektury/settings/custom.py +++ b/src/wolnelektury/settings/custom.py @@ -1,3 +1,7 @@ +# -*- 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. +# import os from .paths import VAR_DIR diff --git a/src/wolnelektury/settings/locale.py b/src/wolnelektury/settings/locale.py index 5069051f9..0a4876671 100644 --- a/src/wolnelektury/settings/locale.py +++ b/src/wolnelektury/settings/locale.py @@ -1,4 +1,7 @@ # -*- 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 os import path from .paths import PROJECT_DIR @@ -15,7 +18,9 @@ LOCALE_PATHS = [ # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'pl' -gettext = lambda s: s + +def gettext(s): + return s LANGUAGES = tuple(sorted([ ('pl', u'polski'), @@ -26,6 +31,6 @@ LANGUAGES = tuple(sorted([ ('ru', u'русский'), ('es', u'español'), ('uk', u'українська'), -# ('jp', u'日本語'), + # ('jp', u'日本語'), ('it', u'italiano'), ], key=lambda x: x[0])) diff --git a/src/wolnelektury/settings/paths.py b/src/wolnelektury/settings/paths.py index dfb99de04..32ab1c24f 100644 --- a/src/wolnelektury/settings/paths.py +++ b/src/wolnelektury/settings/paths.py @@ -1,6 +1,9 @@ +# -*- 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 os import path PROJECT_DIR = path.dirname(path.dirname(path.abspath(__file__))) ROOT_DIR = path.dirname(path.dirname(PROJECT_DIR)) VAR_DIR = path.join(ROOT_DIR, 'var') - diff --git a/src/wolnelektury/settings/static.py b/src/wolnelektury/settings/static.py index 625b4c77f..80bd9ea14 100644 --- a/src/wolnelektury/settings/static.py +++ b/src/wolnelektury/settings/static.py @@ -1,3 +1,7 @@ +# -*- 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 os import path from .paths import VAR_DIR @@ -18,143 +22,143 @@ STATIC_URL = '/static/' PIPELINE = { 'PIPELINE_ENABLED': False, 'STYLESHEETS': { - 'main': { - # styles both for mobile and for big screen - 'source_filenames': [ - 'css/jquery.countdown.css', - 'jplayer/jplayer.blue.monday.css', - - 'sponsors/css/sponsors.css', - - 'uni_form/uni-form.css', - 'uni_form/default.uni-form.css', - - 'css/ui-lightness/jquery-ui-1.8.16.custom.css', - - 'scss/main.scss', - ], - 'output_filename': 'css/compressed/main.css', - }, - 'book': { - 'source_filenames': [ - 'css/master.book.css', - ], - 'output_filename': 'css/compressed/book.css', - }, - 'book_text': { - 'source_filenames': [ - 'scss/book_text.scss', - 'css/new.book.css', - - 'css/master.picture.css', - ], - 'output_filename': 'css/compressed/book_text.css', - }, - 'picture': { - 'source_filenames': [ - 'css/master.book.css', - 'css/master.picture.css', - ], - 'output_filename': 'css/compressed/picture.css', - }, - 'player': { - 'source_filenames': [ - 'jplayer/jplayer.blue.monday.css', - 'player/player.css', - ], - 'output_filename': 'css/compressed/player.css', - }, - 'simple': { - 'source_filenames': ('css/simple.css',), - 'output_filename': 'css/compressed/simple.css', - }, - 'widget': { - 'source_filenames': ('scss/widget.scss',), - 'output_filename': 'css/compressed/widget.css', - }, + 'main': { + # styles both for mobile and for big screen + 'source_filenames': [ + 'css/jquery.countdown.css', + 'jplayer/jplayer.blue.monday.css', + + 'sponsors/css/sponsors.css', + + 'uni_form/uni-form.css', + 'uni_form/default.uni-form.css', + + 'css/ui-lightness/jquery-ui-1.8.16.custom.css', + + 'scss/main.scss', + ], + 'output_filename': 'css/compressed/main.css', + }, + 'book': { + 'source_filenames': [ + 'css/master.book.css', + ], + 'output_filename': 'css/compressed/book.css', + }, + 'book_text': { + 'source_filenames': [ + 'scss/book_text.scss', + 'css/new.book.css', + + 'css/master.picture.css', + ], + 'output_filename': 'css/compressed/book_text.css', + }, + 'picture': { + 'source_filenames': [ + 'css/master.book.css', + 'css/master.picture.css', + ], + 'output_filename': 'css/compressed/picture.css', + }, + 'player': { + 'source_filenames': [ + 'jplayer/jplayer.blue.monday.css', + 'player/player.css', + ], + 'output_filename': 'css/compressed/player.css', + }, + 'simple': { + 'source_filenames': ('css/simple.css',), + 'output_filename': 'css/compressed/simple.css', + }, + 'widget': { + 'source_filenames': ('scss/widget.scss',), + 'output_filename': 'css/compressed/widget.css', + }, }, 'JAVASCRIPT': { - 'base': { - 'source_filenames': ( - 'js/contrib/jquery.cycle.min.js', - 'js/contrib/jquery.jqmodal.js', - 'js/contrib/jquery.form.js', - 'js/contrib/jquery.paging.min.js', - 'js/contrib/jquery.countdown.js', 'js/contrib/jquery.countdown-pl.js', - 'js/contrib/jquery.countdown-de.js', 'js/contrib/jquery.countdown-uk.js', - 'js/contrib/jquery.countdown-es.js', 'js/contrib/jquery.countdown-lt.js', - 'js/contrib/jquery.countdown-ru.js', 'js/contrib/jquery.countdown-fr.js', - - 'js/contrib/jquery-ui-1.8.16.custom.min.js', - - 'jplayer/jquery.jplayer.min.js', - 'jplayer/jplayer.playlist.min.js', - 'player/player.js', - - 'js/locale.js', - 'js/dialogs.js', - 'js/base.js', - 'pdcounter/pdcounter.js', - 'sponsors/js/sponsors.js', - 'player/openplayer.js', - 'js/search.js', - 'funding/funding.js', - - 'uni_form/uni-form.js', + 'base': { + 'source_filenames': ( + 'js/contrib/jquery.cycle.min.js', + 'js/contrib/jquery.jqmodal.js', + 'js/contrib/jquery.form.js', + 'js/contrib/jquery.paging.min.js', + 'js/contrib/jquery.countdown.js', 'js/contrib/jquery.countdown-pl.js', + 'js/contrib/jquery.countdown-de.js', 'js/contrib/jquery.countdown-uk.js', + 'js/contrib/jquery.countdown-es.js', 'js/contrib/jquery.countdown-lt.js', + 'js/contrib/jquery.countdown-ru.js', 'js/contrib/jquery.countdown-fr.js', + + 'js/contrib/jquery-ui-1.8.16.custom.min.js', + + 'jplayer/jquery.jplayer.min.js', + 'jplayer/jplayer.playlist.min.js', + 'player/player.js', + + 'js/locale.js', + 'js/dialogs.js', + 'js/base.js', + 'pdcounter/pdcounter.js', + 'sponsors/js/sponsors.js', + 'player/openplayer.js', + 'js/search.js', + 'funding/funding.js', + + 'uni_form/uni-form.js', + ), + 'output_filename': 'js/base.min.js', + }, + 'player': { + 'source_filenames': [ + 'jplayer/jquery.jplayer.min.js', + 'jplayer/jplayer.playlist.min.js', + 'player/player.js', + ], + 'output_filename': 'js/player.min.js', + }, + 'book': { + 'source_filenames': [ + 'js/contrib/jquery.eventdelegation.js', + 'js/contrib/jquery.scrollto.js', + 'js/contrib/jquery.highlightfade.js', + 'js/book_text/other.js', + 'js/book.js', + + 'js/contrib/raphael-min.js', + 'js/contrib/progressSpin.min.js', + 'js/picture.js', + ], + 'output_filename': 'js/book.min.js', + }, + 'book_text': { + 'source_filenames': [ + 'js/contrib/jquery.form.js', + 'js/contrib/jquery.jqmodal.js', + 'js/book_text/*.js', + 'js/locale.js', + 'js/dialogs.js', + + 'js/contrib/jquery.highlightfade.js', + 'js/contrib/raphael-min.js', + 'player/openplayer.js', + 'js/contrib/progressSpin.min.js', + 'js/picture.js', + ], + 'output_filename': 'js/book_text.js', + }, + 'book_ie': { + 'source_filenames': ('js/contrib/ierange-m2.js',), + 'output_filename': 'js/book_ie.min.js', + }, + 'widget': { + 'source_filenames': ( + 'js/contrib/jquery.js', + 'js/contrib/jquery-ui-1.8.16.custom.min.js', + 'js/search.js', + 'js/widget_run.js', ), - 'output_filename': 'js/base.min.js', - }, - 'player': { - 'source_filenames': [ - 'jplayer/jquery.jplayer.min.js', - 'jplayer/jplayer.playlist.min.js', - 'player/player.js', - ], - 'output_filename': 'js/player.min.js', - }, - 'book': { - 'source_filenames': [ - 'js/contrib/jquery.eventdelegation.js', - 'js/contrib/jquery.scrollto.js', - 'js/contrib/jquery.highlightfade.js', - 'js/book_text/other.js', - 'js/book.js', - - 'js/contrib/raphael-min.js', - 'js/contrib/progressSpin.min.js', - 'js/picture.js', - ], - 'output_filename': 'js/book.min.js', - }, - 'book_text': { - 'source_filenames': [ - 'js/contrib/jquery.form.js', - 'js/contrib/jquery.jqmodal.js', - 'js/book_text/*.js', - 'js/locale.js', - 'js/dialogs.js', - - 'js/contrib/jquery.highlightfade.js', - 'js/contrib/raphael-min.js', - 'player/openplayer.js', - 'js/contrib/progressSpin.min.js', - 'js/picture.js', - ], - 'output_filename': 'js/book_text.js', - }, - 'book_ie': { - 'source_filenames': ('js/contrib/ierange-m2.js',), - 'output_filename': 'js/book_ie.min.js', - }, - 'widget': { - 'source_filenames': ( - 'js/contrib/jquery.js', - 'js/contrib/jquery-ui-1.8.16.custom.min.js', - 'js/search.js', - 'js/widget_run.js', - ), - 'output_filename': 'js/widget.min.js', - }, + 'output_filename': 'js/widget.min.js', + }, }, 'CSS_COMPRESSOR': None, 'JS_COMPRESSOR': 'pipeline.compressors.jsmin.JSMinCompressor', @@ -164,14 +168,14 @@ PIPELINE = { # but they have some serious problems, like: # https://github.com/Kronuz/pyScss/issues/166 (empty list syntax) # https://github.com/Kronuz/pyScss/issues/258 (bad @media order) - #'pyscss_compiler.PySCSSCompiler', + # 'pyscss_compiler.PySCSSCompiler', ) } -#~ STATICFILES_STORAGE = 'fnpdjango.utils.pipeline_storage.GzipPipelineCachedStorage' +# STATICFILES_STORAGE = 'fnpdjango.utils.pipeline_storage.GzipPipelineCachedStorage' -#PIPELINE_PYSCSS_BINARY = '/usr/bin/env pyscss' -#PIPELINE_PYSCSS_ARGUMENTS = '' +# PIPELINE_PYSCSS_BINARY = '/usr/bin/env pyscss' +# PIPELINE_PYSCSS_ARGUMENTS = '' STATICFILES_FINDERS = [ diff --git a/src/wolnelektury/templatetags/switch_tag.py b/src/wolnelektury/templatetags/switch_tag.py index 72476bef0..ca6782384 100644 --- a/src/wolnelektury/templatetags/switch_tag.py +++ b/src/wolnelektury/templatetags/switch_tag.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # Source: http://djangosnippets.org/snippets/967/ # Author: adurdin # Posted: August 13, 2008 @@ -58,6 +59,7 @@ def do_switch(parser, token): # of Parser.parse() relating to the "parse_until" argument. def __init__(self, *names): self.names = set(names) + def __contains__(self, token_contents): name = token_contents.split()[0] return name in self.names @@ -94,6 +96,7 @@ def do_switch(parser, token): return SwitchNode(variable, cases) + class SwitchNode(Node): def __init__(self, variable, cases): self.variable = variable @@ -122,6 +125,7 @@ class SwitchNode(Node): except VariableDoesNotExist: no_value = True value_missing = None + value = None for tests, nodelist in self.cases: if tests is None: diff --git a/src/wolnelektury/urls.py b/src/wolnelektury/urls.py index 58e45ddb2..392af9110 100644 --- a/src/wolnelektury/urls.py +++ b/src/wolnelektury/urls.py @@ -9,7 +9,8 @@ from django.views.generic import RedirectView import wolnelektury.views -urlpatterns = patterns('wolnelektury.views', +urlpatterns = patterns( + 'wolnelektury.views', url(r'^$', 'main_page', name='main_page'), url(r'^planowane/$', 'publish_plan', name='publish_plan'), url(r'^widget\.html$', 'widget', name='widget'), @@ -29,7 +30,8 @@ urlpatterns = patterns('wolnelektury.views', name='latest_blog_posts'), ) -urlpatterns += patterns('', +urlpatterns += patterns( + '', url(r'^katalog/', include('catalogue.urls')), url(r'^opds/', include('opds.urls')), url(r'^sugestia/', include('suggest.urls')), @@ -67,7 +69,8 @@ urlpatterns += patterns('', url(r'^i18n/', include('django.conf.urls.i18n')), ) -urlpatterns += patterns('', +urlpatterns += patterns( + '', # old static pages - redirected url(r'^1procent/$', RedirectView.as_view( url='http://nowoczesnapolska.org.pl/wesprzyj_nas/', permanent=True)), diff --git a/src/wolnelektury/utils.py b/src/wolnelektury/utils.py index 0c256e5df..e8aa7fb27 100644 --- a/src/wolnelektury/utils.py +++ b/src/wolnelektury/utils.py @@ -2,16 +2,24 @@ # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # +import os import pytz from django.utils import timezone from django.conf import settings tz = pytz.timezone(settings.TIME_ZONE) + def localtime_to_utc(localtime): return timezone.utc.normalize( tz.localize(localtime) ) + def utc_for_js(dt): return dt.strftime('%Y/%m/%d %H:%M:%S UTC') + + +def makedirs(path): + if not os.path.isdir(path): + os.makedirs(path) diff --git a/src/wolnelektury/views.py b/src/wolnelektury/views.py index 0ff2d67fe..49f7b240a 100644 --- a/src/wolnelektury/views.py +++ b/src/wolnelektury/views.py @@ -43,7 +43,7 @@ def main_page(request): continue ctx['theme_fragment'] = tf[0] for f in tf: - if not f.book in ctx['theme_books']: + if f.book not in ctx['theme_books']: ctx['theme_books'].append(f.book) if len(ctx['theme_books']) == 3: break @@ -70,9 +70,9 @@ class LoginFormView(AjaxableFormView): def __call__(self, request): if request.user.is_authenticated(): - return self.redirect_or_refresh(request, '/', - message=_('Already logged in as user %(user)s', ) % - {'user': request.user.username}) + return self.redirect_or_refresh( + request, '/', + message=_('Already logged in as user %(user)s', ) % {'user': request.user.username}) return super(LoginFormView, self).__call__(request) def success(self, form, request): @@ -91,9 +91,9 @@ class RegisterFormView(AjaxableFormView): def __call__(self, request): if request.user.is_authenticated(): - return self.redirect_or_refresh(request, '/', - message=_('Already logged in as user %(user)s', ) % - {'user': request.user.username}) + return self.redirect_or_refresh( + request, '/', + message=_('Already logged in as user %(user)s', ) % {'user': request.user.username}) return super(RegisterFormView, self).__call__(request) def success(self, form, request): -- 2.20.1 From bd7c594f3a8ff0576db90c88b71fc818c6b9d0e8 Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Tue, 12 Jan 2016 12:29:40 +0100 Subject: [PATCH 09/16] librarian changed --- lib/librarian | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/librarian b/lib/librarian index 28d85f129..12b5230d8 160000 --- a/lib/librarian +++ b/lib/librarian @@ -1 +1 @@ -Subproject commit 28d85f12957a4b8609b4f419e70dd42a22b57765 +Subproject commit 12b5230d8fdb3ad995e867fb5d58a69e8a627e68 -- 2.20.1 From b457762bcb1a77156da94822fe4eb6d2273a24b9 Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Tue, 12 Jan 2016 12:43:54 +0100 Subject: [PATCH 10/16] PyCharm dir in .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index fd63a8e47..0be95eebc 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,9 @@ thumbs.db .pydevproject .tmp_* +# PyCharm +.idea + # Tags file TAGS -- 2.20.1 From 3f24386508e4c86c6623fe7b0146a2dcbe7df4ef Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Tue, 12 Jan 2016 12:45:15 +0100 Subject: [PATCH 11/16] pipeline bug --- src/wolnelektury/settings/static.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wolnelektury/settings/static.py b/src/wolnelektury/settings/static.py index 80bd9ea14..052a6ff8e 100644 --- a/src/wolnelektury/settings/static.py +++ b/src/wolnelektury/settings/static.py @@ -172,7 +172,7 @@ PIPELINE = { ) } -# STATICFILES_STORAGE = 'fnpdjango.utils.pipeline_storage.GzipPipelineCachedStorage' +STATICFILES_STORAGE = 'fnpdjango.utils.pipeline_storage.GzipPipelineCachedStorage' # PIPELINE_PYSCSS_BINARY = '/usr/bin/env pyscss' # PIPELINE_PYSCSS_ARGUMENTS = '' -- 2.20.1 From 50840b4a75a3ffc806c462b6b9fb4f05303523b3 Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Tue, 12 Jan 2016 15:09:10 +0100 Subject: [PATCH 12/16] audiobooks: no prev/next buttons when only one part --- src/catalogue/templates/catalogue/book_short.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/catalogue/templates/catalogue/book_short.html b/src/catalogue/templates/catalogue/book_short.html index a2b0a5c41..712609552 100644 --- a/src/catalogue/templates/catalogue/book_short.html +++ b/src/catalogue/templates/catalogue/book_short.html @@ -187,9 +187,13 @@
            -« {% trans "previous" %} +{% if audiobooks|length > 1 %} + « {% trans "previous" %} +{% endif %} {% trans "Part" %} 1 / {{ audiobooks|length }} -{% trans "next" %} » +{% if audiobooks|length > 1 %} + {% trans "next" %} » +{% endif %}
            -- 2.20.1 From af17a2c1c05c588407875590a1cd7f82ac360cba Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Tue, 12 Jan 2016 15:57:34 +0100 Subject: [PATCH 13/16] audiobooks: no "Part 1 / 1" --- src/catalogue/templates/catalogue/book_short.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/catalogue/templates/catalogue/book_short.html b/src/catalogue/templates/catalogue/book_short.html index 712609552..dea797bc9 100644 --- a/src/catalogue/templates/catalogue/book_short.html +++ b/src/catalogue/templates/catalogue/book_short.html @@ -189,9 +189,7 @@
            {% if audiobooks|length > 1 %} « {% trans "previous" %} -{% endif %} -{% trans "Part" %} 1 / {{ audiobooks|length }} -{% if audiobooks|length > 1 %} + {% trans "Part" %} 1 / {{ audiobooks|length }} {% trans "next" %} » {% endif %}
            -- 2.20.1 From 2e37735013cf9e1f806851ac82a1f517a597298e Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Thu, 14 Jan 2016 12:35:04 +0100 Subject: [PATCH 14/16] mutagen 1.31 required --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index b466c0eab..75310d000 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -28,7 +28,7 @@ python-fb Feedparser>=5.1 Pillow -mutagen>=1.17 +mutagen>=1.31 sorl-thumbnail>=12.3,<12.4 # home-brewed & dependencies -- 2.20.1 From 8c25acecf3298262cd4b59ca0c9d3b7c35f50167 Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Thu, 14 Jan 2016 13:49:00 +0100 Subject: [PATCH 15/16] pipeline fix --- src/wolnelektury/settings/static.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wolnelektury/settings/static.py b/src/wolnelektury/settings/static.py index 052a6ff8e..80bd9ea14 100644 --- a/src/wolnelektury/settings/static.py +++ b/src/wolnelektury/settings/static.py @@ -172,7 +172,7 @@ PIPELINE = { ) } -STATICFILES_STORAGE = 'fnpdjango.utils.pipeline_storage.GzipPipelineCachedStorage' +# STATICFILES_STORAGE = 'fnpdjango.utils.pipeline_storage.GzipPipelineCachedStorage' # PIPELINE_PYSCSS_BINARY = '/usr/bin/env pyscss' # PIPELINE_PYSCSS_ARGUMENTS = '' -- 2.20.1 From 983376c58dc611ffdb6789f35ab86950af2e71d1 Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Tue, 19 Jan 2016 12:14:00 +0100 Subject: [PATCH 16/16] =?utf8?q?fix=20#3658=20Dane=20ksi=C4=85=C5=BCki=20n?= =?utf8?q?achodz=C4=85=20na=20ramk=C4=99=20odtwarzacza?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../static/jplayer/jplayer.blue.monday.css | 263 +++++++++--------- .../templates/catalogue/book_short.html | 146 +++------- .../templates/catalogue/book_wide.html | 31 ++- .../templates/catalogue/snippets/jplayer.html | 59 ++++ .../catalogue/snippets/like_button.html | 14 + .../static/scss/main/book_box.scss | 26 +- 6 files changed, 279 insertions(+), 260 deletions(-) create mode 100644 src/catalogue/templates/catalogue/snippets/jplayer.html create mode 100644 src/catalogue/templates/catalogue/snippets/like_button.html diff --git a/src/catalogue/static/jplayer/jplayer.blue.monday.css b/src/catalogue/static/jplayer/jplayer.blue.monday.css index d1214c554..8d309941e 100644 --- a/src/catalogue/static/jplayer/jplayer.blue.monday.css +++ b/src/catalogue/static/jplayer/jplayer.blue.monday.css @@ -14,15 +14,15 @@ * Date: 1st September 2011 */ +.jp-type-single { + padding: 5px 10px 0 10px; +} .jp-audio .title { - font-size: 11px; - position: relative; - left: 10px; - top: 5px; - z-index: 100; + font-size: 11px; + z-index: 100; } .play-prev, .play-next { - cursor: pointer; + cursor: pointer; } div.jp-audio, @@ -84,7 +84,8 @@ div.jp-video-full div.jp-interface { div.jp-interface { position: relative; - background-color:#eee; + margin-top: -5px; + margin-left: -10px; width:100%; } @@ -117,28 +118,28 @@ div.jp-controls-holder { div.jp-interface ul.jp-controls { list-style-type:none; margin:0; - padding: 0; - overflow:hidden; -} - -div.jp-audio ul.jp-controls { + padding: 0; + overflow:hidden; +} + +div.jp-audio ul.jp-controls { width: 320px; padding:20px 20px 0 20px; -} - -div.jp-video div.jp-type-single ul.jp-controls { +} + +div.jp-video div.jp-type-single ul.jp-controls { width: 78px; margin-left: 200px; -} - -div.jp-video div.jp-type-playlist ul.jp-controls { +} + +div.jp-video div.jp-type-playlist ul.jp-controls { width: 134px; margin-left: 172px; -} +} div.jp-video ul.jp-controls, div.jp-interface ul.jp-controls li { - display:inline; - float: left; + display:inline; + float: left; } div.jp-interface ul.jp-controls a { @@ -165,29 +166,29 @@ a.jp-pause { a.jp-pause:hover { background: url("/static/jplayer/jplayer.blue.monday.jpg") -41px -42px no-repeat; } - + a.jp-stop, a.jp-previous, a.jp-next { width:28px; - height:28px; + height:28px; margin-top:6px; } - + a.jp-stop { background: url("/static/jplayer/jplayer.blue.monday.jpg") 0 -83px no-repeat; - margin-left:10px; -} + margin-left:10px; +} a.jp-stop:hover { background: url("/static/jplayer/jplayer.blue.monday.jpg") -29px -83px no-repeat; -} +} a.jp-previous { background: url("/static/jplayer/jplayer.blue.monday.jpg") 0 -112px no-repeat; } a.jp-previous:hover { background: url("/static/jplayer/jplayer.blue.monday.jpg") -29px -112px no-repeat; -} - +} + a.jp-next { background: url("/static/jplayer/jplayer.blue.monday.jpg") 0 -141px no-repeat; } @@ -248,19 +249,19 @@ a.jp-mute, a.jp-unmute, a.jp-volume-max { width:18px; - height:15px; - margin-top:12px; -} - + height:15px; + margin-top:12px; +} + div.jp-audio div.jp-type-single a.jp-mute, -div.jp-audio div.jp-type-single a.jp-unmute { - margin-left: 180px; -} - +div.jp-audio div.jp-type-single a.jp-unmute { + margin-left: 180px; +} + div.jp-audio div.jp-type-playlist a.jp-mute, -div.jp-audio div.jp-type-playlist a.jp-unmute { +div.jp-audio div.jp-type-playlist a.jp-unmute { margin-left: 154px; -} +} div.jp-audio a.jp-volume-max { margin-left: 56px; @@ -275,10 +276,11 @@ div.jp-video a.jp-volume-max { } div.jp-video a.jp-mute, -div.jp-video a.jp-unmute { +div.jp-video a.jp-unmute { left: 50px; -} - +} + + div.jp-video a.jp-volume-max { left: 134px; } @@ -295,14 +297,15 @@ a.jp-unmute { } a.jp-unmute:hover { background: url("/static/jplayer/jplayer.blue.monday.jpg") -79px -170px no-repeat; -} - a.jp-volume-max { +} + +a.jp-volume-max { background: url("/static/jplayer/jplayer.blue.monday.jpg") 0 -186px no-repeat; } a.jp-volume-max:hover { background: url("/static/jplayer/jplayer.blue.monday.jpg") -19px -186px no-repeat; } - + div.jp-volume-bar { position: absolute; overflow:hidden; @@ -346,7 +349,7 @@ div.jp-current-time, div.jp-duration { width:60px; font-size:.64em; - font-style:oblique; + font-style:oblique; } div.jp-current-time { float: left; @@ -507,26 +510,26 @@ div.jp-jplayer { div.jp-jplayer { background-color: #000000; -} - - - - - -/* @group TOGGLES */ +} + + + + + +/* @group TOGGLES */ /* The audio toggles are nested inside jp-time-holder */ - -ul.jp-toggles { - list-style-type:none; - padding:0; + +ul.jp-toggles { + list-style-type:none; + padding:0; margin:0 auto; - overflow:hidden; -} - -div.jp-audio .jp-type-single ul.jp-toggles { - width:25px; -} + overflow:hidden; +} + +div.jp-audio .jp-type-single ul.jp-toggles { + width:25px; +} div.jp-audio .jp-type-playlist ul.jp-toggles { width:55px; margin: 0; @@ -534,78 +537,78 @@ div.jp-audio .jp-type-playlist ul.jp-toggles { left: 325px; top: 50px; } - -div.jp-video ul.jp-toggles { + +div.jp-video ul.jp-toggles { margin-top:10px; width:100px; -} - -ul.jp-toggles li { - display:block; - float:right; -} - -ul.jp-toggles li a { - display:block; - width:25px; - height:18px; +} + +ul.jp-toggles li { + display:block; + float:right; +} + +ul.jp-toggles li a { + display:block; + width:25px; + height:18px; text-indent:-9999px; - line-height:100%; /* need this for IE6 */ -} - -a.jp-full-screen { - background: url("/static/jplayer/jplayer.blue.monday.jpg") 0 -310px no-repeat; - margin-left: 20px; -} - -a.jp-full-screen:hover { - background: url("/static/jplayer/jplayer.blue.monday.jpg") -30px -310px no-repeat; -} - -a.jp-restore-screen { - background: url("/static/jplayer/jplayer.blue.monday.jpg") -60px -310px no-repeat; + line-height:100%; /* need this for IE6 */ +} + +a.jp-full-screen { + background: url("/static/jplayer/jplayer.blue.monday.jpg") 0 -310px no-repeat; + margin-left: 20px; +} + +a.jp-full-screen:hover { + background: url("/static/jplayer/jplayer.blue.monday.jpg") -30px -310px no-repeat; +} + +a.jp-restore-screen { + background: url("/static/jplayer/jplayer.blue.monday.jpg") -60px -310px no-repeat; margin-left: 20px; -} - -a.jp-restore-screen:hover { - background: url("/static/jplayer/jplayer.blue.monday.jpg") -90px -310px no-repeat; -} - -a.jp-repeat { - background: url("/static/jplayer/jplayer.blue.monday.jpg") 0 -290px no-repeat; -} - -a.jp-repeat:hover { - background: url("/static/jplayer/jplayer.blue.monday.jpg") -30px -290px no-repeat; -} - -a.jp-repeat-off { - background: url("/static/jplayer/jplayer.blue.monday.jpg") -60px -290px no-repeat; -} - -a.jp-repeat-off:hover { - background: url("/static/jplayer/jplayer.blue.monday.jpg") -90px -290px no-repeat; -} - -a.jp-shuffle { - background: url("/static/jplayer/jplayer.blue.monday.jpg") 0 -270px no-repeat; - margin-left: 5px; -} - -a.jp-shuffle:hover { - background: url("/static/jplayer/jplayer.blue.monday.jpg") -30px -270px no-repeat; -} - -a.jp-shuffle-off { - background: url("/static/jplayer/jplayer.blue.monday.jpg") -60px -270px no-repeat; +} + +a.jp-restore-screen:hover { + background: url("/static/jplayer/jplayer.blue.monday.jpg") -90px -310px no-repeat; +} + +a.jp-repeat { + background: url("/static/jplayer/jplayer.blue.monday.jpg") 0 -290px no-repeat; +} + +a.jp-repeat:hover { + background: url("/static/jplayer/jplayer.blue.monday.jpg") -30px -290px no-repeat; +} + +a.jp-repeat-off { + background: url("/static/jplayer/jplayer.blue.monday.jpg") -60px -290px no-repeat; +} + +a.jp-repeat-off:hover { + background: url("/static/jplayer/jplayer.blue.monday.jpg") -90px -290px no-repeat; +} + +a.jp-shuffle { + background: url("/static/jplayer/jplayer.blue.monday.jpg") 0 -270px no-repeat; margin-left: 5px; -} - -a.jp-shuffle-off:hover { - background: url("/static/jplayer/jplayer.blue.monday.jpg") -90px -270px no-repeat; -} - - +} + +a.jp-shuffle:hover { + background: url("/static/jplayer/jplayer.blue.monday.jpg") -30px -270px no-repeat; +} + +a.jp-shuffle-off { + background: url("/static/jplayer/jplayer.blue.monday.jpg") -60px -270px no-repeat; + margin-left: 5px; +} + +a.jp-shuffle-off:hover { + background: url("/static/jplayer/jplayer.blue.monday.jpg") -90px -270px no-repeat; +} + + /* @end */ /* @group NO SOLUTION error feedback */ diff --git a/src/catalogue/templates/catalogue/book_short.html b/src/catalogue/templates/catalogue/book_short.html index dea797bc9..af4dc82f2 100644 --- a/src/catalogue/templates/catalogue/book_short.html +++ b/src/catalogue/templates/catalogue/book_short.html @@ -1,50 +1,40 @@ {% spaceless %} {% load i18n %} -{% load catalogue_tags ssify %} -{% load likes_book book_shelf_tags from social_tags %} -
            +{% load catalogue_tags %} +{% load book_shelf_tags from social_tags %} +
            -
            - - +{% block book-box-pre %} + {% include "catalogue/snippets/like_button.html" %} +{% endblock %} -
            +
            +
            + {% block book-box-body-pre %} + {% endblock %} - {% likes_book book.pk as likes %} -
            -
            - ★ -
            -
            -
            - {% ssi_csrf_token %} - -
            +
            +
            + {% for tag in tags.author %} + {{ tag.name }}{% if not forloop.last %}, + {% endif %}{% endfor %}{% for parent in parents %}, + {{ parent.title }}{% endfor %} +
            +
            + {% if main_link %}{% endif %}{{ book.title }}{% if main_link %}{% endif %} +
            -
            -
            -
            - {% for tag in tags.author %} - {{ tag.name }}{% if not forloop.last %}, - {% endif %}{% endfor %}{% for parent in parents %}, - {{ parent.title }}{% endfor %} -
            -
            - {% if main_link %}{% endif %}{{ book.title }}{% if main_link %}{% endif %} +
            + {% if book.cover_thumb %} + {% if main_link %}{% endif %} + Cover + {% if main_link %}{% endif %} + {% endif %} + {% block cover-area-extra %}{% endblock %}
            -
            - -
            - {% if book.cover_thumb %} - {% if main_link %}{% endif %} - Cover - {% if main_link %}{% endif %} - {% endif %} - {% block cover-area-extra %}{% endblock %} -
            {% spaceless %} @@ -118,88 +108,22 @@ {% endif %} {% download_audio book %}
            - - {% block book-box-extra-info %}{% endblock %} {% block box-append %} {% endblock %} -
            - - - - - - - {% block right-column %} - {% endblock %} - - -{% if audiobooks %} - - - -{% endif %} +{% block right-column %} + {% if audiobooks %} +
            + {% include 'catalogue/snippets/jplayer.html' %} +
            + {% endif %} +{% endblock %} -
            +
            {% endspaceless %} diff --git a/src/catalogue/templates/catalogue/book_wide.html b/src/catalogue/templates/catalogue/book_wide.html index 4d5617566..26ee55d71 100644 --- a/src/catalogue/templates/catalogue/book_wide.html +++ b/src/catalogue/templates/catalogue/book_wide.html @@ -10,26 +10,31 @@ {% block cover-area-extra %} {% if extra_info.license %} - {% license_icon extra_info.license %} + {% license_icon extra_info.license %} {% endif %} {% endblock %} - - - {% block right-column %} -
            -
            - {% choose_cite book.pk as cite_promo %} - {% choose_fragment book.pk unless=cite_promo as fragment_promo %} - {{ cite_promo.if }} +
            +
            + {% 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 }} + {{ cite_promo.endif }} + {{ fragment_promo.if }} {% ssi_include 'catalogue_fragment_promo' pk=fragment_promo %} - {{ fragment_promo.endif }} + {{ fragment_promo.endif }} +
            + {% include 'catalogue/snippets/jplayer.html' %}
            +{% endblock %} + + +{% block book-box-body-pre %} + {% include "catalogue/snippets/like_button.html" %} +{% endblock %} -
            +{% block book-box-pre %} {% endblock %} diff --git a/src/catalogue/templates/catalogue/snippets/jplayer.html b/src/catalogue/templates/catalogue/snippets/jplayer.html new file mode 100644 index 000000000..dd8ab83ac --- /dev/null +++ b/src/catalogue/templates/catalogue/snippets/jplayer.html @@ -0,0 +1,59 @@ +{% load i18n %} +{% if audiobooks %} + +{% endif %} diff --git a/src/catalogue/templates/catalogue/snippets/like_button.html b/src/catalogue/templates/catalogue/snippets/like_button.html new file mode 100644 index 000000000..aa6969cd6 --- /dev/null +++ b/src/catalogue/templates/catalogue/snippets/like_button.html @@ -0,0 +1,14 @@ +{% load ssify %} +{% load likes_book from social_tags %} +{% likes_book book.pk as likes %} +
            +
            + ★ +
            +
            +
            + {% ssi_csrf_token %} + +
            +
            +
            diff --git a/src/wolnelektury/static/scss/main/book_box.scss b/src/wolnelektury/static/scss/main/book_box.scss index 1674a29b7..d4f1d20d1 100755 --- a/src/wolnelektury/static/scss/main/book_box.scss +++ b/src/wolnelektury/static/scss/main/book_box.scss @@ -119,18 +119,31 @@ @include inner-box; @include size(min-height, 197.5px); } +} + + +.audiobook-box { + .book-left-column { + @media screen and (min-width: 1024px) { + display: inline-block; + @include size(width, 590px); + } + } + + .right-column { + @media screen and (min-width: 1024px) { + @include size(width, 360px); + } + } .jp-type-playlist { margin-top: 24px; @media screen and (min-width: 1024px) { - position: absolute; - margin-top: 0; - right: 20px; - top: 60px; + float: right; + margin-top: 48px; } } - } @@ -249,9 +262,11 @@ .jp-type-playlist { margin-top: 24px; + margin-left: 0.625rem; @media screen and (min-width: 1024px) { float: right; + margin-right: 0.625rem; } } @@ -322,7 +337,6 @@ margin-bottom: 5px; @include min-screen($S_BOOK_SHORT_FULL) { - clear: right; @include size(max-height, 57.6px); overflow: hidden; } -- 2.20.1