Handle temp files being deleted from under the server causing cover/ebook downloads to stop working

This commit is contained in:
Kovid Goyal 2017-05-14 17:30:35 +05:30
parent e43705a3a3
commit ef39992968
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -6,7 +6,7 @@ from __future__ import (unicode_literals, division, absolute_import,
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
import os import os, errno
from binascii import hexlify from binascii import hexlify
from io import BytesIO from io import BytesIO
from threading import Lock from threading import Lock
@ -43,6 +43,17 @@ mtimes = {}
rename_counter = 0 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=''): 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 ''' 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 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) os.remove(dname)
else: else:
os.remove(fname) os.remove(fname)
try: ans = open_for_write(fname)
ans = share_open(fname, 'w+b')
except EnvironmentError:
try:
os.makedirs(base)
except EnvironmentError:
pass
ans = share_open(fname, 'w+b')
mtimes[bname] = mtime mtimes[bname] = mtime
copy_func(ans) copy_func(ans)
ans.seek(0) ans.seek(0)
else: else:
ans = share_open(fname, 'rb') try:
used_cache = 'yes' 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: if ctx.testing:
rd.outheaders['Used-Cache'] = used_cache rd.outheaders['Used-Cache'] = used_cache
rd.outheaders['Tempfile'] = hexlify(fname.encode('utf-8')) rd.outheaders['Tempfile'] = hexlify(fname.encode('utf-8'))