document stages on import,
authorRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Tue, 21 Jun 2011 14:11:10 +0000 (16:11 +0200)
committerRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Tue, 21 Jun 2011 14:11:10 +0000 (16:11 +0200)
assigning documents to users,
import assignments from redmine

21 files changed:
apps/dvcs/fixtures/stages.json [new file with mode: 0644]
apps/dvcs/migrations/0001_initial.py
apps/dvcs/models.py
apps/wiki/forms.py
apps/wiki/helpers.py
apps/wiki/locale/pl/LC_MESSAGES/django.mo
apps/wiki/locale/pl/LC_MESSAGES/django.po
apps/wiki/management/__init__.py [new file with mode: 0755]
apps/wiki/management/commands/__init__.py [new file with mode: 0755]
apps/wiki/management/commands/assign_from_redmine.py [new file with mode: 0755]
apps/wiki/migrations/0003_auto__add_book__add_chunk__add_unique_chunk_book_number__add_unique_ch.py
apps/wiki/templates/wiki/base.html
apps/wiki/templates/wiki/chunk_list_item.html [deleted file]
apps/wiki/templates/wiki/document_list.html
apps/wiki/templates/wiki/document_list_item.html [deleted file]
apps/wiki/templates/wiki/tabs/history_view.html
apps/wiki/templates/wiki/user_list.html [new file with mode: 0755]
apps/wiki/templatetags/wiki.py
apps/wiki/urls.py
apps/wiki/views.py
redakcja/static/css/filelist.css

diff --git a/apps/dvcs/fixtures/stages.json b/apps/dvcs/fixtures/stages.json
new file mode 100644 (file)
index 0000000..fc05d57
--- /dev/null
@@ -0,0 +1,83 @@
+[
+    {
+        "pk": 1, 
+        "model": "dvcs.tag", 
+        "fields": {
+            "ordering": 1, 
+            "name": "Autokorekta", 
+            "slug": "first_correction"
+        }
+    }, 
+    {
+        "pk": 2, 
+        "model": "dvcs.tag", 
+        "fields": {
+            "ordering": 2, 
+            "name": "Tagowanie", 
+            "slug": "tagging"
+        }
+    }, 
+    {
+        "pk": 3, 
+        "model": "dvcs.tag", 
+        "fields": {
+            "ordering": 3, 
+            "name": "Korekta", 
+            "slug": "proofreading"
+        }
+    }, 
+    {
+        "pk": 4, 
+        "model": "dvcs.tag", 
+        "fields": {
+            "ordering": 4, 
+            "name": "Sprawdzenie przypis\u00f3w \u017ar\u00f3d\u0142a", 
+            "slug": "annotation-proofreading"
+        }
+    }, 
+    {
+        "pk": 5, 
+        "model": "dvcs.tag", 
+        "fields": {
+            "ordering": 5, 
+            "name": "Uwsp\u00f3\u0142cze\u015bnienie", 
+            "slug": "modernisation"
+        }
+    }, 
+    {
+        "pk": 6, 
+        "model": "dvcs.tag", 
+        "fields": {
+            "ordering": 6, 
+            "name": "Przypisy", 
+            "slug": "annotations"
+        }
+    }, 
+    {
+        "pk": 7, 
+        "model": "dvcs.tag", 
+        "fields": {
+            "ordering": 7, 
+            "name": "Motywy", 
+            "slug": "themes"
+        }
+    }, 
+    {
+        "pk": 8, 
+        "model": "dvcs.tag", 
+        "fields": {
+            "ordering": 8, 
+            "name": "Ostateczna redakcja literacka", 
+            "slug": "editor-proofreading"
+        }
+    }, 
+    {
+        "pk": 9, 
+        "model": "dvcs.tag", 
+        "fields": {
+            "ordering": 9, 
+            "name": "Ostateczna redakcja techniczna", 
+            "slug": "technical-editor-proofreading"
+        }
+    }
+]
index d9f0984..6bff095 100644 (file)
@@ -4,6 +4,7 @@ from south.db import db
 from south.v2 import SchemaMigration
 from django.db import models
 
 from south.v2 import SchemaMigration
 from django.db import models
 
+
 class Migration(SchemaMigration):
 
     def forwards(self, orm):
 class Migration(SchemaMigration):
 
     def forwards(self, orm):
@@ -52,6 +53,10 @@ class Migration(SchemaMigration):
         ))
         db.send_create_signal('dvcs', ['Document'])
 
         ))
         db.send_create_signal('dvcs', ['Document'])
 
+        if not db.dry_run:
+            from django.core.management import call_command
+            call_command("loaddata", "stages.json")
+
 
     def backwards(self, orm):
         
 
     def backwards(self, orm):
         
index a72556f..f81f2ca 100644 (file)
@@ -39,7 +39,14 @@ class Tag(models.Model):
         sender._object_cache = {}
 
     def next(self):
         sender._object_cache = {}
 
     def next(self):
-        Tag.objects.filter(ordering__gt=self.ordering)
+        """
+            Returns the next tag - stage to work on.
+            Returns None for the last stage.
+        """
+        try:
+            return Tag.objects.filter(ordering__gt=self.ordering)[0]
+        except IndexError:
+            return None
 
 models.signals.pre_save.connect(Tag.listener_changed, sender=Tag)
 
 
 models.signals.pre_save.connect(Tag.listener_changed, sender=Tag)
 
@@ -220,6 +227,9 @@ class Document(models.Model):
         author = kwargs.get('author', None)
         author_desc = kwargs.get('author_desc', None)
         tags = kwargs.get('tags', [])
         author = kwargs.get('author', None)
         author_desc = kwargs.get('author_desc', None)
         tags = kwargs.get('tags', [])
+        if tags:
+            # set stage to next tag after the commited one
+            self.stage = max(tags, key=lambda t: t.ordering).next()
 
         old_head = self.head
         if parent != old_head:
 
         old_head = self.head
         if parent != old_head:
index 3626b6d..e153f7e 100644 (file)
@@ -3,12 +3,14 @@
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # 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.contrib.auth.models import User
+from django.db.models import Count
 from django import forms
 from django import forms
-from wiki.models import Book, Chunk
 from django.utils.translation import ugettext_lazy as _
 
 from dvcs.models import Tag
 from wiki.constants import MASTERS
 from django.utils.translation import ugettext_lazy as _
 
 from dvcs.models import Tag
 from wiki.constants import MASTERS
+from wiki.models import Book, Chunk
 
 class DocumentTagForm(forms.Form):
     """
 
 class DocumentTagForm(forms.Form):
     """
@@ -154,6 +156,10 @@ class ChunkForm(forms.ModelForm):
     """
         Form used for editing a chunk.
     """
     """
         Form used for editing a chunk.
     """
+    user = forms.ModelChoiceField(queryset=
+        User.objects.annotate(count=Count('document')).
+        order_by('-count', 'last_name', 'first_name'))
+
 
     class Meta:
         model = Chunk
 
     class Meta:
         model = Chunk
index ee26c5a..fe4b3b8 100644 (file)
@@ -143,3 +143,28 @@ def active_tab(tab):
         return wrapped
     return wrapper
 
         return wrapped
     return wrapper
 
+
+class BookChunks(object):
+    """
+        Yields the chunks of a book.
+    """
+
+    def __init__(self, book):
+        self.book = book
+
+    @property
+    def chunks(self):
+        return self.book.chunk_set.all()
+
+
+class ChoiceChunks(BookChunks):
+    """
+        Associates the given chunks iterable for a book.
+    """
+
+    chunks = None
+
+    def __init__(self, book, chunks):
+        self.book = book
+        self.chunks = chunks
+
index 1f5e514..f841945 100644 (file)
Binary files a/apps/wiki/locale/pl/LC_MESSAGES/django.mo and b/apps/wiki/locale/pl/LC_MESSAGES/django.mo differ
index 0b102e9..c760f3a 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Platforma Redakcyjna\n"
 "Report-Msgid-Bugs-To: \n"
 msgstr ""
 "Project-Id-Version: Platforma Redakcyjna\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-11-30 15:00+0100\n"
-"PO-Revision-Date: 2010-11-30 15:00+0100\n"
+"POT-Creation-Date: 2011-06-21 13:41+0200\n"
+"PO-Revision-Date: 2011-06-21 13:46+0100\n"
 "Last-Translator: Radek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>\n"
 "Language-Team: Fundacja Nowoczesna Polska <fundacja@nowoczesnapolska.org.pl>\n"
 "Language: \n"
 "Last-Translator: Radek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>\n"
 "Language-Team: Fundacja Nowoczesna Polska <fundacja@nowoczesnapolska.org.pl>\n"
 "Language: \n"
@@ -16,121 +16,223 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: constants.py:6
-msgid "First correction"
-msgstr "Autokorekta"
-
-#: constants.py:7
-msgid "Tagging"
-msgstr "Tagowanie"
-
-#: constants.py:8
-msgid "Initial Proofreading"
-msgstr "Korekta"
-
-#: constants.py:9
-msgid "Annotation Proofreading"
-msgstr "Sprawdzenie przypisów źródła"
-
-#: constants.py:10
-msgid "Modernisation"
-msgstr "Uwspółcześnienie"
-
-#: constants.py:11
-#: templates/wiki/tabs/annotations_view_item.html:3
-msgid "Annotations"
-msgstr "Przypisy"
-
-#: constants.py:12
-msgid "Themes"
-msgstr "Motywy"
-
-#: constants.py:13
-msgid "Editor's Proofreading"
-msgstr "Ostateczna redakcja literacka"
-
-#: constants.py:14
-msgid "Technical Editor's Proofreading"
-msgstr "Ostateczna redakcja techniczna"
-
-#: constants.py:18
-msgid "Ready to publish"
+#: forms.py:32
+msgid "Publishable"
 msgstr "Gotowe do publikacji"
 
 msgstr "Gotowe do publikacji"
 
-#: forms.py:49
+#: forms.py:68
 msgid "ZIP file"
 msgstr "Plik ZIP"
 
 msgid "ZIP file"
 msgstr "Plik ZIP"
 
-#: forms.py:82
+#: forms.py:99
+#: forms.py:137
 msgid "Author"
 msgstr "Autor"
 
 msgid "Author"
 msgstr "Autor"
 
-#: forms.py:83
+#: forms.py:100
+#: forms.py:138
 msgid "Your name"
 msgstr "Imię i nazwisko"
 
 msgid "Your name"
 msgstr "Imię i nazwisko"
 
-#: forms.py:88
+#: forms.py:105
+#: forms.py:143
 msgid "Author's email"
 msgstr "E-mail autora"
 
 msgid "Author's email"
 msgstr "E-mail autora"
 
-#: forms.py:89
+#: forms.py:106
+#: forms.py:144
 msgid "Your email address, so we can show a gravatar :)"
 msgstr "Adres e-mail, żebyśmy mogli pokazać gravatar :)"
 
 msgid "Your email address, so we can show a gravatar :)"
 msgstr "Adres e-mail, żebyśmy mogli pokazać gravatar :)"
 
-#: forms.py:95
+#: forms.py:112
+#: forms.py:150
 msgid "Your comments"
 msgstr "Twój komentarz"
 
 msgid "Your comments"
 msgstr "Twój komentarz"
 
-#: forms.py:96
+#: forms.py:113
 msgid "Describe changes you made."
 msgstr "Opisz swoje zmiany"
 
 msgid "Describe changes you made."
 msgstr "Opisz swoje zmiany"
 
-#: forms.py:102
+#: forms.py:119
 msgid "Completed"
 msgstr "Ukończono"
 
 msgid "Completed"
 msgstr "Ukończono"
 
-#: forms.py:103
+#: forms.py:120
 msgid "If you completed a life cycle stage, select it."
 msgstr "Jeśli został ukończony etap prac, wskaż go."
 
 msgid "If you completed a life cycle stage, select it."
 msgstr "Jeśli został ukończony etap prac, wskaż go."
 
-#: models.py:94
-#, python-format
-msgid "Finished stage: %s"
-msgstr "Ukończony etap: %s"
+#: forms.py:151
+msgid "Describe the reason for reverting."
+msgstr "Opisz powód przywrócenia."
+
+#: forms.py:176
+#: forms.py:190
+msgid "Chunk with this slug already exists"
+msgstr "Część z tym slugiem już istnieje"
+
+#: forms.py:202
+msgid "Append to"
+msgstr "Dołącz do"
+
+#: models.py:25
+msgid "title"
+msgstr "tytuł"
+
+#: models.py:26
+msgid "slug"
+msgstr ""
+
+#: models.py:27
+msgid "scan gallery name"
+msgstr "nazwa galerii skanów"
+
+#: models.py:29
+msgid "parent"
+msgstr "rodzic"
+
+#: models.py:30
+msgid "parent number"
+msgstr "numeracja rodzica"
+
+#: models.py:40
+msgid "book"
+msgstr "książka"
+
+#: models.py:41
+msgid "books"
+msgstr "książki"
 
 
-#: models.py:153
+#: models.py:206
 msgid "name"
 msgstr "nazwa"
 
 msgid "name"
 msgstr "nazwa"
 
-#: models.py:157
+#: models.py:210
 msgid "theme"
 msgstr "motyw"
 
 msgid "theme"
 msgstr "motyw"
 
-#: models.py:158
+#: models.py:211
 msgid "themes"
 msgstr "motywy"
 
 msgid "themes"
 msgstr "motywy"
 
-#: views.py:167
+#: views.py:241
 #, python-format
 #, python-format
-msgid "Title already used for %s"
-msgstr "Nazwa taka sama jak dla pliku %s"
+msgid "Slug already used for %s"
+msgstr "Slug taki sam jak dla pliku %s"
 
 
-#: views.py:169
-msgid "Title already used in repository."
-msgstr "Plik o tej nazwie już istnieje w repozytorium."
+#: views.py:243
+msgid "Slug already used in repository."
+msgstr "Dokument o tym slugu już istnieje w repozytorium."
 
 
-#: views.py:175
+#: views.py:249
 msgid "File should be UTF-8 encoded."
 msgstr "Plik powinien mieć kodowanie UTF-8."
 
 msgid "File should be UTF-8 encoded."
 msgstr "Plik powinien mieć kodowanie UTF-8."
 
-#: views.py:358
+#: views.py:655
 msgid "Tag added"
 msgstr "Dodano tag"
 
 msgid "Tag added"
 msgstr "Dodano tag"
 
-#: templates/wiki/base.html:15
+#: views.py:677
+msgid "Revision marked"
+msgstr "Wersja oznaczona"
+
+#: views.py:679
+msgid "Nothing changed"
+msgstr "Nic nie uległo zmianie"
+
+#: templates/wiki/base.html:9
 msgid "Platforma Redakcyjna"
 msgstr ""
 
 msgid "Platforma Redakcyjna"
 msgstr ""
 
+#: templates/wiki/book_append_to.html:8
+msgid "Append book"
+msgstr "Dołącz książkę"
+
+#: templates/wiki/book_detail.html:6
+#: templates/wiki/book_detail.html.py:46
+msgid "edit"
+msgstr "edytuj"
+
+#: templates/wiki/book_detail.html:16
+msgid "add basic document structure"
+msgstr "dodaj podstawową strukturę dokumentu"
+
+#: templates/wiki/book_detail.html:20
+msgid "change master tag to"
+msgstr "zmień tak master na"
+
+#: templates/wiki/book_detail.html:24
+msgid "add begin trimming tag"
+msgstr "dodaj początkowy ogranicznik"
+
+#: templates/wiki/book_detail.html:28
+msgid "add end trimming tag"
+msgstr "dodaj końcowy ogranicznik"
+
+#: templates/wiki/book_detail.html:34
+msgid "unstructured text"
+msgstr "tekst bez struktury"
+
+#: templates/wiki/book_detail.html:38
+msgid "unknown XML"
+msgstr "nieznany XML"
+
+#: templates/wiki/book_detail.html:42
+msgid "broken document"
+msgstr "uszkodzony dokument"
+
+#: templates/wiki/book_detail.html:60
+msgid "Apply fixes"
+msgstr "Wykonaj zmiany"
+
+#: templates/wiki/book_detail.html:66
+msgid "Append to other book"
+msgstr "Dołącz do innej książki"
+
+#: templates/wiki/book_detail.html:68
+msgid "Last published"
+msgstr "Ostatnio opublikowano"
+
+#: templates/wiki/book_detail.html:72
+msgid "Full XML"
+msgstr "Pełny XML"
+
+#: templates/wiki/book_detail.html:73
+msgid "HTML version"
+msgstr "Wersja HTML"
+
+#: templates/wiki/book_detail.html:74
+msgid "TXT version"
+msgstr "Wersja TXT"
+
+#: templates/wiki/book_detail.html:76
+msgid "EPUB version"
+msgstr "Wersja EPUB"
+
+#: templates/wiki/book_detail.html:77
+msgid "PDF version"
+msgstr "Wersja PDF"
+
+#: templates/wiki/book_detail.html:90
+#: templates/wiki/tabs/summary_view.html:30
+msgid "Publish"
+msgstr "Opublikuj"
+
+#: templates/wiki/book_detail.html:94
+msgid "This book cannot be published yet"
+msgstr "Ta książka nie może jeszcze zostać opublikowana"
+
+#: templates/wiki/book_edit.html:8
+#: templates/wiki/chunk_edit.html:8
+#: templates/wiki/document_details_base.html:35
+#: templates/wiki/pubmark_dialog.html:15
+#: templates/wiki/tag_dialog.html:15
+msgid "Save"
+msgstr "Zapisz"
+
+#: templates/wiki/chunk_add.html:8
+msgid "Add chunk"
+msgstr "Dodaj część"
+
 #: templates/wiki/diff_table.html:5
 msgid "Old version"
 msgstr "Stara wersja"
 #: templates/wiki/diff_table.html:5
 msgid "Old version"
 msgstr "Stara wersja"
@@ -147,87 +249,102 @@ msgstr "Utwórz dokument"
 msgid "Click to open/close gallery"
 msgstr "Kliknij, aby (ro)zwinąć galerię"
 
 msgid "Click to open/close gallery"
 msgstr "Kliknij, aby (ro)zwinąć galerię"
 
-#: templates/wiki/document_details_base.html:36
+#: templates/wiki/document_details_base.html:31
 msgid "Help"
 msgstr "Pomoc"
 
 msgid "Help"
 msgstr "Pomoc"
 
-#: templates/wiki/document_details_base.html:38
+#: templates/wiki/document_details_base.html:33
 msgid "Version"
 msgstr "Wersja"
 
 msgid "Version"
 msgstr "Wersja"
 
-#: templates/wiki/document_details_base.html:38
+#: templates/wiki/document_details_base.html:33
 msgid "Unknown"
 msgstr "nieznana"
 
 msgid "Unknown"
 msgstr "nieznana"
 
-#: templates/wiki/document_details_base.html:40
-#: templates/wiki/tag_dialog.html:15
-msgid "Save"
-msgstr "Zapisz"
-
-#: templates/wiki/document_details_base.html:41
+#: templates/wiki/document_details_base.html:36
 msgid "Save attempt in progress"
 msgstr "Trwa zapisywanie"
 
 msgid "Save attempt in progress"
 msgstr "Trwa zapisywanie"
 
-#: templates/wiki/document_details_base.html:42
+#: templates/wiki/document_details_base.html:37
 msgid "There is a newer version of this document!"
 msgstr "Istnieje nowsza wersja tego dokumentu!"
 
 msgid "There is a newer version of this document!"
 msgstr "Istnieje nowsza wersja tego dokumentu!"
 
-#: templates/wiki/document_list.html:30
+#: templates/wiki/document_list.html:31
 msgid "Clear filter"
 msgstr "Wyczyść filtr"
 
 msgid "Clear filter"
 msgstr "Wyczyść filtr"
 
-#: templates/wiki/document_list.html:48
+#: templates/wiki/document_list.html:46
+msgid "No books found."
+msgstr "Nie znaleziono książek."
+
+#: templates/wiki/document_list.html:89
 msgid "Your last edited documents"
 msgstr "Twoje ostatnie edycje"
 
 msgid "Your last edited documents"
 msgstr "Twoje ostatnie edycje"
 
-#: templates/wiki/document_upload.html:9
+#: templates/wiki/document_upload.html:8
 msgid "Bulk documents upload"
 msgstr "Hurtowe dodawanie dokumentów"
 
 msgid "Bulk documents upload"
 msgstr "Hurtowe dodawanie dokumentów"
 
-#: templates/wiki/document_upload.html:12
+#: templates/wiki/document_upload.html:11
 msgid "Please submit a ZIP with UTF-8 encoded XML files. Files not ending with <code>.xml</code> will be ignored."
 msgstr "Proszę wskazać archiwum ZIP z plikami XML w kodowaniu UTF-8. Pliki nie kończące się na <code>.xml</code> zostaną zignorowane."
 
 msgid "Please submit a ZIP with UTF-8 encoded XML files. Files not ending with <code>.xml</code> will be ignored."
 msgstr "Proszę wskazać archiwum ZIP z plikami XML w kodowaniu UTF-8. Pliki nie kończące się na <code>.xml</code> zostaną zignorowane."
 
-#: templates/wiki/document_upload.html:17
+#: templates/wiki/document_upload.html:16
+#: templatetags/wiki.py:36
 msgid "Upload"
 msgid "Upload"
-msgstr "Dodaj"
+msgstr "Załaduj"
 
 
-#: templates/wiki/document_upload.html:24
+#: templates/wiki/document_upload.html:23
 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."
 
 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/wiki/document_upload.html:25
+#: templates/wiki/document_upload.html:24
 msgid "Offending files"
 msgstr "Błędne pliki"
 
 msgid "Offending files"
 msgstr "Błędne pliki"
 
-#: templates/wiki/document_upload.html:33
+#: templates/wiki/document_upload.html:32
 msgid "Correct files"
 msgstr "Poprawne pliki"
 
 msgid "Correct files"
 msgstr "Poprawne pliki"
 
-#: templates/wiki/document_upload.html:44
+#: templates/wiki/document_upload.html:43
 msgid "Files have been successfully uploaded to the repository."
 msgstr "Pliki zostały dodane do repozytorium."
 
 msgid "Files have been successfully uploaded to the repository."
 msgstr "Pliki zostały dodane do repozytorium."
 
-#: templates/wiki/document_upload.html:45
+#: templates/wiki/document_upload.html:44
 msgid "Uploaded files"
 msgstr "Dodane pliki"
 
 msgid "Uploaded files"
 msgstr "Dodane pliki"
 
-#: templates/wiki/document_upload.html:55
+#: templates/wiki/document_upload.html:54
 msgid "Skipped files"
 msgstr "Pominięte pliki"
 
 msgid "Skipped files"
 msgstr "Pominięte pliki"
 
-#: templates/wiki/document_upload.html:56
+#: templates/wiki/document_upload.html:55
 msgid "Files skipped due to no <code>.xml</code> extension"
 msgstr "Pliki pominięte z powodu braku rozszerzenia <code>.xml</code>."
 
 msgid "Files skipped due to no <code>.xml</code> extension"
 msgstr "Pliki pominięte z powodu braku rozszerzenia <code>.xml</code>."
 
+#: templates/wiki/pubmark_dialog.html:16
+#: templates/wiki/revert_dialog.html:39
 #: templates/wiki/tag_dialog.html:16
 msgid "Cancel"
 msgstr "Anuluj"
 
 #: templates/wiki/tag_dialog.html:16
 msgid "Cancel"
 msgstr "Anuluj"
 
+#: templates/wiki/revert_dialog.html:38
+msgid "Revert"
+msgstr "Przywróć"
+
+#: templates/wiki/user_list.html:7
+#: templatetags/wiki.py:33
+msgid "Users"
+msgstr "Użytkownicy"
+
 #: templates/wiki/tabs/annotations_view.html:9
 msgid "all"
 msgstr "wszystkie"
 
 #: templates/wiki/tabs/annotations_view.html:9
 msgid "all"
 msgstr "wszystkie"
 
+#: templates/wiki/tabs/annotations_view_item.html:3
+msgid "Annotations"
+msgstr "Przypisy"
+
 #: templates/wiki/tabs/gallery_view.html:7
 msgid "Previous"
 msgstr "Poprzednie"
 #: templates/wiki/tabs/gallery_view.html:7
 msgid "Previous"
 msgstr "Poprzednie"
@@ -253,8 +370,8 @@ msgid "Compare versions"
 msgstr "Porównaj wersje"
 
 #: templates/wiki/tabs/history_view.html:7
 msgstr "Porównaj wersje"
 
 #: templates/wiki/tabs/history_view.html:7
-msgid "Mark version"
-msgstr "Oznacz wersję"
+msgid "Mark for publishing"
+msgstr "Oznacz do publikacji"
 
 #: templates/wiki/tabs/history_view.html:9
 msgid "Revert document"
 
 #: templates/wiki/tabs/history_view.html:9
 msgid "Revert document"
@@ -301,31 +418,27 @@ msgstr "Znajdź i zamień"
 msgid "Source code"
 msgstr "Kod źródłowy"
 
 msgid "Source code"
 msgstr "Kod źródłowy"
 
-#: templates/wiki/tabs/summary_view.html:10
+#: templates/wiki/tabs/summary_view.html:9
 msgid "Title"
 msgstr "Tytuł"
 
 msgid "Title"
 msgstr "Tytuł"
 
-#: templates/wiki/tabs/summary_view.html:15
+#: templates/wiki/tabs/summary_view.html:14
 msgid "Document ID"
 msgstr "ID dokumentu"
 
 msgid "Document ID"
 msgstr "ID dokumentu"
 
-#: templates/wiki/tabs/summary_view.html:19
+#: templates/wiki/tabs/summary_view.html:18
 msgid "Current version"
 msgstr "Aktualna wersja"
 
 msgid "Current version"
 msgstr "Aktualna wersja"
 
-#: templates/wiki/tabs/summary_view.html:22
+#: templates/wiki/tabs/summary_view.html:21
 msgid "Last edited by"
 msgstr "Ostatnio edytowane przez"
 
 msgid "Last edited by"
 msgstr "Ostatnio edytowane przez"
 
-#: templates/wiki/tabs/summary_view.html:26
+#: templates/wiki/tabs/summary_view.html:25
 msgid "Link to gallery"
 msgstr "Link do galerii"
 
 msgid "Link to gallery"
 msgstr "Link do galerii"
 
-#: templates/wiki/tabs/summary_view.html:31
-msgid "Publish"
-msgstr "Opublikuj"
-
-#: templates/wiki/tabs/summary_view_item.html:4
+#: templates/wiki/tabs/summary_view_item.html:3
 msgid "Summary"
 msgstr "Podsumowanie"
 
 msgid "Summary"
 msgstr "Podsumowanie"
 
@@ -341,8 +454,55 @@ msgstr "Wstaw przypis"
 msgid "Visual editor"
 msgstr "Edytor wizualny"
 
 msgid "Visual editor"
 msgstr "Edytor wizualny"
 
+#: templatetags/wiki.py:30
+msgid "Assigned to me"
+msgstr "Przypisane do mnie"
+
+#: templatetags/wiki.py:32
+msgid "Unassigned"
+msgstr "Nie przypisane"
+
+#: templatetags/wiki.py:34
+msgid "All"
+msgstr "Wszystkie"
+
+#: templatetags/wiki.py:35
+msgid "Add"
+msgstr "Dodaj"
+
+#: templatetags/wiki.py:39
+msgid "Admin"
+msgstr "Administracja"
+
+#~ msgid "First correction"
+#~ msgstr "Autokorekta"
+
+#~ msgid "Tagging"
+#~ msgstr "Tagowanie"
+
+#~ msgid "Initial Proofreading"
+#~ msgstr "Korekta"
+
+#~ msgid "Annotation Proofreading"
+#~ msgstr "Sprawdzenie przypisów źródła"
+
+#~ msgid "Modernisation"
+#~ msgstr "Uwspółcześnienie"
+
+#~ msgid "Themes"
+#~ msgstr "Motywy"
+
+#~ msgid "Editor's Proofreading"
+#~ msgstr "Ostateczna redakcja literacka"
+
+#~ msgid "Technical Editor's Proofreading"
+#~ msgstr "Ostateczna redakcja techniczna"
+
+#~ msgid "Finished stage: %s"
+#~ msgstr "Ukończony etap: %s"
+
 #~ msgid "Refresh"
 #~ msgstr "Odśwież"
 #~ msgid "Refresh"
 #~ msgstr "Odśwież"
+
 #~ msgid "Insert special character"
 #~ msgstr "Wstaw znak specjalny"
 #~ msgid "Insert special character"
 #~ msgstr "Wstaw znak specjalny"
-
diff --git a/apps/wiki/management/__init__.py b/apps/wiki/management/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/apps/wiki/management/commands/__init__.py b/apps/wiki/management/commands/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/apps/wiki/management/commands/assign_from_redmine.py b/apps/wiki/management/commands/assign_from_redmine.py
new file mode 100755 (executable)
index 0000000..4517749
--- /dev/null
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+
+import csv
+from optparse import make_option
+import re
+import sys
+import urllib
+import urllib2
+
+from django.contrib.auth.models import User
+from django.core.management.base import BaseCommand
+from django.core.management.color import color_style
+from django.db import transaction
+
+from slughifi import slughifi
+from wiki.models import Chunk
+
+
+REDMINE_CSV = 'http://redmine.nowoczesnapolska.org.pl/projects/wl-publikacje/issues.csv'
+REDAKCJA_URL = 'http://redakcja.wolnelektury.pl/documents/'
+
+
+class Command(BaseCommand):
+    option_list = BaseCommand.option_list + (
+        make_option('-r', '--redakcja', dest='redakcja', metavar='URL',
+            help='Base URL of Redakcja documents',
+            default=REDAKCJA_URL),
+        make_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
+            help='Less output'),
+        make_option('-f', '--force', action='store_true', dest='force', default=False,
+            help='Force assignment overwrite'),
+    )
+    help = 'Imports ticket assignments from Redmine.'
+    args = '[redmine-csv-url]'
+
+    def handle(self, *redmine_csv, **options):
+
+        self.style = color_style()
+
+        redakcja = options.get('redakcja')
+        verbose = options.get('verbose')
+        force = options.get('force')
+
+        if not redmine_csv:
+            if verbose:
+                print "Using default Redmine CSV URL:", REDMINE_CSV
+            redmine_csv = REDMINE_CSV
+
+        # Start transaction management.
+        transaction.commit_unless_managed()
+        transaction.enter_transaction_management()
+        transaction.managed(True)
+
+        redakcja_link = re.compile(re.escape(redakcja) + r'([-_.:?&%/a-zA-Z0-9]*)')
+
+        all_tickets = 0
+        all_chunks = 0
+        done_tickets = 0
+        done_chunks = 0
+        empty_users = 0
+        unknown_users = 0
+        unknown_books = 0
+        forced = 0
+
+        if verbose:
+            print 'Downloading CSV file'
+        for r in csv.reader(urllib2.urlopen(redmine_csv)):
+            if r[0] == '#':
+                continue
+            all_tickets += 1
+
+            username = r[6]
+            if not username:
+                if verbose:
+                    print "Empty user, skipping"
+                empty_users += 1
+                continue
+
+            first_name, last_name = unicode(username, 'utf-8').rsplit(u' ', 1)
+            try:
+                user = User.objects.get(first_name=first_name, last_name=last_name)
+            except User.DoesNotExist:
+                print self.style.ERROR('Unknown user: ' + username)
+                print "'%s' '%s'" % (first_name, last_name)
+                print type(last_name)
+                unknown_users += 1
+                continue
+
+            ticket_done = False
+            for fname in redakcja_link.findall(r[-1]):
+                fname = unicode(urllib.unquote(fname), 'utf-8', 'ignore')
+                if fname.endswith('.xml'):
+                    fname = fname[:-4]
+                fname = fname.replace(' ', '_')
+                fname = slughifi(fname)
+
+                chunks = Chunk.objects.filter(book__slug=fname)
+                if not chunks:
+                    print self.style.ERROR('Unknown book: ' + fname)
+                    unknown_books += 1
+                    continue
+                all_chunks += chunks.count()
+
+                for chunk in chunks:
+                    if chunk.user:
+                        if chunk.user == user:
+                            continue
+                        else:
+                            forced += 1
+                            if force:
+                                print self.style.WARNING(
+                                    '%s assigned to %s, forcing change to %s.' %
+                                    (chunk.pretty_name(), chunk.user, user))
+                            else:
+                                print self.style.WARNING(
+                                    '%s assigned to %s not to %s, skipping.' %
+                                    (chunk.pretty_name(), chunk.user, user))
+                                continue
+                    chunk.user = user
+                    chunk.save()
+                    ticket_done = True
+                    done_chunks += 1
+
+            if ticket_done:
+                done_tickets += 1
+
+
+        # Print results
+        print
+        print "Results:"
+        print "Done %d/%d tickets, assigned %d/%d book chunks." % (
+                done_tickets, all_tickets, done_chunks, all_chunks)
+        print "%d tickets unassigned, for %d chunks assignment differed." % (
+                empty_users, forced)
+        print "Unrecognized: %d books, %d users." % (
+                unknown_books, unknown_users)
+        print
+
+
+        transaction.commit()
+        transaction.leave_transaction_management()
+
index 010ed2a..3db141a 100644 (file)
@@ -14,6 +14,7 @@ from south.v2 import SchemaMigration
 from slughifi import slughifi
 
 META_REGEX = re.compile(r'\s*<!--\s(.*?)-->', re.DOTALL | re.MULTILINE)
 from slughifi import slughifi
 
 META_REGEX = re.compile(r'\s*<!--\s(.*?)-->', re.DOTALL | re.MULTILINE)
+STAGE_TAGS_RE = re.compile(r'^#stage-finished: (.*)$', re.MULTILINE)
 
 
 def urlunquote(url):
 
 
 def urlunquote(url):
@@ -93,27 +94,48 @@ def migrate_file_from_hg(orm, fname, entry):
         description=''
         )
     chunk.head = head
         description=''
         )
     chunk.head = head
+    try:
+        chunk.stage = orm['dvcs.Tag'].objects.order_by('ordering')[0]
+    except IndexError:
+        chunk.stage = None
     old_data = ''
 
     maxrev = entry.filerev()
     old_data = ''
 
     maxrev = entry.filerev()
-    gallery_link = None;
+    gallery_link = None
+    
     for rev in xrange(maxrev + 1):
     for rev in xrange(maxrev + 1):
-        # TODO: tags
         fctx = entry.filectx(rev)
         data = fctx.data()
         gallery_link = gallery(fname, data)
         data = plain_text(data)
         fctx = entry.filectx(rev)
         data = fctx.data()
         gallery_link = gallery(fname, data)
         data = plain_text(data)
+
+        # get tags from description
+        description = fctx.description().decode("utf-8", 'replace')
+        tags = STAGE_TAGS_RE.findall(description)
+        tags = [orm['dvcs.Tag'].objects.get(slug=slug.strip()) for slug in tags]
+
+        if tags:
+            max_ordering = max(tags, key=lambda x: x.ordering).ordering
+            try:
+                chunk.stage = orm['dvcs.Tag'].objects.filter(ordering__gt=max_ordering).order_by('ordering')[0]
+            except IndexError:
+                chunk.stage = None
+
+        description = STAGE_TAGS_RE.sub('', description)
+
         head = orm['dvcs.Change'].objects.create(
             tree=chunk,
             revision=rev + 1,
             patch=make_patch(old_data, data),
             created_at=datetime.datetime.fromtimestamp(fctx.date()[0]),
         head = orm['dvcs.Change'].objects.create(
             tree=chunk,
             revision=rev + 1,
             patch=make_patch(old_data, data),
             created_at=datetime.datetime.fromtimestamp(fctx.date()[0]),
-            description=fctx.description().decode("utf-8", 'replace'),
+            description=description,
             author_desc=fctx.user().decode("utf-8", 'replace'),
             parent=chunk.head
             )
             author_desc=fctx.user().decode("utf-8", 'replace'),
             parent=chunk.head
             )
+        head.tags = tags
         chunk.head = head
         old_data = data
         chunk.head = head
         old_data = data
+
     chunk.save()
     if gallery_link:
         book.gallery = gallery_link
     chunk.save()
     if gallery_link:
         book.gallery = gallery_link
@@ -246,7 +268,9 @@ class Migration(SchemaMigration):
             'Meta': {'object_name': 'Document'},
             'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
             'head': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['dvcs.Change']", 'null': 'True', 'blank': 'True'}),
             'Meta': {'object_name': 'Document'},
             'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
             'head': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['dvcs.Change']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'stage': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dvcs.Tag']", 'null': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'})
         },
         'dvcs.tag': {
             'Meta': {'ordering': "['ordering']", 'object_name': 'Tag'},
         },
         'dvcs.tag': {
             'Meta': {'ordering': "['ordering']", 'object_name': 'Tag'},
index 85abaaf..5d20bbc 100644 (file)
 
     <div id="tabs-nav-left">
         {% main_tabs %}
 
     <div id="tabs-nav-left">
         {% main_tabs %}
-        <!--a {% ifequal active_tab "user" %}class="active" {% endifequal %}href="{% url wiki_user %}">{% trans "User" %}</a>
-        <a {% ifequal active_tab "all" %}class="active" {% endifequal %}href="{% url wiki_document_list %}">{% trans "All" %}</a>
-        <a {% ifequal active_tab "create" %}class="active" {% endifequal %}href="{% url wiki_create_missing %}">{% trans "Add" %}</a>
-        <a {% ifequal active_tab "upload" %}class="active" {% endifequal %}href="{% url wiki_upload %}">{% trans "Upload" %}</a-->
     </div>
 
     <span id="login-box">
     </div>
 
     <span id="login-box">
diff --git a/apps/wiki/templates/wiki/chunk_list_item.html b/apps/wiki/templates/wiki/chunk_list_item.html
deleted file mode 100755 (executable)
index bec9e75..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<tr>
-    <td colspan="3">
-        <a target="_blank"
-        href="{% url wiki_chunk_edit chunk.book.slug chunk.slug %}">[?]</a>
-        <a target="_blank"
-                href="{{ chunk.get_absolute_url }}">
-                {{ chunk.pretty_name }}</a>
-    </td>
-</tr>
index 221b63d..9525078 100644 (file)
@@ -2,6 +2,7 @@
 
 {% load i18n %}
 {% load pagination_tags %}
 
 {% load i18n %}
 {% load pagination_tags %}
+{% load wiki %}
 
 {% block extrabody %}
 {{ block.super }}
 
 {% block extrabody %}
 {{ block.super }}
@@ -23,7 +24,7 @@ $(function() {
 
 {% block leftcolumn %}
        <form method="get" action="#">
 
 {% block leftcolumn %}
        <form method="get" action="#">
-    <table id="file-list">
+    <table>
        <thead>
                <tr><th>Filtr:</th>
                        <th><input autocomplete="off" name="filter" id="file-list-filter" type="text" size="40" /></th>
        <thead>
                <tr><th>Filtr:</th>
                        <th><input autocomplete="off" name="filter" id="file-list-filter" type="text" size="40" /></th>
@@ -31,12 +32,54 @@ $(function() {
                        </tr>
                </thead>
                <tbody>
                        </tr>
                </thead>
                <tbody>
+               </tbody>
+    </table>
+       </form>
+
+
+
+       <form method="get" action="#">
+    <table id="file-list">
+               <tbody>
         {% autopaginate books 20 %}
         {% autopaginate books 20 %}
-       {% for book in books %}
-            {{ book.list_html }}
+        {% if not books %}
+            <tr><td>{% trans "No books found." %}</td></tr>
+        {% endif %}
+       {% for item in books %}
+            {% with item.book as book %}
+            
+            {% ifequal book.chunk_set.count 1 %}
+                <tr>
+                    <td><a target="_blank" href="{% url wiki_book book.slug %}">[B]</a></td>
+                    <td><a href="{% url wiki_chunk_edit book.slug book.0.slug %}">[c]</a></td>
+                    <td><a target="_blank"
+                                href="{% url wiki_editor book.slug %}">
+                                {{ book.title }}</a></td>
+                    <td>({{ book.0.stage }})</td>
+                    <td>{% if book.0.user %}<a href="{% url wiki_user book.0.user.username %}">{{ book.0.user.first_name }} {{ book.0.user.last_name }}</a>{% endif %}</td>
+                </tr>
+            {% else %}
+                <tr>
+                    <td><a target="_blank" href="{% url wiki_book book.slug %}">[B]</a></td>
+                    <td></td>
+                    <td>{{ book.title }}</td>
+                </tr>
+                {% for chunk in item.chunks %}
+                    <tr>
+                        <td></td>
+                        <td><a href="{% url wiki_chunk_edit book.slug chunk.slug %}">[c]</a></td>
+                        <td><a target="_blank" href="{{ chunk.get_absolute_url }}">
+                                <span class='chunkno'>{{ chunk.number }}.</span>
+                                {{ chunk.comment }}</a></td>
+                        <td>({{ chunk.stage }})</td>
+                        <td>{% if chunk.user %}<a href="{% url wiki_user chunk.user.username %}">{{ chunk.user.first_name }} {{ chunk.user.last_name }}</a>{% endif %}</td>
+                    </td></tr>
+                {% endfor %}
+            {% endifequal %}
+            {% endwith %}
        {% endfor %}
        {% endfor %}
-               </tbody>
         <tr><td colspan="3">{% paginate %}</td></tr>
         <tr><td colspan="3">{% paginate %}</td></tr>
+               </tbody>
     </table>
        </form>
 {% endblock leftcolumn %}
     </table>
        </form>
 {% endblock leftcolumn %}
diff --git a/apps/wiki/templates/wiki/document_list_item.html b/apps/wiki/templates/wiki/document_list_item.html
deleted file mode 100755 (executable)
index f1c4d37..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<tr>
-    <td colspan="3">
-        <a target="_blank" data-id="{{ book.slug }}"
-        href="{% url wiki_book book.slug %}">[?]</a>
-        {% ifequal book.chunk_set.count 1 %}
-            <a target="_blank" data-id="{{ book.slug }}"
-                    href="{% url wiki_editor book.slug %}">
-                    {{ book.title }}</a>
-        {% else %}
-            {{ book.title }}
-            <div class="chunk-list">
-            {% for chunk in book %}
-                <a target="_blank" data-id="{{ book.slug }}"
-                    href="{{ chunk.get_absolute_url }}">
-                    <span class='chunkno'>{{ forloop.counter }}.</span>
-                    {{ chunk.comment }}</a><br/>
-            {% endfor %}
-            </div>
-        {% endifequal %}
-    </td>
-</tr>
index db207bb..0764f98 100644 (file)
@@ -3,8 +3,6 @@
     <div class="toolbar">
        <button type="button" id="make-diff-button"
                        data-enabled-when="2" disabled="disabled">{% trans "Compare versions" %}</button>
     <div class="toolbar">
        <button type="button" id="make-diff-button"
                        data-enabled-when="2" disabled="disabled">{% trans "Compare versions" %}</button>
-               <button type="button" id="tag-changeset-button"
-                       data-enabled-when="1" disabled="disabled">{% trans "Mark version" %}</button>
                <button type="button" id="pubmark-changeset-button"
                        data-enabled-when="1" disabled="disabled">{% trans "Mark for publishing" %}</button>
                <button type="button" id="doc-revert-button"
                <button type="button" id="pubmark-changeset-button"
                        data-enabled-when="1" disabled="disabled">{% trans "Mark for publishing" %}</button>
                <button type="button" id="doc-revert-button"
diff --git a/apps/wiki/templates/wiki/user_list.html b/apps/wiki/templates/wiki/user_list.html
new file mode 100755 (executable)
index 0000000..8996cc0
--- /dev/null
@@ -0,0 +1,18 @@
+{% extends "wiki/base.html" %}
+
+{% load i18n %}
+
+{% block leftcolumn %}
+
+<h1>{% trans "Users" %}</h1>
+
+<ul>
+{% for user in users %}
+    <li><a href="{% url wiki_user user.username %}">
+        <span class="chunkno">{{ forloop.counter }}.</span>
+        {{ user.first_name }} {{ user.last_name }}</a>
+        ({{ user.count }})</li>
+{% endfor %}
+</ul>
+
+{% endblock leftcolumn %}
index 8acf761..1fb1a2e 100644 (file)
@@ -30,6 +30,7 @@ def main_tabs(context):
         tabs.append(Tab('my', _('Assigned to me'), reverse("wiki_user")))
 
     tabs.append(Tab('unassigned', _('Unassigned'), reverse("wiki_unassigned")))
         tabs.append(Tab('my', _('Assigned to me'), reverse("wiki_user")))
 
     tabs.append(Tab('unassigned', _('Unassigned'), reverse("wiki_unassigned")))
+    tabs.append(Tab('users', _('Users'), reverse("wiki_users")))
     tabs.append(Tab('all', _('All'), reverse("wiki_document_list")))
     tabs.append(Tab('create', _('Add'), reverse("wiki_create_missing")))
     tabs.append(Tab('upload', _('Upload'), reverse("wiki_upload")))
     tabs.append(Tab('all', _('All'), reverse("wiki_document_list")))
     tabs.append(Tab('create', _('Add'), reverse("wiki_create_missing")))
     tabs.append(Tab('upload', _('Upload'), reverse("wiki_upload")))
index f0b602c..097de60 100644 (file)
@@ -18,6 +18,7 @@ urlpatterns = patterns('wiki.views',
     url(r'^unassigned/$', 'unassigned', name='wiki_unassigned'),
     url(r'^user/$', 'my', name='wiki_user'),
     url(r'^user/(?P<username>[^/]+)/$', 'user', name='wiki_user'),
     url(r'^unassigned/$', 'unassigned', name='wiki_unassigned'),
     url(r'^user/$', 'my', name='wiki_user'),
     url(r'^user/(?P<username>[^/]+)/$', 'user', name='wiki_user'),
+    url(r'^users/$', 'users', name='wiki_users'),
 
     url(r'^edit/(?P<slug>[^/]+)/(?:(?P<chunk>[^/]+)/)?$',
         'editor', name="wiki_editor"),
 
     url(r'^edit/(?P<slug>[^/]+)/(?:(?P<chunk>[^/]+)/)?$',
         'editor', name="wiki_editor"),
index 0821488..7bff1a0 100644 (file)
@@ -9,11 +9,13 @@ from django.conf import settings
 
 from django.contrib.auth.models import User
 from django.contrib.auth.decorators import login_required
 
 from django.contrib.auth.models import User
 from django.contrib.auth.decorators import login_required
+from django.db.models import Count
 from django.views.generic.simple import direct_to_template
 from django.views.decorators.http import require_POST, require_GET
 from django.core.urlresolvers import reverse
 from wiki.helpers import (JSONResponse, JSONFormInvalid, JSONServerError,
                 ajax_require_permission, recursive_groupby, active_tab)
 from django.views.generic.simple import direct_to_template
 from django.views.decorators.http import require_POST, require_GET
 from django.core.urlresolvers import reverse
 from wiki.helpers import (JSONResponse, JSONFormInvalid, JSONServerError,
                 ajax_require_permission, recursive_groupby, active_tab)
+from wiki import helpers
 from django import http
 from django.shortcuts import get_object_or_404, redirect
 from django.http import Http404
 from django import http
 from django.shortcuts import get_object_or_404, redirect
 from django.http import Http404
@@ -46,7 +48,7 @@ MAX_LAST_DOCS = 10
 @never_cache
 def document_list(request):
     return direct_to_template(request, 'wiki/document_list.html', extra_context={
 @never_cache
 def document_list(request):
     return direct_to_template(request, 'wiki/document_list.html', extra_context={
-        'books': Book.objects.all(),
+        'books': [helpers.BookChunks(b) for b in Book.objects.all()],
         'last_books': sorted(request.session.get("wiki_last_books", {}).items(),
                         key=lambda x: x[1]['time'], reverse=True),
     })
         'last_books': sorted(request.session.get("wiki_last_books", {}).items(),
                         key=lambda x: x[1]['time'], reverse=True),
     })
@@ -55,8 +57,18 @@ def document_list(request):
 @active_tab('unassigned')
 @never_cache
 def unassigned(request):
 @active_tab('unassigned')
 @never_cache
 def unassigned(request):
+    chunks = Chunk.objects.filter(user=None).order_by('book__title', 'book', 'number')
+    books = []
+    book = None
+    for chunk in chunks:
+        if chunk.book != book:
+            book = chunk.book
+            books.append(helpers.ChoiceChunks(book, [chunk]))
+        else:
+            books[-1].chunks.append(chunk)
+
     return direct_to_template(request, 'wiki/document_list.html', extra_context={
     return direct_to_template(request, 'wiki/document_list.html', extra_context={
-        'books': Chunk.objects.filter(user=None),
+        'books': books,
         'last_books': sorted(request.session.get("wiki_last_books", {}).items(),
                         key=lambda x: x[1]['time'], reverse=True),
     })
         'last_books': sorted(request.session.get("wiki_last_books", {}).items(),
                         key=lambda x: x[1]['time'], reverse=True),
     })
@@ -72,14 +84,32 @@ def user(request, username=None):
     else:
         user = get_object_or_404(User, username=username)
 
     else:
         user = get_object_or_404(User, username=username)
 
+    chunks = Chunk.objects.filter(user=user).order_by('book__title', 'number')
+    books = []
+    book = None
+    for chunk in chunks:
+        if chunk.book != book:
+            book = chunk.book
+            books.append(helpers.ChoiceChunks(book, [chunk]))
+        else:
+            books[-1].chunks.append(chunk)
+
     return direct_to_template(request, 'wiki/document_list.html', extra_context={
     return direct_to_template(request, 'wiki/document_list.html', extra_context={
-        'books': Chunk.objects.filter(user=user),
+        'books': books,
         'last_books': sorted(request.session.get("wiki_last_books", {}).items(),
                         key=lambda x: x[1]['time'], reverse=True),
     })
 my = login_required(active_tab('my')(user))
 
 
         'last_books': sorted(request.session.get("wiki_last_books", {}).items(),
                         key=lambda x: x[1]['time'], reverse=True),
     })
 my = login_required(active_tab('my')(user))
 
 
+@active_tab('users')
+def users(request):
+    return direct_to_template(request, 'wiki/user_list.html', extra_context={
+        'users': User.objects.all().annotate(count=Count('document')).order_by(
+            '-count', 'last_name', 'first_name'),
+    })
+
+
 @never_cache
 def editor(request, slug, chunk=None, template_name='wiki/document_details.html'):
     try:
 @never_cache
 def editor(request, slug, chunk=None, template_name='wiki/document_details.html'):
     try:
index bb6bea7..4c5ffb3 100644 (file)
@@ -61,7 +61,7 @@ body {
 #file-list {
        overflow: visible;
        float: left;
 #file-list {
        overflow: visible;
        float: left;
-       max-width: 50%;
+       /*max-width: 50%;*/
        padding-right: 2%;
        border-right: 1px dashed black;
 
        padding-right: 2%;
        border-right: 1px dashed black;
 
@@ -116,14 +116,12 @@ a:hover {
 
 .chunkno {
     font-size: .7em;
 
 .chunkno {
     font-size: .7em;
+    padding-left: 2em;
 }
 
 td {
     vertical-align: top;
 }
 }
 
 td {
     vertical-align: top;
 }
-.chunk-list {
-    padding-left: 2em;
-}
 
 
 .fix {
 
 
 .fix {