[merge] From Official

This commit is contained in:
Kolenka 2011-10-09 22:23:02 -07:00
commit 523a11c0c2
5 changed files with 333 additions and 295 deletions

View File

@ -217,7 +217,7 @@ class DevicePlugin(Plugin):
''' '''
Unix version of :meth:`can_handle_windows` Unix version of :meth:`can_handle_windows`
:param device_info: Is a tupe of (vid, pid, bcd, manufacturer, product, :param device_info: Is a tuple of (vid, pid, bcd, manufacturer, product,
serial number) serial number)
''' '''

View File

@ -2,5 +2,6 @@
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2010, Timothy Legge <timlegge at gmail.com> and Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@ -1,9 +0,0 @@
__license__ = 'GPL v3'
__copyright__ = '2010, Timothy Legge <timlegge at gmail.com>'
'''
'''
class ImageWrapper(object):
def __init__(self, image_path):
self.image_path = image_path

View File

@ -2,7 +2,7 @@
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2010, Timothy Legge <timlegge at gmail.com> and Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
''' '''
@ -10,20 +10,26 @@ Device driver for the SONY T1 devices
''' '''
import os, time, calendar, re import os, time, calendar, re
import sqlite3 as sqlite import sqlite3 as sqlite
from contextlib import closing from contextlib import closing
from itertools import cycle
from calibre.devices.usbms.driver import USBMS, debug_print from calibre.devices.usbms.driver import USBMS, debug_print
from calibre import __appname__, prints from calibre.devices.usbms.device import USBDevice
from calibre.devices.usbms.books import CollectionsBookList from calibre.devices.usbms.books import CollectionsBookList
from calibre.devices.usbms.books import BookList from calibre.devices.usbms.books import BookList
from calibre.devices.prst1.books import ImageWrapper from calibre.constants import islinux
DBPATH = 'Sony_Reader/database/books.db'
THUMBPATH = 'Sony_Reader/database/cache/books/%s/thumbnail/main_thumbnail.jpg'
class ImageWrapper(object):
def __init__(self, image_path):
self.image_path = image_path
class PRST1(USBMS): class PRST1(USBMS):
name = 'SONY PRST1 and newer Device Interface' name = 'SONY PRST1 and newer Device Interface'
gui_name = 'SONY Reader' gui_name = 'SONY Reader'
description = _('Communicate with Sony PRST1 and newer eBook readers') description = _('Communicate with the PRST1 and newer SONY eBook readers')
author = 'Kovid Goyal' author = 'Kovid Goyal'
supported_platforms = ['windows', 'osx', 'linux'] supported_platforms = ['windows', 'osx', 'linux']
path_sep = '/' path_sep = '/'
@ -41,6 +47,8 @@ class PRST1(USBMS):
WINDOWS_MAIN_MEM = re.compile( WINDOWS_MAIN_MEM = re.compile(
r'(PRS-T1&)' r'(PRS-T1&)'
) )
MAIN_MEMORY_VOLUME_LABEL = 'SONY Reader Main Memory'
STORAGE_CARD_VOLUME_LABEL = 'SONY Reader Storage Card'
THUMBNAIL_HEIGHT = 144 THUMBNAIL_HEIGHT = 144
SUPPORTS_SUB_DIRS = True SUPPORTS_SUB_DIRS = True
@ -51,29 +59,29 @@ class PRST1(USBMS):
_('Comma separated list of metadata fields ' _('Comma separated list of metadata fields '
'to turn into collections on the device. Possibilities include: ')+\ 'to turn into collections on the device. Possibilities include: ')+\
'series, tags, authors', 'series, tags, authors',
_('Upload separate cover thumbnails for books') + _('Upload separate cover thumbnails for books') +
':::'+_('Normally, the SONY readers get the cover image from the' ':::'+_('Normally, the SONY readers get the cover image from the'
' ebook file itself. With this option, calibre will send a ' ' ebook file itself. With this option, calibre will send a '
'separate cover image to the reader, useful if you are ' 'separate cover image to the reader, useful if you are '
'sending DRMed books in which you cannot change the cover.'), 'sending DRMed books in which you cannot change the cover.'),
_('Refresh separate covers when using automatic management') + _('Refresh separate covers when using automatic management') +
':::' + ':::' +
_('Set this option to have separate book covers uploaded ' _('Set this option to have separate book covers uploaded '
'every time you connect your device. Unset this option if ' 'every time you connect your device. Unset this option if '
'you have so many books on the reader that performance is ' 'you have so many books on the reader that performance is '
'unacceptable.'), 'unacceptable.'),
_('Preserve cover aspect ratio when building thumbnails') + _('Preserve cover aspect ratio when building thumbnails') +
':::' + ':::' +
_('Set this option if you want the cover thumbnails to have ' _('Set this option if you want the cover thumbnails to have '
'the same aspect ratio (width to height) as the cover. ' 'the same aspect ratio (width to height) as the cover. '
'Unset it if you want the thumbnail to be the maximum size, ' 'Unset it if you want the thumbnail to be the maximum size, '
'ignoring aspect ratio.'), 'ignoring aspect ratio.'),
] ]
EXTRA_CUSTOMIZATION_DEFAULT = [ EXTRA_CUSTOMIZATION_DEFAULT = [
', '.join(['series', 'tags']), ', '.join(['series', 'tags']),
False, True,
False, False,
True, True,
] ]
OPT_COLLECTIONS = 0 OPT_COLLECTIONS = 0
@ -103,284 +111,317 @@ class PRST1(USBMS):
return self.EBOOK_DIR_MAIN return self.EBOOK_DIR_MAIN
return '' return ''
def books(self, oncard=None, end_session=True): def can_handle(self, devinfo, debug=False):
from calibre.ebooks.metadata.meta import path_to_ext if islinux:
dev = USBDevice(devinfo)
main, carda, cardb = self.find_device_nodes(detected_device=dev)
if main is None and carda is None and cardb is None:
if debug:
print ('\tPRS-T1: Appears to be in non data mode'
' or was ejected, ignoring')
return False
return True
dummy_bl = BookList(None, None, None) def books(self, oncard=None, end_session=True):
dummy_bl = BookList(None, None, None)
if oncard == 'carda' and not self._card_a_prefix: if (
self.report_progress(1.0, _('Getting list of books on device...')) (oncard == 'carda' and not self._card_a_prefix) or
return dummy_bl (oncard and oncard != 'carda')
elif oncard and oncard != 'carda': ):
self.report_progress(1.0, _('Getting list of books on device...')) self.report_progress(1.0, _('Getting list of books on device...'))
return dummy_bl return dummy_bl
prefix = self._card_a_prefix if oncard == 'carda' else self._main_prefix
# Let parent driver get the books prefix = self._card_a_prefix if oncard == 'carda' else self._main_prefix
self.booklist_class.rebuild_collections = self.rebuild_collections
bl = USBMS.books(self, oncard=oncard, end_session=end_session) # Let parent driver get the books
self.booklist_class.rebuild_collections = self.rebuild_collections
debug_print("SQLite DB Path: " + self.normalize_path(prefix + 'Sony_Reader/database/books.db')) bl = USBMS.books(self, oncard=oncard, end_session=end_session)
with closing(sqlite.connect(self.normalize_path(prefix + 'Sony_Reader/database/books.db'))) as connection: dbpath = self.normalize_path(prefix + DBPATH)
# return bytestrings if the content cannot the decoded as unicode debug_print("SQLite DB Path: " + dbpath)
connection.text_factory = lambda x: unicode(x, "utf-8", "ignore")
with closing(sqlite.connect(dbpath)) as connection:
# Replace undecodable characters in the db instead of erroring out
connection.text_factory = lambda x: unicode(x, "utf-8", "replace")
cursor = connection.cursor() cursor = connection.cursor()
# Query collections # Query collections
query = 'select books._id, collection.title ' \ query = '''
'from collections ' \ SELECT books._id, collection.title
'left outer join books ' \ FROM collections
'left outer join collection ' \ LEFT OUTER JOIN books
'where collections.content_id = books._id and collections.collection_id = collection._id' LEFT OUTER JOIN collection
cursor.execute (query) WHERE collections.content_id = books._id AND
collections.collection_id = collection._id
bl_collections = {} '''
for i, row in enumerate(cursor): cursor.execute(query)
bl_collections.setdefault(row[0], [])
bl_collections[row[0]].append(row[1])
for idx,book in enumerate(bl):
query = 'select _id, thumbnail from books where file_path = ?'
t = (book.lpath,)
cursor.execute (query, t)
for i, row in enumerate(cursor):
book.device_collections = bl_collections.get(row[0], None)
thumbnail = row[1]
if thumbnail is not None:
thumbnail = self.normalize_path(prefix + thumbnail)
book.thumbnail = ImageWrapper(thumbnail)
cursor.close()
return bl bl_collections = {}
for i, row in enumerate(cursor):
def set_plugboards(self, plugboards, pb_func): bl_collections.setdefault(row[0], [])
self.plugboards = plugboards bl_collections[row[0]].append(row[1])
self.plugboard_func = pb_func
for idx, book in enumerate(bl):
def sync_booklists(self, booklists, end_session=True): query = 'SELECT _id, thumbnail FROM books WHERE file_path = ?'
debug_print('PRST1: starting sync_booklists') t = (book.lpath,)
cursor.execute (query, t)
opts = self.settings()
for i, row in enumerate(cursor):
book.device_collections = bl_collections.get(row[0], None)
thumbnail = row[1]
if thumbnail is not None:
thumbnail = self.normalize_path(prefix + thumbnail)
book.thumbnail = ImageWrapper(thumbnail)
cursor.close()
return bl
def set_plugboards(self, plugboards, pb_func):
self.plugboards = plugboards
self.plugboard_func = pb_func
def sync_booklists(self, booklists, end_session=True):
debug_print('PRST1: starting sync_booklists')
opts = self.settings()
if opts.extra_customization: if opts.extra_customization:
collections = [x.strip() for x in collections = [x.strip() for x in
opts.extra_customization[self.OPT_COLLECTIONS].split(',')] opts.extra_customization[self.OPT_COLLECTIONS].split(',')]
else: else:
collections = [] collections = []
debug_print('PRST1: collection fields:', collections) debug_print('PRST1: collection fields:', collections)
if booklists[0] is not None:
self.update_device_database(booklists[0], collections, None)
if booklists[1] is not None:
self.update_device_database(booklists[1], collections, 'carda')
USBMS.sync_booklists(self, booklists, end_session=end_session)
debug_print('PRST1: finished sync_booklists')
def update_device_database(self, booklist, collections_attributes, oncard):
debug_print('PRST1: starting update_device_database')
plugboard = None
if self.plugboard_func:
plugboard = self.plugboard_func(self.__class__.__name__, 'device_db', self.plugboards)
debug_print("PRST1: Using Plugboard", plugboard)
prefix = self._card_a_prefix if oncard == 'carda' else self._main_prefix
source_id = 1 if oncard == 'carda' else 0
debug_print("SQLite DB Path: " + self.normalize_path(prefix + 'Sony_Reader/database/books.db'))
collections = booklist.get_collections(collections_attributes)
with closing(sqlite.connect(self.normalize_path(prefix + 'Sony_Reader/database/books.db'))) as connection:
self.update_device_books(connection, booklist, source_id, plugboard)
self.update_device_collections(connection, booklist, collections, source_id)
debug_print('PRST1: finished update_device_database')
def update_device_books(self, connection, booklist, source_id, plugboard): if booklists[0] is not None:
opts = self.settings() self.update_device_database(booklists[0], collections, None)
upload_covers = opts.extra_customization[self.OPT_UPLOAD_COVERS] if booklists[1] is not None:
refresh_covers = opts.extra_customization[self.OPT_REFRESH_COVERS] self.update_device_database(booklists[1], collections, 'carda')
cursor = connection.cursor() USBMS.sync_booklists(self, booklists, end_session=end_session)
debug_print('PRST1: finished sync_booklists')
# Get existing books
query = 'select file_path, _id ' \ def update_device_database(self, booklist, collections_attributes, oncard):
'from books' debug_print('PRST1: starting update_device_database')
cursor.execute(query)
plugboard = None
dbBooks = {} if self.plugboard_func:
for i, row in enumerate(cursor): plugboard = self.plugboard_func(self.__class__.__name__,
lpath = row[0].replace('\\', '/') 'device_db', self.plugboards)
dbBooks[lpath] = row[1] debug_print("PRST1: Using Plugboard", plugboard)
for book in booklist: prefix = self._card_a_prefix if oncard == 'carda' else self._main_prefix
# Run through plugboard if needed if prefix is None:
if plugboard is not None: # Reader has no sd card inserted
return
source_id = 1 if oncard == 'carda' else 0
dbpath = self.normalize_path(prefix + DBPATH)
debug_print("SQLite DB Path: " + dbpath)
collections = booklist.get_collections(collections_attributes)
with closing(sqlite.connect(dbpath)) as connection:
self.update_device_books(connection, booklist, source_id, plugboard)
self.update_device_collections(connection, booklist, collections, source_id)
debug_print('PRST1: finished update_device_database')
def update_device_books(self, connection, booklist, source_id, plugboard):
opts = self.settings()
upload_covers = opts.extra_customization[self.OPT_UPLOAD_COVERS]
refresh_covers = opts.extra_customization[self.OPT_REFRESH_COVERS]
cursor = connection.cursor()
# Get existing books
query = 'SELECT file_path, _id FROM books'
cursor.execute(query)
db_books = {}
for i, row in enumerate(cursor):
lpath = row[0].replace('\\', '/')
db_books[lpath] = row[1]
for book in booklist:
# Run through plugboard if needed
if plugboard is not None:
newmi = book.deepcopy_metadata() newmi = book.deepcopy_metadata()
newmi.template_to_attribute(book, plugboard) newmi.template_to_attribute(book, plugboard)
else: else:
newmi = book newmi = book
# Get Metadata We Want
lpath = book.lpath
author = newmi.authors[0]
title = newmi.title
if lpath not in dbBooks: # Get Metadata We Want
query = 'insert into books ' \ lpath = book.lpath
'(title, author, source_id, added_date, modified_date, file_path, file_name, file_size, mime_type, corrupted, prevent_delete) ' \ author = newmi.authors[0]
'values (?,?,?,?,?,?,?,?,?,0,0)' title = newmi.title
t = (title, author, source_id, int(time.time() * 1000), calendar.timegm(book.datetime), lpath, os.path.basename(book.lpath), book.size, book.mime )
cursor.execute(query, t)
book.bookId = cursor.lastrowid
if upload_covers:
self.upload_book_cover(connection, book, source_id)
debug_print('Inserted New Book: ' + book.title)
else:
query = 'update books ' \
'set title = ?, author = ?, modified_date = ?, file_size = ? ' \
'where file_path = ?'
t = (title, author, calendar.timegm(book.datetime), book.size, lpath)
cursor.execute(query, t)
book.bookId = dbBooks[lpath]
if refresh_covers:
self.upload_book_cover(connection, book, source_id)
dbBooks[lpath] = None
for book, bookId in dbBooks.items():
if bookId is not None:
# Remove From Collections
query = 'delete from collections ' \
'where content_id = ?'
t = (bookId,)
cursor.execute(query, t)
# Remove from Books
query = 'delete from books ' \
'where _id = ?'
t = (bookId,)
cursor.execute(query, t)
debug_print('Deleted Book:' + book)
connection.commit()
cursor.close()
def update_device_collections(self, connection, booklist, collections, source_id):
cursor = connection.cursor()
if collections:
# Get existing collections
query = 'select _id, title ' \
'from collection'
cursor.execute(query)
dbCollections = {}
for i, row in enumerate(cursor):
dbCollections[row[1]] = row[0]
for collection, books in collections.items():
if collection not in dbCollections:
query = 'insert into collection (title, source_id) values (?,?)'
t = (collection, source_id)
cursor.execute(query, t)
dbCollections[collection] = cursor.lastrowid
debug_print('Inserted New Collection: ' + collection)
# Get existing books in collection
query = 'select books.file_path, content_id ' \
'from collections ' \
'left outer join books ' \
'where collection_id = ? and books._id = collections.content_id'
t = (dbCollections[collection],)
cursor.execute(query, t)
dbBooks = {} if lpath not in db_books:
for i, row in enumerate(cursor): query = '''
dbBooks[row[0]] = row[1] INSERT INTO books
(title, author, source_id, added_date, modified_date,
for idx, book in enumerate(books): file_path, file_name, file_size, mime_type, corrupted,
if dbBooks.get(book.lpath, None) is None: prevent_delete)
if collection not in book.device_collections: values (?,?,?,?,?,?,?,?,?,0,0)
book.device_collections.append(collection) '''
query = 'insert into collections (collection_id, content_id, added_order) values (?,?,?)' t = (title, author, source_id, int(time.time() * 1000),
t = (dbCollections[collection], book.bookId, idx) calendar.timegm(book.datetime), lpath,
cursor.execute(query, t) os.path.basename(book.lpath), book.size, book.mime)
debug_print('Inserted Book Into Collection: ' + book.title + ' -> ' + collection) cursor.execute(query, t)
else: book.bookId = cursor.lastrowid
query = 'update collections ' \ if upload_covers:
'set added_order = ? ' \ self.upload_book_cover(connection, book, source_id)
'where content_id = ? and collection_id = ? ' debug_print('Inserted New Book: ' + book.title)
t = (idx, book.bookId, dbCollections[collection]) else:
cursor.execute(query, t) query = '''
UPDATE books
dbBooks[book.lpath] = None SET title = ?, author = ?, modified_date = ?, file_size = ?
WHERE file_path = ?
for bookPath, bookId in dbBooks.items(): '''
if bookId is not None: t = (title, author, calendar.timegm(book.datetime), book.size,
query = 'delete from collections ' \ lpath)
'where content_id = ? and collection_id = ? ' cursor.execute(query, t)
t = (bookId,dbCollections[collection],) book.bookId = db_books[lpath]
cursor.execute(query, t) if refresh_covers:
debug_print('Deleted Book From Collection: ' + bookPath + ' -> ' + collection) self.upload_book_cover(connection, book, source_id)
db_books[lpath] = None
dbCollections[collection] = None
for book, bookId in db_books.items():
for collection, collectionId in dbCollections.items(): if bookId is not None:
if collectionId is not None: # Remove From Collections
# Remove Books from Collection query = 'DELETE FROM collections WHERE content_id = ?'
query = 'delete from collections ' \ t = (bookId,)
'where collection_id = ?' cursor.execute(query, t)
t = (collectionId,) # Remove from Books
cursor.execute(query, t) query = 'DELETE FROM books where _id = ?'
# Remove Collection t = (bookId,)
query = 'delete from collection ' \ cursor.execute(query, t)
'where _id = ?' debug_print('Deleted Book:' + book)
t = (collectionId,)
cursor.execute(query, t) connection.commit()
debug_print('Deleted Collection: ' + collection) cursor.close()
def update_device_collections(self, connection, booklist, collections,
connection.commit() source_id):
cursor.close() cursor = connection.cursor()
def rebuild_collections(self, booklist, oncard): if collections:
debug_print('PRST1: starting rebuild_collections') # Get existing collections
query = 'SELECT _id, title FROM collection'
opts = self.settings() cursor.execute(query)
db_collections = {}
for i, row in enumerate(cursor):
db_collections[row[1]] = row[0]
for collection, books in collections.items():
if collection not in db_collections:
query = 'INSERT INTO collection (title, source_id) VALUES (?,?)'
t = (collection, source_id)
cursor.execute(query, t)
db_collections[collection] = cursor.lastrowid
debug_print('Inserted New Collection: ' + collection)
# Get existing books in collection
query = '''
SELECT books.file_path, content_id
FROM collections
LEFT OUTER JOIN books
WHERE collection_id = ? AND books._id = collections.content_id
'''
t = (db_collections[collection],)
cursor.execute(query, t)
db_books = {}
for i, row in enumerate(cursor):
db_books[row[0]] = row[1]
for idx, book in enumerate(books):
if db_books.get(book.lpath, None) is None:
if collection not in book.device_collections:
book.device_collections.append(collection)
query = '''
INSERT INTO collections (collection_id, content_id,
added_order) values (?,?,?)
'''
t = (db_collections[collection], book.bookId, idx)
cursor.execute(query, t)
debug_print('Inserted Book Into Collection: ' +
book.title + ' -> ' + collection)
else:
query = '''
UPDATE collections
SET added_order = ?
WHERE content_id = ? AND collection_id = ?
'''
t = (idx, book.bookId, db_collections[collection])
cursor.execute(query, t)
db_books[book.lpath] = None
for bookPath, bookId in db_books.items():
if bookId is not None:
query = ('DELETE FROM collections '
'WHERE content_id = ? AND collection_id = ? ')
t = (bookId, db_collections[collection],)
cursor.execute(query, t)
debug_print('Deleted Book From Collection: ' + bookPath
+ ' -> ' + collection)
db_collections[collection] = None
for collection, collectionId in db_collections.items():
if collectionId is not None:
# Remove Books from Collection
query = ('DELETE FROM collections '
'WHERE collection_id = ?')
t = (collectionId,)
cursor.execute(query, t)
# Remove Collection
query = ('DELETE FROM collection '
'WHERE _id = ?')
t = (collectionId,)
cursor.execute(query, t)
debug_print('Deleted Collection: ' + collection)
connection.commit()
cursor.close()
def rebuild_collections(self, booklist, oncard):
debug_print('PRST1: starting rebuild_collections')
opts = self.settings()
if opts.extra_customization: if opts.extra_customization:
collections = [x.strip() for x in collections = [x.strip() for x in
opts.extra_customization[self.OPT_COLLECTIONS].split(',')] opts.extra_customization[self.OPT_COLLECTIONS].split(',')]
else: else:
collections = [] collections = []
debug_print('PRST1: collection fields:', collections) debug_print('PRST1: collection fields:', collections)
self.update_device_database(booklist, collections, oncard)
debug_print('PRS-T1: finished rebuild_collections')
def upload_book_cover(self, connection, book, source_id):
debug_print('PRST1: Uploading/Refreshing Cover for ' + book.title)
cursor = connection.cursor()
if book.thumbnail and book.thumbnail[-1]:
thumbnailPath = 'Sony_Reader/database/cache/books/' + str(book.bookId) +'/thumbnail/main_thumbnail.jpg'
prefix = self._main_prefix if source_id is 0 else self._card_a_prefix
thumbnailFilePath = os.path.join(prefix, *thumbnailPath.split('/'))
thumbnailDirPath = os.path.dirname(thumbnailFilePath)
if not os.path.exists(thumbnailDirPath):
os.makedirs(thumbnailDirPath)
with open(thumbnailFilePath, 'wb') as f: self.update_device_database(booklist, collections, oncard)
f.write(book.thumbnail[-1])
debug_print('PRS-T1: finished rebuild_collections')
query = 'update books ' \
'set thumbnail = ?' \ def upload_book_cover(self, connection, book, source_id):
'where _id = ? ' debug_print('PRST1: Uploading/Refreshing Cover for ' + book.title)
t = (thumbnailPath,book.bookId,) if not book.thumbnail and book.thumbnail[-1]:
cursor.execute(query, t) return
cursor = connection.cursor()
cursor.close()
thumbnail_path = THUMBPATH%book.bookId
prefix = self._main_prefix if source_id is 0 else self._card_a_prefix
thumbnail_file_path = os.path.join(prefix, *thumbnail_path.split('/'))
thumbnail_dir_path = os.path.dirname(thumbnail_file_path)
if not os.path.exists(thumbnail_dir_path):
os.makedirs(thumbnail_dir_path)
with open(thumbnail_file_path, 'wb') as f:
f.write(book.thumbnail[-1])
query = 'UPDATE books SET thumbnail = ? WHERE _id = ?'
t = (thumbnail_path, book.bookId,)
cursor.execute(query, t)
cursor.close()

View File

@ -483,7 +483,7 @@ class Device(DeviceConfig, DevicePlugin):
self._card_a_prefix = get_card_prefix('carda') self._card_a_prefix = get_card_prefix('carda')
self._card_b_prefix = get_card_prefix('cardb') self._card_b_prefix = get_card_prefix('cardb')
def find_device_nodes(self): def find_device_nodes(self, detected_device=None):
def walk(base): def walk(base):
base = os.path.abspath(os.path.realpath(base)) base = os.path.abspath(os.path.realpath(base))
@ -507,8 +507,11 @@ class Device(DeviceConfig, DevicePlugin):
d, j = os.path.dirname, os.path.join d, j = os.path.dirname, os.path.join
usb_dir = None usb_dir = None
if detected_device is None:
detected_device = self.detected_device
def test(val, attr): def test(val, attr):
q = getattr(self.detected_device, attr) q = getattr(detected_device, attr)
return q == val return q == val
for x, isfile in walk('/sys/devices'): for x, isfile in walk('/sys/devices'):
@ -596,6 +599,8 @@ class Device(DeviceConfig, DevicePlugin):
label = self.STORAGE_CARD2_VOLUME_LABEL label = self.STORAGE_CARD2_VOLUME_LABEL
if not label: if not label:
label = self.STORAGE_CARD_VOLUME_LABEL + ' 2' label = self.STORAGE_CARD_VOLUME_LABEL + ' 2'
if not label:
label = 'E-book Reader (%s)'%type
extra = 0 extra = 0
while True: while True:
q = ' (%d)'%extra if extra else '' q = ' (%d)'%extra if extra else ''