from librarian.functions import lang_code_3to2
from librarian.html import transform_abstrakt
from librarian.builders import EpubBuilder, MobiBuilder
-from librarian.cover import LegimiCornerCover, LegimiCover
+from librarian.covers.marquise import MarquiseCover, LabelMarquiseCover
import requests
+from slugify import slugify
"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."
]
+description_add = '<p>Książkę polecają <a href="https://wolnelektury.pl">Wolne Lektury</a> — najpopularniejsza biblioteka on-line.</p>'
+
+
class Legimi:
#BASE_URL = 'https://wydawca.legimi.com'
BASE_URL = 'https://panel.legimi.pl'
CREATE_URL = BASE_URL + '/publishers/publications/create'
EDIT_URL = BASE_URL + '/publishers/publications/edit/%s'
EDIT_FILES_URL = BASE_URL + '/publishers/publications/editfiles/%s'
+ EDIT_SALE_URL = BASE_URL + '/publishers/publications/editsale/%s'
+
+ CATEGORIES = {
+ 'Dla dzieci i młodzieży': 94,
+ 'Książki dla dzieci': 15,
+ 'Literatura młodzieżowa': 24,
+ 'Kryminał': 29,
+ 'Kryminał klasyczny': 31,
+ 'Kryminał współczesny': 32,
+ 'Kryminał historyczny': 30,
+ 'default': 8886,
+ 'Edukacja': 10,
+ 'Słowniki i leksykony': 14,
+ 'Encyklopedie': 13,
+ 'Lektury': 11,
+ 'Starożytność': 80,
+ 'Barok': 83,
+ 'Oświecenie': 84,
+ 'Dwudziestolecie międzywojenne': 88,
+ 'Średniowiecze': 81,
+ 'Współczesność': 90,
+ 'Modernizm': 87,
+ 'Pozytywizm': 86,
+ 'Renesans': 82,
+ 'Romantyzm': 85,
+ 'Młoda Polska': 89,
+ 'Podręczniki': 52,
+ 'Fantastyka i sci-fi': 25,
+ 'Fantastyka': 26,
+ 'Science fiction': 27,
+ 'Języki obce': 59,
+ 'Antyki i kolekcjonerstwo': 53,
+ 'Astrologia i wróżbiarstwo': 54,
+ 'Zdrowie i rodzina': 57,
+ 'Hobby': 55,
+ 'Medycyna i zdrowie': 58,
+ 'Psychologiczne': 78,
+ 'Styl': 56,
+ 'Humanistyka': 97,
+ 'Kultura i sztuka': 64,
+ 'Film': 66,
+ 'Muzyka': 65,
+ 'Eseje literackie': 49,
+ 'Historia': 60,
+ 'Styl życia': 73,
+ 'Wakacje i podróże': 69,
+ 'Dla mężczyzn': 79,
+ 'Sport': 76,
+ 'Obyczajowe i romanse': 93,
+ 'Humor': 68,
+ 'Obyczajowe': 35,
+ 'Powieść': 41,
+ 'Powieść przygodowa': 42,
+ 'Współczesna powieść przygodowa': 44,
+ 'Historyczna powieść przygodowa': 43,
+ 'Powieść historyczna': 46,
+ 'Powieść psychologiczna': 47,
+ 'Powieść religijna': 45,
+ 'Romans': 36,
+ 'Romans klasyczny': 38,
+ 'Romans współczesny': 39,
+ 'Literatura erotyczna': 40,
+ 'Romans historyczny': 37,
+ 'Dla kobiet': 77,
+ 'Sensacja, thriller, horror': 91,
+ 'Horror': 28,
+ 'Sensacja': 33,
+ 'Thriller': 34,
+ 'Aktualności': 70,
+ 'Czasopisma': 71,
+ 'Literatura faktu, reportaże, biografie': 92,
+ 'Literatura faktu': 16,
+ 'Biografie': 17,
+ 'Publicystyka': 20,
+ 'Dzienniki': 19,
+ 'Dokument, esej': 18,
+ 'Historia literatury i krytyka literacka': 23,
+ 'Literatura popularnonaukowa': 22,
+ 'Reportaż': 21,
+ 'Społeczno-polityczne': 72,
+ 'Poezja i dramat': 95,
+ 'Dramat': 48,
+ 'Poezja': 50,
+ 'Religia i duchowość': 51,
+ 'Nauka i nowe technologie': 98,
+ 'Nauka i technika': 61,
+ 'Nauki ścisłe': 62,
+ 'Nauki humanistyczne': 63,
+ 'Technologia i Internet': 75,
+ 'Specjalistyczne': 99,
+ 'Biznes i finanse': 1,
+ 'Ekonomia': 5,
+ 'Finanse': 6,
+ 'Zarządzanie': 3,
+ 'Marketing': 2,
+ 'Rozwój osobisty': 7,
+ 'Kariera i sukces zawodowy': 8,
+ 'Psychologia, motywacja': 9,
+ 'PR': 4,
+ 'Prawo': 67,
+ 'Branżowe': 74,
+ }
def __init__(self, username, password, publisher_id):
self.username = username
"url": model['Url'],
}
-# name=files[]
-# filename
-# content-type
-# response: json
-# success: true
-# model.Url
-
- def send_book(self, book):
- wlbook = book.wldocument(librarian2=True)
+ def send_book(self, book, changes=None):
+ wlbook = book.wldocument(librarian2=True, changes=changes)
meta = wlbook.meta
- cover = LegimiCornerCover(meta, width=1200).output_file()
- epub_file = EpubBuilder(cover=LegimiCover, fundraising=fundraising).build(wlbook).get_file()
- mobi_file = MobiBuilder(cover=LegimiCover, fundraising=fundraising).build(wlbook).get_file()
+ cover = LabelMarquiseCover(meta, width=1200).output_file()
+ epub_file = EpubBuilder(
+ cover=MarquiseCover,
+ fundraising=fundraising,
+ base_url='file://' + book.gallery_path() + '/'
+ ).build(wlbook).get_file()
+ mobi_file = MobiBuilder(
+ cover=MarquiseCover,
+ fundraising=fundraising,
+ base_url='file://' + book.gallery_path() + '/'
+ ).build(wlbook).get_file()
+ thema = []
+ if meta.thema_main:
+ thema.append(meta.thema_main)
+ thema.extend(meta.thema)
+
book_data = {
"Title": meta.title,
"Author": ", ".join(p.readable() for p in meta.authors),
- "Year": meta.created_at[:4],
+ "Year": str(date.today().year),
- 'GenreId': '11', # TODO
+ 'GenreId': str(self.get_genre(wlbook)),
+ 'themaCategories': ';'.join(thema),
+ 'thema-search': '',
'Isbn': '',
'LanguageLocale': lang_code_3to2(meta.language),
- 'Description': '<p>—</p>',
+ 'Description': self.get_description(wlbook),
}
if meta.isbn_html:
isbn = meta.isbn_html
- if isbn.upper().startswith('ISBN '):
+ if isbn.upper().startswith(('ISBN ', 'ISBN-')):
isbn = isbn[5:]
isbn = isbn.strip()
book_data['Isbn'] = isbn
files_data = {}
- abstract = wlbook.tree.find('.//abstrakt')
- if abstract is not None:
- book_data['Description'] = transform_abstrakt(abstract)
-
-
cover_data = self.upload(
(meta.url.slug + '.jpg', cover.get_file(), 'image/jpeg')
)
files_data.update({
'BookEpub.Token': epub_data['token'],
'BookEpub.Name': epub_data['name'],
+ 'SampleEpubType': 'Generation',
})
mobi_data = self.upload(
book.legimi_id = legimi_id
book.save(update_fields=['legimi_id'])
+ def get_description(self, wlbook):
+ description = ''
+ abstract = wlbook.tree.find('.//abstrakt')
+ if abstract is not None:
+ description = transform_abstrakt(abstract)
+ description += description_add
+ description += '<p>'
+ description += ', '.join(
+ '<a href="https://wolnelektury.pl/katalog/autor/{}/">{}</a>'.format(
+ slugify(p.readable()),
+ p.readable(),
+ )
+ for p in wlbook.meta.authors
+ ) + '<br>'
+ description += '<a href="https://wolnelektury.pl/katalog/lektura/{}/">{}</a><br>'.format(
+ wlbook.meta.url.slug,
+ wlbook.meta.title
+ )
+ if wlbook.meta.translators:
+ description += 'tłum. ' + ', '.join(p.readable() for p in wlbook.meta.translators) + '<br>'
+ description += 'Epoka: ' + ', '.join(
+ '<a href="https://wolnelektury.pl/katalog/epoka/{}/">{}</a>'.format(
+ slugify(p),
+ p,
+ )
+ for p in wlbook.meta.epochs
+ ) + ' '
+ description += 'Rodzaj: ' + ', '.join(
+ '<a href="https://wolnelektury.pl/katalog/rodzaj/{}/">{}</a>'.format(
+ slugify(p),
+ p,
+ )
+ for p in wlbook.meta.kinds
+ ) + ' '
+ description += 'Gatunek: ' + ', '.join(
+ '<a href="https://wolnelektury.pl/katalog/gatunek/{}/">{}</a>'.format(
+ slugify(p),
+ p,
+ )
+ for p in wlbook.meta.genres
+ ) + '</p>'
+
+ # TODO: Move away from using audiences for this.
+ if wlbook.meta.audience in ('L', 'SP1', 'SP2', 'SP3', 'SP4'):
+ description += '<p><em>{}</em> to lektura szkolna.'.format(wlbook.meta.title)
+ if wlbook.tree.find('//pe') is not None:
+ description += '<br>Ebook <em>{title}</em> zawiera przypisy opracowane specjalnie dla uczennic i uczniów {school}.'.format(
+ title=wlbook.meta.title,
+ school='szkoły podstawowej' if wlbook.meta.audience.startswith('SP') else 'liceum i technikum'
+ )
+ description += '</p>'
+ return description
+
+ def get_genre(self, wlbook):
+ if wlbook.meta.legimi and wlbook.meta.legimi in self.CATEGORIES:
+ return self.CATEGORIES[wlbook.meta.legimi]
+ for epoch in wlbook.meta.epochs:
+ if epoch in self.CATEGORIES:
+ return self.CATEGORIES[epoch]
+ return self.CATEGORIES['Lektury']
+
def create_book(self, book_data, files_data):
data = {
'createValidationTrue': 'true',
'SamplesGenerationPercent': '10',
'EnterToTheMarketType': 'No',
- 'EnterToTheMarketDate': date.today().strftime('%d.%m.%Y'),
+ 'EnterToTheMarketDate': '',
'HidingDate': '',
'SalesNoLimitOption': 'false',
'SalesNoLimitKindle': 'false',
def edit(self, legimi_id, data):
current = {
'ValidationTrue': 'true',
- 'Is': legimi_id
+ 'Id': legimi_id
}
current.update(data)
data=current
)
+ def edit_sale(self, book):
+ assert book.legimi_id
+
+ words = book.wldocument().get_statistics()['total']['words_with_fn']
+
+ price = settings.LEGIMI_SMALL_PRICE
+ if words > settings.LEGIMI_SMALL_WORDS:
+ price = settings.LEGIMI_BIG_PRICE
+
+ abo = 'true' if words > settings.LEGIMI_BIG_WORDS else 'false'
+
+ data = {
+ 'ValidationTrue': 'true',
+ 'Id': book.legimi_id,
+ 'SalesPromotionId': "0",
+ 'IsLibraryPass': "False",
+ 'OriginalEnterToTheMarketType': "No",
+ 'OriginalHidingDate': "",
+ 'OriginalEnterToTheMarketDate': "",
+ 'EnterToTheMarketType': "Yes",
+ 'EnterToTheMarketDate': "",
+ 'HidingDate': "",
+ 'SalesNoLimitOption': abo,
+ 'SalesNoLimitKindle': abo,
+ 'SalesInStoreEbookGrossValue': f'{price},00',
+ 'SalesPromotion': "False",
+ 'SalesPromotionGrossValue': "0,00",
+ 'SalesPromotionDatesRange.DateStart': "",
+ 'SalesPromotionDatesRange.DateEnd': "",
+ }
+
+ self.session.post(
+ self.EDIT_SALE_URL % book.legimi_id,
+ data=data
+ )
+
legimi = Legimi(
settings.LEGIMI_USERNAME,