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>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../../../../resources/images.qrc">
|
||||
<iconset resource="../../../work/calibre/resources/images.qrc">
|
||||
<normaloff>:/images/jobs.svg</normaloff>:/images/jobs.svg</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
@ -57,6 +57,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="stop_all_jobs_button">
|
||||
<property name="text">
|
||||
<string>Stop &all jobs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
@ -67,7 +74,7 @@
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../../../resources/images.qrc"/>
|
||||
<include location="../../../work/calibre/resources/images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -193,6 +193,12 @@ class JobManager(QAbstractTableModel):
|
||||
_('Job has already run')).exec_()
|
||||
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):
|
||||
self.server.killall()
|
||||
|
||||
@ -230,6 +236,8 @@ class JobsDialog(QDialog, Ui_JobsDialog):
|
||||
self.kill_job)
|
||||
self.connect(self.details_button, SIGNAL('clicked()'),
|
||||
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.jobs_view.model().kill_job)
|
||||
self.pb_delegate = ProgressBarDelegate(self)
|
||||
@ -247,7 +255,8 @@ class JobsDialog(QDialog, Ui_JobsDialog):
|
||||
self.jobs_view.show_details(index)
|
||||
return
|
||||
|
||||
|
||||
def kill_all_jobs(self):
|
||||
self.model.kill_all_jobs()
|
||||
|
||||
def closeEvent(self, e):
|
||||
self.jobs_view.write_settings()
|
||||
|
@ -156,8 +156,6 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None):
|
||||
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, repr(mi.title))
|
||||
|
||||
args = [in_file, out_file.name, lrecs]
|
||||
temp_files.append(out_file)
|
||||
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),
|
||||
msg).exec_()
|
||||
|
||||
jobs.reverse()
|
||||
return jobs, changed, bad
|
||||
|
||||
def fetch_scheduled_recipe(recipe, script):
|
||||
|
@ -30,6 +30,7 @@ class BaseJob(object):
|
||||
self.done2 = None
|
||||
self.killed = False
|
||||
self.failed = False
|
||||
self.kill_on_start = False
|
||||
self.start_time = None
|
||||
self.result = None
|
||||
self.duration = None
|
||||
|
@ -170,6 +170,7 @@ class Server(Thread):
|
||||
except Empty:
|
||||
pass
|
||||
|
||||
# Get notifications from worker process
|
||||
for worker in self.workers:
|
||||
while True:
|
||||
try:
|
||||
@ -179,6 +180,7 @@ class Server(Thread):
|
||||
except Empty:
|
||||
break
|
||||
|
||||
# Remove finished jobs
|
||||
for worker in [w for w in self.workers if not w.is_alive]:
|
||||
self.workers.remove(worker)
|
||||
job = worker.job
|
||||
@ -191,19 +193,27 @@ class Server(Thread):
|
||||
job.duration = time.time() - job.start_time
|
||||
self.changed_jobs_queue.put(job)
|
||||
|
||||
# Start new workers
|
||||
if len(self.pool) + len(self.workers) < self.pool_size:
|
||||
try:
|
||||
self.pool.append(self.launch_worker())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Start waiting jobs
|
||||
if len(self.pool) > 0 and len(self.waiting_jobs) > 0:
|
||||
job = self.waiting_jobs.pop()
|
||||
worker = self.pool.pop()
|
||||
job.start_time = time.time()
|
||||
worker.start_job(job)
|
||||
self.workers.append(worker)
|
||||
job.log_path = worker.log_path
|
||||
if job.kill_on_start:
|
||||
job.duration = 0.0
|
||||
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)
|
||||
|
||||
while True:
|
||||
@ -217,11 +227,13 @@ class Server(Thread):
|
||||
self.kill_queue.put(job)
|
||||
|
||||
def killall(self):
|
||||
for job in self.workers:
|
||||
self.kill_queue.put(job)
|
||||
for worker in self.workers:
|
||||
self.kill_queue.put(worker.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:
|
||||
if job is worker.job:
|
||||
worker.kill()
|
||||
|
Loading…
x
Reference in New Issue
Block a user