1# -*- coding: utf-8 -*-
2
3
4__license__   = 'GPL v3'
5__copyright__ = '2009, John Schember <john at nachtimwald.com>'
6__docformat__ = 'restructuredtext en'
7
8'''
9Device driver for Hanvon devices
10'''
11import re, os
12
13from calibre import fsync
14from calibre.devices.usbms.driver import USBMS
15
16
17def is_alex(device_info):
18    return device_info[3] == 'Linux 2.6.28 with pxa3xx_u2d' and \
19            device_info[4] == 'Seleucia Disk'
20
21
22class N516(USBMS):
23
24    name           = 'N516 driver'
25    gui_name       = 'N516'
26    description    = _('Communicate with the Hanvon N520 e-book reader.')
27    author         = 'John Schember'
28    supported_platforms = ['windows', 'osx', 'linux']
29
30    # Ordered list of supported formats
31    FORMATS     = ['epub', 'prc', 'mobi', 'html', 'pdf', 'txt']
32
33    VENDOR_ID   = [0x0525]
34    PRODUCT_ID  = [0xa4a5]
35    BCD         = [0x323, 0x326, 0x327]
36
37    VENDOR_NAME      = 'INGENIC'
38    WINDOWS_MAIN_MEM = '_FILE-STOR_GADGE'
39
40    MAIN_MEMORY_VOLUME_LABEL  = 'N520 Internal Memory'
41
42    EBOOK_DIR_MAIN = 'e_book'
43    SUPPORTS_SUB_DIRS = True
44
45    def can_handle(self, device_info, debug=False):
46        return not is_alex(device_info)
47
48
49class KIBANO(N516):
50
51    name = 'Kibano driver'
52    gui_name = 'Kibano'
53    description    = _('Communicate with the Kibano e-book reader.')
54    FORMATS     = ['epub', 'pdf', 'txt']
55    BCD         = [0x323]
56
57    VENDOR_NAME      = 'EBOOK'
58    # We use EXTERNAL_SD_CARD for main mem as some devices have not working
59    # main memories
60    WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = ['INTERNAL_SD_CARD',
61                                             'EXTERNAL_SD_CARD']
62
63
64class THEBOOK(N516):
65    name = 'The Book driver'
66    gui_name = 'The Book'
67    description    = _('Communicate with The Book reader.')
68    author         = 'Kovid Goyal'
69
70    BCD = [0x399]
71    MAIN_MEMORY_VOLUME_LABEL  = 'The Book Main Memory'
72    EBOOK_DIR_MAIN = 'My books'
73    WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = ['_FILE-STOR_GADGE',
74            'FILE-STOR_GADGET']
75
76
77class LIBREAIR(N516):
78    name = 'Libre Air Driver'
79    gui_name = 'Libre Air'
80    description    = _('Communicate with the Libre Air reader.')
81    author         = 'Kovid Goyal'
82    FORMATS = ['epub', 'mobi', 'prc', 'fb2', 'rtf', 'txt', 'pdf']
83
84    BCD = [0x399]
85    VENDOR_NAME      = ['ALURATEK', 'LINUX']
86    WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'FILE-STOR_GADGET'
87    EBOOK_DIR_MAIN = 'Books'
88
89
90class ALEX(N516):
91
92    name = 'Alex driver'
93    gui_name = 'SpringDesign Alex'
94    description    = _('Communicate with the SpringDesign Alex e-book reader.')
95    author         = 'Kovid Goyal'
96
97    FORMATS     = ['epub', 'fb2', 'pdf']
98    VENDOR_NAME      = 'ALEX'
99    WINDOWS_MAIN_MEM = 'READER'
100
101    MAIN_MEMORY_VOLUME_LABEL  = 'Alex Internal Memory'
102
103    EBOOK_DIR_MAIN = 'eBooks'
104    SUPPORTS_SUB_DIRS = False
105    THUMBNAIL_HEIGHT = 120
106
107    def can_handle(self, device_info, debug=False):
108        return is_alex(device_info)
109
110    def alex_cpath(self, file_abspath):
111        base = os.path.dirname(file_abspath)
112        name = os.path.splitext(os.path.basename(file_abspath))[0] + '.png'
113        return os.path.join(base, 'covers', name)
114
115    def upload_cover(self, path, filename, metadata, filepath):
116        from calibre.ebooks.covers import calibre_cover2
117        from calibre.utils.img import scale_image
118        coverdata = getattr(metadata, 'thumbnail', None)
119        if coverdata and coverdata[2]:
120            cover = coverdata[2]
121        else:
122            cover = calibre_cover2(metadata.get('title', _('Unknown')),
123                    metadata.get('authors', _('Unknown')))
124
125        cover = scale_image(cover, width=self.THUMBNAIL_HEIGHT,
126                height=self.THUMBNAIL_HEIGHT, as_png=True)[-1]
127
128        cpath = self.alex_cpath(os.path.join(path, filename))
129        cdir = os.path.dirname(cpath)
130        if not os.path.exists(cdir):
131            os.makedirs(cdir)
132        with lopen(cpath, 'wb') as coverfile:
133            coverfile.write(cover)
134            fsync(coverfile)
135
136    def delete_books(self, paths, end_session=True):
137        for i, path in enumerate(paths):
138            self.report_progress((i+1) / float(len(paths)), _('Removing books from device...'))
139            path = self.normalize_path(path)
140            if os.path.exists(path):
141                # Delete the ebook
142                os.unlink(path)
143            try:
144                cpath = self.alex_cpath(path)
145                if os.path.exists(cpath):
146                    os.remove(cpath)
147            except:
148                pass
149        self.report_progress(1.0, _('Removing books from device...'))
150
151
152class AZBOOKA(ALEX):
153
154    name = 'Azbooka driver'
155    gui_name = 'Azbooka'
156    description = _('Communicate with the Azbooka')
157
158    VENDOR_NAME      = 'LINUX'
159    WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'FILE-STOR_GADGET'
160
161    MAIN_MEMORY_VOLUME_LABEL  = 'Azbooka Internal Memory'
162
163    EBOOK_DIR_MAIN = ''
164    SUPPORTS_SUB_DIRS = True
165
166    def can_handle(self, device_info, debug=False):
167        return not is_alex(device_info)
168
169    def upload_cover(self, path, filename, metadata, filepath):
170        pass
171
172
173class EB511(USBMS):
174    name           = 'Elonex EB 511 driver'
175    gui_name       = 'EB 511'
176    description    = _('Communicate with the Elonex EB 511 e-book reader.')
177    author         = 'Kovid Goyal'
178    supported_platforms = ['windows', 'osx', 'linux']
179
180    FORMATS     = ['epub', 'html', 'pdf', 'txt']
181
182    VENDOR_ID   = [0x45e]
183    PRODUCT_ID  = [0xffff]
184    BCD         = [0x0]
185
186    MAIN_MEMORY_VOLUME_LABEL  = 'EB 511 Internal Memory'
187
188    EBOOK_DIR_MAIN = 'e_book'
189    SUPPORTS_SUB_DIRS = True
190
191    OSX_MAIN_MEM_VOL_PAT = re.compile(r'/eReader')
192
193
194class ODYSSEY(N516):
195    name  = 'Cybook Odyssey driver'
196    gui_name       = 'Odyssey'
197    description    = _('Communicate with the Cybook Odyssey e-book reader.')
198
199    BCD = [0x316]
200    VENDOR_NAME      = ['LINUX', 'BOOKEEN']
201    WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = ['FILE-STOR_GADGET', 'FLASH_DISK']
202
203    FORMATS     = ['epub', 'fb2', 'html', 'pdf', 'txt']
204
205    EBOOK_DIR_MAIN = 'Digital Editions'
206
207    def get_main_ebook_dir(self, for_upload=False):
208        if for_upload:
209            return self.EBOOK_DIR_MAIN
210        return ''
211