When bulk deleting formats use a single temp dir

When bulk deleting formats, use a single temporary directory for the
deleted files. This makes restoring them from the recycle bin a little
cleaner. Also might fix the reported issue with windows choking on
creating a large number of folders.
This commit is contained in:
Kovid Goyal 2013-10-22 18:16:34 +05:30
parent e260906211
commit c9a88a1a80
4 changed files with 44 additions and 35 deletions

View File

@ -1199,14 +1199,18 @@ class DB(object):
def has_format(self, book_id, fmt, fname, path): def has_format(self, book_id, fmt, fname, path):
return self.format_abspath(book_id, fmt, fname, path) is not None return self.format_abspath(book_id, fmt, fname, path) is not None
def remove_format(self, book_id, fmt, fname, path): def remove_formats(self, remove_map):
path = self.format_abspath(book_id, fmt, fname, path) paths = []
if path is not None: for book_id, removals in remove_map.iteritems():
try: for fmt, fname, path in removals:
delete_service().delete_files((path,), self.library_path) path = self.format_abspath(book_id, fmt, fname, path)
except: if path is not None:
import traceback paths.append(path)
traceback.print_exc() try:
delete_service().delete_files(paths, self.library_path)
except:
import traceback
traceback.print_exc()
def cover_last_modified(self, path): def cover_last_modified(self, path):
path = os.path.abspath(os.path.join(self.library_path, path, 'cover.jpg')) path = os.path.abspath(os.path.join(self.library_path, path, 'cover.jpg'))

View File

@ -1280,6 +1280,7 @@ class Cache(object):
self.format_metadata_cache[book_id].pop(fmt, None) self.format_metadata_cache[book_id].pop(fmt, None)
if not db_only: if not db_only:
removes = defaultdict(set)
for book_id, fmts in formats_map.iteritems(): for book_id, fmts in formats_map.iteritems():
try: try:
path = self._field_for('path', book_id).replace('/', os.sep) path = self._field_for('path', book_id).replace('/', os.sep)
@ -1291,7 +1292,9 @@ class Cache(object):
except: except:
continue continue
if name and path: if name and path:
self.backend.remove_format(book_id, fmt, name, path) removes[book_id].add((fmt, name, path))
if removes:
self.backend.remove_formats(removes)
size_map = table.remove_formats(formats_map, self.backend) size_map = table.remove_formats(formats_map, self.backend)
self.fields['size'].table.update_sizes(size_map) self.fields['size'].table.update_sizes(size_map)

View File

@ -196,12 +196,10 @@ class DeleteAction(InterfaceAction):
_('Choose formats to be deleted'), ids) _('Choose formats to be deleted'), ids)
if not fmts: if not fmts:
return return
for id in ids: m = self.gui.library_view.model()
for fmt in fmts: m.db.new_api.remove_formats({book_id:fmts for book_id in ids})
self.gui.library_view.model().db.remove_format(id, fmt, m.refresh_ids(ids)
index_is_id=True, notify=False) m.current_changed(self.gui.library_view.currentIndex(),
self.gui.library_view.model().refresh_ids(ids)
self.gui.library_view.model().current_changed(self.gui.library_view.currentIndex(),
self.gui.library_view.currentIndex()) self.gui.library_view.currentIndex())
if ids: if ids:
self.gui.tags_view.recount() self.gui.tags_view.recount()
@ -216,8 +214,10 @@ class DeleteAction(InterfaceAction):
exclude=True) exclude=True)
if fmts is None: if fmts is None:
return return
m = self.gui.library_view.model()
removals = {}
for id in ids: for id in ids:
bfmts = self.gui.library_view.model().db.formats(id, index_is_id=True) bfmts = m.db.formats(id, index_is_id=True)
if bfmts is None: if bfmts is None:
continue continue
bfmts = set([x.lower() for x in bfmts.split(',')]) bfmts = set([x.lower() for x in bfmts.split(',')])
@ -225,14 +225,14 @@ class DeleteAction(InterfaceAction):
if bfmts - rfmts: if bfmts - rfmts:
# Do not delete if it will leave the book with no # Do not delete if it will leave the book with no
# formats # formats
for fmt in rfmts: removals[id] = rfmts
self.gui.library_view.model().db.remove_format(id, fmt, if removals:
index_is_id=True, notify=False) m.db.new_api.remove_formats(removals)
self.gui.library_view.model().refresh_ids(ids) m.refresh_ids(ids)
self.gui.library_view.model().current_changed(self.gui.library_view.currentIndex(), m.current_changed(self.gui.library_view.currentIndex(),
self.gui.library_view.currentIndex()) self.gui.library_view.currentIndex())
if ids: if ids:
self.gui.tags_view.recount() self.gui.tags_view.recount()
def delete_all_formats(self, *args): def delete_all_formats(self, *args):
ids = self._get_selected_ids() ids = self._get_selected_ids()
@ -244,17 +244,18 @@ class DeleteAction(InterfaceAction):
+'</p>', 'delete_all_formats', self.gui): +'</p>', 'delete_all_formats', self.gui):
return return
db = self.gui.library_view.model().db db = self.gui.library_view.model().db
removals = {}
for id in ids: for id in ids:
fmts = db.formats(id, index_is_id=True, verify_formats=False) fmts = db.formats(id, index_is_id=True, verify_formats=False)
if fmts: if fmts:
for fmt in fmts.split(','): removals[id] = fmts.split(',')
self.gui.library_view.model().db.remove_format(id, fmt, if removals:
index_is_id=True, notify=False) db.new_api.remove_formats(removals)
self.gui.library_view.model().refresh_ids(ids) self.gui.library_view.model().refresh_ids(ids)
self.gui.library_view.model().current_changed(self.gui.library_view.currentIndex(), self.gui.library_view.model().current_changed(self.gui.library_view.currentIndex(),
self.gui.library_view.currentIndex()) self.gui.library_view.currentIndex())
if ids: if ids:
self.gui.tags_view.recount() self.gui.tags_view.recount()
def remove_matching_books_from_device(self, *args): def remove_matching_books_from_device(self, *args):
if not self.gui.device_manager.is_device_present: if not self.gui.device_manager.is_device_present:

View File

@ -398,13 +398,14 @@ def command_add(args, dbpath):
return 0 return 0
def do_remove(db, ids): def do_remove(db, ids):
book_ids = set()
for x in ids: for x in ids:
if isinstance(x, int): if isinstance(x, int):
db.delete_book(x) book_ids.add(x)
else: else:
for y in x: book_ids |= set(x)
db.delete_book(y)
db.new_api.remove_books(book_ids)
db.clean() db.clean()
send_message() send_message()