{% load book_list i18n %}
{% load bootstrap4 %}
{% load depot %}
+{% load isbn %}
{% block titleextra %}{{ book.title }}{% endblock %}
<a href="{% url 'documents_book_mobi' book.slug %}" rel="nofollow">{% trans "MOBI version" %}</a><br/>
</p>
+ {% isbn_status book %}
+
{% if user.is_authenticated %}
<!--
Angel photos:
tabs.append(Tab('upload', _('Upload'), reverse("documents_upload")))
tabs.append(Tab('cover', _('Covers'), reverse("cover_image_list")))
+ tabs.append(Tab('isbn', 'ISBN', reverse("isbn_list")))
return {"tabs": tabs, "active_tab": active}
+from datetime import date
from django.apps import apps
from django.db import models
from lxml import etree
def get_code(self, dashes=True):
return self.pool.get_code(self.suffix, dashes=dashes)
+ @classmethod
+ def get_for_book(cls, book, form):
+ isbn = cls.objects.filter(book=book, form=form).first()
+ if isbn is None:
+ return cls.assign(book, form)
+ return isbn
+
+ @classmethod
+ def assign(cls, book, form):
+ pool = IsbnPool.objects.filter(purpose=IsbnPool.PURPOSE_WL).first()
+ suffix = pool.isbn_set.aggregate(s=models.Max('suffix'))['s'] + 1
+ assert suffix <= pool.suffix_to
+ return pool.isbn_set.create(
+ book=book, form=form, suffix=suffix, datestamp=date.today()
+ )
+
+ @classmethod
+ def formats_from_document(cls, document):
+ # This is a document
+ meta = document.wldocument(librarian2=True).meta
+ is_parent = len(meta.parts)
+ formats = []
+ for form, config in FORMS:
+ if config.book and (not is_parent or config.parent):
+ formats.append((
+ form,
+ getattr(meta, f'isbn_{form}')
+ ))
+ return formats
+
@classmethod
def import_from_documents(cls):
Book = apps.get_model('documents', 'Book')
+from collections import namedtuple
+
+FormConfig = namedtuple('FormConfig', ['book', 'parent', 'product_form', 'product_form_detail'])
+
FORMS = [
- ('html', ('EC', 'E105')),
- ('txt', ('EB', 'E112')),
- ('pdf', ('EB', 'E107')),
- ('epub', ('ED', 'E101')),
- ('mobi', ('ED', 'E127')),
- ('mp3', ('AN', 'A103')),
- ('paperback', ('BC', '')),
+ ('html', FormConfig(True, False, 'EC', 'E105')),
+ ('txt', FormConfig(True, False, 'EB', 'E112')),
+ ('pdf', FormConfig(True, True, 'EB', 'E107')),
+ ('epub', FormConfig(True, True, 'ED', 'E101')),
+ ('mobi', FormConfig(True, True, 'ED', 'E127')),
+ ('mp3', FormConfig(False, False, 'AN', 'A103')),
+ ('paperback', FormConfig(False, False, 'BC', '')),
]
--- /dev/null
+<div class="row mb-4">
+ <div class="col-4">
+ ISBN
+ {% for form, value in formats %}
+ <span class="badge badge-{% if value %}primary{% else %}secondary{% endif %}" title="{{ value }}">{{ form }}</span>
+ {% endfor %}
+ </div>
+ <div class="col-4">
+ {% if can_generate %}
+ <form method="post" action="{% url 'isbn_generate' book.pk %}">
+ {% csrf_token %}
+ <button class="btn btn-primary btn-sm">
+ uzupełnij
+ </button>
+ </form>
+ {% endif %}
+ {{ error }}
+ </div>
+</div>
--- /dev/null
+from django.template import Library
+from isbn.models import Isbn
+
+
+register = Library()
+
+
+@register.inclusion_tag('isbn/isbn_status.html', takes_context=True)
+def isbn_status(context, book):
+ user = context['request'].user
+ formats = Isbn.formats_from_document(book)
+
+ can_generate = False
+ error = ''
+ for f, v in formats:
+ if not v:
+ can_generate = True
+
+ if can_generate:
+ if not user.has_perm('isbn.add_isbn'):
+ can_generate = False
+
+ if can_generate:
+ try:
+ book.catalogue_book
+ except:
+ can_generate = False
+ error = 'Brak książki w katalogu.'
+
+ return {
+ 'book': book,
+ 'formats': formats,
+ 'can_generate': can_generate,
+ 'error': error,
+ }
+
urlpatterns = [
path('', views.isbn_list, name='isbn_list'),
+ path('genarate/<int:document_id>/', views.generate, name='isbn_generate'),
]
-from django.shortcuts import render
+from django.contrib.auth.decorators import permission_required
+from django.shortcuts import render, get_object_or_404, redirect
+from librarian import DCNS, RDFNS
+from lxml import etree
+from documents.models import Book
from .models import Isbn, IsbnPool
'pools': IsbnPool.objects.all(),
'list': Isbn.objects.all(),
})
+
+
+MIME = {
+ 'html': 'text/html',
+ 'pdf': 'application/pdf',
+ 'txt': 'text/plain',
+ 'epub': 'application/epub+zip',
+ 'mobi': 'application/x-mobipocket-ebook',
+}
+
+
+@permission_required('isbn.add_isbn')
+def generate(request, document_id):
+ document = get_object_or_404(Book, id=document_id)
+ book = document.catalogue_book
+ chunk = document[0]
+ head = chunk.head
+ orig_xml = head.materialize()
+ tree = etree.fromstring(orig_xml)
+ rdfdesc = tree.find('.//' + RDFNS('Description'))
+
+ for form, value in Isbn.formats_from_document(document):
+ if value: continue
+ isbn = Isbn.get_for_book(book, form)
+
+ etree.SubElement(rdfdesc, DCNS('relation.hasFormat'), id="mobi").text = f"https://wolnelektury.pl/media/book/{form}mobi/{book.slug}.{form}"
+ etree.SubElement(
+ rdfdesc, 'meta', refines=f'#{form}', id=f'{form}-id', property='dcterms:identifier'
+ ).text = 'ISBN-' + isbn.get_code(True)
+ etree.SubElement(rdfdesc, 'meta', refines=f'#{form}-id', property='identifier-type').text = 'ISBN'
+ etree.SubElement(rdfdesc, 'meta', refines=f'#{form}', property='dcterms:format').text = MIME[form]
+
+ xml = etree.tostring(tree, encoding='unicode')
+ chunk.commit(
+ text=xml,
+ author=request.user,
+ parent=head,
+ description='Auto ISBN',
+ publishable=head.publishable
+ )
+
+ return redirect(document.get_absolute_url())