Commit 66d407a0c3369ae02b221e176a1b7e5a0793021e

Authored by Bartłomiej Nitoń
1 parent 9adac789

Add Website and WebPage Document types.

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)
... ...