From: Radek Czajka Date: Wed, 26 Mar 2014 15:32:58 +0000 (+0100) Subject: Merge with master. X-Git-Url: https://git.mdrn.pl/redakcja.git/commitdiff_plain/ec5b493bff5efa683aadf5f78aa891eff3550156 Merge with master. --- ec5b493bff5efa683aadf5f78aa891eff3550156 diff --cc apps/catalogue/admin.py index 8ba803e7,7fbacad9..53e8a256 --- a/apps/catalogue/admin.py +++ b/apps/catalogue/admin.py @@@ -7,9 -9,8 +9,10 @@@ class BookAdmin(admin.ModelAdmin) search_fields = ['title'] + admin.site.register(models.Project) admin.site.register(models.Book, BookAdmin) admin.site.register(models.Chunk) - admin.site.register(models.Chunk.tag_model) + +admin.site.register(models.Image) +admin.site.register(models.Image.tag_model) diff --cc apps/catalogue/locale/pl/LC_MESSAGES/django.mo index d933b5a9,b6a12e32..64f78b46 Binary files differ diff --cc apps/catalogue/locale/pl/LC_MESSAGES/django.po index 99241c46,6790400c..d98440f3 --- a/apps/catalogue/locale/pl/LC_MESSAGES/django.po +++ b/apps/catalogue/locale/pl/LC_MESSAGES/django.po @@@ -7,10 -7,11 +7,11 @@@ msgid " msgstr "" "Project-Id-Version: Platforma Redakcyjna\n" "Report-Msgid-Bugs-To: \n" - "POT-Creation-Date: 2011-12-21 12:44+0100\n" - "PO-Revision-Date: 2011-12-21 12:45+0100\n" -"POT-Creation-Date: 2013-07-16 13:22+0200\n" -"PO-Revision-Date: 2013-07-16 13:22+0100\n" ++"POT-Creation-Date: 2014-03-26 16:13+0100\n" ++"PO-Revision-Date: 2014-03-26 16:14+0100\n" "Last-Translator: Radek Czajka \n" - "Language-Team: Fundacja Nowoczesna Polska \n" + "Language-Team: Fundacja Nowoczesna Polska \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@@ -33,8 -36,7 +36,7 @@@ msgstr "Plik ZIP msgid "Directories are documents in chunks" msgstr "Katalogi zawierają dokumenty w częściach" --#: forms.py:76 - #: forms.py:164 ++#: forms.py:76 forms.py:165 msgid "Assigned to" msgstr "Przypisane do" @@@ -47,33 -48,36 +48,36 @@@ msgstr "Część z tym slugiem już ist msgid "Append to" msgstr "Dołącz do" - #: views.py:165 -#: views.py:160 ++#: views.py:166 #, python-format msgid "Slug already used for %s" msgstr "Slug taki sam jak dla pliku %s" - #: views.py:167 -#: views.py:162 ++#: views.py:168 msgid "Slug already used in repository." msgstr "Dokument o tym slugu już istnieje w repozytorium." - #: views.py:173 -#: views.py:168 ++#: views.py:174 msgid "File should be UTF-8 encoded." msgstr "Plik powinien mieć kodowanie UTF-8." - #: models/book.py:21 - #: models/chunk.py:23 - #: models/image.py:21 -#: views.py:498 models/book.py:56 ++#: views.py:552 models/book.py:56 + msgid "books" + msgstr "książki" + -#: views.py:500 ++#: views.py:554 + msgid "scan gallery" + msgstr "galeria skanów" + -#: models/book.py:28 models/chunk.py:23 ++#: models/book.py:28 models/chunk.py:23 models/image.py:21 msgid "title" msgstr "tytuł" - #: models/book.py:22 - #: models/chunk.py:24 - #: models/image.py:22 -#: models/book.py:29 models/chunk.py:24 ++#: models/book.py:29 models/chunk.py:24 models/image.py:22 msgid "slug" msgstr "slug" - #: models/book.py:23 - #: models/image.py:23 -#: models/book.py:30 ++#: models/book.py:30 models/image.py:23 msgid "public" msgstr "publiczna" @@@ -107,23 -105,19 +105,19 @@@ msgstr "Książka nie ma części. msgid "Not all chunks have publishable revisions." msgstr "Niektóre części nie są gotowe do publikacji." - #: models/book.py:233 - #: models/image.py:80 -#: models/book.py:266 ++#: models/book.py:266 models/image.py:80 msgid "Invalid XML" msgstr "Nieprawidłowy XML" - #: models/book.py:235 - #: models/image.py:82 -#: models/book.py:268 ++#: models/book.py:268 models/image.py:82 msgid "No Dublin Core found." msgstr "Brak sekcji Dublin Core." - #: models/book.py:237 - #: models/image.py:84 -#: models/book.py:270 ++#: models/book.py:270 models/image.py:84 msgid "Invalid Dublin Core" msgstr "Nieprawidłowy Dublin Core" - #: models/book.py:240 - #: models/image.py:88 -#: models/book.py:273 ++#: models/book.py:273 models/image.py:88 msgid "rdf:about is not" msgstr "rdf:about jest różny od" @@@ -143,28 -137,27 +137,40 @@@ msgstr "część msgid "chunks" msgstr "części" - #: models/image.py:20 - #: models/image.py:34 - #: models/publish_log.py:45 ++#: models/image.py:20 models/image.py:34 models/publish_log.py:45 +msgid "image" +msgstr "obraz" + +#: models/image.py:35 +msgid "images" +msgstr "obrazy" + +#: models/image.py:73 +msgid "There is no publishable revision" +msgstr "Żadna wersja nie została oznaczona do publikacji." + - #: models/publish_log.py:18 - #: models/publish_log.py:46 + #: models/project.py:13 + msgid "name" + msgstr "nazwa" + + #: models/project.py:14 + msgid "notes" + msgstr "notatki" + -#: models/project.py:19 templates/catalogue/book_list/book_list.html:62 ++#: models/project.py:19 templates/catalogue/book_list/book_list.html:64 + msgid "project" + msgstr "projekt" + + #: models/project.py:20 + msgid "projects" + msgstr "projekty" + -#: models/publish_log.py:18 ++#: models/publish_log.py:18 models/publish_log.py:46 msgid "time" msgstr "czas" - #: models/publish_log.py:19 - #: models/publish_log.py:47 - #: templates/catalogue/wall.html:18 -#: models/publish_log.py:19 templates/catalogue/wall.html:18 ++#: models/publish_log.py:19 models/publish_log.py:47 ++#: templates/catalogue/wall.html:19 msgid "user" msgstr "użytkownik" @@@ -177,8 -169,7 +182,7 @@@ msgstr "zapis publikacji książki msgid "book publish records" msgstr "zapisy publikacji książek" --#: models/publish_log.py:34 - #: models/publish_log.py:48 ++#: models/publish_log.py:34 models/publish_log.py:48 msgid "change" msgstr "zmiana" @@@ -190,16 -181,7 +194,16 @@@ msgstr "zapis publikacji części msgid "chunk publish records" msgstr "zapisy publikacji części" -#: templates/catalogue/activity.html:9 templatetags/catalogue.py:29 +#: models/publish_log.py:53 +msgid "image publish record" +msgstr "zapis publikacji obrazu" + +#: models/publish_log.py:54 +msgid "image publish records" +msgstr "zapisy publikacji obrazów" + - #: templates/catalogue/activity.html:10 ++#: templates/catalogue/activity.html:6 templates/catalogue/activity.html:12 +#: templatetags/catalogue.py:29 msgid "Activity" msgstr "Aktywność" @@@ -207,248 -189,210 +211,282 @@@ msgid "Platforma Redakcyjna" msgstr "Platforma Redakcyjna" --#: templates/catalogue/book_append_to.html:9 ++#: templates/catalogue/book_append_to.html:4 ++#: templates/catalogue/book_append_to.html:11 msgid "Append book" msgstr "Dołącz książkę" --#: templates/catalogue/book_detail.html:14 - #: templates/catalogue/book_edit.html:9 - #: templates/catalogue/chunk_edit.html:13 - #: templates/catalogue/image_detail.html:14 -#: templates/catalogue/book_edit.html:9 templates/catalogue/chunk_edit.html:12 ++#: templates/catalogue/book_detail.html:18 ++#: templates/catalogue/book_edit.html:13 ++#: templates/catalogue/chunk_edit.html:16 ++#: templates/catalogue/image_detail.html:18 msgid "Save" msgstr "Zapisz" --#: templates/catalogue/book_detail.html:21 ++#: templates/catalogue/book_detail.html:25 + msgid "Edit gallery" + msgstr "Edytuj galerię" + -#: templates/catalogue/book_detail.html:24 ++#: templates/catalogue/book_detail.html:28 msgid "Append to other book" msgstr "Dołącz do innej książki" - #: templates/catalogue/book_detail.html:27 -#: templates/catalogue/book_detail.html:30 ++#: templates/catalogue/book_detail.html:34 msgid "Chunks" msgstr "Części" - #: templates/catalogue/book_detail.html:42 - #: templates/catalogue/image_detail.html:32 - #: templatetags/wall.py:78 -#: templates/catalogue/book_detail.html:45 templatetags/wall.py:78 ++#: templates/catalogue/book_detail.html:49 ++#: templates/catalogue/image_detail.html:36 templatetags/wall.py:78 msgid "Publication" msgstr "Publikacja" - #: templates/catalogue/book_detail.html:44 - #: templates/catalogue/image_detail.html:34 -#: templates/catalogue/book_detail.html:54 ++#: templates/catalogue/book_detail.html:58 ++#: templates/catalogue/image_detail.html:38 msgid "Last published" msgstr "Ostatnio opublikowano" - #: templates/catalogue/book_detail.html:54 -#: templates/catalogue/book_detail.html:64 ++#: templates/catalogue/book_detail.html:68 msgid "Full XML" msgstr "Pełny XML" - #: templates/catalogue/book_detail.html:55 -#: templates/catalogue/book_detail.html:65 ++#: templates/catalogue/book_detail.html:69 msgid "HTML version" msgstr "Wersja HTML" - #: templates/catalogue/book_detail.html:56 -#: templates/catalogue/book_detail.html:66 ++#: templates/catalogue/book_detail.html:70 msgid "TXT version" msgstr "Wersja TXT" - #: templates/catalogue/book_detail.html:57 -#: templates/catalogue/book_detail.html:67 ++#: templates/catalogue/book_detail.html:71 msgid "PDF version" msgstr "Wersja PDF" - #: templates/catalogue/book_detail.html:58 -#: templates/catalogue/book_detail.html:68 ++#: templates/catalogue/book_detail.html:72 msgid "EPUB version" msgstr "Wersja EPUB" - #: templates/catalogue/book_detail.html:71 - #: templates/catalogue/image_detail.html:53 -#: templates/catalogue/book_detail.html:81 ++#: templates/catalogue/book_detail.html:85 ++#: templates/catalogue/image_detail.html:57 msgid "Publish" msgstr "Opublikuj" - #: templates/catalogue/book_detail.html:75 - #: templates/catalogue/image_detail.html:57 -#: templates/catalogue/book_detail.html:85 ++#: templates/catalogue/book_detail.html:89 ++#: templates/catalogue/image_detail.html:61 msgid "Log in to publish." msgstr "Zaloguj się, aby opublikować." - #: templates/catalogue/book_detail.html:78 - #: templates/catalogue/image_detail.html:60 -#: templates/catalogue/book_detail.html:88 ++#: templates/catalogue/book_detail.html:92 ++#: templates/catalogue/image_detail.html:64 msgid "This book can't be published yet, because:" msgstr "Ta książka nie może jeszcze zostać opublikowana. Powód:" - #: templates/catalogue/book_detail.html:87 - #: templates/catalogue/image_detail.html:68 -#: templates/catalogue/book_detail.html:98 ++#: templates/catalogue/book_detail.html:102 ++#: templates/catalogue/image_detail.html:72 msgid "Comments" msgstr "Komentarze" - #: templates/catalogue/book_html.html:13 -#: templates/catalogue/book_text.html:7 -msgid "Redakcja" -msgstr "" ++#: templates/catalogue/book_edit.html:5 ++msgid "Edit book" ++msgstr "Edytuj książkę" + -#: templates/catalogue/book_text.html:15 ++#: templates/catalogue/book_html.html:13 templates/catalogue/book_text.html:15 msgid "Table of contents" msgstr "Spis treści" - #: templates/catalogue/book_html.html:14 -#: templates/catalogue/book_text.html:17 ++#: templates/catalogue/book_html.html:14 templates/catalogue/book_text.html:17 msgid "Edit. note" msgstr "Nota red." -#: templates/catalogue/chunk_add.html:5 templates/catalogue/chunk_edit.html:18 +#: templates/catalogue/book_html.html:15 +msgid "Infobox" +msgstr "Informacje" + - #: templates/catalogue/chunk_add.html:5 - #: templates/catalogue/chunk_edit.html:19 ++#: templates/catalogue/book_text.html:7 ++msgid "Redakcja" ++msgstr "" ++ ++#: templates/catalogue/chunk_add.html:5 templates/catalogue/chunk_add.html:9 ++#: templates/catalogue/chunk_edit.html:22 msgid "Split chunk" msgstr "Podziel część" --#: templates/catalogue/chunk_add.html:10 ++#: templates/catalogue/chunk_add.html:14 msgid "Insert empty chunk after" msgstr "Wstaw pustą część po" --#: templates/catalogue/chunk_add.html:13 ++#: templates/catalogue/chunk_add.html:17 msgid "Add chunk" msgstr "Dodaj część" - #: templates/catalogue/chunk_edit.html:6 - #: templates/catalogue/book_list/book.html:7 - #: templates/catalogue/book_list/chunk.html:5 -#: templates/catalogue/chunk_edit.html:5 ++#: templates/catalogue/chunk_edit.html:5 templates/catalogue/chunk_edit.html:9 + #: templates/catalogue/book_list/book.html:8 + #: templates/catalogue/book_list/chunk.html:6 msgid "Chunk settings" msgstr "Ustawienia części" - #: templates/catalogue/chunk_edit.html:11 -#: templates/catalogue/chunk_edit.html:10 ++#: templates/catalogue/chunk_edit.html:14 msgid "Book" msgstr "Książka" #: templates/catalogue/document_create_missing.html:5 ++#: templates/catalogue/document_create_missing.html:9 msgid "Create a new book" msgstr "Utwórz nową książkę" --#: templates/catalogue/document_create_missing.html:11 ++#: templates/catalogue/document_create_missing.html:15 msgid "Create book" msgstr "Utwórz książkę" --#: templates/catalogue/document_upload.html:8 --msgid "Bulk documents upload" ++#: templates/catalogue/document_list.html:7 ++msgid "Book list" ++msgstr "Lista książek" ++ ++#: templates/catalogue/document_upload.html:5 ++msgid "Bulk document upload" msgstr "Hurtowe dodawanie dokumentów" #: templates/catalogue/document_upload.html:11 - msgid "Please submit a ZIP with UTF-8 encoded XML files. Files not ending with .xml will be ignored." - msgstr "Proszę wskazać archiwum ZIP z plikami XML w kodowaniu UTF-8. Pliki nie kończące się na .xml zostaną zignorowane." ++msgid "Bulk documents upload" ++msgstr "Hurtowe dodawanie dokumentów" ++ ++#: templates/catalogue/document_upload.html:14 + msgid "" + "Please submit a ZIP with UTF-8 encoded XML files. Files not ending with " + ".xml will be ignored." + msgstr "" + "Proszę wskazać archiwum ZIP z plikami XML w kodowaniu UTF-8. Pliki nie " + "kończące się na .xml zostaną zignorowane." - #: templates/catalogue/document_upload.html:17 - #: templates/catalogue/upload_pdf.html:13 - #: templatetags/catalogue.py:36 -#: templates/catalogue/document_upload.html:17 templatetags/catalogue.py:35 ++#: templates/catalogue/document_upload.html:20 ++#: templates/catalogue/upload_pdf.html:16 templatetags/catalogue.py:36 msgid "Upload" msgstr "Załaduj" --#: templates/catalogue/document_upload.html:24 - msgid "There have been some errors. No files have been added to the repository." ++#: templates/catalogue/document_upload.html:27 + msgid "" + "There have been some errors. No files have been added to the repository." msgstr "Wystąpiły błędy. Żadne pliki nie zostały dodane do repozytorium." --#: templates/catalogue/document_upload.html:25 ++#: templates/catalogue/document_upload.html:28 msgid "Offending files" msgstr "Błędne pliki" --#: templates/catalogue/document_upload.html:33 ++#: templates/catalogue/document_upload.html:36 msgid "Correct files" msgstr "Poprawne pliki" --#: templates/catalogue/document_upload.html:44 ++#: templates/catalogue/document_upload.html:47 msgid "Files have been successfully uploaded to the repository." msgstr "Pliki zostały dodane do repozytorium." --#: templates/catalogue/document_upload.html:45 ++#: templates/catalogue/document_upload.html:48 msgid "Uploaded files" msgstr "Dodane pliki" --#: templates/catalogue/document_upload.html:55 ++#: templates/catalogue/document_upload.html:58 msgid "Skipped files" msgstr "Pominięte pliki" --#: templates/catalogue/document_upload.html:56 ++#: templates/catalogue/document_upload.html:59 msgid "Files skipped due to no .xml extension" msgstr "Pliki pominięte z powodu braku rozszerzenia .xml." - #: templates/catalogue/image_detail.html:22 -#: templates/catalogue/my_page.html:21 -msgid "Your last edited documents" -msgstr "Twoje ostatnie edycje" ++#: templates/catalogue/image_detail.html:26 +msgid "Editor" +msgstr "Edytor" - #: templates/catalogue/image_detail.html:24 -#: templates/catalogue/my_page.html:30 templates/catalogue/user_page.html:13 -msgid "Recent activity for" -msgstr "Ostatnia aktywność dla:" ++#: templates/catalogue/image_detail.html:28 +msgid "Proceed to the editor." +msgstr "Przejdź do edytora." -#: templates/catalogue/user_list.html:7 templatetags/catalogue.py:31 -msgid "Users" -msgstr "Użytkownicy" - -#: templates/catalogue/wall.html:28 -msgid "not logged in" -msgstr "nie zalogowany" ++#: templates/catalogue/image_list.html:7 ++msgid "Image list" ++msgstr "Lista obrazów" + -#: templates/catalogue/wall.html:33 -msgid "No activity recorded." -msgstr "Nie zanotowano aktywności." - -#: templates/catalogue/book_list/book.html:7 -#: templates/catalogue/book_list/book.html:28 -msgid "Book settings" -msgstr "Ustawienia książki" - -#: templates/catalogue/book_list/book_list.html:22 -msgid "Show hidden books" -msgstr "Pokaż ukryte książki" +#: templates/catalogue/image_short.html:4 +msgid "Image settings" +msgstr "Ustawienia obrazu" +#: templates/catalogue/image_table.html:19 - #: templates/catalogue/book_list/book_list.html:24 + #: templates/catalogue/book_list/book_list.html:27 msgid "Search in book titles" msgstr "Szukaj w tytułach książek" +#: templates/catalogue/image_table.html:24 - #: templates/catalogue/book_list/book_list.html:29 + #: templates/catalogue/book_list/book_list.html:32 msgid "stage" msgstr "etap" +#: templates/catalogue/image_table.html:26 +#: templates/catalogue/image_table.html:37 - #: templates/catalogue/book_list/book_list.html:31 - #: templates/catalogue/book_list/book_list.html:42 + #: templates/catalogue/book_list/book_list.html:34 + #: templates/catalogue/book_list/book_list.html:45 -#: templates/catalogue/book_list/book_list.html:64 ++#: templates/catalogue/book_list/book_list.html:66 msgid "none" msgstr "brak" +#: templates/catalogue/image_table.html:35 - #: templates/catalogue/book_list/book_list.html:40 + #: templates/catalogue/book_list/book_list.html:43 msgid "editor" msgstr "redaktor" -#: templates/catalogue/book_list/book_list.html:54 +#: templates/catalogue/image_table.html:46 - #: templates/catalogue/book_list/book_list.html:51 ++#: templates/catalogue/book_list/book_list.html:56 msgid "status" msgstr "status" -#: templates/catalogue/book_list/book_list.html:88 +#: templates/catalogue/image_table.html:63 +#, python-format +msgid "%(c)s image" +msgid_plural "%(c)s images" +msgstr[0] "%(c)s obraz" +msgstr[1] "%(c)s obrazy" +msgstr[2] "%(c)s obrazów" + +#: templates/catalogue/image_table.html:68 +msgid "No images found." +msgstr "Nie znaleziono obrazów." + - #: templates/catalogue/my_page.html:13 ++#: templates/catalogue/my_page.html:15 templatetags/catalogue.py:27 ++msgid "My page" ++msgstr "Moja strona" ++ ++#: templates/catalogue/my_page.html:24 +msgid "Your last edited documents" +msgstr "Twoje ostatnie edycje" + - #: templates/catalogue/my_page.html:22 - #: templates/catalogue/user_page.html:13 ++#: templates/catalogue/my_page.html:33 templates/catalogue/user_page.html:16 +msgid "Recent activity for" +msgstr "Ostatnia aktywność dla:" + - #: templates/catalogue/upload_pdf.html:8 ++#: templates/catalogue/upload_pdf.html:5 ++#: templates/catalogue/upload_pdf.html:11 +msgid "PDF file upload" - msgstr "" ++msgstr "Ładowanie pliku PDF" + - #: templates/catalogue/user_list.html:7 ++#: templates/catalogue/user_list.html:6 templates/catalogue/user_list.html:11 +#: templatetags/catalogue.py:32 +msgid "Users" +msgstr "Użytkownicy" + - #: templates/catalogue/wall.html:28 ++#: templates/catalogue/wall.html:29 +msgid "not logged in" +msgstr "nie zalogowany" + - #: templates/catalogue/wall.html:33 ++#: templates/catalogue/wall.html:34 +msgid "No activity recorded." +msgstr "Nie zanotowano aktywności." + - #: templates/catalogue/book_list/book.html:6 - #: templates/catalogue/book_list/book.html:25 ++#: templates/catalogue/book_list/book.html:7 ++#: templates/catalogue/book_list/book.html:28 +msgid "Book settings" +msgstr "Ustawienia książki" + - #: templates/catalogue/book_list/book_list.html:19 ++#: templates/catalogue/book_list/book_list.html:22 +msgid "Show hidden books" +msgstr "Pokaż ukryte książki" + - #: templates/catalogue/book_list/book_list.html:75 ++#: templates/catalogue/book_list/book_list.html:90 #, python-format msgid "%(c)s book" msgid_plural "%(c)s books" @@@ -456,39 -400,58 +494,54 @@@ msgstr[0] "%(c)s książka msgstr[1] "%(c)s książki" msgstr[2] "%(c)s książek" - #: templates/catalogue/book_list/book_list.html:80 -#: templates/catalogue/book_list/book_list.html:93 ++#: templates/catalogue/book_list/book_list.html:95 msgid "No books found." msgstr "Nie znaleziono książek." - #: templatetags/book_list.py:84 - #: templatetags/book_list.py:145 -#: templates/catalogue/book_list/book_list.html:99 ++#: templates/catalogue/book_list/book_list.html:101 + msgid "Set stage" + msgstr "Ustaw etap" + -#: templates/catalogue/book_list/book_list.html:100 ++#: templates/catalogue/book_list/book_list.html:102 + msgid "Set user" + msgstr "Przypisz redaktora" + -#: templates/catalogue/book_list/book_list.html:102 ++#: templates/catalogue/book_list/book_list.html:104 + msgid "Project" + msgstr "Projekt" + -#: templates/catalogue/book_list/book_list.html:103 ++#: templates/catalogue/book_list/book_list.html:105 + msgid "Mark publishable" + msgstr "Oznacz do publikacji" + -#: templates/catalogue/book_list/book_list.html:104 ++#: templates/catalogue/book_list/book_list.html:106 + msgid "Mark not publishable" + msgstr "Odznacz do publikacji" + -#: templates/catalogue/book_list/book_list.html:105 ++#: templates/catalogue/book_list/book_list.html:107 + msgid "Other user" + msgstr "Inny użytkownik" + -#: templatetags/book_list.py:84 ++#: templatetags/book_list.py:84 templatetags/book_list.py:152 msgid "publishable" msgstr "do publikacji" --#: templatetags/book_list.py:85 - #: templatetags/book_list.py:146 ++#: templatetags/book_list.py:85 templatetags/book_list.py:153 msgid "changed" msgstr "zmienione" --#: templatetags/book_list.py:86 - #: templatetags/book_list.py:147 ++#: templatetags/book_list.py:86 templatetags/book_list.py:154 msgid "published" msgstr "opublikowane" --#: templatetags/book_list.py:87 - #: templatetags/book_list.py:148 ++#: templatetags/book_list.py:87 templatetags/book_list.py:155 msgid "unpublished" msgstr "nie opublikowane" --#: templatetags/book_list.py:88 - #: templatetags/book_list.py:149 ++#: templatetags/book_list.py:88 templatetags/book_list.py:156 msgid "empty" msgstr "puste" --#: templatetags/catalogue.py:27 --msgid "My page" --msgstr "Moja strona" -- #: templatetags/catalogue.py:30 msgid "All" msgstr "Wszystkie" @@@ -501,6 -460,10 +554,10 @@@ msgstr "Obrazy msgid "Add" msgstr "Dodaj" -#: templatetags/catalogue.py:37 ++#: templatetags/catalogue.py:38 + msgid "Covers" + msgstr "Okładki" + #: templatetags/wall.py:49 msgid "Related edit" msgstr "Powiązana zmiana" diff --cc apps/catalogue/migrations/0012_auto__add_imagepublishrecord__add_imagechange__add_unique_imagechange_.py index 00000000,00000000..599e103e new file mode 100644 --- /dev/null +++ b/apps/catalogue/migrations/0012_auto__add_imagepublishrecord__add_imagechange__add_unique_imagechange_.py @@@ -1,0 -1,0 +1,270 @@@ ++# -*- coding: utf-8 -*- ++import datetime ++from south.db import db ++from south.v2 import SchemaMigration ++from django.db import models ++ ++ ++class Migration(SchemaMigration): ++ ++ def forwards(self, orm): ++ # Adding model 'ImagePublishRecord' ++ db.create_table(u'catalogue_imagepublishrecord', ( ++ (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ++ ('image', self.gf('django.db.models.fields.related.ForeignKey')(related_name='publish_log', to=orm['catalogue.Image'])), ++ ('timestamp', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), ++ ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), ++ ('change', self.gf('django.db.models.fields.related.ForeignKey')(related_name='publish_log', to=orm['catalogue.ImageChange'])), ++ )) ++ db.send_create_signal('catalogue', ['ImagePublishRecord']) ++ ++ # Adding model 'ImageChange' ++ db.create_table(u'catalogue_imagechange', ( ++ (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ++ ('author', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True)), ++ ('author_name', self.gf('django.db.models.fields.CharField')(max_length=128, null=True, blank=True)), ++ ('author_email', self.gf('django.db.models.fields.CharField')(max_length=128, null=True, blank=True)), ++ ('revision', self.gf('django.db.models.fields.IntegerField')(db_index=True)), ++ ('parent', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='children', null=True, blank=True, to=orm['catalogue.ImageChange'])), ++ ('merge_parent', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='merge_children', null=True, blank=True, to=orm['catalogue.ImageChange'])), ++ ('description', self.gf('django.db.models.fields.TextField')(default='', blank=True)), ++ ('created_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now, db_index=True)), ++ ('publishable', self.gf('django.db.models.fields.BooleanField')(default=False)), ++ ('tree', self.gf('django.db.models.fields.related.ForeignKey')(related_name='change_set', to=orm['catalogue.Image'])), ++ ('data', self.gf('django.db.models.fields.files.FileField')(max_length=100)), ++ )) ++ db.send_create_signal('catalogue', ['ImageChange']) ++ ++ # Adding M2M table for field tags on 'ImageChange' ++ db.create_table(u'catalogue_imagechange_tags', ( ++ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), ++ ('imagechange', models.ForeignKey(orm['catalogue.imagechange'], null=False)), ++ ('imagetag', models.ForeignKey(orm['catalogue.imagetag'], null=False)) ++ )) ++ db.create_unique(u'catalogue_imagechange_tags', ['imagechange_id', 'imagetag_id']) ++ ++ # Adding unique constraint on 'ImageChange', fields ['tree', 'revision'] ++ db.create_unique(u'catalogue_imagechange', ['tree_id', 'revision']) ++ ++ # Adding model 'ImageTag' ++ db.create_table(u'catalogue_imagetag', ( ++ (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ++ ('name', self.gf('django.db.models.fields.CharField')(max_length=64)), ++ ('slug', self.gf('django.db.models.fields.SlugField')(max_length=64, unique=True, null=True, blank=True)), ++ ('ordering', self.gf('django.db.models.fields.IntegerField')()), ++ )) ++ db.send_create_signal('catalogue', ['ImageTag']) ++ ++ # Adding model 'Image' ++ db.create_table(u'catalogue_image', ( ++ (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ++ ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True)), ++ ('image', self.gf('django.db.models.fields.files.FileField')(max_length=100)), ++ ('title', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), ++ ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50)), ++ ('public', self.gf('django.db.models.fields.BooleanField')(default=True, db_index=True)), ++ ('_short_html', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), ++ ('_new_publishable', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)), ++ ('_published', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)), ++ ('_changed', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)), ++ ('stage', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.ImageTag'], null=True, blank=True)), ++ ('head', self.gf('django.db.models.fields.related.ForeignKey')(default=None, to=orm['catalogue.ImageChange'], null=True, blank=True)), ++ ('creator', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='created_image', null=True, to=orm['auth.User'])), ++ )) ++ db.send_create_signal('catalogue', ['Image']) ++ ++ ++ def backwards(self, orm): ++ # Removing unique constraint on 'ImageChange', fields ['tree', 'revision'] ++ db.delete_unique(u'catalogue_imagechange', ['tree_id', 'revision']) ++ ++ # Deleting model 'ImagePublishRecord' ++ db.delete_table(u'catalogue_imagepublishrecord') ++ ++ # Deleting model 'ImageChange' ++ db.delete_table(u'catalogue_imagechange') ++ ++ # Removing M2M table for field tags on 'ImageChange' ++ db.delete_table('catalogue_imagechange_tags') ++ ++ # Deleting model 'ImageTag' ++ db.delete_table(u'catalogue_imagetag') ++ ++ # Deleting model 'Image' ++ db.delete_table(u'catalogue_image') ++ ++ ++ models = { ++ u'auth.group': { ++ 'Meta': {'object_name': 'Group'}, ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), ++ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) ++ }, ++ u'auth.permission': { ++ 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, ++ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), ++ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) ++ }, ++ u'auth.user': { ++ 'Meta': {'object_name': 'User'}, ++ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), ++ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), ++ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), ++ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), ++ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), ++ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), ++ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), ++ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), ++ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), ++ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), ++ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) ++ }, ++ 'catalogue.book': { ++ 'Meta': {'ordering': "['title', 'slug']", 'object_name': 'Book'}, ++ '_new_publishable': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), ++ '_on_track': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), ++ '_published': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), ++ '_short_html': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), ++ '_single': ('django.db.models.fields.NullBooleanField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), ++ 'dc_cover_image': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['cover.Image']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), ++ 'dc_slug': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '128', 'null': 'True', 'blank': 'True'}), ++ 'gallery': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['catalogue.Book']"}), ++ 'parent_number': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), ++ 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Project']", 'null': 'True', 'blank': 'True'}), ++ 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}), ++ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}), ++ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}) ++ }, ++ 'catalogue.bookpublishrecord': { ++ 'Meta': {'ordering': "['-timestamp']", 'object_name': 'BookPublishRecord'}, ++ 'book': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'publish_log'", 'to': "orm['catalogue.Book']"}), ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), ++ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) ++ }, ++ 'catalogue.chunk': { ++ 'Meta': {'ordering': "['number']", 'unique_together': "[['book', 'number'], ['book', 'slug']]", 'object_name': 'Chunk'}, ++ '_changed': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), ++ '_hidden': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), ++ '_short_html': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), ++ 'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Book']"}), ++ 'creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'created_chunk'", 'null': 'True', 'to': u"orm['auth.User']"}), ++ 'gallery_start': ('django.db.models.fields.IntegerField', [], {'default': '1', 'null': 'True', 'blank': 'True'}), ++ 'head': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['catalogue.ChunkChange']", 'null': 'True', 'blank': 'True'}), ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'number': ('django.db.models.fields.IntegerField', [], {}), ++ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}), ++ 'stage': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.ChunkTag']", 'null': 'True', 'blank': 'True'}), ++ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), ++ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}) ++ }, ++ 'catalogue.chunkchange': { ++ 'Meta': {'ordering': "('created_at',)", 'unique_together': "(['tree', 'revision'],)", 'object_name': 'ChunkChange'}, ++ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}), ++ 'author_email': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), ++ 'author_name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), ++ 'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), ++ 'data': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), ++ 'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'merge_parent': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'merge_children'", 'null': 'True', 'blank': 'True', 'to': "orm['catalogue.ChunkChange']"}), ++ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'children'", 'null': 'True', 'blank': 'True', 'to': "orm['catalogue.ChunkChange']"}), ++ 'publishable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), ++ 'revision': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}), ++ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'change_set'", 'symmetrical': 'False', 'to': "orm['catalogue.ChunkTag']"}), ++ 'tree': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'change_set'", 'to': "orm['catalogue.Chunk']"}) ++ }, ++ 'catalogue.chunkpublishrecord': { ++ 'Meta': {'object_name': 'ChunkPublishRecord'}, ++ 'book_record': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.BookPublishRecord']"}), ++ 'change': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'publish_log'", 'to': "orm['catalogue.ChunkChange']"}), ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) ++ }, ++ 'catalogue.chunktag': { ++ 'Meta': {'ordering': "['ordering']", 'object_name': 'ChunkTag'}, ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), ++ 'ordering': ('django.db.models.fields.IntegerField', [], {}), ++ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'}) ++ }, ++ 'catalogue.image': { ++ 'Meta': {'ordering': "['title']", 'object_name': 'Image'}, ++ '_changed': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), ++ '_new_publishable': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), ++ '_published': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), ++ '_short_html': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), ++ 'creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'created_image'", 'null': 'True', 'to': u"orm['auth.User']"}), ++ 'head': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['catalogue.ImageChange']", 'null': 'True', 'blank': 'True'}), ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'image': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), ++ 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}), ++ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), ++ 'stage': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.ImageTag']", 'null': 'True', 'blank': 'True'}), ++ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), ++ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}) ++ }, ++ 'catalogue.imagechange': { ++ 'Meta': {'ordering': "('created_at',)", 'unique_together': "(['tree', 'revision'],)", 'object_name': 'ImageChange'}, ++ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}), ++ 'author_email': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), ++ 'author_name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), ++ 'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'db_index': 'True'}), ++ 'data': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), ++ 'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'merge_parent': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'merge_children'", 'null': 'True', 'blank': 'True', 'to': "orm['catalogue.ImageChange']"}), ++ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'children'", 'null': 'True', 'blank': 'True', 'to': "orm['catalogue.ImageChange']"}), ++ 'publishable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), ++ 'revision': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}), ++ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'change_set'", 'symmetrical': 'False', 'to': "orm['catalogue.ImageTag']"}), ++ 'tree': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'change_set'", 'to': "orm['catalogue.Image']"}) ++ }, ++ 'catalogue.imagepublishrecord': { ++ 'Meta': {'ordering': "['-timestamp']", 'object_name': 'ImagePublishRecord'}, ++ 'change': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'publish_log'", 'to': "orm['catalogue.ImageChange']"}), ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'publish_log'", 'to': "orm['catalogue.Image']"}), ++ 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), ++ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) ++ }, ++ 'catalogue.imagetag': { ++ 'Meta': {'ordering': "['ordering']", 'object_name': 'ImageTag'}, ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), ++ 'ordering': ('django.db.models.fields.IntegerField', [], {}), ++ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'}) ++ }, ++ 'catalogue.project': { ++ 'Meta': {'ordering': "['name']", 'object_name': 'Project'}, ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), ++ 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) ++ }, ++ u'contenttypes.contenttype': { ++ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, ++ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), ++ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) ++ }, ++ u'cover.image': { ++ 'Meta': {'object_name': 'Image'}, ++ 'author': ('django.db.models.fields.CharField', [], {'max_length': '255'}), ++ 'download_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'unique': 'True', 'null': 'True', 'blank': 'True'}), ++ 'file': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), ++ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'license_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), ++ 'license_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'blank': 'True'}), ++ 'source_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), ++ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) ++ } ++ } ++ ++ complete_apps = ['catalogue'] diff --cc apps/catalogue/models/__init__.py index 08cedd00,bd069f1c..d0015c79 --- a/apps/catalogue/models/__init__.py +++ b/apps/catalogue/models/__init__.py @@@ -3,10 -3,9 +3,11 @@@ # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # + from catalogue.models.project import Project from catalogue.models.chunk import Chunk -from catalogue.models.publish_log import BookPublishRecord, ChunkPublishRecord +from catalogue.models.image import Image +from catalogue.models.publish_log import (BookPublishRecord, + ChunkPublishRecord, ImagePublishRecord) from catalogue.models.book import Book from catalogue.models.listeners import * diff --cc apps/catalogue/models/image.py index 558f4c1f,00000000..7b5ce1f2 mode 100755,000000..100755 --- a/apps/catalogue/models/image.py +++ b/apps/catalogue/models/image.py @@@ -1,157 -1,0 +1,165 @@@ +# -*- coding: utf-8 -*- +# +# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# +from django.conf import settings +from django.contrib.sites.models import Site +from django.db import models +from django.template.loader import render_to_string +from django.utils.translation import ugettext_lazy as _ +from catalogue.helpers import cached_in_field +from catalogue.tasks import refresh_instance +from dvcs import models as dvcs_models + + +class Image(dvcs_models.Document): + """ An editable chunk of text. Every Book text is divided into chunks. """ + REPO_PATH = settings.CATALOGUE_IMAGE_REPO_PATH + + image = models.FileField(_('image'), upload_to='catalogue/images') + title = models.CharField(_('title'), max_length=255, blank=True) + slug = models.SlugField(_('slug'), unique=True) + public = models.BooleanField(_('public'), default=True, db_index=True) + + # cache + _short_html = models.TextField(null=True, blank=True, editable=False) + _new_publishable = models.NullBooleanField(editable=False) + _published = models.NullBooleanField(editable=False) + _changed = models.NullBooleanField(editable=False) + + class Meta: + app_label = 'catalogue' + ordering = ['title'] + verbose_name = _('image') + verbose_name_plural = _('images') + permissions = [('can_pubmark_image', 'Can mark images for publishing')] + + # Representing + # ============ + + def __unicode__(self): + return self.title + + @models.permalink + def get_absolute_url(self): + return ("catalogue_image", [self.slug]) + + def correct_about(self): + return "http://%s%s" % ( + Site.objects.get_current().domain, + self.get_absolute_url() + ) + + # State & cache + # ============= + + def last_published(self): + try: + return self.publish_log.all()[0].timestamp + except IndexError: + return None + + def assert_publishable(self): + from librarian.picture import WLPicture + from librarian import NoDublinCore, ParseError, ValidationError + + class SelfImageStore(object): + def path(self_, slug, mime_type): + """Returns own file object. Ignores slug ad mime_type.""" + return open(self.image.path) + + publishable = self.publishable() + assert publishable, _("There is no publishable revision") + picture_xml = publishable.materialize() + + try: + picture = WLPicture.from_string(picture_xml.encode('utf-8'), + image_store=SelfImageStore) + except ParseError, e: + raise AssertionError(_('Invalid XML') + ': ' + str(e)) + except NoDublinCore: + raise AssertionError(_('No Dublin Core found.')) + except ValidationError, e: + raise AssertionError(_('Invalid Dublin Core') + ': ' + str(e)) + + valid_about = self.correct_about() + assert picture.picture_info.about == valid_about, \ + _("rdf:about is not") + " " + valid_about + ++ def publishable_error(self): ++ try: ++ return self.assert_publishable() ++ except AssertionError, e: ++ return e ++ else: ++ return None ++ + def accessible(self, request): + return self.public or request.user.is_authenticated() + + def is_new_publishable(self): + change = self.publishable() + if not change: + return False + return not change.publish_log.exists() + new_publishable = cached_in_field('_new_publishable')(is_new_publishable) + + def is_published(self): + return self.publish_log.exists() + published = cached_in_field('_published')(is_published) + + def is_changed(self): + if self.head is None: + return False + return not self.head.publishable + changed = cached_in_field('_changed')(is_changed) + + @cached_in_field('_short_html') + def short_html(self): + return render_to_string( + 'catalogue/image_short.html', {'image': self}) + + def refresh(self): + """This should be done offline.""" + self.short_html + self.single + self.new_publishable + self.published + + def touch(self): + update = { + "_changed": self.is_changed(), + "_short_html": None, + "_new_publishable": self.is_new_publishable(), + "_published": self.is_published(), + } + Image.objects.filter(pk=self.pk).update(**update) + refresh_instance(self) + + def refresh(self): + """This should be done offline.""" + self.changed + self.short_html + + + # Publishing + # ========== + + def publish(self, user): + """Publishes the picture on behalf of a (local) user.""" + from base64 import b64encode + import apiclient + from catalogue.signals import post_publish + + self.assert_publishable() + change = self.publishable() + picture_xml = change.materialize() + picture_data = open(self.image.path).read() + apiclient.api_call(user, "pictures/", { + "picture_xml": picture_xml, + "picture_image_data": b64encode(picture_data), + }) + # record the publish + log = self.publish_log.create(user=user, change=change) + post_publish.send(sender=log) diff --cc apps/catalogue/templates/catalogue/base.html index 78a8ee51,d2af462b..9a56d726 --- a/apps/catalogue/templates/catalogue/base.html +++ b/apps/catalogue/templates/catalogue/base.html @@@ -2,18 -2,18 +2,19 @@@ {% load catalogue %} - + {% compressed_css 'catalogue' %} - {% block title %}{% trans "Platforma Redakcyjna" %}{% endblock title %} + {% block title %}{% trans "Platforma Redakcyjna" %} :: + {% block titleextra %}{% endblock %}{% endblock title %} + {% block add_css %}{% endblock %}
- + - +
diff --cc apps/catalogue/templates/catalogue/chunk_edit.html index cac192a2,3c1f3bf5..20062265 --- a/apps/catalogue/templates/catalogue/chunk_edit.html +++ b/apps/catalogue/templates/catalogue/chunk_edit.html @@@ -1,11 -1,6 +1,10 @@@ {% extends "catalogue/base.html" %} - {% load url from future %} {% load i18n %} + +{% block titleextra %}{% trans "Chunk settings" %}{% endblock %} + + {% block content %}

{% trans "Chunk settings" %}

diff --cc apps/catalogue/templates/catalogue/document_list.html index 2d608dcf,294c6299..f0bd50c8 --- a/apps/catalogue/templates/catalogue/document_list.html +++ b/apps/catalogue/templates/catalogue/document_list.html @@@ -2,10 -2,17 +2,19 @@@ {% load i18n %} {% load catalogue book_list %} + {% load compressed %} +{% block titleextra %}{% trans "Book list" %}{% endblock %} + + {% block add_js %} + {% compressed_js 'book_list' %} + {% endblock %} + + {% block add_css %} + {% compressed_css 'book_list' %} + {% endblock %} + {% block content %} {% book_list %} {% endblock content %} diff --cc apps/catalogue/templates/catalogue/image_detail.html index cd77654f,00000000..d791bfd8 mode 100755,000000..100755 --- a/apps/catalogue/templates/catalogue/image_detail.html +++ b/apps/catalogue/templates/catalogue/image_detail.html @@@ -1,80 -1,0 +1,80 @@@ +{% extends "catalogue/base.html" %} +{% load book_list comments i18n %} + + +{% block titleextra %}{{ object.title }}{% endblock %} + + +{% block content %} + + +

{{ object.title }}

+ + +{% if editable %}
{% csrf_token %}{% endif %} + + {{ form.as_table }} + {% if editable %} + + {% endif %} +
+{% if editable %}
{% endif %} + + + + + + + +
+ + +

{% trans "Publication" %}

+ +

{% trans "Last published" %}: + {% if object.last_published %} + {{ object.last_published }} + {% else %} + — + {% endif %} +

+ +{% if publishable %} + {% if user.is_authenticated %} + -
{% csrf_token %} ++ {% csrf_token %} + + + +
+ {% else %} - {% trans "Log in to publish." %} ++ {% trans "Log in to publish." %} + {% endif %} +{% else %} +

{% trans "This book can't be published yet, because:" %}

+
  • {{ publishable_error }}
+{% endif %} + +
+ + +
+

{% trans "Comments" %}

+ + {% render_comment_list for object %} + {% with object.get_absolute_url as next %} + {% render_comment_form for object %} + {% endwith %} +
+ +{% endblock content %} diff --cc apps/catalogue/templates/catalogue/image_short.html index 2e2b386c,00000000..e64733b6 mode 100755,000000..100755 --- a/apps/catalogue/templates/catalogue/image_short.html +++ b/apps/catalogue/templates/catalogue/image_short.html @@@ -1,18 -1,0 +1,18 @@@ +{% load i18n %} + + - [B] ++ [B] + ++ href="{% url 'wiki_img_editor' image.slug %}"> + {{ image.title }} + {% if image.stage %} + {{ image.stage }} + {% else %}– + {% endif %} - {% if image.user %}{{ image.user.first_name }} {{ image.user.last_name }}{% endif %} ++ {% if image.user %}{{ image.user.first_name }} {{ image.user.last_name }}{% endif %} + + {% if image.published %}P{% endif %} + {% if image.new_publishable %}p{% endif %} + {% if image.changed %}+{% endif %} + + diff --cc apps/catalogue/templates/catalogue/my_page.html index 07b92422,fd4e84ef..c6b61ce8 --- a/apps/catalogue/templates/catalogue/my_page.html +++ b/apps/catalogue/templates/catalogue/my_page.html @@@ -2,11 -2,16 +2,19 @@@ {% load i18n %} {% load catalogue book_list wall %} + {% load compressed %} + {% block add_js %} + {% compressed_js 'book_list' %} + {% endblock %} + + {% block add_css %} + {% compressed_css 'book_list' %} + {% endblock %} +{% block titleextra %}{% trans "My page" %}{% endblock %} + + {% block leftcolumn %} {% book_list request.user %} {% endblock leftcolumn %} diff --cc apps/catalogue/templatetags/book_list.py index 9344053b,14149e84..1357c321 --- a/apps/catalogue/templatetags/book_list.py +++ b/apps/catalogue/templatetags/book_list.py @@@ -5,7 -5,7 +5,7 @@@ from django.db.models import Q, Coun from django import template from django.utils.translation import ugettext_lazy as _ from django.contrib.auth.models import User - from catalogue.models import Chunk, Image -from catalogue.models import Chunk, Project ++from catalogue.models import Chunk, Image, Project register = template.Library() diff --cc apps/catalogue/urls.py index 31df1c19,e72b88db..3627bf04 --- a/apps/catalogue/urls.py +++ b/apps/catalogue/urls.py @@@ -4,13 -7,8 +7,13 @@@ from catalogue.views import GalleryVie urlpatterns = patterns('catalogue.views', - url(r'^$', redirect_to, {'url': 'catalogue/'}), + url(r'^$', RedirectView.as_view(url='catalogue/')), + url(r'^images/$', 'image_list', name='catalogue_image_list'), + url(r'^image/(?P[^/]+)/$', 'image', name="catalogue_image"), + url(r'^image/(?P[^/]+)/publish$', 'publish_image', + name="catalogue_publish_image"), + url(r'^catalogue/$', 'document_list', name='catalogue_document_list'), url(r'^user/$', 'my', name='catalogue_user'), url(r'^user/(?P[^/]+)/$', 'user', name='catalogue_user'), @@@ -28,8 -26,12 +31,11 @@@ 'create_missing', name='catalogue_create_missing'), url(r'^book/(?P[^/]+)/publish$', 'publish', name="catalogue_publish"), - #url(r'^(?P[^/]+)/publish/(?P\d+)$', 'publish', name="catalogue_publish"), url(r'^book/(?P[^/]+)/$', 'book', name="catalogue_book"), + url(r'^book/(?P[^/]+)/gallery/$', + permission_required('catalogue.change_book')(GalleryView.as_view()), + name="catalogue_book_gallery"), url(r'^book/(?P[^/]+)/xml$', 'book_xml', name="catalogue_book_xml"), url(r'^book/(?P[^/]+)/txt$', 'book_txt', name="catalogue_book_txt"), url(r'^book/(?P[^/]+)/html$', 'book_html', name="catalogue_book_html"), diff --cc apps/catalogue/views.py index ed5b15f2,ebc35751..01e4d1fa --- a/apps/catalogue/views.py +++ b/apps/catalogue/views.py @@@ -10,22 -11,22 +11,22 @@@ from django.contrib.auth.models import from django.contrib.auth.decorators import login_required, permission_required from django.core.urlresolvers import reverse from django.db.models import Count, Q + from django.db import transaction from django import http from django.http import Http404, HttpResponse, HttpResponseForbidden -from django.shortcuts import get_object_or_404, render, render_to_response +from django.shortcuts import get_object_or_404, render from django.utils.encoding import iri_to_uri from django.utils.http import urlquote_plus from django.utils.translation import ugettext_lazy as _ from django.views.decorators.http import require_POST - from django.views.generic.simple import direct_to_template -from django.template import RequestContext from apiclient import NotAuthorizedError from catalogue import forms from catalogue import helpers from catalogue.helpers import active_tab -from catalogue.models import Book, Chunk, BookPublishRecord, ChunkPublishRecord, Project +from catalogue.models import (Book, Chunk, Image, BookPublishRecord, - ChunkPublishRecord, ImagePublishRecord) - from catalogue.tasks import publishable_error ++ ChunkPublishRecord, ImagePublishRecord, Project) + from fileupload.views import UploadView # # Quick hack around caching problems, TODO: use ETags @@@ -234,16 -225,22 +231,21 @@@ def book_html(request, slug) book = get_object_or_404(Book, slug=slug) if not book.accessible(request): return HttpResponseForbidden("Not authorized.") - xml = book.materialize() - output = StringIO() - # errors? - - import librarian.html - librarian.html.transform(StringIO(xml), output, parse_dublincore=False, - flags=['full-page']) - html = output.getvalue() - response = http.HttpResponse(html, content_type='text/html', mimetype='text/html') - return response + + doc = book.wldocument(parse_dublincore=False) + html = doc.as_html() + + html = html.get_string() if html is not None else '' + # response = http.HttpResponse(html, content_type='text/html', mimetype='text/html') + # return response + # book_themes = {} + # for fragment in book.fragments.all().iterator(): + # for theme in fragment.tags.filter(category='theme').iterator(): + # book_themes.setdefault(theme, []).append(fragment) + + # book_themes = book_themes.items() + # book_themes.sort(key=lambda s: s[0].sort_key) - return render_to_response('catalogue/book_text.html', locals(), - context_instance=RequestContext(request)) ++ return render(request, 'catalogue/book_text.html', locals()) @never_cache @@@ -340,36 -315,6 +320,36 @@@ def book(request, slug) }) +def image(request, slug): + image = get_object_or_404(Image, slug=slug) + if not image.accessible(request): + return HttpResponseForbidden("Not authorized.") + + if request.user.has_perm('catalogue.change_image'): + if request.method == "POST": + form = forms.ImageForm(request.POST, instance=image) + if form.is_valid(): + form.save() + return http.HttpResponseRedirect(image.get_absolute_url()) + else: + form = forms.ImageForm(instance=image) + editable = True + else: + form = forms.ReadonlyImageForm(instance=image) + editable = False + - publish_error = publishable_error(image) ++ publish_error = image.publishable_error() + publishable = publish_error is None + - return direct_to_template(request, "catalogue/image_detail.html", extra_context={ ++ return render(request, "catalogue/image_detail.html", { + "object": image, + "publishable": publishable, + "publishable_error": publish_error, + "form": form, + "editable": editable, + }) + + @permission_required('catalogue.add_chunk') def chunk_add(request, slug, chunk): try: @@@ -482,18 -488,19 +523,36 @@@ def publish(request, slug) return http.HttpResponseRedirect(book.get_absolute_url()) +@require_POST +@login_required +def publish_image(request, slug): + image = get_object_or_404(Image, slug=slug) + if not image.accessible(request): + return HttpResponseForbidden("Not authorized.") + + try: + image.publish(request.user) + except NotAuthorizedError: + return http.HttpResponseRedirect(reverse('apiclient_oauth')) + except BaseException, e: + return http.HttpResponse(e) + else: + return http.HttpResponseRedirect(image.get_absolute_url()) ++ ++ + class GalleryView(UploadView): + def get_object(self, request, slug): + book = get_object_or_404(Book, slug=slug) + if not book.gallery: + raise Http404 + return book + + def breadcrumbs(self): + return [ + (_('books'), reverse('catalogue_document_list')), + (self.object.title, self.object.get_absolute_url()), + (_('scan gallery'),), + ] + + def get_directory(self): + return "%s%s/" % (settings.IMAGE_DIR, self.object.gallery) diff --cc apps/dvcs/models.py index 2526028f,cf8d75dc..ec647946 --- a/apps/dvcs/models.py +++ b/apps/dvcs/models.py @@@ -6,8 -6,8 +6,8 @@@ from django.core.files.base import Cont from django.core.files.storage import FileSystemStorage from django.db import models, transaction from django.db.models.base import ModelBase -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import string_concat, ugettext_lazy as _ - from mercurial import mdiff, simplemerge + from mercurial import simplemerge from django.conf import settings from dvcs.signals import post_commit, post_publishable diff --cc apps/wiki/templates/wiki/document_details_base.html index 5eda0942,e164a9ee..891e9e85 --- a/apps/wiki/templates/wiki/document_details_base.html +++ b/apps/wiki/templates/wiki/document_details_base.html @@@ -27,7 -27,7 +27,7 @@@