75ddaa1224125842e3d8ff944d8e5e918798ca56
[redakcja.git] / src / depot / legimi.py
1 from datetime import date
2 import re
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
8 import requests
9 from slugify import slugify
10
11
12
13 fundraising=[
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."
19 ]
20
21 description_add = '<p>Książkę polecają <a href="https://wolnelektury.pl">Wolne Lektury</a> — najpopularniejsza biblioteka on-line.</p>'
22
23
24 class Legimi:
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     
33     def __init__(self, username, password, publisher_id):
34         self.username = username
35         self.password = password
36         self.publisher_id = publisher_id
37         self._session = None
38
39     @property
40     def session(self):
41         if self._session is None:
42             session = requests.Session()
43             response = session.post(
44                 self.LOGIN_URL,
45                 data={
46                     'ValidationTrue': 'true',
47                     'UserName': self.username,
48                     'Password': self.password,
49                 })
50             self._session = session
51         return self._session
52         
53     def list(self):
54         return self.session.get('https://wydawca.legimi.com/publishers/publications')
55         
56     def upload(self, content):
57         response = self.session.post(
58             self.UPLOAD_URL,
59             files={
60                 "files": content,
61             })
62         model = response.json()['model']
63         return {
64             "name": model['Name'],
65             "token": model['Token'],
66             "url": model['Url'],
67         }
68
69 #    name=files[]
70 #    filename
71 #    content-type
72 #    response: json
73 #     success: true
74 #     model.Url
75
76     def send_book(self, book):
77         wlbook = book.wldocument(librarian2=True)
78         meta = wlbook.meta
79
80         cover = LabelMarquiseCover(meta, width=1200).output_file()
81         epub_file = EpubBuilder(cover=MarquiseCover, fundraising=fundraising).build(wlbook).get_file()
82         mobi_file = MobiBuilder(cover=MarquiseCover, fundraising=fundraising).build(wlbook).get_file()
83
84         book_data = {
85             "Title": meta.title,
86             "Author": ", ".join(p.readable() for p in meta.authors),
87             "Year": meta.created_at[:4],
88
89             'GenreId': str(self.get_genre(wlbook)),
90             'Isbn': '',
91             'LanguageLocale': lang_code_3to2(meta.language),
92
93             'Description': self.get_description(wlbook),
94         }
95         if meta.isbn_html:
96             isbn = meta.isbn_html
97             if isbn.upper().startswith('ISBN '):
98                 isbn = isbn[5:]
99             isbn = isbn.strip()
100             book_data['Isbn'] = isbn
101
102         files_data = {}
103
104         cover_data = self.upload(
105             (meta.url.slug + '.jpg', cover.get_file(), 'image/jpeg')
106         )
107         book_data.update({
108             "Cover.Name": cover_data['name'],
109             "Cover.Token": cover_data['token'],
110             "Cover.Url": cover_data['url'],
111         })
112
113         epub_data = self.upload(
114             (meta.url.slug + '.epub', epub_file, 'application/epub+zip')
115         )
116         files_data.update({
117             'BookEpub.Token': epub_data['token'],
118             'BookEpub.Name': epub_data['name'],
119         })
120
121         mobi_data = self.upload(
122             (meta.url.slug + '.mobi', mobi_file, 'application/x-mobipocket-ebook')
123         )
124         files_data.update({
125             'BookMobi.Token': mobi_data['token'],
126             'BookMobi.Name': mobi_data['name'],
127         })
128         
129         if book.legimi_id:
130             self.edit(
131                 book.legimi_id,
132                 book_data
133             )
134             self.edit_files(
135                 book.legimi_id,
136                 files_data
137             )
138         else:
139             legimi_id = self.create_book(book_data, files_data)
140             if legimi_id:
141                 book.legimi_id = legimi_id
142                 book.save(update_fields=['legimi_id'])
143
144     def get_description(self, wlbook):
145         description = ''
146         abstract = wlbook.tree.find('.//abstrakt')
147         if abstract is not None:
148             description = transform_abstrakt(abstract)
149         description += description_add
150         description += '<p>'
151         description += ', '.join(
152             '<a href="https://wolnelektury.pl/katalog/autor/{}/">{}</a>'.format(
153                 slugify(p.readable()),
154                 p.readable(),
155             )
156             for p in wlbook.meta.authors
157         ) + '<br>'
158         description += '<a href="https://wolnelektury.pl/katalog/lektura/{}/">{}</a><br>'.format(
159             wlbook.meta.url.slug,
160             wlbook.meta.title
161         )
162         if wlbook.meta.translators:
163             description += 'tłum. ' + ', '.join(p.readable() for p in wlbook.meta.translators) + '<br>'
164         description += 'Epoka: ' + ', '.join(
165             '<a href="https://wolnelektury.pl/katalog/epoka/{}/">{}</a>'.format(
166                 slugify(p),
167                 p,
168             )
169             for p in wlbook.meta.epochs
170         ) + ' '
171         description += 'Rodzaj: ' + ', '.join(
172             '<a href="https://wolnelektury.pl/katalog/rodzaj/{}/">{}</a>'.format(
173                 slugify(p),
174                 p,
175             )
176             for p in wlbook.meta.kinds
177         ) + ' '
178         description += 'Gatunek: ' + ', '.join(
179             '<a href="https://wolnelektury.pl/katalog/gatunek/{}/">{}</a>'.format(
180                 slugify(p),
181                 p,
182             )
183             for p in wlbook.meta.genres
184         ) + '</p>'
185
186         if wlbook.meta.audience:
187             description += '<p><em>{}</em> to lektura szkolna.'.format(wlbook.meta.title)
188             if wlbook.tree.find('//pe') is not None:
189                 description += '<br>Ebook <em>{title}</em> zawiera przypisy opracowane specjalnie dla uczennic i uczniów {school}.'.format(
190                     title=wlbook.meta.title,
191                     school='szkoły podstawowej' if wlbook.meta.audience == 'SP' else 'liceum i technikum'
192                 )
193             description += '</p>'
194         return description
195
196     def get_genre(self, wlbook):
197         epoch_map = {
198             'Starożytność': 80,
199             'Średniowiecze': 81,
200             'Renesans': 82,
201             'Barok': 83,
202             'Oświecenie': 84,
203             'Romantyzm': 85,
204             'Pozytywizm': 86,
205             'Modernizm': 87,
206             'Dwudziestolecie międzywojenne': 88,
207             'Współczesność': 90,
208         }
209
210         for epoch in wlbook.meta.epochs:
211             if epoch in epoch_map:
212                 return epoch_map[epoch]
213         return 11
214     
215     def create_book(self, book_data, files_data):
216         data = {
217             'createValidationTrue': 'true',
218             'PublisherId': self.publisher_id,#3609954
219             'IsLibraryPass': 'False',
220
221             'SamplesGenerationType': 'Quantity',
222             'SamplesGenerationPercent': '10',
223
224             'EnterToTheMarketType': 'No',
225             'EnterToTheMarketDate': date.today().strftime('%d.%m.%Y'),
226             'HidingDate': '',
227             'SalesNoLimitOption': 'false',
228             'SalesNoLimitKindle': 'false',
229             'SalesInStoreEbookGrossValue': '0,00',
230             'SalesPromotion': 'False',
231             'SalesPromotionGrossValue': '0,00',
232             'SalesPromotionDatesRange.DateStart': '',
233             'SalesPromotionDatesRange.DateEnd': '',
234         }
235
236         for form in 'Epub', 'Mobi', 'Pdf':
237             data.update({
238                 f'Book{form}.Token': '',
239                 f'Book{form}.Name': '',
240                 f'Book{form}.StorageName': '',
241                 f'Book{form}.Order': '',
242
243                 f'Sample{form}Type': 'Files',
244                 f'Sample{form}.Token': '',
245                 f'Sample{form}.Name': '',
246                 f'Sample{form}.StorageName': '',
247                 f'Sample{form}.Order': '',
248             })
249
250         data.update(book_data)
251         data.update(files_data)
252
253         response = self.session.post(self.CREATE_URL, data=data)
254         m = re.search(r'/(\d+)$', response.url)
255         if m is not None:
256             return m.group(1)
257
258     def edit(self, legimi_id, data):
259         current = {
260             'ValidationTrue': 'true',
261             'Is': legimi_id
262         }
263
264         current.update(data)
265         
266         self.session.post(
267             self.EDIT_URL % legimi_id,
268             data=current
269         )
270
271     def edit_files(self, legimi_id, files_data):
272         current = {
273             'ValidationTrue': 'true',
274             'Id': legimi_id,
275             'SamplesGenerationType': 'Quantity',
276             'SamplesGenerationPercent': '10',
277         }
278
279         for form in 'Epub', 'Mobi', 'Pdf':
280             current.update({
281                 f'Book{form}.Token': '',
282                 f'Book{form}.Name': '',
283                 f'Book{form}.StorageName': '',
284                 f'Book{form}.Order': '',
285
286                 f'Sample{form}.Type': 'Files',
287                 f'Sample{form}.Token': '',
288                 f'Sample{form}.Name': '',
289                 f'Sample{form}.StorageName': '',
290                 f'Sample{form}.Order': '',
291             })
292
293         current.update(files_data)
294  
295         response = self.session.post(
296             self.EDIT_FILES_URL % legimi_id,
297             data=current
298         )
299
300
301 legimi = Legimi(
302     settings.LEGIMI_USERNAME,
303     settings.LEGIMI_PASSWORD,
304     settings.LEGIMI_PUBLISHER_ID,
305 )