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):
return self.format_abspath(book_id, fmt, fname, path) is not None
def remove_format(self, book_id, fmt, fname, path):
path = self.format_abspath(book_id, fmt, fname, path)
if path is not None:
try:
delete_service().delete_files((path,), self.library_path)
except:
import traceback
traceback.print_exc()
def remove_formats(self, remove_map):
paths = []
for book_id, removals in remove_map.iteritems():
for fmt, fname, path in removals:
path = self.format_abspath(book_id, fmt, fname, path)
if path is not None:
paths.append(path)
try:
delete_service().delete_files(paths, self.library_path)
except:
import traceback
traceback.print_exc()
def cover_last_modified(self, path):
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)
if not db_only:
removes = defaultdict(set)
for book_id, fmts in formats_map.iteritems():
try:
path = self._field_for('path', book_id).replace('/', os.sep)
@ -1291,7 +1292,9 @@ class Cache(object):
except:
continue
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)
self.fields['size'].table.update_sizes(size_map)

View File

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

View File

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