6
6
a backend that implement the Device interface for the SONY PRS500 Reader.
12
Defines the interface that should be implemented by backends that
13
communicate with an ebook reader.
9
from calibre.customize import Plugin
11
class DevicePlugin(Plugin):
13
Defines the interface that should be implemented by backends that
14
communicate with an ebook reader.
15
16
The C{end_session} variables are used for USB session management. Sometimes
16
the front-end needs to call several methods one after another, in which case
17
the front-end needs to call several methods one after another, in which case
17
18
the USB session should not be closed after each method call.
20
type = _('Device Interface')
19
22
# Ordered list of supported formats
20
23
FORMATS = ["lrf", "rtf", "pdf", "txt"]
22
25
PRODUCT_ID = 0x0000
23
# BCD can be either None to not distinguish between devices based on BCD, or
26
# BCD can be either None to not distinguish between devices based on BCD, or
24
27
# it can be a list of the BCD numbers of all devices supported by this driver.
26
29
THUMBNAIL_HEIGHT = 68 # Height for thumbnails on device
27
30
# Whether the metadata on books can be set via the GUI.
28
31
CAN_SET_METADATA = True
30
def __init__(self, key='-1', log_packets=False, report_progress=None) :
33
def reset(self, key='-1', log_packets=False, report_progress=None) :
32
35
@param key: The key to unlock the device
33
@param log_packets: If true the packet stream to/from the device is logged
34
@param report_progress: Function that is called with a % progress
36
@param log_packets: If true the packet stream to/from the device is logged
37
@param report_progress: Function that is called with a % progress
35
38
(number between 0 and 100) for various tasks
36
If it is called with -1 that means that the
39
If it is called with -1 that means that the
37
40
task does not have any progress information
39
42
raise NotImplementedError()
43
46
'''Return the FDI description of this device for HAL on linux.'''
47
50
def can_handle(cls, device_info):
51
54
is only called after the vendor, product ids and the bcd have matched, so
52
55
it can do some relatively time intensive checks. The default implementation
55
:param device_info: On windows a device ID string. On Unix a tuple of
56
``(vendor_id, product_id, bcd)``.
58
:param device_info: On windows a device ID string. On Unix a tuple of
59
``(vendor_id, product_id, bcd)``.
62
65
Perform any device specific initialization. Called after the device is
63
66
detected but before any other functions that communicate with the device.
64
67
For example: For devices that present themselves as USB Mass storage
65
68
devices, this method would be responsible for mounting the device or
66
if the device has been automounted, for finding out where it has been
67
mounted. The driver for the PRS505 has a implementation of this function
68
that should serve as a good example for USB Mass storage devices.
70
raise NotImplementedError()
69
if the device has been automounted, for finding out where it has been
70
mounted. The base class within USBMS device.py has a implementation of
71
this function that should serve as a good example for USB Mass storage
74
raise NotImplementedError()
78
Un-mount / eject the device from the OS. This does not check if there
79
are pending GUI jobs that need to communicate with the device.
81
raise NotImplementedError()
72
83
def set_progress_reporter(self, report_progress):
74
@param report_progress: Function that is called with a % progress
85
@param report_progress: Function that is called with a % progress
75
86
(number between 0 and 100) for various tasks
76
If it is called with -1 that means that the
87
If it is called with -1 that means that the
77
88
task does not have any progress information
79
90
raise NotImplementedError()
81
92
def get_device_information(self, end_session=True):
83
Ask device for device information. See L{DeviceInfoQuery}.
94
Ask device for device information. See L{DeviceInfoQuery}.
84
95
@return: (device name, device version, software version on device, mime type)
86
97
raise NotImplementedError()
88
99
def card_prefix(self, end_session=True):
90
Return prefix to paths on the card or '' if no cards present.
101
Return a 2 element list of the prefix to paths on the cards.
102
If no card is present None is set for the card's prefix.
104
('/place', '/place2')
92
109
raise NotImplementedError()
94
111
def total_space(self, end_session=True):
96
113
Get total space available on the mountpoints:
101
118
@return: A 3 element list with total space in bytes of (1, 2, 3). If a
102
119
particular device doesn't have any of these locations it should return 0.
104
121
raise NotImplementedError()
106
123
def free_space(self, end_session=True):
108
125
Get free space available on the mountpoints:
113
130
@return: A 3 element list with free space in bytes of (1, 2, 3). If a
114
131
particular device doesn't have any of these locations it should return -1.
116
133
raise NotImplementedError()
118
def books(self, oncard=False, end_session=True):
135
def books(self, oncard=None, end_session=True):
120
137
Return a list of ebooks on the device.
121
@param oncard: If True return a list of ebooks on the storage card,
122
otherwise return list of ebooks in main memory of device.
123
If True and no books on card return empty list.
138
@param oncard: If 'carda' or 'cardb' return a list of ebooks on the
139
specific storage card, otherwise return list of ebooks
140
in main memory of device. If a card is specified and no
141
books are on the card return empty list.
126
144
raise NotImplementedError()
128
def upload_books(self, files, names, on_card=False, end_session=True,
146
def upload_books(self, files, names, on_card=None, end_session=True,
131
149
Upload a list of books to the device. If a file already
132
150
exists on the device, it should be replaced.
133
151
This method should raise a L{FreeSpaceError} if there is not enough
134
152
free space on the device. The text of the FreeSpaceError must contain the
135
word "card" if C{on_card} is True otherwise it must contain the word "memory".
153
word "card" if C{on_card} is not None otherwise it must contain the word "memory".
136
154
@param files: A list of paths and/or file-like objects.
137
@param names: A list of file names that the books should have
155
@param names: A list of file names that the books should have
138
156
once uploaded to the device. len(names) == len(files)
139
@return: A list of 3-element tuples. The list is meant to be passed
157
@return: A list of 3-element tuples. The list is meant to be passed
140
158
to L{add_books_to_metadata}.
141
@param metadata: If not None, it is a list of dictionaries. Each dictionary
159
@param metadata: If not None, it is a list of dictionaries. Each dictionary
142
160
will have at least the key tags to allow the driver to choose book location
143
161
based on tags. len(metadata) == len(files). If your device does not support
144
162
hierarchical ebook folders, you can safely ignore this parameter.
146
164
raise NotImplementedError()
149
167
def add_books_to_metadata(cls, locations, metadata, booklists):
151
Add locations to the booklists. This function must not communicate with
169
Add locations to the booklists. This function must not communicate with
153
171
@param locations: Result of a call to L{upload_books}
154
172
@param metadata: List of dictionaries. Each dictionary must have the
155
keys C{title}, C{authors}, C{author_sort}, C{cover}, C{tags}.
156
The value of the C{cover}
173
keys C{title}, C{authors}, C{author_sort}, C{cover}, C{tags}.
174
The value of the C{cover}
157
175
element can be None or a three element tuple (width, height, data)
158
176
where data is the image data in JPEG format as a string. C{tags} must be
159
177
a possibly empty list of strings. C{authors} must be a string.
162
180
The dictionary can also have an optional key "tag order" which should be
163
181
another dictionary that maps tag names to lists of book ids. The ids are
164
182
ids from the book database.
165
@param booklists: A tuple containing the result of calls to
166
(L{books}(oncard=False), L{books}(oncard=True)).
183
@param booklists: A tuple containing the result of calls to
184
(L{books}(oncard=None), L{books}(oncard='carda'),
185
L{books}(oncard='cardb')).
168
187
raise NotImplementedError
170
189
def delete_books(self, paths, end_session=True):
172
191
Delete books at paths on device.
174
193
raise NotImplementedError()
177
196
def remove_books_from_metadata(cls, paths, booklists):
179
Remove books from the metadata list. This function must not communicate
198
Remove books from the metadata list. This function must not communicate
181
200
@param paths: paths to books on the device.
182
@param booklists: A tuple containing the result of calls to
183
(L{books}(oncard=False), L{books}(oncard=True)).
201
@param booklists: A tuple containing the result of calls to
202
(L{books}(oncard=None), L{books}(oncard='carda'),
203
L{books}(oncard='cardb')).
185
205
raise NotImplementedError()
187
207
def sync_booklists(self, booklists, end_session=True):
189
209
Update metadata on device.
190
@param booklists: A tuple containing the result of calls to
191
(L{books}(oncard=False), L{books}(oncard=True)).
210
@param booklists: A tuple containing the result of calls to
211
(L{books}(oncard=None), L{books}(oncard='carda'),
212
L{books}(oncard='cardb')).
193
214
raise NotImplementedError()
195
def get_file(self, path, outfile, end_session=True):
216
def get_file(self, path, outfile, end_session=True):
197
218
Read the file at C{path} on the device and write it to outfile.
198
219
@param outfile: file object like C{sys.stdout} or the result of an C{open} call
200
raise NotImplementedError()
221
raise NotImplementedError()
224
def config_widget(cls):
226
Should return a QWidget. The QWidget contains the settings for the device interface
228
raise NotImplementedError()
231
def save_settings(cls, settings_widget):
233
Should save settings to disk. Takes the widget created in config_widget
234
and saves all settings to disk.
236
raise NotImplementedError()
241
Should return an opts object. The opts object should have one attribute
242
`format_map` which is an ordered list of formats for the device.
244
raise NotImplementedError()
204
249
class BookList(list):
206
251
A list of books. Each Book object must have the fields:
210
255
4. datetime (a UTC time tuple)
211
256
5. path (path on the device to the book)
212
257
6. thumbnail (can be None)
213
7. tags (a list of strings, can be empty).
258
7. tags (a list of strings, can be empty).
216
261
__getslice__ = None
217
262
__setslice__ = None
219
264
def supports_tags(self):
220
265
''' Return True if the the device supports tags (collections) for this book list. '''
221
266
raise NotImplementedError()
223
268
def set_tags(self, book, tags):
225
Set the tags for C{book} to C{tags}.
270
Set the tags for C{book} to C{tags}.
226
271
@param tags: A list of strings. Can be empty.
227
@param book: A book object that is in this BookList.
272
@param book: A book object that is in this BookList.
229
274
raise NotImplementedError()