mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Ondevice works with Sony PRS-300
This commit is contained in:
parent
41755c20ef
commit
afadcc7a1b
@ -46,6 +46,14 @@ class Book(object):
|
||||
return self.title.encode('utf-8') + " by " + \
|
||||
self.authors.encode('utf-8') + " at " + self.path.encode('utf-8')
|
||||
|
||||
@dynamic_property
|
||||
def db_id(self):
|
||||
doc = '''The database id in the application database that this file corresponds to'''
|
||||
def fget(self):
|
||||
match = re.search(r'_(\d+)$', self.rpath.rpartition('.')[0])
|
||||
if match:
|
||||
return int(match.group(1))
|
||||
return property(fget=fget, doc=doc)
|
||||
|
||||
class BookList(_BookList):
|
||||
|
||||
|
@ -979,54 +979,62 @@ class DeviceGUI(object):
|
||||
if memory and memory[1]:
|
||||
self.library_view.model().delete_books_by_id(memory[1])
|
||||
|
||||
def book_on_device(self, index, index_is_id=False, format=None):
|
||||
def book_on_device(self, index, index_is_id=False, format=None, reset=False):
|
||||
loc = [None, None, None]
|
||||
|
||||
if reset:
|
||||
self.book_on_device_cache = None
|
||||
return
|
||||
|
||||
if self.book_on_device_cache is None:
|
||||
self.book_on_device_cache = []
|
||||
for i, l in enumerate(self.booklists()):
|
||||
self.book_on_device_cache.append({})
|
||||
for book in l:
|
||||
book_title = book.title.lower() if book.title else ''
|
||||
book_title = re.sub('(?u)\W|[_]', '', book_title)
|
||||
if book_title not in self.book_on_device_cache[i]:
|
||||
self.book_on_device_cache[i][book_title] = \
|
||||
{'authors':set(), 'db_ids':set()}
|
||||
book_authors = authors_to_string(book.authors).lower()
|
||||
book_authors = re.sub('(?u)\W|[_]', '', book_authors)
|
||||
self.book_on_device_cache[i][book_title]['authors'].add(book_authors)
|
||||
self.book_on_device_cache[i][book_title]['db_ids'].add(book.db_id)
|
||||
|
||||
db_title = self.library_view.model().db.title(index, index_is_id).lower()
|
||||
db_title = re.sub('(?u)\W|[_]', '', db_title)
|
||||
au = self.library_view.model().db.authors(index, index_is_id)
|
||||
db_authors = au.lower() if au else ''
|
||||
db_authors = re.sub('(?u)\W|[_]', '', db_authors)
|
||||
|
||||
for i, l in enumerate(self.booklists()):
|
||||
for book in l:
|
||||
book_title = book.title.lower() if book.title else ''
|
||||
book_title = re.sub('(?u)\W|[_]', '', book_title)
|
||||
book_authors = authors_to_string(book.authors).lower()
|
||||
book_authors = re.sub('(?u)\W|[_]', '', book_authors)
|
||||
if book_title == db_title and book_authors == db_authors:
|
||||
d = self.book_on_device_cache[i].get(db_title, None)
|
||||
if d and (index in d['db_ids'] or db_authors in d['authors']):
|
||||
loc[i] = True
|
||||
break
|
||||
return loc
|
||||
|
||||
def book_in_library(self, index, oncard=None):
|
||||
def set_books_in_library(self, booklist):
|
||||
'''
|
||||
Used to determine if a book on the device is in the library.
|
||||
Returns the book's id in the library.
|
||||
Set the 'in_library' attribute for all books on a device to True if a
|
||||
book on the device is in the library, else False
|
||||
'''
|
||||
bl = []
|
||||
if oncard == 'carda':
|
||||
bl = self.booklists()[1]
|
||||
elif oncard == 'cardb':
|
||||
bl = self.booklists()[2]
|
||||
else:
|
||||
bl = self.booklists()[0]
|
||||
# First build a cache of the library, so the search isn't On**2
|
||||
cache = {}
|
||||
for id, title in self.library_view.model().db.all_titles():
|
||||
title = re.sub('(?u)\W|[_]', '', title.lower())
|
||||
au = self.library_view.model().db.authors(id, index_is_id=True)
|
||||
authors = au.lower() if au else ''
|
||||
authors = re.sub('(?u)\W|[_]', '', authors)
|
||||
cache[title+authors] = id
|
||||
|
||||
book = bl[index]
|
||||
# Now iterate through all the books on the device, setting the in_library field
|
||||
for book in booklist:
|
||||
book_title = book.title.lower() if book.title else ''
|
||||
book_title = re.sub('(?u)\W|[_]', '', book_title)
|
||||
book_authors = authors_to_string(book.authors).lower() if book.authors else ''
|
||||
book_authors = re.sub('(?u)\W|[_]', '', book_authors)
|
||||
|
||||
# if getattr(book, 'application_id', None) != None and self.library_view.model().db.has_id(book.application_id):
|
||||
# if book.uuid and self.library_view.model().db.uuid(book.application_id, index_is_id=True) == book.uuid:
|
||||
# return book.application_id
|
||||
for id, title in self.library_view.model().db.all_titles():
|
||||
title = re.sub('(?u)\W|[_]', '', title.lower())
|
||||
if title == book_title:
|
||||
au = self.library_view.model().db.authors(id, index_is_id=True)
|
||||
authors = au.lower() if au else ''
|
||||
authors = re.sub('(?u)\W|[_]', '', authors)
|
||||
if authors == book_authors:
|
||||
return id
|
||||
return None
|
||||
if cache.get(book_title + book_authors, None) is not None:
|
||||
book.in_library = True
|
||||
else:
|
||||
book.in_library = False
|
||||
|
@ -1268,6 +1268,8 @@ class DeviceBooksModel(BooksModel):
|
||||
def set_book_in_library_func(self, func, loc):
|
||||
self.book_in_library = func
|
||||
self.loc = loc
|
||||
# Not convinced that this should be here ...
|
||||
func(self.db)
|
||||
|
||||
def mark_for_deletion(self, job, rows):
|
||||
self.marked_for_deletion[job] = self.indices(rows)
|
||||
@ -1356,7 +1358,7 @@ class DeviceBooksModel(BooksModel):
|
||||
x, y = ','.join(self.db[x].tags), ','.join(self.db[y].tags)
|
||||
return cmp(x, y)
|
||||
def libcmp(x, y):
|
||||
x, y = self.book_in_library(self.map[x], self.loc), self.book_in_library(self.map[y], self.loc)
|
||||
x, y = self.db[x].in_library, self.db[y].in_library
|
||||
return cmp(x, y)
|
||||
fcmp = strcmp('title_sorter') if col == 0 else strcmp('authors') if col == 1 else \
|
||||
sizecmp if col == 2 else datecmp if col == 3 else tagscmp if col == 4 else libcmp
|
||||
@ -1429,7 +1431,7 @@ class DeviceBooksModel(BooksModel):
|
||||
if role == Qt.EditRole:
|
||||
return QVariant(au)
|
||||
authors = string_to_authors(au)
|
||||
return QVariant("\n".join(authors))
|
||||
return QVariant(" & ".join(authors))
|
||||
elif col == 2:
|
||||
size = self.db[self.map[row]].size
|
||||
return QVariant(BooksView.human_readable(size))
|
||||
@ -1442,9 +1444,8 @@ class DeviceBooksModel(BooksModel):
|
||||
if tags:
|
||||
return QVariant(', '.join(tags))
|
||||
elif col == 5:
|
||||
if self.book_in_library:
|
||||
if self.book_in_library(self.map[row], self.loc) != None:
|
||||
return QVariant(_("True"))
|
||||
return QVariant(_('Yes')) \
|
||||
if self.db[self.map[row]].in_library else QVariant(_('No'))
|
||||
elif role == Qt.TextAlignmentRole and index.column() in [2, 3]:
|
||||
return QVariant(Qt.AlignRight | Qt.AlignVCenter)
|
||||
elif role == Qt.ToolTipRole and index.isValid():
|
||||
|
@ -520,6 +520,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
||||
if self.system_tray_icon.isVisible() and opts.start_in_tray:
|
||||
self.hide_windows()
|
||||
self.stack.setCurrentIndex(0)
|
||||
self.book_on_device(None, reset=True)
|
||||
db.set_book_on_device_func(self.book_on_device)
|
||||
self.library_view.set_database(db)
|
||||
self.library_view.model().set_book_on_device_func(self.book_on_device)
|
||||
@ -993,13 +994,13 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
||||
return
|
||||
mainlist, cardalist, cardblist = job.result
|
||||
self.memory_view.set_database(mainlist)
|
||||
self.memory_view.model().set_book_in_library_func(self.book_in_library, 'main')
|
||||
self.memory_view.model().set_book_in_library_func(self.set_books_in_library, 'main')
|
||||
self.memory_view.set_editable(self.device_manager.device.CAN_SET_METADATA)
|
||||
self.card_a_view.set_database(cardalist)
|
||||
self.card_a_view.model().set_book_in_library_func(self.book_in_library, 'carda')
|
||||
self.card_a_view.model().set_book_in_library_func(self.set_books_in_library, 'carda')
|
||||
self.card_a_view.set_editable(self.device_manager.device.CAN_SET_METADATA)
|
||||
self.card_b_view.set_database(cardblist)
|
||||
self.card_b_view.model().set_book_in_library_func(self.book_in_library, 'cardb')
|
||||
self.card_b_view.model().set_book_in_library_func(self.set_books_in_library, 'cardb')
|
||||
self.card_b_view.set_editable(self.device_manager.device.CAN_SET_METADATA)
|
||||
for view in (self.memory_view, self.card_a_view, self.card_b_view):
|
||||
view.sortByColumn(3, Qt.DescendingOrder)
|
||||
@ -1007,6 +1008,10 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
||||
if not view.restore_column_widths():
|
||||
view.resizeColumnsToContents()
|
||||
view.resize_on_select = not view.isVisible()
|
||||
if view.model().rowCount(None) > 1:
|
||||
view.resizeRowToContents(0)
|
||||
height = view.rowHeight(0)
|
||||
view.verticalHeader().setDefaultSectionSize(height)
|
||||
self.sync_news()
|
||||
self.sync_catalogs()
|
||||
self.refresh_ondevice_info()
|
||||
@ -1014,15 +1019,10 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
||||
############################################################################
|
||||
### Force the library view to refresh, taking into consideration books information
|
||||
def refresh_ondevice_info(self, clear_flags = False):
|
||||
# self.library_view.model().db.set_all_ondevice('')
|
||||
# if not clear_flags:
|
||||
# for id in self.library_view.model().db:
|
||||
# self.library_view.model().db.set_book_on_device_string(id, index_is_id=True))
|
||||
self.book_on_device(None, reset=True)
|
||||
self.library_view.model().refresh()
|
||||
############################################################################
|
||||
|
||||
############################################################################
|
||||
|
||||
######################### Fetch annotations ################################
|
||||
|
||||
def fetch_annotations(self, *args):
|
||||
@ -2246,6 +2246,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
||||
def library_moved(self, newloc):
|
||||
if newloc is None: return
|
||||
db = LibraryDatabase2(newloc)
|
||||
self.book_on_device(None, reset=True)
|
||||
db.set_book_on_device_func(self.book_on_device)
|
||||
self.library_view.set_database(db)
|
||||
self.library_view.model().set_book_on_device_func(self.book_on_device)
|
||||
|
@ -370,7 +370,7 @@ class ResultCache(SearchQueryParser):
|
||||
location += 's'
|
||||
|
||||
all = ('title', 'authors', 'publisher', 'tags', 'comments', 'series',
|
||||
'formats', 'isbn', 'rating', 'cover')
|
||||
'formats', 'isbn', 'rating', 'cover', 'ondevice')
|
||||
MAP = {}
|
||||
|
||||
for x in all: # get the db columns for the standard searchables
|
||||
|
@ -100,6 +100,7 @@ class SearchQueryParser(object):
|
||||
'search',
|
||||
'date',
|
||||
'pubdate',
|
||||
'ondevice',
|
||||
'all',
|
||||
]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user