From ef39992968e9744c8481c1a086de338bbca86eb9 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 14 May 2017 17:30:35 +0530 Subject: [PATCH] Handle temp files being deleted from under the server causing cover/ebook downloads to stop working --- src/calibre/srv/content.py | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/calibre/srv/content.py b/src/calibre/srv/content.py index 6e46233e59..b970520365 100644 --- a/src/calibre/srv/content.py +++ b/src/calibre/srv/content.py @@ -6,7 +6,7 @@ from __future__ import (unicode_literals, division, absolute_import, __license__ = 'GPL v3' __copyright__ = '2015, Kovid Goyal ' -import os +import os, errno from binascii import hexlify from io import BytesIO from threading import Lock @@ -43,6 +43,17 @@ mtimes = {} rename_counter = 0 +def open_for_write(fname): + try: + return share_open(fname, 'w+b') + except EnvironmentError: + try: + os.makedirs(os.path.dirname(fname)) + except EnvironmentError: + pass + return share_open(fname, 'w+b') + + def create_file_copy(ctx, rd, prefix, library_id, book_id, ext, mtime, copy_func, extra_etag_data=''): ''' We cannot copy files directly from the library folder to the output socket, as this can potentially lock the library for an extended period. So @@ -78,20 +89,21 @@ def create_file_copy(ctx, rd, prefix, library_id, book_id, ext, mtime, copy_func os.remove(dname) else: os.remove(fname) - try: - ans = share_open(fname, 'w+b') - except EnvironmentError: - try: - os.makedirs(base) - except EnvironmentError: - pass - ans = share_open(fname, 'w+b') + ans = open_for_write(fname) mtimes[bname] = mtime copy_func(ans) ans.seek(0) else: - ans = share_open(fname, 'rb') - used_cache = 'yes' + try: + ans = share_open(fname, 'rb') + used_cache = 'yes' + except EnvironmentError as err: + if err.errno != errno.ENOENT: + raise + ans = open_for_write(fname) + mtimes[bname] = mtime + copy_func(ans) + ans.seek(0) if ctx.testing: rd.outheaders['Used-Cache'] = used_cache rd.outheaders['Tempfile'] = hexlify(fname.encode('utf-8'))