directory deletion fix

frdel committed Jun 12, 2025 at 10:22 UTC d7eef4d92f4c8df06eebda444e55a7d3c99026bc
1 file changed +32 -11
python/helpers/files.py
+32 -11
@@ -71,7 +71,7 @@ def read_file_base64(_relative_path, _backup_dirs=None):
71
72 # read binary content and encode to base64
73 with open(absolute_path, "rb") as f:
74 - return base64.b64encode(f.read()).decode('utf-8')
74 + return base64.b64encode(f.read()).decode("utf-8")
75
76
77 def replace_placeholders_text(_content: str, **kwargs):
@@ -214,16 +214,30 @@ def write_file_base64(relative_path: str, content: str):
214 f.write(data)
215
216
217 -def delete_file(relative_path: str):
218 - abs_path = get_abs_path(relative_path)
219 - if os.path.exists(abs_path):
220 - os.remove(abs_path)
221 -
222 -
217 def delete_dir(relative_path: str):
218 + # ensure deletion of directory without propagating errors
219 abs_path = get_abs_path(relative_path)
220 if os.path.exists(abs_path):
226 - shutil.rmtree(abs_path)
221 + # first try with ignore_errors=True which is the safest option
222 + shutil.rmtree(abs_path, ignore_errors=True)
223 +
224 + # if directory still exists, try more aggressive methods
225 + if os.path.exists(abs_path):
226 + try:
227 + # try to change permissions and delete again
228 + for root, dirs, files in os.walk(abs_path, topdown=False):
229 + for name in files:
230 + file_path = os.path.join(root, name)
231 + os.chmod(file_path, 0o777)
232 + for name in dirs:
233 + dir_path = os.path.join(root, name)
234 + os.chmod(dir_path, 0o777)
235 +
236 + # try again after changing permissions
237 + shutil.rmtree(abs_path, ignore_errors=True)
238 + except:
239 + # suppress all errors - we're ensuring no errors propagate
240 + pass
241
242
243 def list_files(relative_path: str, filter: str = "*"):
@@ -252,6 +266,7 @@ def get_base_dir():
266 base_dir = os.path.dirname(os.path.abspath(os.path.join(__file__, "../../")))
267 return base_dir
268
269 +
270 def is_in_base_dir(path: str):
271 # check if the given path is within the base directory
272 base_dir = get_base_dir()
@@ -261,7 +276,11 @@ def is_in_base_dir(path: str):
276 return os.path.commonpath([abs_path, base_dir]) == base_dir
277
278
264 -def get_subdirectories(relative_path: str, include: str | list[str] = "*", exclude: str | list[str] | None = None):
279 +def get_subdirectories(
280 + relative_path: str,
281 + include: str | list[str] = "*",
282 + exclude: str | list[str] | None = None,
283 +):
284 abs_path = get_abs_path(relative_path)
285 if not os.path.exists(abs_path):
286 return []
@@ -297,7 +316,9 @@ def move_file(relative_path: str, new_path: str):
316 os.makedirs(os.path.dirname(new_abs_path), exist_ok=True)
317 os.rename(abs_path, new_abs_path)
318
300 -def safe_file_name(filename:str)-> str:
319 +
320 +def safe_file_name(filename: str) -> str:
321 # Replace any character that's not alphanumeric, dash, underscore, or dot with underscore
322 import re
303 - return re.sub(r'[^a-zA-Z0-9-._]', '_', filename)
\ No newline at end of file
323 +
324 + return re.sub(r"[^a-zA-Z0-9-._]", "_", filename)