From 674b47bdbd0206ddabbef000de4516e4ef7710c9 Mon Sep 17 00:00:00 2001 From: haraldpdl Date: Sat, 18 Apr 2026 06:28:58 +0200 Subject: [PATCH] Remove staged download from /tmp/calibre_web after response is sent When config_embed_metadata is enabled with config_binariesdir or config_kepubifypath set, do_download_file stages a copy of every downloaded book under get_temp_dir() but never removes it. A bulk OPDS or Kobo sync can fill the host filesystem in minutes; the effect is amplified for comic formats (CBZ/CBR), where each staged file can run to hundreds of MB or several GB. Once the disk fills, downloads silently 404 and a container restart does not recover the space. Add an after_this_request hook that removes the staged copy after the response is sent, gated on filename == get_temp_dir() so the non-embed and gdrive-direct paths are untouched. --- cps/helper.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/cps/helper.py b/cps/helper.py index f85e6fa17..0dfb761c6 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -30,7 +30,7 @@ import requests import unidecode from uuid import uuid4 -from flask import send_from_directory, make_response, abort, url_for, Response, request +from flask import send_from_directory, make_response, abort, url_for, Response, request, after_this_request from flask_babel import gettext as _ from flask_babel import lazy_gettext as N_ from flask_babel import get_locale @@ -956,6 +956,17 @@ def do_download_file(book, book_format, client, data, headers): else: download_name = book_name + # Clean up staged copies in /tmp/calibre_web after the response is sent + # (kepubify / calibre-export branches) so the temp dir does not grow unbounded. + if filename == get_temp_dir(): + _tmp_path = os.path.join(filename, download_name + "." + book_format) + @after_this_request + def _cleanup_staged_download(resp): + try: + os.remove(_tmp_path) + except OSError as ex: + log.warning('Failed to remove staged download %s: %s', _tmp_path, ex) + return resp response = make_response(send_from_directory(filename, download_name + "." + book_format)) # ToDo Check headers parameter for element in headers: