Skip to content

Instantly share code, notes, and snippets.

Created July 1, 2017 12:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/0e96b1ee1044b8c29464e6f535761d31 to your computer and use it in GitHub Desktop.
Save anonymous/0e96b1ee1044b8c29464e6f535761d31 to your computer and use it in GitHub Desktop.
Index: calibre-plugin/jobs.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- calibre-plugin/jobs.py (revision e2f2b5ed8c29347e36daa1d5f416568ced55daeb)
+++ calibre-plugin/jobs.py (revision )
@@ -3,6 +3,13 @@
from __future__ import (unicode_literals, division, absolute_import,
print_function)
+import os
+import tempfile
+
+import shutil
+
+import uuid
+
__license__ = 'GPL v3'
__copyright__ = '2017, Jim Miller, 2011, Grant Drake <grant.drake@gmail.com>'
__docformat__ = 'restructuredtext en'
@@ -11,7 +18,7 @@
logger = logging.getLogger(__name__)
import traceback
-from datetime import time
+from datetime import time, datetime
from StringIO import StringIO
from calibre.utils.ipc.server import Server
@@ -221,7 +228,32 @@
logger.info("write to %s"%outfile)
inject_cal_cols(book,story,configuration)
- writer.writeStory(outfilename=outfile, forceOverwrite=True)
+
+ # Copy original story to a temporary directory before attempting to write an updated version, since the
+ # story is fetched in writer.writeStory() and might raise an error; In that case we don't have to create
+ # the backup since the original file remains unchanged. The outfile path is guaranteed to exist since we
+ # are updating the story
+ temp_path = tempfile.mkdtemp()
+ original_path = os.path.join(temp_path, os.path.basename(outfile))
+ shutil.copy(outfile, original_path)
+
+ try:
+ writer.writeStory(outfilename=outfile, forceOverwrite=True)
+ except Exception:
+ # Make sure to remove the temporary directory and let the exception bubble up
+ shutil.rmtree(temp_path, ignore_errors=True)
+ raise
+
+ # Use date for easy visual differentiation and a random UUID to make sure (however unlikely) that we
+ # don't overwrite a previous backup of the story if it was updated within the same minute according
+ # to the running system
+ backup_destination = os.path.join('/', 'home', 'user', 'Documents')
+ backup_filename = '%s.%s_%s' % (
+ writer.getOutputFileName(), datetime.now().strftime('%d_%m_%Y_%H_%M'), uuid.uuid4().hex
+ )
+ backup_path = os.path.join(backup_destination, backup_filename)
+ shutil.move(original_path, backup_path)
+ shutil.rmtree(temp_path, ignore_errors=True)
book['comment'] = _('Download %s completed, %s chapters.')%(options['fileform'],story.getMetadata("numChapters"))
book['all_metadata'] = story.getAllMetadata(removeallentities=True)
@@ -269,7 +301,32 @@
logger.info("write to %s"%outfile)
inject_cal_cols(book,story,configuration)
- writer.writeStory(outfilename=outfile, forceOverwrite=True)
+
+ # Copy original story to a temporary directory before attempting to write an updated version, since the
+ # story is fetched in writer.writeStory() and might raise an error; In that case we don't have to create
+ # the backup since the original file remains unchanged. The outfile path is guaranteed to exist since we
+ # are updating the story
+ temp_path = tempfile.mkdtemp()
+ original_path = os.path.join(temp_path, os.path.basename(outfile))
+ shutil.copy(outfile, original_path)
+
+ try:
+ writer.writeStory(outfilename=outfile, forceOverwrite=True)
+ except Exception:
+ # Make sure to remove the temporary directory and let the exception bubble up
+ shutil.rmtree(temp_path, ignore_errors=True)
+ raise
+
+ # Use date for easy visual differentiation and a random UUID to make sure (however unlikely) that we
+ # don't overwrite a previous backup of the story if it was updated within the same minute according
+ # to the running system
+ backup_destination = os.path.join('/', 'home', 'user', 'Documents')
+ backup_filename = '%s.%s_%s' % (
+ writer.getOutputFileName(), datetime.now().strftime('%d_%m_%Y_%H_%M'), uuid.uuid4().hex
+ )
+ backup_path = os.path.join(backup_destination, backup_filename)
+ shutil.move(original_path, backup_path)
+ shutil.rmtree(temp_path, ignore_errors=True)
book['comment'] = _('Update %s completed, added %s chapters for %s total.')%\
(options['fileform'],(urlchaptercount-chaptercount),urlchaptercount)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment