mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Jobs dialog:Allow stopping of waiting jobs and add Stop all jobs button
This commit is contained in:
parent
b759adcee6
commit
8323e8b8b2
@ -14,7 +14,7 @@
|
|||||||
<string>Active Jobs</string>
|
<string>Active Jobs</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowIcon">
|
<property name="windowIcon">
|
||||||
<iconset resource="../../../../resources/images.qrc">
|
<iconset resource="../../../work/calibre/resources/images.qrc">
|
||||||
<normaloff>:/images/jobs.svg</normaloff>:/images/jobs.svg</iconset>
|
<normaloff>:/images/jobs.svg</normaloff>:/images/jobs.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout">
|
<layout class="QVBoxLayout">
|
||||||
@ -57,6 +57,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="stop_all_jobs_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Stop &all jobs</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
@ -67,7 +74,7 @@
|
|||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../../../../resources/images.qrc"/>
|
<include location="../../../work/calibre/resources/images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -193,6 +193,12 @@ class JobManager(QAbstractTableModel):
|
|||||||
_('Job has already run')).exec_()
|
_('Job has already run')).exec_()
|
||||||
self.server.kill_job(job)
|
self.server.kill_job(job)
|
||||||
|
|
||||||
|
def kill_all_jobs(self):
|
||||||
|
for job in self.jobs:
|
||||||
|
if isinstance(job, DeviceJob) or job.duration is not None:
|
||||||
|
continue
|
||||||
|
self.server.kill_job(job)
|
||||||
|
|
||||||
def terminate_all_jobs(self):
|
def terminate_all_jobs(self):
|
||||||
self.server.killall()
|
self.server.killall()
|
||||||
|
|
||||||
@ -230,6 +236,8 @@ class JobsDialog(QDialog, Ui_JobsDialog):
|
|||||||
self.kill_job)
|
self.kill_job)
|
||||||
self.connect(self.details_button, SIGNAL('clicked()'),
|
self.connect(self.details_button, SIGNAL('clicked()'),
|
||||||
self.show_details)
|
self.show_details)
|
||||||
|
self.connect(self.stop_all_jobs_button, SIGNAL('clicked()'),
|
||||||
|
self.kill_all_jobs)
|
||||||
self.connect(self, SIGNAL('kill_job(int, PyQt_PyObject)'),
|
self.connect(self, SIGNAL('kill_job(int, PyQt_PyObject)'),
|
||||||
self.jobs_view.model().kill_job)
|
self.jobs_view.model().kill_job)
|
||||||
self.pb_delegate = ProgressBarDelegate(self)
|
self.pb_delegate = ProgressBarDelegate(self)
|
||||||
@ -247,7 +255,8 @@ class JobsDialog(QDialog, Ui_JobsDialog):
|
|||||||
self.jobs_view.show_details(index)
|
self.jobs_view.show_details(index)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def kill_all_jobs(self):
|
||||||
|
self.model.kill_all_jobs()
|
||||||
|
|
||||||
def closeEvent(self, e):
|
def closeEvent(self, e):
|
||||||
self.jobs_view.write_settings()
|
self.jobs_view.write_settings()
|
||||||
|
@ -156,8 +156,6 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None):
|
|||||||
dtitle = repr(mi.title)
|
dtitle = repr(mi.title)
|
||||||
desc = _('Convert book %d of %d (%s)') % (i + 1, total, dtitle)
|
desc = _('Convert book %d of %d (%s)') % (i + 1, total, dtitle)
|
||||||
|
|
||||||
desc = _('Convert book %d of %d (%s)') % (i + 1, total, repr(mi.title))
|
|
||||||
|
|
||||||
args = [in_file, out_file.name, lrecs]
|
args = [in_file, out_file.name, lrecs]
|
||||||
temp_files.append(out_file)
|
temp_files.append(out_file)
|
||||||
jobs.append(('gui_convert', args, desc, d.output_format.upper(), book_id, temp_files))
|
jobs.append(('gui_convert', args, desc, d.output_format.upper(), book_id, temp_files))
|
||||||
@ -178,6 +176,7 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None):
|
|||||||
'source format was found.') % (len(res), total),
|
'source format was found.') % (len(res), total),
|
||||||
msg).exec_()
|
msg).exec_()
|
||||||
|
|
||||||
|
jobs.reverse()
|
||||||
return jobs, changed, bad
|
return jobs, changed, bad
|
||||||
|
|
||||||
def fetch_scheduled_recipe(recipe, script):
|
def fetch_scheduled_recipe(recipe, script):
|
||||||
|
@ -30,6 +30,7 @@ class BaseJob(object):
|
|||||||
self.done2 = None
|
self.done2 = None
|
||||||
self.killed = False
|
self.killed = False
|
||||||
self.failed = False
|
self.failed = False
|
||||||
|
self.kill_on_start = False
|
||||||
self.start_time = None
|
self.start_time = None
|
||||||
self.result = None
|
self.result = None
|
||||||
self.duration = None
|
self.duration = None
|
||||||
|
@ -170,6 +170,7 @@ class Server(Thread):
|
|||||||
except Empty:
|
except Empty:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Get notifications from worker process
|
||||||
for worker in self.workers:
|
for worker in self.workers:
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
@ -179,6 +180,7 @@ class Server(Thread):
|
|||||||
except Empty:
|
except Empty:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# Remove finished jobs
|
||||||
for worker in [w for w in self.workers if not w.is_alive]:
|
for worker in [w for w in self.workers if not w.is_alive]:
|
||||||
self.workers.remove(worker)
|
self.workers.remove(worker)
|
||||||
job = worker.job
|
job = worker.job
|
||||||
@ -191,19 +193,27 @@ class Server(Thread):
|
|||||||
job.duration = time.time() - job.start_time
|
job.duration = time.time() - job.start_time
|
||||||
self.changed_jobs_queue.put(job)
|
self.changed_jobs_queue.put(job)
|
||||||
|
|
||||||
|
# Start new workers
|
||||||
if len(self.pool) + len(self.workers) < self.pool_size:
|
if len(self.pool) + len(self.workers) < self.pool_size:
|
||||||
try:
|
try:
|
||||||
self.pool.append(self.launch_worker())
|
self.pool.append(self.launch_worker())
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Start waiting jobs
|
||||||
if len(self.pool) > 0 and len(self.waiting_jobs) > 0:
|
if len(self.pool) > 0 and len(self.waiting_jobs) > 0:
|
||||||
job = self.waiting_jobs.pop()
|
job = self.waiting_jobs.pop()
|
||||||
worker = self.pool.pop()
|
|
||||||
job.start_time = time.time()
|
job.start_time = time.time()
|
||||||
worker.start_job(job)
|
if job.kill_on_start:
|
||||||
self.workers.append(worker)
|
job.duration = 0.0
|
||||||
job.log_path = worker.log_path
|
job.returncode = 1
|
||||||
|
job.killed = job.failed = True
|
||||||
|
job.result = None
|
||||||
|
else:
|
||||||
|
worker = self.pool.pop()
|
||||||
|
worker.start_job(job)
|
||||||
|
self.workers.append(worker)
|
||||||
|
job.log_path = worker.log_path
|
||||||
self.changed_jobs_queue.put(job)
|
self.changed_jobs_queue.put(job)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@ -217,11 +227,13 @@ class Server(Thread):
|
|||||||
self.kill_queue.put(job)
|
self.kill_queue.put(job)
|
||||||
|
|
||||||
def killall(self):
|
def killall(self):
|
||||||
for job in self.workers:
|
for worker in self.workers:
|
||||||
self.kill_queue.put(job)
|
self.kill_queue.put(worker.job)
|
||||||
|
|
||||||
def _kill_job(self, job):
|
def _kill_job(self, job):
|
||||||
if job.start_time is None: return
|
if job.start_time is None:
|
||||||
|
job.kill_on_start = True
|
||||||
|
return
|
||||||
for worker in self.workers:
|
for worker in self.workers:
|
||||||
if job is worker.job:
|
if job is worker.job:
|
||||||
worker.kill()
|
worker.kill()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user