for work_type in WorkType.objects.all()
}
- def scans_gallery(self):
- bs = self.booksource_set.first()
- if bs is None:
- return ''
- return bs.pk
+ def scans_galleries(self):
+ return [bs.pk for bs in self.booksource_set.all()]
def is_published(self):
return any(b.is_published() for b in self.document_books.all())
self._content_stats = stats
return stats
+ @property
+ def are_sources_ready(self):
+ if not self.booksource_set.exists():
+ return False
+ for bs in self.booksource_set.all():
+ if not bs.source.has_view_files() or not bs.source.has_ocr_files() or bs.source.modified_at > bs.source.processed_at:
+ return False
+ return True
+
chars = lambda self: self.content_stats.get('chars', '')
chars_with_fn = lambda self: self.content_stats.get('chars_with_fn', '')
words = lambda self: self.content_stats.get('words', '')
Źródło
</div>
<div class="card-body">
- {% for bs in book.booksource_set.all %}
- <a href="{{ bs.source.get_absolute_url }}">
- {{ bs.source }}
- </a>
- {% if bs.page_start or bs.page_end %}
- (strony {{ bs.page_start }}—{{ bs.page_end }})
- {% else %}
- <small>
- (źródło w całości przypisane do utworu <em>{{ book }}</em>)
- </small>
- {% endif %}
-
- {% if not bs.source.has_upload_files %}
-
- <div class="alert alert-info">
- Źródło nie ma jeszcze załadowanych skanów.
- <a href="{% url 'source_upload' bs.source.id %}">
- Załaduj skany</a>.
- </div>
+ <table class="table">
+ <tbody>
+ {% for bs in book.booksource_set.all %}
+ <tr>
+ <td>
+ <a href="{{ bs.source.get_absolute_url }}">
+ {{ bs.source }}
+ </a>
+ </td>
+ <td>
+ {% if bs.page_start or bs.page_end %}
+ (strony {{ bs.page_start }}—{{ bs.page_end }})
+ {% else %}
+ <small>
+ (źródło w całości przypisane do utworu <em>{{ book }}</em>)
+ </small>
+ {% endif %}
+ </td>
+ <td>
+ {% if not bs.source.has_upload_files %}
+ <div class="alert alert-info">
+ Źródło nie ma jeszcze załadowanych skanów.
+ <a href="{% url 'source_upload' bs.source.id %}">
+ Załaduj skany</a>.
+ </div>
+ {% elif not bs.source.has_view_files %}
+ <div class="alert alert-info">
+ Trwa generowanie podglądu.
+ </div>
+ {% elif not bs.source.has_ocr_files %}
+ <div class="alert alert-info">
+ Trwa OCR.
+ </div>
+ {% elif bs.source.modified_at > bs.source.processed_at %}
+ <div class="alert alert-info">
+ Zmodyfikowano skany, trwa aktualizacja.
+ </div>
+ {% endif %}
+ </td>
+ </tr>
+ {% empty %}
+ Brak źródła.
+ Możesz je dodać.
+ {% endfor %}
+ </tbody>
+ </table>
- {% elif not bs.source.has_view_files %}
- <div class="alert alert-info">
- Trwa generowanie podglądu.
- </div>
- {% elif not bs.source.has_ocr_files %}
- <div class="alert alert-info">
- Trwa OCR.
- </div>
- {% elif bs.source.modified_at > bs.source.processed_at %}
- <div class="alert alert-info">
- Zmodyfikowano skany, trwa aktualizacja.
- </div>
- {% else %}
- <form method="post" action="{% url 'source_book_prepare' bs.pk %}">
- {% csrf_token %}
- <button class="btn btn-primary">Utwórz tekst książki</button>
- </form>
- {% endif %}
- {% empty %}
- Brak źródła.
- Możesz je dodać.
- {% endfor %}
+ <form method="post" action="{% url 'source_book_prepare' book.pk %}">
+ {% csrf_token %}
+ <button class="btn btn-primary"
+ {% if not book.are_sources_ready %}disabled="disabled"{% endif %}
+ >Utwórz tekst książki</button>
+ </form>
</div>
</div>
from django.conf import settings
-def build_document_texts(book_source):
+def build_document_texts(book):
texts = []
for builder in text_builders:
root = etree.Element('utwor')
# add meta
- add_rdf(root, book_source)
+ add_rdf(root, book)
# add master
master = etree.SubElement(root, 'powiesc')
- for page in book_source.get_ocr_files():
- builder(master, page)
-
+ for book_source in book.booksource_set.all():
+ for page in book_source.get_ocr_files():
+ builder(master, page)
+
texts.append(etree.tostring(root, encoding='unicode', pretty_print=True))
return texts
]
-def add_rdf(root, book_source):
- book = book_source.book
-
+def add_rdf(root, book):
# TODO: to librarian
rdf = etree.SubElement(root, RDFNS('RDF'))
desc = etree.SubElement(rdf, RDFNS('Description'), **{})
etree.SubElement(desc, DCNS('language')).text = book.language # 3to2?
#description
#source_name
- etree.SubElement(desc, DCNS('source')).text = book_source.source.name
+ # TODO: allow multiple source meta entries.
+ sources = []
+ for book_source in book.booksource_set.all():
+ sources.append(book_source.source.name)
+ etree.SubElement(desc, DCNS('source')).text = ';\n '.join(sources)
#url
etree.SubElement(desc, DCNS('identifier.url')).text = f'https://wolnelektury.pl/katalog/lektura/{book.slug}/'
#license?
--- /dev/null
+# Generated by Django 4.1.9 on 2024-05-22 15:26
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("sources", "0003_source_modified_at_source_processed_at"),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name="booksource",
+ options={"ordering": ("ordering", "page_start")},
+ ),
+ migrations.AddField(
+ model_name="booksource",
+ name="ordering",
+ field=models.IntegerField(default=1),
+ ),
+ ]
class BookSource(models.Model):
book = models.ForeignKey('catalogue.Book', models.CASCADE)
source = models.ForeignKey(Source, models.CASCADE)
+ ordering = models.IntegerField(default=1)
page_start = models.IntegerField(null=True, blank=True)
page_end = models.IntegerField(null=True, blank=True)
class Meta:
- ordering = ('page_start',)
+ ordering = ('ordering', 'page_start',)
def __str__(self):
return f'{self.source} -> {self.book}'
def get_document(self):
return self.book.document_books.first()
-
- def prepare_document(self, user=None):
+
+ @classmethod
+ def prepare_document(cls, book, user=None):
DBook = apps.get_model('documents', 'Book')
- texts = document.build_document_texts(self)
+ texts = document.build_document_texts(book)
- dbook = self.get_document()
+ dbook = book.document_books.first()
if dbook is None:
dbook = DBook.create(
user, texts[0],
- title=self.book.title,
+ title=book.title,
slug=str(uuid.uuid4()),
)
else:
urlpatterns = [
path('source/<int:pk>/', views.SourceView.as_view(), name='source'),
path('upload/<int:sid>/', views.SourceUploadView.as_view(), name='source_upload'),
- path('prepare/<int:bsid>/', views.prepare, name='source_book_prepare'),
+ path('prepare/book/<int:pk>/', views.prepare, name='source_book_prepare'),
]
from django.utils.translation import gettext as _
from django.views.generic import DetailView
from fileupload.views import UploadView
+import catalogue.models
from . import models
return response
-def prepare(request, bsid):
- bs = get_object_or_404(models.BookSource, id=bsid)
+def prepare(request, pk):
+ book = get_object_or_404(catalogue.models.Book, id=pk)
if request.POST:
- dbook = bs.prepare_document(request.user)
+ dbook = models.BookSource.prepare_document(book, request.user)
return redirect('wiki_editor', dbook.slug, dbook[0].slug)
else:
- return render(
- request,
- 'sources/prepare.html',
- {
- 'book_source': bs,
- }
- )
+ return redirect(book.get_absolute_url())
data-chunk-id="{{ chunk.pk }}" style="display:none">
<span data-key="book-slug">{{ chunk.book.slug }}</span>
- <span data-key="scans">{{ chunk.book.catalogue_book.scans_gallery }}</span>
+ <span data-key="scans">{{ chunk.book.catalogue_book.scans_galleries|join:',' }}</span>
<span data-key="gallery">{{ chunk.book.gallery }}</span>
<span data-key="gallery-start">{% if chunk.gallery_start %}{{ chunk.gallery_start }}{% endif %}</span>
<span data-key="revision">{{ revision }}</span>
views.editor_readonly, name="wiki_editor_readonly"),
path('gallery/<directory>/', views.gallery, name="wiki_gallery"),
- path('scans/<int:pk>/', views.scans_list, name="wiki_scans"),
+ path('scans/<str:pks>/', views.scans_list, name="wiki_scans"),
path('history/<int:chunk_id>/', views.history, name="wiki_history"),
path('rev/<int:chunk_id>/', views.revision, name="wiki_revision"),
path('text/<int:chunk_id>/', views.text, name="wiki_text"),
@never_cache
-def scans_list(request, pk):
- bs = get_object_or_404(sources.models.BookSource, pk=pk)
+def scans_list(request, pks):
+ pks = pks.split(',')
+ bss = [
+ get_object_or_404(sources.models.BookSource, pk=pk)
+ for pk in pks
+ ]
def map_to_url(filename):
return quote(("%s/%s" % (settings.MEDIA_URL, filename)))
- images = [
- {
- "url": map_to_url(f),
- } for f in bs.get_view_files()
- ]
+ images = []
+ for bs in bss:
+ images.extend([
+ {
+ "url": map_to_url(f),
+ } for f in bs.get_view_files()
+ ])
return JSONResponse(images)