Remove DateValue, drop Py<3.6, fix tests.
[librarian.git] / src / librarian / partners.py
1 # -*- coding: utf-8 -*-
2 #
3 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
4 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
5 #
6
7 """
8 Classes for packaging ebooks for some old partners.
9 These should be removed from librarian to separate package,
10 along with custom cover images etc.
11
12 New partners shouldn't be added here, but in the partners repository.
13 """
14 from __future__ import print_function, unicode_literals
15
16 from librarian import packagers, cover
17 from .util import makedirs
18
19
20 class GandalfEpub(packagers.EpubPackager):
21     cover = cover.GandalfCover
22
23
24 class GandalfPdf(packagers.PdfPackager):
25     cover = cover.GandalfCover
26
27
28 class BookotekaEpub(packagers.EpubPackager):
29     cover = cover.BookotekaCover
30
31
32 class PrestigioEpub(packagers.EpubPackager):
33     cover = cover.PrestigioCover
34     flags = ('less-advertising',)
35
36
37 class PrestigioPdf(packagers.PdfPackager):
38     cover = cover.PrestigioCover
39     flags = ('less-advertising',)
40
41
42 class Virtualo(packagers.Packager):
43     @staticmethod
44     def utf_trunc(text, limit):
45         """ truncates text to at most `limit' bytes in utf-8 """
46         if text is None:
47             return text
48         if len(text.encode('utf-8')) > limit:
49             newlimit = limit - 3
50             while len(text.encode('utf-8')) > newlimit:
51                 text = text[:(newlimit - len(text.encode('utf-8'))) / 4]
52             text += '...'
53         return text
54
55     @classmethod
56     def prepare(cls, input_filenames, output_dir='', verbose=False):
57         from lxml import etree
58         from librarian import DirDocProvider, ParseError
59         from librarian.parser import WLDocument
60         from copy import deepcopy
61         import os.path
62
63         xml = etree.fromstring(
64             """<?xml version="1.0" encoding="utf-8"?>
65             <products xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">"""
66             "</products>"
67         )
68         product = etree.fromstring("""<product>
69                 <publisherProductId></publisherProductId>
70                 <title></title>
71                 <info></info>
72                 <description></description>
73                 <authors>
74                     <author>
75                         <names>Jan</names>
76                         <lastName>Kowalski</lastName>
77                     </author>
78                 </authors>
79                 <price>0.0</price>
80                 <language>PL</language>
81             </product>""")
82
83         try:
84             for main_input in input_filenames:
85                 if verbose:
86                     print(main_input)
87                 path, fname = os.path.realpath(main_input).rsplit('/', 1)
88                 provider = DirDocProvider(path)
89                 slug, ext = os.path.splitext(fname)
90
91                 outfile_dir = os.path.join(output_dir, slug)
92                 makedirs(os.path.join(output_dir, slug))
93
94                 doc = WLDocument.from_file(main_input, provider=provider)
95                 info = doc.book_info
96
97                 product_elem = deepcopy(product)
98                 product_elem[0].text = cls.utf_trunc(slug, 100)
99                 product_elem[1].text = cls.utf_trunc(info.title, 255)
100                 product_elem[2].text = cls.utf_trunc(info.description, 255)
101                 product_elem[3].text = cls.utf_trunc(info.source_name, 3000)
102                 product_elem[4][0][0].text = cls.utf_trunc(
103                     u' '.join(info.author.first_names), 100
104                 )
105                 product_elem[4][0][1].text = cls.utf_trunc(
106                     info.author.last_name, 100
107                 )
108                 xml.append(product_elem)
109
110                 cover.VirtualoCover(info).save(
111                     os.path.join(outfile_dir, slug+'.jpg')
112                 )
113                 outfile = os.path.join(outfile_dir, '1.epub')
114                 outfile_sample = os.path.join(outfile_dir, '1.sample.epub')
115                 doc.save_output_file(doc.as_epub(), output_path=outfile)
116                 doc.save_output_file(doc.as_epub(doc, sample=25),
117                                      output_path=outfile_sample)
118                 outfile = os.path.join(outfile_dir, '1.mobi')
119                 outfile_sample = os.path.join(outfile_dir, '1.sample.mobi')
120                 doc.save_output_file(doc.as_mobi(cover=cover.VirtualoCover),
121                                      output_path=outfile)
122                 doc.save_output_file(
123                     doc.as_mobi(doc, cover=cover.VirtualoCover, sample=25),
124                     output_path=outfile_sample)
125         except ParseError as e:
126             print('%(file)s:%(name)s:%(message)s' % {
127                 'file': main_input,
128                 'name': e.__class__.__name__,
129                 'message': e.message
130             })
131
132         with open(os.path.join(
133                     output_dir, 'import_products.xml'
134                 ), 'w') as xml_file:
135             xml_file.write(
136                 etree.tostring(
137                     xml, pretty_print=True, encoding='unicode'
138                 ).encode('utf-8')
139             )
140         xml_file.close()