Tweak Book: notify calibre on save when launched from within calibre

This commit is contained in:
Kovid Goyal 2013-12-11 11:05:02 +05:30
parent a30db00a8e
commit 71aeed7cb5
7 changed files with 62 additions and 11 deletions

View File

@ -135,8 +135,9 @@ class TweakEpubAction(InterfaceAction):
mi = db.new_api.get_metadata(book_id)
with pretty_print, open(path, 'r+b') as f:
set_metadata(f, mi, stream_type=fmt.lower())
notify = '%d:%s:%s:%s' % (book_id, fmt, db.library_id, db.library_path)
try:
self.gui.job_manager.launch_gui_app(tweak, kwargs=dict(args=[tweak, path]))
self.gui.job_manager.launch_gui_app(tweak, kwargs=dict(path=path, notify=notify))
time.sleep(2)
finally:
self.gui.unsetCursor()

View File

@ -71,12 +71,12 @@ def in_thread_job(func):
class Boss(QObject):
def __init__(self, parent):
def __init__(self, parent, notify=None):
QObject.__init__(self, parent)
self.global_undo = GlobalUndoHistory()
self.container_count = 0
self.tdir = None
self.save_manager = SaveManager(parent)
self.save_manager = SaveManager(parent, notify)
self.save_manager.report_error.connect(self.report_save_error)
self.doing_terminal_save = False
self.ignore_preview_to_editor_sync = False
@ -131,7 +131,7 @@ class Boss(QObject):
self.container_count += 1
return tempfile.mkdtemp(prefix='%s%05d-' % (prefix, self.container_count), dir=self.tdir)
def open_book(self, path=None, edit_file=None):
def open_book(self, path=None, edit_file=None, clear_notify_data=True):
if self.gui.action_save.isEnabled():
if not question_dialog(self.gui, _('Unsaved changes'), _(
'The current book has unsaved changes. If you open a new book, they will be lost'
@ -167,10 +167,12 @@ class Boss(QObject):
shutil.rmtree(self.tdir, ignore_errors=True)
self.tdir = PersistentTemporaryDirectory()
self._edit_file_on_open = edit_file
self._clear_notify_data = clear_notify_data
self.gui.blocking_job('open_book', _('Opening book, please wait...'), self.book_opened, get_container, path, tdir=self.mkdtemp())
def book_opened(self, job):
ef = getattr(self, '_edit_file_on_open', None)
cn = getattr(self, '_clear_notify_data', True)
self._edit_file_on_open = None
if job.traceback is not None:
@ -180,6 +182,8 @@ class Boss(QObject):
return error_dialog(self.gui, _('Failed to open book'),
_('Failed to open book, click Show details for more information.'),
det_msg=job.traceback, show=True)
if cn:
self.save_manager.clear_notify_data()
parse_worker.clear()
container = job.result
set_current_container(container)

View File

@ -26,8 +26,10 @@ Launch the calibre edit book tool.
'Edit the named file inside the book'))
return parser
def gui_main(path=None, notify=None):
_run(['ebook-edit', path], notify=notify)
def main(args=sys.argv):
def _run(args, notify=None):
# Ensure we can continue to function if GUI is closed
os.environ.pop('CALIBRE_WORKER_TEMP_DIR', None)
reset_base_dir()
@ -48,13 +50,16 @@ def main(args=sys.argv):
app.setWindowIcon(QIcon(I('tweak.png')))
Application.setOrganizationName(ORG_NAME)
Application.setApplicationName(APP_UID)
main = Main(opts)
main = Main(opts, notify=notify)
sys.excepthook = main.unhandled_exception
main.show()
if len(args) > 1:
main.boss.open_book(args[1], edit_file=opts.edit_file)
main.boss.open_book(args[1], edit_file=opts.edit_file, clear_notify_data=False)
app.exec_()
def main(args=sys.argv):
_run(args)
if __name__ == '__main__':
main()

View File

@ -17,6 +17,7 @@ from calibre.ptempfile import PersistentTemporaryFile
from calibre.gui2.progress_indicator import ProgressIndicator
from calibre.utils import join_with_timeout
from calibre.utils.filenames import atomic_rename
from calibre.utils.ipc import RC
def save_container(container, path):
temp = PersistentTemporaryFile(
@ -30,6 +31,15 @@ def save_container(container, path):
if os.path.exists(temp):
os.remove(temp)
def send_message(msg=''):
if msg:
t = RC(print_error=False)
t.start()
t.join(3)
if t.done:
t.conn.send('bookedited:'+msg)
t.conn.close()
class SaveWidget(QWidget):
def __init__(self, parent=None):
@ -61,14 +71,19 @@ class SaveManager(QObject):
report_error = pyqtSignal(object)
save_done = pyqtSignal()
def __init__(self, parent):
def __init__(self, parent, notify=None):
QObject.__init__(self, parent)
self.count = 0
self.last_saved = -1
self.requests = LifoQueue()
self.notify_requests = LifoQueue()
self.notify_data = notify
t = Thread(name='save-thread', target=self.run)
t.daemon = True
t.start()
t = Thread(name='notify-thread', target=self.notify_calibre)
t.daemon = True
t.start()
self.status_widget = w = SaveWidget(parent)
self.start_save.connect(w.start, type=Qt.QueuedConnection)
self.save_done.connect(w.stop, type=Qt.QueuedConnection)
@ -93,6 +108,15 @@ class SaveManager(QObject):
finally:
self.requests.task_done()
def notify_calibre(self):
while True:
if not self.notify_requests.get():
break
send_message(self.notify_data)
def clear_notify_data(self):
self.notify_data = None
def __empty_queue(self):
' Only to be used during shutdown '
while True:
@ -115,6 +139,8 @@ class SaveManager(QObject):
import traceback
self.report_error.emit(traceback.format_exc())
self.save_done.emit()
if self.notify_data:
self.notify_requests.put(True)
def do_save(self, tdir, container):
try:
@ -138,3 +164,4 @@ class SaveManager(QObject):
def shutdown(self):
self.requests.put(None)
self.notify_requests.put(None)

View File

@ -182,9 +182,9 @@ class Main(MainWindow):
APP_NAME = _('Edit Book')
STATE_VERSION = 0
def __init__(self, opts):
def __init__(self, opts, notify=None):
MainWindow.__init__(self, opts, disable_automatic_gc=True)
self.boss = Boss(self)
self.boss = Boss(self, notify=notify)
self.setWindowTitle(self.APP_NAME)
self.setWindowIcon(QIcon(I('tweak.png')))
self.opts = opts

View File

@ -558,6 +558,20 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
self.tags_view.recount()
elif msg.startswith('shutdown:'):
self.quit(confirm_quit=False)
elif msg.startswith('bookedited:'):
parts = msg.split(':')[1:]
try:
book_id, fmt, library_id = parts[:3]
book_id = int(book_id)
m = self.library_view.model()
db = m.db.new_api
if m.db.library_id == library_id and db.has_id(book_id):
db.format_metadata(book_id, fmt, allow_cache=False, update_db=True)
db.update_last_modified((book_id,))
m.refresh_ids((book_id,))
except Exception:
import traceback
traceback.print_exc()
else:
print msg

View File

@ -26,7 +26,7 @@ PARALLEL_FUNCS = {
('calibre.gui2.viewer.main', 'main', None),
'ebook-edit' :
('calibre.gui2.tweak_book.main', 'main', None),
('calibre.gui2.tweak_book.main', 'gui_main', None),
'render_pages' :
('calibre.ebooks.comic.input', 'render_pages', 'notification'),