version 0.3.106. Serialised conversion jobs. Fix export_to_dir.

This commit is contained in:
Kovid Goyal 2007-08-25 21:24:44 +00:00
parent a71d0dc341
commit b1f10f3059
5 changed files with 55 additions and 23 deletions

View File

@ -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'

View File

@ -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()))

View File

@ -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'

View File

@ -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):
@ -686,7 +688,7 @@ def main():
QCoreApplication.setApplicationName(APP_TITLE)
initialize_file_icon_provider()
main = Main(window)
main = Main(window)
sys.excepthook = main.unhandled_exception
return app.exec_()

View File

@ -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'''
return self.data[index][2]
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)
@ -1002,13 +1004,14 @@ class LibraryDatabase(object):
au = self.conn.execute('SELECT author_sort FROM books WHERE id=?',
(id,)).fetchone()[0]
if not au:
au = 'Unknown'
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)