mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
version 0.3.106. Serialised conversion jobs. Fix export_to_dir.
This commit is contained in:
parent
a71d0dc341
commit
b1f10f3059
@ -13,7 +13,7 @@
|
||||
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
''' E-book management software'''
|
||||
__version__ = "0.3.105"
|
||||
__version__ = "0.3.106"
|
||||
__docformat__ = "epytext"
|
||||
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
||||
__appname__ = 'libprs500'
|
||||
|
@ -58,7 +58,7 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog):
|
||||
self.setup_tooltips()
|
||||
self.initialize_options()
|
||||
self.db = db
|
||||
self.row = row.row()
|
||||
self.row = row
|
||||
self.id = self.db.id(self.row)
|
||||
self.cover_changed = False
|
||||
self.cpixmap = None
|
||||
@ -266,7 +266,13 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog):
|
||||
au = qstring_to_unicode(self.gui_author.text()).split(',')
|
||||
if au: self.db.set_authors(self.id, au)
|
||||
aus = qstring_to_unicode(self.gui_author_sort.text())
|
||||
if aus: self.db.set_author_sort(self.id, aus)
|
||||
if not aus:
|
||||
t = self.db.authors(self.id, index_is_id=True)
|
||||
if not t:
|
||||
t = 'Unknown'
|
||||
aus = t.split(',')[0].strip()
|
||||
print aus
|
||||
self.db.set_author_sort(self.id, aus)
|
||||
self.db.set_publisher(self.id, qstring_to_unicode(self.gui_publisher.text()))
|
||||
self.db.set_tags(self.id, qstring_to_unicode(self.tags.text()).split(','))
|
||||
self.db.set_series(self.id, qstring_to_unicode(self.series.currentText()))
|
||||
|
@ -12,7 +12,7 @@
|
||||
## You should have received a copy of the GNU General Public License along
|
||||
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
import traceback, textwrap, logging, cStringIO
|
||||
import traceback, logging, cStringIO
|
||||
|
||||
from PyQt4.QtCore import QAbstractTableModel, QMutex, QObject, SIGNAL, Qt, \
|
||||
QVariant, QThread, QModelIndex
|
||||
@ -43,6 +43,7 @@ class Job(QThread):
|
||||
self.percent_done = 0
|
||||
self.logger = logging.getLogger('Job #'+str(id))
|
||||
self.logger.setLevel(logging.DEBUG)
|
||||
self.is_locked = False
|
||||
self.log_dest = cStringIO.StringIO()
|
||||
handler = logging.StreamHandler(self.log_dest)
|
||||
handler.setLevel(logging.DEBUG)
|
||||
@ -50,6 +51,18 @@ class Job(QThread):
|
||||
self.logger.addHandler(handler)
|
||||
|
||||
|
||||
def lock(self):
|
||||
if self.mutex is not None:
|
||||
self.is_locked = True
|
||||
self.mutex.lock()
|
||||
self.is_locked = False
|
||||
|
||||
|
||||
def unlock(self):
|
||||
if self.mutex is not None:
|
||||
self.mutex.unlock()
|
||||
self.is_locked = False
|
||||
|
||||
def progress_update(self, val):
|
||||
self.percent_done = val
|
||||
self.emit(SIGNAL('status_update(int, int)'), self.id, int(val))
|
||||
@ -59,8 +72,7 @@ class DeviceJob(Job):
|
||||
Jobs that involve communication with the device. Synchronous.
|
||||
'''
|
||||
def run(self):
|
||||
if self.mutex != None:
|
||||
self.mutex.lock()
|
||||
self.lock()
|
||||
last_traceback, exception = None, None
|
||||
try:
|
||||
try:
|
||||
@ -69,15 +81,15 @@ class DeviceJob(Job):
|
||||
exception = err
|
||||
last_traceback = traceback.format_exc()
|
||||
finally:
|
||||
if self.mutex != None:
|
||||
self.mutex.unlock()
|
||||
self.unlock()
|
||||
self.emit(SIGNAL('jobdone(PyQt_PyObject, PyQt_PyObject, PyQt_PyObject, PyQt_PyObject, PyQt_PyObject)'),
|
||||
self.id, self.description, self.result, exception, last_traceback)
|
||||
|
||||
|
||||
class ConversionJob(Job):
|
||||
''' Jobs that invlove conversion of content. Asynchronous. '''
|
||||
''' Jobs that invlove conversion of content. Synchronous. '''
|
||||
def run(self):
|
||||
self.lock()
|
||||
last_traceback, exception = None, None
|
||||
try:
|
||||
try:
|
||||
@ -87,6 +99,7 @@ class ConversionJob(Job):
|
||||
exception = err
|
||||
last_traceback = traceback.format_exc()
|
||||
finally:
|
||||
self.unlock()
|
||||
self.emit(SIGNAL('jobdone(PyQt_PyObject, PyQt_PyObject, PyQt_PyObject, PyQt_PyObject, PyQt_PyObject, PyQt_PyObject)'),
|
||||
self.id, self.description, self.result, exception, last_traceback, self.log_dest.getvalue())
|
||||
|
||||
@ -101,6 +114,7 @@ class JobManager(QAbstractTableModel):
|
||||
self.job_create_lock = QMutex()
|
||||
self.job_remove_lock = QMutex()
|
||||
self.device_lock = QMutex()
|
||||
self.conversion_lock = QMutex()
|
||||
self.cleanup_lock = QMutex()
|
||||
self.cleanup = {}
|
||||
self.device_job_icon = QVariant(QIcon(':/images/reader.svg'))
|
||||
@ -143,8 +157,16 @@ class JobManager(QAbstractTableModel):
|
||||
return len(self.jobs.values()) > 0
|
||||
|
||||
def run_conversion_job(self, slot, callable, *args, **kwargs):
|
||||
'''
|
||||
Run a conversion job.
|
||||
@param slot: The function to call with the job result.
|
||||
@param callable: The function to call to communicate with the device.
|
||||
@param args: The arguments to pass to callable
|
||||
@param kwargs: The keyword arguments to pass to callable
|
||||
'''
|
||||
desc = kwargs.pop('job_description', '')
|
||||
job = self.create_job(ConversionJob, desc, None, callable, *args, **kwargs)
|
||||
job = self.create_job(ConversionJob, desc, self.conversion_lock,
|
||||
callable, *args, **kwargs)
|
||||
QObject.connect(job, SIGNAL('jobdone(PyQt_PyObject, PyQt_PyObject, PyQt_PyObject, PyQt_PyObject, PyQt_PyObject, PyQt_PyObject)'),
|
||||
self.job_done)
|
||||
if slot:
|
||||
@ -156,8 +178,7 @@ class JobManager(QAbstractTableModel):
|
||||
def run_device_job(self, slot, callable, *args, **kwargs):
|
||||
'''
|
||||
Run a job to communicate with the device.
|
||||
@param slot: The function to call with the job result. It is called with
|
||||
the parameters id, result, exception, formatted_traceback
|
||||
@param slot: The function to call with the job result.
|
||||
@param callable: The function to call to communicate with the device.
|
||||
@param args: The arguments to pass to callable
|
||||
@param kwargs: The keyword arguments to pass to callable
|
||||
@ -237,7 +258,7 @@ class JobManager(QAbstractTableModel):
|
||||
return QVariant(job.description)
|
||||
if col == 1:
|
||||
status = 'Waiting'
|
||||
if job.isRunning():
|
||||
if job.isRunning() and not job.is_locked:
|
||||
status = 'Working'
|
||||
if job.isFinished():
|
||||
status = 'Done'
|
||||
|
@ -536,14 +536,14 @@ class Main(QObject, Ui_MainWindow):
|
||||
d.exec_()
|
||||
|
||||
changed = False
|
||||
for row in rows:
|
||||
for row in [r.row() for r in rows]:
|
||||
d = LRFSingleDialog(self.window, self.library_view.model().db, row)
|
||||
if d.selected_format:
|
||||
d.exec_()
|
||||
if d.result() == QDialog.Accepted:
|
||||
changed = True
|
||||
cmdline = d.cmdline
|
||||
data = self.library_view.model().db.format(row.row(), d.selected_format)
|
||||
data = self.library_view.model().db.format(row, d.selected_format)
|
||||
pt = PersistentTemporaryFile('.'+d.selected_format.lower())
|
||||
pt.write(data)
|
||||
pt.close()
|
||||
@ -551,6 +551,7 @@ class Main(QObject, Ui_MainWindow):
|
||||
of.close()
|
||||
cmdline.extend(['-o', of.name])
|
||||
cmdline.append(pt.name)
|
||||
|
||||
id = self.job_manager.run_conversion_job(self.book_converted,
|
||||
any2lrf, args=cmdline,
|
||||
job_description='Convert book:'+d.title())
|
||||
@ -642,8 +643,9 @@ class Main(QObject, Ui_MainWindow):
|
||||
settings.setValue("size", QVariant(self.window.size()))
|
||||
settings.endGroup()
|
||||
settings.beginGroup('Book Views')
|
||||
for view in (self.library_view, self.memory_view):
|
||||
view.write_settings()
|
||||
self.library_view.write_settings()
|
||||
if self.device_connected:
|
||||
self.memory_view.write_settings()
|
||||
settings.endGroup()
|
||||
|
||||
def close_event(self, e):
|
||||
|
@ -694,9 +694,11 @@ class LibraryDatabase(object):
|
||||
def title(self, index):
|
||||
return self.data[index][1]
|
||||
|
||||
def authors(self, index):
|
||||
def authors(self, index, index_is_id=False):
|
||||
''' Authors as a comman separated list or None'''
|
||||
if not index_is_id:
|
||||
return self.data[index][2]
|
||||
return self.conn.execute('SELECT authors FROM meta WHERE id=?',(index,)).fetchone()[0]
|
||||
|
||||
def author_sort(self, index):
|
||||
id = self.id(index)
|
||||
@ -1001,14 +1003,15 @@ class LibraryDatabase(object):
|
||||
id = self.id(index)
|
||||
au = self.conn.execute('SELECT author_sort FROM books WHERE id=?',
|
||||
(id,)).fetchone()[0]
|
||||
if not au:
|
||||
au = self.authors(index)
|
||||
if not au:
|
||||
au = 'Unknown'
|
||||
au = au.split(',')[0]
|
||||
if not by_author.has_key(au):
|
||||
by_author[au] = []
|
||||
by_author[au].append(index)
|
||||
for au in by_author.keys():
|
||||
if not au:
|
||||
au = 'Unknown'
|
||||
apath = os.path.join(dir, au)
|
||||
if not os.path.exists(apath):
|
||||
os.mkdir(apath)
|
||||
|
Loading…
x
Reference in New Issue
Block a user