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):
137 meta = document.wldocument(librarian2=True).meta
138 is_parent = len(meta.parts)
140 for form, config in FORMS:
141 if config.book and (not is_parent or config.parent):
144 getattr(meta, f'isbn_{form}')
149 def import_from_documents(cls):
150 Book = apps.get_model('documents', 'Book')
151 for book in Book.objects.all():
153 catalogue_book = book.catalogue_book
154 if catalogue_book is None:
159 meta = book.wldocument(publishable=False, librarian2=True).meta
162 for form in ('html', 'txt', 'pdf', 'epub', 'mobi'):
163 isbn = getattr(meta, f'isbn_{form}')
165 parts = isbn.split('-')
166 assert parts[0] == 'ISBN'
167 suffix = int(parts[-2])
168 prefix = ''.join(parts[1:-2])
169 pool = IsbnPool.objects.get(prefix=prefix)
170 isbn, created = pool.isbn_set.get_or_create(
174 if isbn.book is None:
175 isbn.book = catalogue_book
176 elif isbn.book != catalogue_book:
180 elif isbn.form != form:
183 isbn.notes += '\n\n' + catalogue_book.slug + ' ' + form
184 isbn.save(update_fields=['book', 'form', 'notes'])