1 from datetime import date
3 from django.conf import settings
4 from librarian.functions import lang_code_3to2
5 from librarian.html import transform_abstrakt
6 from librarian.builders import EpubBuilder, MobiBuilder
7 from librarian.covers.marquise import MarquiseCover, LabelMarquiseCover
9 from slugify import slugify
14 "Książka, którą czytasz, pochodzi z <a href=\"https://wolnelektury.pl/\">Wolnych Lektur</a>. Naszą misją jest wspieranie dzieciaków w dostępie do lektur szkolnych oraz zachęcanie ich do czytania. Miło Cię poznać!",
15 "Podoba Ci się to, co robimy? Jesteśmy organizacją pożytku publicznego. Wesprzyj Wolne Lektury drobną wpłatą: <a href=\"https://wolnelektury.pl/towarzystwo/\">wolnelektury.pl/towarzystwo/</a>",
16 "Przyjaciele Wolnych Lektur otrzymują dostęp do prapremier wcześniej niż inni. Zadeklaruj stałą wpłatę i dołącz do Towarzystwa Przyjaciół Wolnych Lektur: <a href=\"https://wolnelektury.pl/towarzystwo/\">wolnelektury.pl/towarzystwo/</a>",
17 "Informacje o nowościach w naszej bibliotece w Twojej skrzynce mailowej? Nic prostszego, zapisz się do newslettera. Kliknij, by pozostawić swój adres e-mail: <a href=\"https://wolnelektury.pl/newsletter/zapisz-sie/\">wolnelektury.pl/newsletter/zapisz-sie/</a>",
18 "Przekaż 1% podatku na Wolne Lektury.<br/>\nKRS: 0000070056<br/>\nNazwa organizacji: Fundacja Nowoczesna Polska<br/>\nKażda wpłacona kwota zostanie przeznaczona na rozwój Wolnych Lektur."
21 description_add = '<p>Książkę polecają <a href="https://wolnelektury.pl">Wolne Lektury</a> — najpopularniejsza biblioteka on-line.</p>'
25 #BASE_URL = 'https://wydawca.legimi.com'
26 BASE_URL = 'https://panel.legimi.pl'
27 LOGIN_URL = BASE_URL + '/publishers/membership'
28 UPLOAD_URL = BASE_URL + '/administration/upload/start'
29 CREATE_URL = BASE_URL + '/publishers/publications/create'
30 EDIT_URL = BASE_URL + '/publishers/publications/edit/%s'
31 EDIT_FILES_URL = BASE_URL + '/publishers/publications/editfiles/%s'
32 EDIT_SALE_URL = BASE_URL + '/publishers/publications/editsale/%s'
35 'Dla dzieci i młodzieży': 94,
36 'Książki dla dzieci': 15,
37 'Literatura młodzieżowa': 24,
39 'Kryminał klasyczny': 31,
40 'Kryminał współczesny': 32,
41 'Kryminał historyczny': 30,
44 'Słowniki i leksykony': 14,
50 'Dwudziestolecie międzywojenne': 88,
59 'Fantastyka i sci-fi': 25,
61 'Science fiction': 27,
63 'Antyki i kolekcjonerstwo': 53,
64 'Astrologia i wróżbiarstwo': 54,
65 'Zdrowie i rodzina': 57,
67 'Medycyna i zdrowie': 58,
71 'Kultura i sztuka': 64,
74 'Eseje literackie': 49,
77 'Wakacje i podróże': 69,
80 'Obyczajowe i romanse': 93,
84 'Powieść przygodowa': 42,
85 'Współczesna powieść przygodowa': 44,
86 'Historyczna powieść przygodowa': 43,
87 'Powieść historyczna': 46,
88 'Powieść psychologiczna': 47,
89 'Powieść religijna': 45,
91 'Romans klasyczny': 38,
92 'Romans współczesny': 39,
93 'Literatura erotyczna': 40,
94 'Romans historyczny': 37,
96 'Sensacja, thriller, horror': 91,
102 'Literatura faktu, reportaże, biografie': 92,
103 'Literatura faktu': 16,
107 'Dokument, esej': 18,
108 'Historia literatury i krytyka literacka': 23,
109 'Literatura popularnonaukowa': 22,
111 'Społeczno-polityczne': 72,
112 'Poezja i dramat': 95,
115 'Religia i duchowość': 51,
116 'Nauka i nowe technologie': 98,
117 'Nauka i technika': 61,
119 'Nauki humanistyczne': 63,
120 'Technologia i Internet': 75,
121 'Specjalistyczne': 99,
122 'Biznes i finanse': 1,
127 'Rozwój osobisty': 7,
128 'Kariera i sukces zawodowy': 8,
129 'Psychologia, motywacja': 9,
135 def __init__(self, username, password, publisher_id):
136 self.username = username
137 self.password = password
138 self.publisher_id = publisher_id
143 if self._session is None:
144 session = requests.Session()
145 response = session.post(
148 'ValidationTrue': 'true',
149 'UserName': self.username,
150 'Password': self.password,
152 self._session = session
156 return self.session.get('https://wydawca.legimi.com/publishers/publications')
158 def upload(self, content):
159 response = self.session.post(
164 model = response.json()['model']
166 "name": model['Name'],
167 "token": model['Token'],
171 def send_book(self, book, changes=None):
172 wlbook = book.wldocument(librarian2=True, changes=changes)
175 cover = LabelMarquiseCover(meta, width=1200).output_file()
176 epub_file = EpubBuilder(
178 fundraising=fundraising,
179 base_url='file://' + book.gallery_path() + '/'
180 ).build(wlbook).get_file()
181 mobi_file = MobiBuilder(
183 fundraising=fundraising,
184 base_url='file://' + book.gallery_path() + '/'
185 ).build(wlbook).get_file()
189 thema.append(meta.thema_main)
190 thema.extend(meta.thema)
194 "Author": ", ".join(p.readable() for p in meta.authors),
195 "Year": str(date.today().year),
197 'GenreId': str(self.get_genre(wlbook)),
198 'themaCategories': ';'.join(thema),
201 'LanguageLocale': lang_code_3to2(meta.language),
203 'Description': self.get_description(wlbook),
206 isbn = meta.isbn_html
207 if isbn.upper().startswith(('ISBN ', 'ISBN-')):
210 book_data['Isbn'] = isbn
214 cover_data = self.upload(
215 (meta.url.slug + '.jpg', cover.get_file(), 'image/jpeg')
218 "Cover.Name": cover_data['name'],
219 "Cover.Token": cover_data['token'],
220 "Cover.Url": cover_data['url'],
223 epub_data = self.upload(
224 (meta.url.slug + '.epub', epub_file, 'application/epub+zip')
227 'BookEpub.Token': epub_data['token'],
228 'BookEpub.Name': epub_data['name'],
229 'SampleEpubType': 'Generation',
232 mobi_data = self.upload(
233 (meta.url.slug + '.mobi', mobi_file, 'application/x-mobipocket-ebook')
236 'BookMobi.Token': mobi_data['token'],
237 'BookMobi.Name': mobi_data['name'],
250 legimi_id = self.create_book(book_data, files_data)
252 book.legimi_id = legimi_id
253 book.save(update_fields=['legimi_id'])
255 def get_description(self, wlbook):
257 abstract = wlbook.tree.find('.//abstrakt')
258 if abstract is not None:
259 description = transform_abstrakt(abstract)
260 description += description_add
262 description += ', '.join(
263 '<a href="https://wolnelektury.pl/katalog/autor/{}/">{}</a>'.format(
264 slugify(p.readable()),
267 for p in wlbook.meta.authors
269 description += '<a href="https://wolnelektury.pl/katalog/lektura/{}/">{}</a><br>'.format(
270 wlbook.meta.url.slug,
273 if wlbook.meta.translators:
274 description += 'tłum. ' + ', '.join(p.readable() for p in wlbook.meta.translators) + '<br>'
275 description += 'Epoka: ' + ', '.join(
276 '<a href="https://wolnelektury.pl/katalog/epoka/{}/">{}</a>'.format(
280 for p in wlbook.meta.epochs
282 description += 'Rodzaj: ' + ', '.join(
283 '<a href="https://wolnelektury.pl/katalog/rodzaj/{}/">{}</a>'.format(
287 for p in wlbook.meta.kinds
289 description += 'Gatunek: ' + ', '.join(
290 '<a href="https://wolnelektury.pl/katalog/gatunek/{}/">{}</a>'.format(
294 for p in wlbook.meta.genres
297 # TODO: Move away from using audiences for this.
298 if wlbook.meta.audience in ('L', 'SP1', 'SP2', 'SP3', 'SP4'):
299 description += '<p><em>{}</em> to lektura szkolna.'.format(wlbook.meta.title)
300 if wlbook.tree.find('//pe') is not None:
301 description += '<br>Ebook <em>{title}</em> zawiera przypisy opracowane specjalnie dla uczennic i uczniów {school}.'.format(
302 title=wlbook.meta.title,
303 school='szkoły podstawowej' if wlbook.meta.audience.startswith('SP') else 'liceum i technikum'
305 description += '</p>'
308 def get_genre(self, wlbook):
309 if wlbook.meta.legimi and wlbook.meta.legimi in self.CATEGORIES:
310 return self.CATEGORIES[wlbook.meta.legimi]
311 for epoch in wlbook.meta.epochs:
312 if epoch in self.CATEGORIES:
313 return self.CATEGORIES[epoch]
314 return self.CATEGORIES['Lektury']
316 def create_book(self, book_data, files_data):
318 'createValidationTrue': 'true',
319 'PublisherId': self.publisher_id,#3609954
320 'IsLibraryPass': 'False',
322 'SamplesGenerationType': 'Quantity',
323 'SamplesGenerationPercent': '10',
325 'EnterToTheMarketType': 'No',
326 'EnterToTheMarketDate': '',
328 'SalesNoLimitOption': 'false',
329 'SalesNoLimitKindle': 'false',
330 'SalesInStoreEbookGrossValue': '0,00',
331 'SalesPromotion': 'False',
332 'SalesPromotionGrossValue': '0,00',
333 'SalesPromotionDatesRange.DateStart': '',
334 'SalesPromotionDatesRange.DateEnd': '',
337 for form in 'Epub', 'Mobi', 'Pdf':
339 f'Book{form}.Token': '',
340 f'Book{form}.Name': '',
341 f'Book{form}.StorageName': '',
342 f'Book{form}.Order': '',
344 f'Sample{form}Type': 'Files',
345 f'Sample{form}.Token': '',
346 f'Sample{form}.Name': '',
347 f'Sample{form}.StorageName': '',
348 f'Sample{form}.Order': '',
351 data.update(book_data)
352 data.update(files_data)
354 response = self.session.post(self.CREATE_URL, data=data)
355 m = re.search(r'/(\d+)$', response.url)
359 def edit(self, legimi_id, data):
361 'ValidationTrue': 'true',
368 self.EDIT_URL % legimi_id,
372 def edit_files(self, legimi_id, files_data):
374 'ValidationTrue': 'true',
376 'SamplesGenerationType': 'Quantity',
377 'SamplesGenerationPercent': '10',
380 for form in 'Epub', 'Mobi', 'Pdf':
382 f'Book{form}.Token': '',
383 f'Book{form}.Name': '',
384 f'Book{form}.StorageName': '',
385 f'Book{form}.Order': '',
387 f'Sample{form}.Type': 'Files',
388 f'Sample{form}.Token': '',
389 f'Sample{form}.Name': '',
390 f'Sample{form}.StorageName': '',
391 f'Sample{form}.Order': '',
394 current.update(files_data)
396 response = self.session.post(
397 self.EDIT_FILES_URL % legimi_id,
401 def edit_sale(self, book):
402 assert book.legimi_id
404 words = book.wldocument().get_statistics()['total']['words_with_fn']
406 price = settings.LEGIMI_SMALL_PRICE
407 if words > settings.LEGIMI_SMALL_WORDS:
408 price = settings.LEGIMI_BIG_PRICE
410 abo = 'true' if words > settings.LEGIMI_BIG_WORDS else 'false'
413 'ValidationTrue': 'true',
414 'Id': book.legimi_id,
415 'SalesPromotionId': "0",
416 'IsLibraryPass': "False",
417 'OriginalEnterToTheMarketType': "No",
418 'OriginalHidingDate': "",
419 'OriginalEnterToTheMarketDate': "",
420 'EnterToTheMarketType': "Yes",
421 'EnterToTheMarketDate': "",
423 'SalesNoLimitOption': abo,
424 'SalesNoLimitKindle': abo,
425 'SalesInStoreEbookGrossValue': f'{price},00',
426 'SalesPromotion': "False",
427 'SalesPromotionGrossValue': "0,00",
428 'SalesPromotionDatesRange.DateStart': "",
429 'SalesPromotionDatesRange.DateEnd': "",
433 self.EDIT_SALE_URL % book.legimi_id,
439 settings.LEGIMI_USERNAME,
440 settings.LEGIMI_PASSWORD,
441 settings.LEGIMI_PUBLISHER_ID,