mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Prevent setting an incorrect value for compression quality in the wireless driver causing an error
Show a busy cursor while calibre is working on matching books on the device to books int he library, which can take a while if the user has a lot of books on the device. Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
commit
882a280c12
@ -208,6 +208,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
THUMBNAIL_HEIGHT = 160
|
THUMBNAIL_HEIGHT = 160
|
||||||
DEFAULT_THUMBNAIL_HEIGHT = 160
|
DEFAULT_THUMBNAIL_HEIGHT = 160
|
||||||
THUMBNAIL_COMPRESSION_QUALITY = 75
|
THUMBNAIL_COMPRESSION_QUALITY = 75
|
||||||
|
DEFAULT_THUMBNAIL_COMPRESSION_QUALITY = 75
|
||||||
|
|
||||||
PREFIX = ''
|
PREFIX = ''
|
||||||
BACKLOADING_ERROR_MESSAGE = None
|
BACKLOADING_ERROR_MESSAGE = None
|
||||||
@ -680,6 +681,8 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
return self.OPT_PORT_NUMBER
|
return self.OPT_PORT_NUMBER
|
||||||
elif opt_string == 'force_ip_address':
|
elif opt_string == 'force_ip_address':
|
||||||
return self.OPT_FORCE_IP_ADDRESS
|
return self.OPT_FORCE_IP_ADDRESS
|
||||||
|
elif opt_string == 'thumbnail_compression_quality':
|
||||||
|
return self.OPT_COMPRESSION_QUALITY
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -1463,6 +1466,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
self.connection_attempts = {}
|
self.connection_attempts = {}
|
||||||
self.client_wants_uuid_file_names = False
|
self.client_wants_uuid_file_names = False
|
||||||
|
|
||||||
|
message = None
|
||||||
compression_quality_ok = True
|
compression_quality_ok = True
|
||||||
try:
|
try:
|
||||||
cq = int(self.settings().extra_customization[self.OPT_COMPRESSION_QUALITY])
|
cq = int(self.settings().extra_customization[self.OPT_COMPRESSION_QUALITY])
|
||||||
@ -1474,11 +1478,12 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
compression_quality_ok = False
|
compression_quality_ok = False
|
||||||
if not compression_quality_ok:
|
if not compression_quality_ok:
|
||||||
self.THUMBNAIL_COMPRESSION_QUALITY = 70
|
self.THUMBNAIL_COMPRESSION_QUALITY = 70
|
||||||
message = 'Bad compression quality setting. It must be a number between 50 and 99'
|
message = _('Bad compression quality setting. It must be a number '
|
||||||
|
'between 50 and 99. Forced to be %d.')%self.DEFAULT_THUMBNAIL_COMPRESSION_QUALITY
|
||||||
self._debug(message)
|
self._debug(message)
|
||||||
return message
|
self.set_option('thumbnail_compression_quality',
|
||||||
|
str(self.DEFAULT_THUMBNAIL_COMPRESSION_QUALITY))
|
||||||
|
|
||||||
message = None
|
|
||||||
try:
|
try:
|
||||||
self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
set_socket_inherit(self.listen_socket, False)
|
set_socket_inherit(self.listen_socket, False)
|
||||||
@ -1541,7 +1546,6 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
|
|
||||||
# Now try to open a UDP socket to receive broadcasts on
|
# Now try to open a UDP socket to receive broadcasts on
|
||||||
|
|
||||||
message = None
|
|
||||||
try:
|
try:
|
||||||
self.broadcast_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
self.broadcast_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
except:
|
except:
|
||||||
|
@ -8,7 +8,8 @@ from threading import Thread, Event
|
|||||||
|
|
||||||
from PyQt4.Qt import (
|
from PyQt4.Qt import (
|
||||||
QMenu, QAction, QActionGroup, QIcon, SIGNAL, Qt, pyqtSignal, QDialog,
|
QMenu, QAction, QActionGroup, QIcon, SIGNAL, Qt, pyqtSignal, QDialog,
|
||||||
QObject, QVBoxLayout, QDialogButtonBox, QCursor)
|
QObject, QVBoxLayout, QDialogButtonBox, QCursor, QCoreApplication,
|
||||||
|
QApplication, QEventLoop)
|
||||||
|
|
||||||
from calibre.customize.ui import (available_input_formats, available_output_formats,
|
from calibre.customize.ui import (available_input_formats, available_output_formats,
|
||||||
device_plugins, disabled_device_plugins)
|
device_plugins, disabled_device_plugins)
|
||||||
@ -122,11 +123,9 @@ def device_name_for_plugboards(device_class):
|
|||||||
class BusyCursor(object):
|
class BusyCursor(object):
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
from PyQt4.Qt import QApplication
|
|
||||||
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
|
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
|
||||||
|
|
||||||
def __exit__(self, *args):
|
def __exit__(self, *args):
|
||||||
from PyQt4.Qt import QApplication
|
|
||||||
QApplication.restoreOverrideCursor()
|
QApplication.restoreOverrideCursor()
|
||||||
|
|
||||||
|
|
||||||
@ -1092,8 +1091,14 @@ class DeviceMixin(object): # {{{
|
|||||||
self.device_job_exception(job)
|
self.device_job_exception(job)
|
||||||
return
|
return
|
||||||
self.device_manager.slow_driveinfo()
|
self.device_manager.slow_driveinfo()
|
||||||
|
|
||||||
# set_books_in_library might schedule a sync_booklists job
|
# set_books_in_library might schedule a sync_booklists job
|
||||||
|
if DEBUG:
|
||||||
|
prints('DeviceJob: metadata_downloaded: Starting set_books_in_library')
|
||||||
self.set_books_in_library(job.result, reset=True, add_as_step_to_job=job)
|
self.set_books_in_library(job.result, reset=True, add_as_step_to_job=job)
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
prints('DeviceJob: metadata_downloaded: updating views')
|
||||||
mainlist, cardalist, cardblist = job.result
|
mainlist, cardalist, cardblist = job.result
|
||||||
self.memory_view.set_database(mainlist)
|
self.memory_view.set_database(mainlist)
|
||||||
self.memory_view.set_editable(self.device_manager.device.CAN_SET_METADATA,
|
self.memory_view.set_editable(self.device_manager.device.CAN_SET_METADATA,
|
||||||
@ -1107,9 +1112,17 @@ class DeviceMixin(object): # {{{
|
|||||||
self.card_b_view.set_editable(self.device_manager.device.CAN_SET_METADATA,
|
self.card_b_view.set_editable(self.device_manager.device.CAN_SET_METADATA,
|
||||||
self.device_manager.device.BACKLOADING_ERROR_MESSAGE
|
self.device_manager.device.BACKLOADING_ERROR_MESSAGE
|
||||||
is None)
|
is None)
|
||||||
|
if DEBUG:
|
||||||
|
prints('DeviceJob: metadata_downloaded: syncing')
|
||||||
self.sync_news()
|
self.sync_news()
|
||||||
self.sync_catalogs()
|
self.sync_catalogs()
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
prints('DeviceJob: metadata_downloaded: refreshing ondevice')
|
||||||
self.refresh_ondevice()
|
self.refresh_ondevice()
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
prints('DeviceJob: metadata_downloaded: sending metadata_available signal')
|
||||||
device_signals.device_metadata_available.emit()
|
device_signals.device_metadata_available.emit()
|
||||||
|
|
||||||
def refresh_ondevice(self, reset_only=False):
|
def refresh_ondevice(self, reset_only=False):
|
||||||
@ -1766,71 +1779,104 @@ class DeviceMixin(object): # {{{
|
|||||||
except:
|
except:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
total_book_count = 0
|
||||||
for booklist in booklists:
|
for booklist in booklists:
|
||||||
for book in booklist:
|
for book in booklist:
|
||||||
book.in_library = None
|
if book:
|
||||||
if getattr(book, 'uuid', None) in self.db_book_uuid_cache:
|
total_book_count += 1
|
||||||
id_ = db_book_uuid_cache[book.uuid]
|
if DEBUG:
|
||||||
if updateq(id_, book):
|
prints('DeviceJob: set_books_in_library: books to process=', total_book_count)
|
||||||
update_book(id_, book)
|
|
||||||
book.in_library = 'UUID'
|
|
||||||
# ensure that the correct application_id is set
|
|
||||||
book.application_id = id_
|
|
||||||
continue
|
|
||||||
# No UUID exact match. Try metadata matching.
|
|
||||||
book_title = clean_string(book.title)
|
|
||||||
d = self.db_book_title_cache.get(book_title, None)
|
|
||||||
if d is not None:
|
|
||||||
# At this point we know that the title matches. The book
|
|
||||||
# will match if any of the db_id, author, or author_sort
|
|
||||||
# also match.
|
|
||||||
if getattr(book, 'application_id', None) in d['db_ids']:
|
|
||||||
id_ = getattr(book, 'application_id', None)
|
|
||||||
update_book(id_, book)
|
|
||||||
book.in_library = 'APP_ID'
|
|
||||||
# app_id already matches a db_id. No need to set it.
|
|
||||||
continue
|
|
||||||
# Sonys know their db_id independent of the application_id
|
|
||||||
# in the metadata cache. Check that as well.
|
|
||||||
if getattr(book, 'db_id', None) in d['db_ids']:
|
|
||||||
update_book(book.db_id, book)
|
|
||||||
book.in_library = 'DB_ID'
|
|
||||||
book.application_id = book.db_id
|
|
||||||
continue
|
|
||||||
# We now know that the application_id is not right. Set it
|
|
||||||
# to None to prevent book_on_device from accidentally
|
|
||||||
# matching on it. It will be set to a correct value below if
|
|
||||||
# the book is matched with one in the library
|
|
||||||
book.application_id = None
|
|
||||||
if book.authors:
|
|
||||||
# Compare against both author and author sort, because
|
|
||||||
# either can appear as the author
|
|
||||||
book_authors = clean_string(authors_to_string(book.authors))
|
|
||||||
if book_authors in d['authors']:
|
|
||||||
id_ = d['authors'][book_authors]
|
|
||||||
update_book(id_, book)
|
|
||||||
book.in_library = 'AUTHOR'
|
|
||||||
book.application_id = id_
|
|
||||||
elif book_authors in d['author_sort']:
|
|
||||||
id_ = d['author_sort'][book_authors]
|
|
||||||
update_book(id_, book)
|
|
||||||
book.in_library = 'AUTH_SORT'
|
|
||||||
book.application_id = id_
|
|
||||||
else:
|
|
||||||
# Book definitely not matched. Clear its application ID
|
|
||||||
book.application_id = None
|
|
||||||
# Set author_sort if it isn't already
|
|
||||||
asort = getattr(book, 'author_sort', None)
|
|
||||||
if not asort and book.authors:
|
|
||||||
book.author_sort = self.library_view.model().db.\
|
|
||||||
author_sort_from_authors(book.authors)
|
|
||||||
|
|
||||||
if update_metadata:
|
start_time = time.time()
|
||||||
if self.device_manager.is_device_connected:
|
|
||||||
plugboards = self.library_view.model().db.prefs.get('plugboards', {})
|
with BusyCursor():
|
||||||
self.device_manager.sync_booklists(
|
current_book_count = 0
|
||||||
FunctionDispatcher(self.metadata_synced), booklists,
|
for booklist in booklists:
|
||||||
plugboards, add_as_step_to_job)
|
for book in booklist:
|
||||||
|
if current_book_count % 100 == 0:
|
||||||
|
self.status_bar.show_message(
|
||||||
|
_('Analyzing books on the device: %d%% finished')%(
|
||||||
|
int((float(current_book_count)/total_book_count)*100.0)))
|
||||||
|
|
||||||
|
# I am assuming that this sort-of multi-threading won't break
|
||||||
|
# anything. Reasons: excluding UI events prevents the user
|
||||||
|
# from explicitly changing anything, and (in theory) no
|
||||||
|
# changes are happening because of timers and the like.
|
||||||
|
# Why every tenth book? WAG balancing performance in the
|
||||||
|
# loop with preventing App Not Responding errors
|
||||||
|
if current_book_count % 10 == 0:
|
||||||
|
QCoreApplication.processEvents(flags=
|
||||||
|
QEventLoop.ExcludeUserInputEvents|
|
||||||
|
QEventLoop.ExcludeSocketNotifiers)
|
||||||
|
current_book_count += 1
|
||||||
|
book.in_library = None
|
||||||
|
if getattr(book, 'uuid', None) in self.db_book_uuid_cache:
|
||||||
|
id_ = db_book_uuid_cache[book.uuid]
|
||||||
|
if updateq(id_, book):
|
||||||
|
update_book(id_, book)
|
||||||
|
book.in_library = 'UUID'
|
||||||
|
# ensure that the correct application_id is set
|
||||||
|
book.application_id = id_
|
||||||
|
continue
|
||||||
|
# No UUID exact match. Try metadata matching.
|
||||||
|
book_title = clean_string(book.title)
|
||||||
|
d = self.db_book_title_cache.get(book_title, None)
|
||||||
|
if d is not None:
|
||||||
|
# At this point we know that the title matches. The book
|
||||||
|
# will match if any of the db_id, author, or author_sort
|
||||||
|
# also match.
|
||||||
|
if getattr(book, 'application_id', None) in d['db_ids']:
|
||||||
|
id_ = getattr(book, 'application_id', None)
|
||||||
|
update_book(id_, book)
|
||||||
|
book.in_library = 'APP_ID'
|
||||||
|
# app_id already matches a db_id. No need to set it.
|
||||||
|
continue
|
||||||
|
# Sonys know their db_id independent of the application_id
|
||||||
|
# in the metadata cache. Check that as well.
|
||||||
|
if getattr(book, 'db_id', None) in d['db_ids']:
|
||||||
|
update_book(book.db_id, book)
|
||||||
|
book.in_library = 'DB_ID'
|
||||||
|
book.application_id = book.db_id
|
||||||
|
continue
|
||||||
|
# We now know that the application_id is not right. Set it
|
||||||
|
# to None to prevent book_on_device from accidentally
|
||||||
|
# matching on it. It will be set to a correct value below if
|
||||||
|
# the book is matched with one in the library
|
||||||
|
book.application_id = None
|
||||||
|
if book.authors:
|
||||||
|
# Compare against both author and author sort, because
|
||||||
|
# either can appear as the author
|
||||||
|
book_authors = clean_string(authors_to_string(book.authors))
|
||||||
|
if book_authors in d['authors']:
|
||||||
|
id_ = d['authors'][book_authors]
|
||||||
|
update_book(id_, book)
|
||||||
|
book.in_library = 'AUTHOR'
|
||||||
|
book.application_id = id_
|
||||||
|
elif book_authors in d['author_sort']:
|
||||||
|
id_ = d['author_sort'][book_authors]
|
||||||
|
update_book(id_, book)
|
||||||
|
book.in_library = 'AUTH_SORT'
|
||||||
|
book.application_id = id_
|
||||||
|
else:
|
||||||
|
# Book definitely not matched. Clear its application ID
|
||||||
|
book.application_id = None
|
||||||
|
# Set author_sort if it isn't already
|
||||||
|
asort = getattr(book, 'author_sort', None)
|
||||||
|
if not asort and book.authors:
|
||||||
|
book.author_sort = self.library_view.model().db.\
|
||||||
|
author_sort_from_authors(book.authors)
|
||||||
|
|
||||||
|
if update_metadata:
|
||||||
|
if self.device_manager.is_device_connected:
|
||||||
|
plugboards = self.library_view.model().db.prefs.get('plugboards', {})
|
||||||
|
self.device_manager.sync_booklists(
|
||||||
|
FunctionDispatcher(self.metadata_synced), booklists,
|
||||||
|
plugboards, add_as_step_to_job)
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
prints('DeviceJob: set_books_in_library finished: time=',
|
||||||
|
time.time() - start_time)
|
||||||
|
# The status line is reset when the job finishes
|
||||||
return update_metadata
|
return update_metadata
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ class SmartdeviceDialog(QDialog, Ui_Dialog):
|
|||||||
|
|
||||||
if not self.device_manager.is_running('smartdevice'):
|
if not self.device_manager.is_running('smartdevice'):
|
||||||
error_dialog(self, _('Problem starting the wireless device'),
|
error_dialog(self, _('Problem starting the wireless device'),
|
||||||
_('The wireless device driver did not start. It said "%s"')%message,
|
_('The wireless device driver had problems starting. It said "%s"')%message,
|
||||||
show=True)
|
show=True)
|
||||||
self.device_manager.set_option('smartdevice', 'use_fixed_port',
|
self.device_manager.set_option('smartdevice', 'use_fixed_port',
|
||||||
self.orig_fixed_port)
|
self.orig_fixed_port)
|
||||||
|
@ -432,7 +432,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
|||||||
if message:
|
if message:
|
||||||
if not self.device_manager.is_running('Wireless Devices'):
|
if not self.device_manager.is_running('Wireless Devices'):
|
||||||
error_dialog(self, _('Problem starting the wireless device'),
|
error_dialog(self, _('Problem starting the wireless device'),
|
||||||
_('The wireless device driver did not start. '
|
_('The wireless device driver had problems starting. '
|
||||||
'It said "%s"')%message, show=True)
|
'It said "%s"')%message, show=True)
|
||||||
self.iactions['Connect Share'].set_smartdevice_action_state()
|
self.iactions['Connect Share'].set_smartdevice_action_state()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user