1 from datetime import date
 
   2 from django.apps import apps
 
   3 from django.db import models
 
   6 from .product_forms import FORMS
 
   9 class IsbnPool(models.Model):
 
  10     PURPOSE_GENERAL = 'GENERAL'
 
  13         (PURPOSE_WL, 'Wolne Lektury'),
 
  14         (PURPOSE_GENERAL, 'Ogólne'),
 
  17     prefix = models.CharField(max_length=10)
 
  18     suffix_from = models.IntegerField()
 
  19     suffix_to = models.IntegerField()
 
  20     ref_from = models.IntegerField()
 
  21     purpose = models.CharField(max_length=8, choices=PURPOSE_CHOICES)
 
  28             'X' * (12 - len(self.prefix)),
 
  33     def check_digit(prefix12):
 
  34         digits = [int(d) for d in prefix12]
 
  35         return str((-sum(digits[0::2]) + 7 * sum(digits[1::2])) % 10)
 
  37     def get_code(self, suffix, dashes=False):
 
  38         suffix_length = 12 - len(self.prefix)
 
  39         suffix_str = f'{suffix:0{suffix_length}d}'
 
  40         prefix12 = self.prefix + suffix_str
 
  41         check_digit = self.check_digit(prefix12)
 
  59         return self.suffix_to - self.suffix_from + 1
 
  63         return self.isbn_set.count()
 
  66     def fill_percentage(self):
 
  67         return 100 * self.entries / self.size
 
  69     def bn_record_id_for(self, suffix):
 
  70         return self.ref_from + suffix
 
  72     def import_all_bn_data(self):
 
  73         for suffix in range(self.suffix_from, self.suffix_to + 1):
 
  75             self.import_bn_data_for(suffix)
 
  77     def import_bn_data_for(self, suffix):
 
  78         record_id = self.bn_record_id_for(suffix)
 
  79         content = requests.get(
 
  80             f'https://e-isbn.pl/IsbnWeb/record/export_onix.xml?record_id={record_id}').content
 
  81         elem = etree.fromstring(content)
 
  82         product = elem.find('{http://ns.editeur.org/onix/3.0/reference}Product')
 
  83         if product is not None:
 
  84             isbn, created = self.isbn_set.get_or_create(
 
  87             isbn.bn_data = etree.tostring(product, pretty_print=True, encoding='unicode')
 
  88             isbn.save(update_fields=['bn_data'])
 
  91 class Isbn(models.Model):
 
  92     pool = models.ForeignKey(IsbnPool, models.PROTECT)
 
  93     suffix = models.IntegerField()
 
  94     datestamp = models.DateField(blank=True, null=True)
 
  95     book = models.ForeignKey(
 
  96         'catalogue.Book', models.PROTECT, null=True, blank=True
 
  98     form = models.CharField(
 
  99         max_length=32, choices=[
 
 101             for form, config in FORMS
 
 104     bn_data = models.TextField(blank=True)
 
 105     wl_data = models.TextField(blank=True)
 
 106     notes = models.TextField(blank=True)
 
 109         ordering = ['pool', 'suffix']
 
 110         unique_together = ['pool', 'suffix']
 
 113         return self.get_code(True)
 
 115     def get_code(self, dashes=True):
 
 116         return self.pool.get_code(self.suffix, dashes=dashes)
 
 119     def get_for_book(cls, book, form):
 
 120         isbn = cls.objects.filter(book=book, form=form).first()
 
 122             return cls.assign(book, form)
 
 126     def assign(cls, book, form):
 
 127         pool = IsbnPool.objects.filter(purpose=IsbnPool.PURPOSE_WL).first()
 
 128         suffix = pool.isbn_set.aggregate(s=models.Max('suffix'))['s'] + 1
 
 129         assert suffix <= pool.suffix_to
 
 130         return pool.isbn_set.create(
 
 131             book=book, form=form, suffix=suffix, datestamp=date.today()
 
 135     def formats_from_document(cls, document):
 
 138             meta = document.wldocument(librarian2=True).meta
 
 141         is_parent = len(meta.parts)
 
 143         for form, config in FORMS:
 
 144             if config.book and (not is_parent or config.parent):
 
 147                     getattr(meta, f'isbn_{form}')
 
 152     def import_from_documents(cls):
 
 153         Book = apps.get_model('documents', 'Book')
 
 154         for book in Book.objects.all():
 
 156                 catalogue_book = book.catalogue_book
 
 157                 if catalogue_book is None:
 
 162                 meta = book.wldocument(publishable=False, librarian2=True).meta
 
 165             for form in ('html', 'txt', 'pdf', 'epub', 'mobi'):
 
 166                 isbn = getattr(meta, f'isbn_{form}')
 
 168                     parts = isbn.split('-')
 
 169                     assert parts[0] == 'ISBN'
 
 170                     suffix = int(parts[-2])
 
 171                     prefix = ''.join(parts[1:-2])
 
 172                     pool = IsbnPool.objects.get(prefix=prefix)
 
 173                     isbn, created = pool.isbn_set.get_or_create(
 
 177                     if isbn.book is None:
 
 178                         isbn.book = catalogue_book
 
 179                     elif isbn.book != catalogue_book:
 
 183                     elif isbn.form != form:
 
 186                         isbn.notes += '\n\n' + catalogue_book.slug + ' ' + form
 
 187                     isbn.save(update_fields=['book', 'form', 'notes'])