mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
SONY driver: Never delete collections. Instead set collections to those that already exist+those that come from calibre metadata. If you want to delete collections do it from the device view
This commit is contained in:
commit
3cf6969d8a
@ -9,7 +9,6 @@ import os, time
|
|||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
from calibre import prints, guess_type
|
from calibre import prints, guess_type
|
||||||
@ -151,15 +150,14 @@ class XMLCache(object):
|
|||||||
else:
|
else:
|
||||||
seen.add(title)
|
seen.add(title)
|
||||||
|
|
||||||
def get_playlist_map(self):
|
def build_playlist_id_map(self):
|
||||||
debug_print('Start get_playlist_map')
|
debug_print('Start build_playlist_id_map')
|
||||||
ans = {}
|
ans = {}
|
||||||
self.ensure_unique_playlist_titles()
|
self.ensure_unique_playlist_titles()
|
||||||
debug_print('after ensure_unique_playlist_titles')
|
debug_print('after ensure_unique_playlist_titles')
|
||||||
self.prune_empty_playlists()
|
self.prune_empty_playlists()
|
||||||
debug_print('get_playlist_map loop')
|
|
||||||
for i, root in self.record_roots.items():
|
for i, root in self.record_roots.items():
|
||||||
debug_print('get_playlist_map loop', i)
|
debug_print('build_playlist_id_map loop', i)
|
||||||
id_map = self.build_id_map(root)
|
id_map = self.build_id_map(root)
|
||||||
ans[i] = []
|
ans[i] = []
|
||||||
for playlist in root.xpath('//*[local-name()="playlist"]'):
|
for playlist in root.xpath('//*[local-name()="playlist"]'):
|
||||||
@ -170,9 +168,23 @@ class XMLCache(object):
|
|||||||
if record is not None:
|
if record is not None:
|
||||||
items.append(record)
|
items.append(record)
|
||||||
ans[i].append((playlist.get('title'), items))
|
ans[i].append((playlist.get('title'), items))
|
||||||
debug_print('end get_playlist_map')
|
debug_print('end build_playlist_id_map')
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
def build_id_playlist_map(self, bl_index):
|
||||||
|
debug_print('Start build_id_playlist_map')
|
||||||
|
pmap = self.build_playlist_id_map()[bl_index]
|
||||||
|
playlist_map = {}
|
||||||
|
for title, records in pmap:
|
||||||
|
for record in records:
|
||||||
|
path = record.get('path', None)
|
||||||
|
if path:
|
||||||
|
if path not in playlist_map:
|
||||||
|
playlist_map[path] = set()
|
||||||
|
playlist_map[path].add(title)
|
||||||
|
debug_print('Finish build_id_playlist_map. Found', len(playlist_map))
|
||||||
|
return playlist_map
|
||||||
|
|
||||||
def get_or_create_playlist(self, bl_idx, title):
|
def get_or_create_playlist(self, bl_idx, title):
|
||||||
root = self.record_roots[bl_idx]
|
root = self.record_roots[bl_idx]
|
||||||
for playlist in root.xpath('//*[local-name()="playlist"]'):
|
for playlist in root.xpath('//*[local-name()="playlist"]'):
|
||||||
@ -192,8 +204,7 @@ class XMLCache(object):
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
def fix_ids(self): # {{{
|
def fix_ids(self): # {{{
|
||||||
if DEBUG:
|
debug_print('Running fix_ids()')
|
||||||
debug_print('Running fix_ids()')
|
|
||||||
|
|
||||||
def ensure_numeric_ids(root):
|
def ensure_numeric_ids(root):
|
||||||
idmap = {}
|
idmap = {}
|
||||||
@ -276,38 +287,19 @@ class XMLCache(object):
|
|||||||
def update_booklist(self, bl, bl_index):
|
def update_booklist(self, bl, bl_index):
|
||||||
if bl_index not in self.record_roots:
|
if bl_index not in self.record_roots:
|
||||||
return
|
return
|
||||||
if DEBUG:
|
debug_print('Updating JSON cache:', bl_index)
|
||||||
debug_print('Updating JSON cache:', bl_index)
|
playlist_map = self.build_id_playlist_map(bl_index)
|
||||||
root = self.record_roots[bl_index]
|
root = self.record_roots[bl_index]
|
||||||
pmap = self.get_playlist_map()[bl_index]
|
|
||||||
playlist_map = {}
|
|
||||||
for title, records in pmap:
|
|
||||||
for record in records:
|
|
||||||
path = record.get('path', None)
|
|
||||||
if path:
|
|
||||||
if path not in playlist_map:
|
|
||||||
playlist_map[path] = []
|
|
||||||
playlist_map[path].append(title)
|
|
||||||
|
|
||||||
lpath_map = self.build_lpath_map(root)
|
lpath_map = self.build_lpath_map(root)
|
||||||
for book in bl:
|
for book in bl:
|
||||||
record = lpath_map.get(book.lpath, None)
|
record = lpath_map.get(book.lpath, None)
|
||||||
if record is not None:
|
if record is not None:
|
||||||
title = record.get('title', None)
|
title = record.get('title', None)
|
||||||
if title is not None and title != book.title:
|
if title is not None and title != book.title:
|
||||||
if DEBUG:
|
debug_print('Renaming title', book.title, 'to', title)
|
||||||
debug_print('Renaming title', book.title, 'to', title)
|
|
||||||
book.title = title
|
book.title = title
|
||||||
# We shouldn't do this for Sonys, because the reader strips
|
# Don't set the author, because the reader strips all but
|
||||||
# all but the first author.
|
# the first author.
|
||||||
# authors = record.get('author', None)
|
|
||||||
# if authors is not None:
|
|
||||||
# authors = string_to_authors(authors)
|
|
||||||
# if authors != book.authors:
|
|
||||||
# if DEBUG:
|
|
||||||
# prints('Renaming authors', book.authors, 'to',
|
|
||||||
# authors)
|
|
||||||
# book.authors = authors
|
|
||||||
for thumbnail in record.xpath(
|
for thumbnail in record.xpath(
|
||||||
'descendant::*[local-name()="thumbnail"]'):
|
'descendant::*[local-name()="thumbnail"]'):
|
||||||
for img in thumbnail.xpath(
|
for img in thumbnail.xpath(
|
||||||
@ -318,45 +310,45 @@ class XMLCache(object):
|
|||||||
book.thumbnail = raw
|
book.thumbnail = raw
|
||||||
break
|
break
|
||||||
break
|
break
|
||||||
if book.lpath in playlist_map:
|
book.device_collections = list(playlist_map.get(book.lpath, set()))
|
||||||
tags = playlist_map[book.lpath]
|
|
||||||
book.device_collections = tags
|
|
||||||
debug_print('Finished updating JSON cache:', bl_index)
|
debug_print('Finished updating JSON cache:', bl_index)
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Update XML from JSON {{{
|
# Update XML from JSON {{{
|
||||||
def update(self, booklists, collections_attributes):
|
def update(self, booklists, collections_attributes):
|
||||||
debug_print('Starting update XML from JSON')
|
debug_print('In update. Starting update XML from JSON')
|
||||||
playlist_map = self.get_playlist_map()
|
|
||||||
|
|
||||||
for i, booklist in booklists.items():
|
for i, booklist in booklists.items():
|
||||||
if DEBUG:
|
playlist_map = self.build_id_playlist_map(i)
|
||||||
debug_print('Updating XML Cache:', i)
|
debug_print('Updating XML Cache:', i)
|
||||||
root = self.record_roots[i]
|
root = self.record_roots[i]
|
||||||
lpath_map = self.build_lpath_map(root)
|
lpath_map = self.build_lpath_map(root)
|
||||||
for book in booklist:
|
for book in booklist:
|
||||||
path = os.path.join(self.prefixes[i], *(book.lpath.split('/')))
|
path = os.path.join(self.prefixes[i], *(book.lpath.split('/')))
|
||||||
# record = self.book_by_lpath(book.lpath, root)
|
|
||||||
record = lpath_map.get(book.lpath, None)
|
record = lpath_map.get(book.lpath, None)
|
||||||
if record is None:
|
if record is None:
|
||||||
record = self.create_text_record(root, i, book.lpath)
|
record = self.create_text_record(root, i, book.lpath)
|
||||||
self.update_text_record(record, book, path, i)
|
self.update_text_record(record, book, path, i)
|
||||||
|
# Ensure the collections in the XML database are recorded for
|
||||||
bl_pmap = playlist_map[i]
|
# this book
|
||||||
self.update_playlists(i, root, booklist, bl_pmap,
|
if book.device_collections is None:
|
||||||
collections_attributes)
|
book.device_collections = []
|
||||||
|
book.device_collections = list(set(book.device_collections) |
|
||||||
self.fix_ids()
|
playlist_map.get(book.lpath, set()))
|
||||||
|
self.update_playlists(i, root, booklist, collections_attributes)
|
||||||
# This is needed to update device_collections
|
# Update the device collections because update playlist could have added
|
||||||
|
# some new ones.
|
||||||
|
debug_print('In update/ Starting refresh of device_collections')
|
||||||
for i, booklist in booklists.items():
|
for i, booklist in booklists.items():
|
||||||
self.update_booklist(booklist, i)
|
playlist_map = self.build_id_playlist_map(i)
|
||||||
|
for book in booklist:
|
||||||
|
book.device_collections = list(set(book.device_collections) |
|
||||||
|
playlist_map.get(book.lpath, set()))
|
||||||
|
self.fix_ids()
|
||||||
debug_print('Finished update XML from JSON')
|
debug_print('Finished update XML from JSON')
|
||||||
|
|
||||||
def update_playlists(self, bl_index, root, booklist, playlist_map,
|
def update_playlists(self, bl_index, root, booklist, collections_attributes):
|
||||||
collections_attributes):
|
debug_print('Starting update_playlists', collections_attributes)
|
||||||
debug_print('Starting update_playlists')
|
|
||||||
collections = booklist.get_collections(collections_attributes)
|
collections = booklist.get_collections(collections_attributes)
|
||||||
lpath_map = self.build_lpath_map(root)
|
lpath_map = self.build_lpath_map(root)
|
||||||
for category, books in collections.items():
|
for category, books in collections.items():
|
||||||
@ -372,10 +364,8 @@ class XMLCache(object):
|
|||||||
rec.set('id', str(self.max_id(root)+1))
|
rec.set('id', str(self.max_id(root)+1))
|
||||||
ids = [x.get('id', None) for x in records]
|
ids = [x.get('id', None) for x in records]
|
||||||
if None in ids:
|
if None in ids:
|
||||||
if DEBUG:
|
debug_print('WARNING: Some <text> elements do not have ids')
|
||||||
debug_print('WARNING: Some <text> elements do not have ids')
|
ids = [x for x in ids if x is not None]
|
||||||
ids = [x for x in ids if x is not None]
|
|
||||||
|
|
||||||
playlist = self.get_or_create_playlist(bl_index, category)
|
playlist = self.get_or_create_playlist(bl_index, category)
|
||||||
playlist_ids = []
|
playlist_ids = []
|
||||||
for item in playlist:
|
for item in playlist:
|
||||||
@ -544,10 +534,5 @@ class XMLCache(object):
|
|||||||
break
|
break
|
||||||
self.namespaces[i] = ns
|
self.namespaces[i] = ns
|
||||||
|
|
||||||
# if DEBUG:
|
|
||||||
# debug_print('Found nsmaps:')
|
|
||||||
# pprint(self.nsmaps)
|
|
||||||
# debug_print('Found namespaces:')
|
|
||||||
# pprint(self.namespaces)
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
@ -1228,6 +1228,11 @@ class DeviceMixin(object): # {{{
|
|||||||
return
|
return
|
||||||
cp, fs = job.result
|
cp, fs = job.result
|
||||||
self.location_view.model().update_devices(cp, fs)
|
self.location_view.model().update_devices(cp, fs)
|
||||||
|
# reset the views so that up-to-date info is shown. These need to be
|
||||||
|
# here because the sony driver updates collections in sync_booklists
|
||||||
|
self.memory_view.reset()
|
||||||
|
self.card_a_view.reset()
|
||||||
|
self.card_b_view.reset()
|
||||||
|
|
||||||
def upload_books(self, files, names, metadata, on_card=None, memory=None):
|
def upload_books(self, files, names, metadata, on_card=None, memory=None):
|
||||||
'''
|
'''
|
||||||
|
@ -1109,7 +1109,7 @@ class DeviceBooksModel(BooksModel): # {{{
|
|||||||
elif cname == 'collections':
|
elif cname == 'collections':
|
||||||
tags = self.db[self.map[row]].device_collections
|
tags = self.db[self.map[row]].device_collections
|
||||||
if tags:
|
if tags:
|
||||||
return QVariant(', '.join(tags))
|
return QVariant(', '.join(sorted(tags, key=str.lower)))
|
||||||
elif role == Qt.ToolTipRole and index.isValid():
|
elif role == Qt.ToolTipRole and index.isValid():
|
||||||
if self.map[row] in self.indices_to_be_deleted():
|
if self.map[row] in self.indices_to_be_deleted():
|
||||||
return QVariant(_('Marked for deletion'))
|
return QVariant(_('Marked for deletion'))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user