Commit 66d407a0c3369ae02b221e176a1b7e5a0793021e
1 parent
9adac789
Add Website and WebPage Document types.
Showing
8 changed files
with
220 additions
and
58 deletions
collector/storage/admin.py
... | ... | @@ -3,7 +3,7 @@ from django.contrib import admin |
3 | 3 | from admin_numeric_filter.admin import RangeNumericFilter |
4 | 4 | |
5 | 5 | from storage.models import Chunk, Document, Keyword, Metadata, Participant, Annotation, Magazine, \ |
6 | - Book, BookWithMultipleAuthors, Article, Chapter | |
6 | + Book, BookWithMultipleAuthors, Website, Article, Chapter, WebPage | |
7 | 7 | |
8 | 8 | |
9 | 9 | class ChunkInline(admin.StackedInline): |
... | ... | @@ -57,8 +57,10 @@ admin.site.register(Document, DocumentAdmin) |
57 | 57 | admin.site.register(Magazine) |
58 | 58 | admin.site.register(Book) |
59 | 59 | admin.site.register(BookWithMultipleAuthors) |
60 | +admin.site.register(Website) | |
60 | 61 | admin.site.register(Article) |
61 | 62 | admin.site.register(Chapter) |
63 | +admin.site.register(WebPage) | |
62 | 64 | admin.site.register(Keyword) |
63 | 65 | admin.site.register(Participant, ParticipantAdmin) |
64 | 66 | admin.site.register(Annotation, AnnotationAdmin) |
... | ... |
collector/storage/forms.py
... | ... | @@ -3,7 +3,8 @@ import re |
3 | 3 | from django.forms import ChoiceField, ModelChoiceField, ModelForm, Textarea, CharField, Form |
4 | 4 | from django import forms |
5 | 5 | |
6 | -from .models import Chunk, Document, Participant, Metadata, Keyword, Magazine, Book, BookWithMultipleAuthors | |
6 | +from .models import Chunk, Document, Participant, Metadata, Keyword, Magazine, Book, BookWithMultipleAuthors, Website, \ | |
7 | + WebPage | |
7 | 8 | from .utils import get_doc_with_type |
8 | 9 | from projects.ppc.models import Utterance |
9 | 10 | from collector import settings |
... | ... | @@ -306,6 +307,15 @@ DOC_TYPE_DETAILS_FIELDS = { |
306 | 307 | 'channel': 'Kanał', |
307 | 308 | 'original_lang': 'Język oryginału' |
308 | 309 | } |
310 | + }, | |
311 | + Website: { | |
312 | + 'fields': ['title', 'url', 'channel', 'original_lang'], | |
313 | + 'labels': { | |
314 | + 'title': 'Nazwa', | |
315 | + 'url': 'Adres URL', | |
316 | + 'channel': 'Kanał', | |
317 | + 'original_lang': 'Język oryginału' | |
318 | + } | |
309 | 319 | } |
310 | 320 | } |
311 | 321 | |
... | ... | @@ -405,6 +415,28 @@ class BWMADetailsForm(ModelForm): |
405 | 415 | } |
406 | 416 | |
407 | 417 | |
418 | +class WebsiteDetailsForm(ModelForm): | |
419 | + def __init__(self, *args, **kwargs): | |
420 | + super(WebsiteDetailsForm, self).__init__(*args, **kwargs) | |
421 | + self.fields['title'].widget = Textarea(attrs={'rows': 1}) | |
422 | + | |
423 | + def save(self, commit=True): | |
424 | + website = super(WebsiteDetailsForm, self).save(commit) | |
425 | + website.changed = True | |
426 | + website.save() | |
427 | + return website | |
428 | + | |
429 | + class Meta: | |
430 | + model = Website | |
431 | + fields = ['title', 'url', 'channel', 'original_lang'] | |
432 | + labels = { | |
433 | + 'title': 'Nazwa', | |
434 | + 'url': 'Adres URL', | |
435 | + 'channel': 'Kanał', | |
436 | + 'original_lang': 'Język oryginału' | |
437 | + } | |
438 | + | |
439 | + | |
408 | 440 | class SubDocDetailsForm(ModelForm): |
409 | 441 | |
410 | 442 | def __init__(self, *args, **kwargs): |
... | ... | @@ -426,6 +458,28 @@ class SubDocDetailsForm(ModelForm): |
426 | 458 | } |
427 | 459 | |
428 | 460 | |
461 | +class WebPageDetailsForm(ModelForm): | |
462 | + | |
463 | + def __init__(self, *args, **kwargs): | |
464 | + super(WebPageDetailsForm, self).__init__(*args, **kwargs) | |
465 | + self.fields['title'].widget = Textarea(attrs={'rows': 1}) | |
466 | + | |
467 | + def save(self, commit=True): | |
468 | + webpage = super(WebPageDetailsForm, self).save(commit) | |
469 | + webpage.changed = True | |
470 | + webpage.save() | |
471 | + return webpage | |
472 | + | |
473 | + class Meta: | |
474 | + model = WebPage | |
475 | + fields = ['title', 'url', 'original_lang'] | |
476 | + labels = { | |
477 | + 'title': 'Tytuł', | |
478 | + 'url': 'Adres URL', | |
479 | + 'original_lang': 'Język oryginału' | |
480 | + } | |
481 | + | |
482 | + | |
429 | 483 | class KeywordForm(Form): |
430 | 484 | label = CharField(max_length=200, label='Etykieta') |
431 | 485 | |
... | ... |
collector/storage/models.py
... | ... | @@ -197,6 +197,19 @@ class Book(Document): |
197 | 197 | return 'książka' |
198 | 198 | |
199 | 199 | |
200 | +class Website(Document): | |
201 | + url = models.URLField(blank=True) | |
202 | + | |
203 | + def check_details_filling(self): | |
204 | + if self.title == '' or self.original_lang == '' or self.url == '': | |
205 | + return False | |
206 | + return True | |
207 | + | |
208 | + @staticmethod | |
209 | + def get_doc_type_display(): | |
210 | + return 'serwis internetowy' | |
211 | + | |
212 | + | |
200 | 213 | class Article(Document): |
201 | 214 | @staticmethod |
202 | 215 | def get_doc_type_display(): |
... | ... | @@ -209,6 +222,19 @@ class Chapter(Document): |
209 | 222 | return 'rozdział' |
210 | 223 | |
211 | 224 | |
225 | +class WebPage(Document): | |
226 | + url = models.URLField(blank=True) | |
227 | + | |
228 | + def check_details_filling(self): | |
229 | + if self.title == '' or self.original_lang == '' or self.url == '': | |
230 | + return False | |
231 | + return True | |
232 | + | |
233 | + @staticmethod | |
234 | + def get_doc_type_display(): | |
235 | + return 'strona internetowa' | |
236 | + | |
237 | + | |
212 | 238 | class Chunk(models.Model): |
213 | 239 | document = models.ForeignKey(Document, related_name='chunks', on_delete=models.CASCADE) |
214 | 240 | sequence = models.PositiveIntegerField() |
... | ... |
collector/storage/templates/storage/annotation.html
... | ... | @@ -174,11 +174,19 @@ |
174 | 174 | <thead> |
175 | 175 | <tr id="doc-details"> |
176 | 176 | <th class="col-title">Tytuł</th> |
177 | + {% if document|isinst:"storage.models.WebPage" %} | |
178 | + <th>Adres URL</th> | |
179 | + {% endif %} | |
177 | 180 | <th>Język oryginału</th> |
178 | 181 | <th class="actions col-actions"> |
179 | 182 | {% if user.is_authenticated %} |
180 | - <i class="edit-doc-details material-icons button edit" data-id="{% url 'edit_subdoc_details' document.pk %}" | |
181 | - title="Edytuj">edit</i> | |
183 | + {% if document|isinst:"storage.models.WebPage" %} | |
184 | + <i class="edit-doc-details material-icons button edit" data-id="{% url 'edit_webpage_details' document.pk %}" | |
185 | + title="Edytuj">edit</i> | |
186 | + {% else %} | |
187 | + <i class="edit-doc-details material-icons button edit" data-id="{% url 'edit_subdoc_details' document.pk %}" | |
188 | + title="Edytuj">edit</i> | |
189 | + {% endif %} | |
182 | 190 | {% endif %} |
183 | 191 | </th> |
184 | 192 | </tr> |
... | ... | @@ -187,6 +195,9 @@ |
187 | 195 | <tbody> |
188 | 196 | <tr> |
189 | 197 | <td>{{ document.title }}</td> |
198 | + {% if document|isinst:"storage.models.WebPage" %} | |
199 | + <td>{{ document.url }}</td> | |
200 | + {% endif %} | |
190 | 201 | <td>{{ document.original_lang }}</td> |
191 | 202 | </tr> |
192 | 203 | <tr> |
... | ... | @@ -200,9 +211,17 @@ |
200 | 211 | <table class="data-table doc-table"> |
201 | 212 | <thead> |
202 | 213 | <tr id="doc-details"> |
203 | - <th class="col-title">Tytuł</th> | |
204 | - <th>Data publikacji</th> | |
205 | - <th>Miejsce publikacji</th> | |
214 | + {% if document|isinst:"storage.models.Website" %} | |
215 | + <th class="col-title">Nazwa</th> | |
216 | + {% else %} | |
217 | + <th class="col-title">Tytuł</th> | |
218 | + {% endif %} | |
219 | + {% if document|isinst:"storage.models.Website" %} | |
220 | + <th>Adres URL</th> | |
221 | + {% else %} | |
222 | + <th>Data publikacji</th> | |
223 | + <th>Miejsce publikacji</th> | |
224 | + {% endif %} | |
206 | 225 | {% if document|isinst:"storage.models.Magazine" %} |
207 | 226 | <th>Numer</th> |
208 | 227 | {% elif document|isinst:"storage.models.BookWithMultipleAuthors" %} |
... | ... | @@ -225,6 +244,9 @@ |
225 | 244 | {% elif document|isinst:"storage.models.Book" %} |
226 | 245 | <i class="edit-doc-details material-icons button edit" data-id="{% url 'edit_book_details' document.pk %}" |
227 | 246 | title="Edytuj">edit</i> |
247 | + {% elif document|isinst:"storage.models.Website" %} | |
248 | + <i class="edit-doc-details material-icons button edit" data-id="{% url 'edit_website_details' document.pk %}" | |
249 | + title="Edytuj">edit</i> | |
228 | 250 | {% elif document|isinst:"storage.models.Document" %} |
229 | 251 | <i class="edit-doc-details material-icons button edit" data-id="{% url 'edit_doc_details' document.pk %}" |
230 | 252 | title="Edytuj">edit</i> |
... | ... | @@ -237,8 +259,12 @@ |
237 | 259 | <tbody> |
238 | 260 | <tr> |
239 | 261 | <td>{{ document.title }}</td> |
240 | - <td>{{ document.publication_date|default_if_none:'' }}</td> | |
241 | - <td>{{ document.publication_place }}</td> | |
262 | + {% if document|isinst:"storage.models.Website" %} | |
263 | + <td>{{ document.url|default_if_none:'' }}</td> | |
264 | + {% else %} | |
265 | + <td>{{ document.publication_date|default_if_none:'' }}</td> | |
266 | + <td>{{ document.publication_place }}</td> | |
267 | + {% endif %} | |
242 | 268 | {% if document|isinst:"storage.models.Magazine" %} |
243 | 269 | <td>{{ document.number|default_if_none:'' }}</td> |
244 | 270 | {% elif document|isinst:"storage.models.BookWithMultipleAuthors" %} |
... | ... |
collector/storage/templates/storage/review.html
... | ... | @@ -125,46 +125,83 @@ |
125 | 125 | <div class="info"> |
126 | 126 | <p>Szczegóły:</p> |
127 | 127 | </div> |
128 | - | |
129 | - <table class="data-table doc-table"> | |
130 | - <thead> | |
131 | - <tr id="doc-details"> | |
132 | - <th class="col-title">Tytuł</th> | |
133 | - <th>Data publikacji</th> | |
134 | - <th>Miejsce publikacji</th> | |
135 | - {% if document|isinst:Magazine %} | |
136 | - <th>Numer</th> | |
137 | - {% elif document|isinst:BookWithMultipleAuthors %} | |
138 | - <th>Wydawca</th> | |
139 | - {% elif document|isinst:Book %} | |
140 | - <th>Wydawca</th> | |
141 | - {% endif %} | |
142 | - <th>Kanał</th> | |
143 | - <th>Typ</th> | |
144 | - <th class="col-text-origin">Pochodzenie</th> | |
145 | - <th>Język oryginału</th> | |
146 | - </tr> | |
147 | - </thead> | |
148 | - | |
149 | - <tbody> | |
150 | - <tr> | |
151 | - <td>{{ document.title }}</td> | |
152 | - <td>{{ document.publication_date|default_if_none:'' }}</td> | |
153 | - <td>{{ document.publication_place }}</td> | |
154 | - {% if document|isinst:Magazine %} | |
155 | - <td>{{ document.number }}</td> | |
156 | - {% elif document|isinst:BookWithMultipleAuthors %} | |
157 | - <td>{{ document.publisher }}</td> | |
158 | - {% elif document|isinst:Book %} | |
159 | - <td>{{ document.publisher }}</td> | |
160 | - {% endif %} | |
161 | - <td>{{ document.channel }}</td> | |
162 | - <td>{{ document.type }}</td> | |
163 | - <td>{{ document.text_origin }}</td> | |
164 | - <td>{{ document.original_lang }}</td> | |
165 | - </tr> | |
166 | - </tbody> | |
167 | - </table> | |
128 | + | |
129 | + {% if document.parent %} | |
130 | + | |
131 | + <table class="data-table doc-table"> | |
132 | + <thead> | |
133 | + <tr id="doc-details"> | |
134 | + <th class="col-title">Tytuł</th> | |
135 | + {% if document|isinst:"storage.models.WebPage" %} | |
136 | + <th>Adres URL</th> | |
137 | + {% endif %} | |
138 | + <th>Język oryginału</th> | |
139 | + </tr> | |
140 | + </thead> | |
141 | + | |
142 | + <tbody> | |
143 | + <tr> | |
144 | + <td>{{ document.title }}</td> | |
145 | + {% if document|isinst:"storage.models.WebPage" %} | |
146 | + <td>{{ document.url }}</td> | |
147 | + {% endif %} | |
148 | + <td>{{ document.original_lang }}</td> | |
149 | + </tr> | |
150 | + <tr> | |
151 | + <td colspan="3"></td> | |
152 | + </tr> | |
153 | + </tbody> | |
154 | + </table> | |
155 | + {% else %} | |
156 | + <table class="data-table doc-table"> | |
157 | + <thead> | |
158 | + <tr id="doc-details"> | |
159 | + {% if document|isinst:"storage.models.Website" %} | |
160 | + <th class="col-title">Nazwa</th> | |
161 | + <th>Adres URL</th> | |
162 | + {% else %} | |
163 | + <th class="col-title">Tytuł</th> | |
164 | + <th>Data publikacji</th> | |
165 | + <th>Miejsce publikacji</th> | |
166 | + {% endif %} | |
167 | + {% if document|isinst:"storage.models.Magazine" %} | |
168 | + <th>Numer</th> | |
169 | + {% elif document|isinst:"storage.models.BookWithMultipleAuthors" %} | |
170 | + <th>Wydawca</th> | |
171 | + {% elif document|isinst:"storage.models.Book" %} | |
172 | + <th>Wydawca</th> | |
173 | + {% endif %} | |
174 | + <th>Kanał</th> | |
175 | + <th>Typ</th> | |
176 | + <th class="col-text-origin">Pochodzenie</th> | |
177 | + <th>Język oryginału</th> | |
178 | + </tr> | |
179 | + </thead> | |
180 | + | |
181 | + <tbody> | |
182 | + <tr> | |
183 | + <td>{{ document.title }}</td> | |
184 | + {% if document|isinst:"storage.models.Website" %} | |
185 | + <td>{{ document.url|default_if_none:'' }}</td> | |
186 | + {% else %} | |
187 | + <td>{{ document.publication_date|default_if_none:'' }}</td> | |
188 | + <td>{{ document.publication_place }}</td> | |
189 | + {% endif %} | |
190 | + {% if document|isinst:"storage.models.Magazine" %} | |
191 | + <td>{{ document.number }}</td> | |
192 | + {% elif document|isinst:"storage.models.BookWithMultipleAuthors" %} | |
193 | + <td>{{ document.publisher }}</td> | |
194 | + {% elif document|isinst:"storage.models.Book" %} | |
195 | + <td>{{ document.publisher }}</td> | |
196 | + {% endif %} | |
197 | + <td>{{ document.channel }}</td> | |
198 | + <td>{{ document.type }}</td> | |
199 | + <td>{{ document.text_origin }}</td> | |
200 | + <td>{{ document.original_lang }}</td> | |
201 | + </tr> | |
202 | + </tbody> | |
203 | + </table> | |
204 | + {% endif %} | |
168 | 205 | |
169 | 206 | <div class="info"> |
170 | 207 | <p>Autorzy, tłumacze i redaktorzy:</p> |
... | ... |
collector/storage/urls.py
... | ... | @@ -16,8 +16,12 @@ urlpatterns = [ |
16 | 16 | name='edit_bwma_details'), |
17 | 17 | path('document/edit-book-details/<int:pk>', login_required(views.BookDetailsEditView.as_view()), |
18 | 18 | name='edit_book_details'), |
19 | + path('document/edit-website-details/<int:pk>', login_required(views.WebsiteDetailsEditView.as_view()), | |
20 | + name='edit_website_details'), | |
19 | 21 | path('document/edit-subdoc-details/<int:pk>', login_required(views.SubDocDetailsEditView.as_view()), |
20 | 22 | name='edit_subdoc_details'), |
23 | + path('document/edit-webpage-details/<int:pk>', login_required(views.WebPageDetailsEditView.as_view()), | |
24 | + name='edit_webpage_details'), | |
21 | 25 | path('chunk/add/<str:doc_id>', login_required(views.ChunkAddBetweenView.as_view()), name='add_chunk_between'), |
22 | 26 | path('chunk/add/<str:doc_id>/<int:pk>', login_required(views.ChunkAddBetweenView.as_view()), |
23 | 27 | name='add_chunk_between'), |
... | ... |
collector/storage/utils.py
1 | -from .models import Document, Magazine, Book, BookWithMultipleAuthors, Article, Chapter | |
1 | +from .models import Document, Magazine, Book, BookWithMultipleAuthors, Website, Article, Chapter, WebPage | |
2 | 2 | |
3 | -DOCUMENT_TYPES_CLASSES = Document, Magazine, Book, BookWithMultipleAuthors | |
3 | +DOCUMENT_TYPES_CLASSES = Document, Magazine, Book, BookWithMultipleAuthors, Website | |
4 | 4 | |
5 | 5 | SUBDOCUMENT_TYPES = { # first subdocument type in tuples are the default ones for this type of the document |
6 | 6 | Document: (Document,), |
7 | 7 | Magazine: (Article,), |
8 | 8 | Book: (Chapter,), |
9 | - BookWithMultipleAuthors: (Chapter,) | |
9 | + BookWithMultipleAuthors: (Chapter,), | |
10 | + Website: (WebPage,) | |
10 | 11 | } |
11 | 12 | |
12 | 13 | |
... | ... |
collector/storage/views.py
... | ... | @@ -22,9 +22,10 @@ from sys import maxsize, modules |
22 | 22 | from functools import partial, wraps |
23 | 23 | |
24 | 24 | from .forms import ChunkForm, ParticipantForm, SubchunkForm, MetadataForm, KeywordForm, DocSplitForm, ChunkMoveForm, \ |
25 | - SubDocDetailsForm, AuthorForm, ChunkMergeForm, ChunkSplitForm, DocTypeForm, DocDetailsForm, MagazineDetailsForm, \ | |
26 | - BookDetailsForm, BWMADetailsForm | |
27 | -from .models import Chunk, Document, Participant, Metadata, Keyword, Annotation, Magazine, Book, BookWithMultipleAuthors | |
25 | + SubDocDetailsForm, WebPageDetailsForm, AuthorForm, ChunkMergeForm, ChunkSplitForm, DocTypeForm, DocDetailsForm, \ | |
26 | + MagazineDetailsForm, BookDetailsForm, BWMADetailsForm, WebsiteDetailsForm | |
27 | +from .models import Chunk, Document, Participant, Metadata, Keyword, Annotation, Magazine, Book, \ | |
28 | + BookWithMultipleAuthors, Website, Article, Chapter, WebPage | |
28 | 29 | from .utils import get_remaining_doc_types_tuple, get_remaining_subdoc_types_tuple, get_doc_with_type, SUBDOCUMENT_TYPES |
29 | 30 | from projects.ppc.models import Utterance |
30 | 31 | from pipeline.models import ProcessingStatus |
... | ... | @@ -781,10 +782,20 @@ class BWMADetailsEditView(DocDetailsEditView): |
781 | 782 | form_class = BWMADetailsForm |
782 | 783 | |
783 | 784 | |
785 | +class WebsiteDetailsEditView(DocDetailsEditView): | |
786 | + model = Website | |
787 | + form_class = WebsiteDetailsForm | |
788 | + | |
789 | + | |
784 | 790 | class SubDocDetailsEditView(DocDetailsEditView): |
785 | 791 | form_class = SubDocDetailsForm |
786 | 792 | |
787 | 793 | |
794 | +class WebPageDetailsEditView(DocDetailsEditView): | |
795 | + model = WebPage | |
796 | + form_class = WebPageDetailsForm | |
797 | + | |
798 | + | |
788 | 799 | def add_keyword(request, doc_id): |
789 | 800 | if request.method == 'POST': |
790 | 801 | form = KeywordForm(request.POST) |
... | ... | @@ -905,6 +916,7 @@ class FinishAnnotationView(RedirectView): |
905 | 916 | messages.error(request, 'Błąd: Dokument posiada tłumacza, ale posiada polski język oryginału.') |
906 | 917 | return HttpResponseRedirect(reverse('annotation', kwargs={'doc_id': document.id})) |
907 | 918 | for subdoc in subdocuments: |
919 | + subdoc = get_doc_with_type(subdoc.id) | |
908 | 920 | if not subdoc.check_details_filling(): |
909 | 921 | messages.error(request, f'Błąd: Nie wypełniono wszystkich szczegółów poddokumentu o ID "{subdoc.id}".') |
910 | 922 | return HttpResponseRedirect(reverse('annotation', kwargs={'doc_id': document.id})) |
... | ... | @@ -955,7 +967,6 @@ class DocSplitView(UpdateView): |
955 | 967 | parent = self.object.parent |
956 | 968 | self.object = get_doc_with_type(self.object.id) |
957 | 969 | subdocument_class = SUBDOCUMENT_TYPES[type(self.object)][0] |
958 | - print('sd class: ', subdocument_class) | |
959 | 970 | new_document = subdocument_class.objects.create(name=parent.name, |
960 | 971 | lang=parent.lang, |
961 | 972 | original_lang=parent.original_lang, |
... | ... | @@ -1073,7 +1084,7 @@ class DocumentListView(ListView): |
1073 | 1084 | else: |
1074 | 1085 | docs = docs.order_by(order_by) |
1075 | 1086 | |
1076 | - return docs | |
1087 | + return docs.distinct() | |
1077 | 1088 | |
1078 | 1089 | |
1079 | 1090 | class RetakeDocForAnnoView(UserPassesTestMixin, RedirectView): |
... | ... | @@ -1163,7 +1174,8 @@ def change_doc_type(doc, target_type): |
1163 | 1174 | processing_status=doc.processing_status, |
1164 | 1175 | new=doc.new, |
1165 | 1176 | unk_coverage=doc.unk_coverage, |
1166 | - sequence=1000000) | |
1177 | + sequence=1000000, | |
1178 | + parent=doc.parent) | |
1167 | 1179 | seq = doc.sequence |
1168 | 1180 | new_doc.keywords.add(*doc.keywords.all()) |
1169 | 1181 | subdocs = Document.objects.filter(parent=doc) |
... | ... |