~ubuntu-branches/ubuntu/karmic/calibre/karmic

« back to all changes in this revision

Viewing changes to src/calibre/devices/interface.py

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-30 12:49:41 UTC
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20090730124941-kviipg9ypwgppulc
Tags: upstream-0.6.3+dfsg
ImportĀ upstreamĀ versionĀ 0.6.3+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
a backend that implement the Device interface for the SONY PRS500 Reader.
7
7
"""
8
8
 
9
 
 
10
 
class Device(object):
11
 
    """ 
12
 
    Defines the interface that should be implemented by backends that 
13
 
    communicate with an ebook reader. 
14
 
    
 
9
from calibre.customize import Plugin
 
10
 
 
11
class DevicePlugin(Plugin):
 
12
    """
 
13
    Defines the interface that should be implemented by backends that
 
14
    communicate with an ebook reader.
 
15
 
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.
18
19
    """
 
20
    type = _('Device Interface')
 
21
 
19
22
    # Ordered list of supported formats
20
23
    FORMATS     = ["lrf", "rtf", "pdf", "txt"]
21
24
    VENDOR_ID   = 0x0000
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.
25
28
    BCD         = None
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
29
 
    
30
 
    def __init__(self, key='-1', log_packets=False, report_progress=None) :
31
 
        """ 
 
32
 
 
33
    def reset(self, key='-1', log_packets=False, report_progress=None) :
 
34
        """
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
38
41
        """
39
42
        raise NotImplementedError()
40
 
    
 
43
 
41
44
    @classmethod
42
45
    def get_fdi(cls):
43
46
        '''Return the FDI description of this device for HAL on linux.'''
44
47
        return ''
45
 
    
 
48
 
46
49
    @classmethod
47
50
    def can_handle(cls, device_info):
48
51
        '''
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
53
56
        returns True.
54
 
        
55
 
        :param device_info: On windows a device ID string. On Unix a tuple of 
56
 
        ``(vendor_id, product_id, bcd)``. 
 
57
 
 
58
        :param device_info: On windows a device ID string. On Unix a tuple of
 
59
        ``(vendor_id, product_id, bcd)``.
57
60
        '''
58
61
        return True
59
 
    
 
62
 
60
63
    def open(self):
61
64
        '''
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.
69
 
        '''
70
 
        raise NotImplementedError()
71
 
    
 
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
 
72
        devices.
 
73
        '''
 
74
        raise NotImplementedError()
 
75
 
 
76
    def eject(self):
 
77
        '''
 
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.
 
80
        '''
 
81
        raise NotImplementedError()
 
82
 
72
83
    def set_progress_reporter(self, report_progress):
73
84
        '''
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
78
89
        '''
79
90
        raise NotImplementedError()
80
 
    
 
91
 
81
92
    def get_device_information(self, end_session=True):
82
 
        """ 
83
 
        Ask device for device information. See L{DeviceInfoQuery}. 
 
93
        """
 
94
        Ask device for device information. See L{DeviceInfoQuery}.
84
95
        @return: (device name, device version, software version on device, mime type)
85
96
        """
86
97
        raise NotImplementedError()
87
 
    
 
98
 
88
99
    def card_prefix(self, end_session=True):
89
100
        '''
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.
 
103
        E.G.
 
104
        ('/place', '/place2')
 
105
        (None, 'place2')
 
106
        ('place', None)
 
107
        (None, None)
91
108
        '''
92
109
        raise NotImplementedError()
93
 
    
 
110
 
94
111
    def total_space(self, end_session=True):
95
 
        """ 
 
112
        """
96
113
        Get total space available on the mountpoints:
97
114
            1. Main memory
98
 
            2. Memory Stick
99
 
            3. SD Card
 
115
            2. Memory Card A
 
116
            3. Memory Card B
100
117
 
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.
103
120
        """
104
121
        raise NotImplementedError()
105
 
    
 
122
 
106
123
    def free_space(self, end_session=True):
107
 
        """ 
 
124
        """
108
125
        Get free space available on the mountpoints:
109
126
          1. Main memory
110
127
          2. Card A
112
129
 
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.
115
 
        """    
 
132
        """
116
133
        raise NotImplementedError()
117
 
    
118
 
    def books(self, oncard=False, end_session=True):
119
 
        """ 
 
134
 
 
135
    def books(self, oncard=None, end_session=True):
 
136
        """
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. 
124
 
        @return: A BookList. 
125
 
        """    
 
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.
 
142
        @return: A BookList.
 
143
        """
126
144
        raise NotImplementedError()
127
 
    
128
 
    def upload_books(self, files, names, on_card=False, end_session=True,
 
145
 
 
146
    def upload_books(self, files, names, on_card=None, end_session=True,
129
147
                     metadata=None):
130
148
        '''
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.
145
163
        '''
146
164
        raise NotImplementedError()
147
 
    
 
165
 
148
166
    @classmethod
149
167
    def add_books_to_metadata(cls, locations, metadata, booklists):
150
168
        '''
151
 
        Add locations to the booklists. This function must not communicate with 
152
 
        the device. 
 
169
        Add locations to the booklists. This function must not communicate with
 
170
        the device.
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')).
167
186
        '''
168
187
        raise NotImplementedError
169
 
    
 
188
 
170
189
    def delete_books(self, paths, end_session=True):
171
190
        '''
172
191
        Delete books at paths on device.
173
192
        '''
174
193
        raise NotImplementedError()
175
 
    
 
194
 
176
195
    @classmethod
177
196
    def remove_books_from_metadata(cls, paths, booklists):
178
197
        '''
179
 
        Remove books from the metadata list. This function must not communicate 
 
198
        Remove books from the metadata list. This function must not communicate
180
199
        with the device.
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')).
184
204
        '''
185
205
        raise NotImplementedError()
186
 
        
 
206
 
187
207
    def sync_booklists(self, booklists, end_session=True):
188
208
        '''
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')).
192
213
        '''
193
214
        raise NotImplementedError()
194
 
    
195
 
    def get_file(self, path, outfile, end_session=True): 
 
215
 
 
216
    def get_file(self, path, outfile, end_session=True):
196
217
        '''
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
199
220
        '''
200
 
        raise NotImplementedError()         
201
 
 
202
 
 
203
 
    
 
221
        raise NotImplementedError()
 
222
 
 
223
    @classmethod
 
224
    def config_widget(cls):
 
225
        '''
 
226
        Should return a QWidget. The QWidget contains the settings for the device interface
 
227
        '''
 
228
        raise NotImplementedError()
 
229
 
 
230
    @classmethod
 
231
    def save_settings(cls, settings_widget):
 
232
        '''
 
233
        Should save settings to disk. Takes the widget created in config_widget
 
234
        and saves all settings to disk.
 
235
        '''
 
236
        raise NotImplementedError()
 
237
 
 
238
    @classmethod
 
239
    def settings(cls):
 
240
        '''
 
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.
 
243
        '''
 
244
        raise NotImplementedError()
 
245
 
 
246
 
 
247
 
 
248
 
204
249
class BookList(list):
205
250
    '''
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).
214
259
    '''
215
 
    
 
260
 
216
261
    __getslice__ = None
217
262
    __setslice__ = None
218
 
    
 
263
 
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()
222
 
    
 
267
 
223
268
    def set_tags(self, book, tags):
224
269
        '''
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.
228
273
        '''
229
274
        raise NotImplementedError()
230
275