From 88a72ea14d0e3b90b5aa08675f9662b5fd24b62e Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Sun, 21 Jun 2020 10:13:55 +0100 Subject: [PATCH] Handle access errors scanning directories Trying to read a directory that is visible but not accessible, or a symlink to a file in a directory that is not accessible will raise a PermissionError. Output these and then continue. If os.scandir() raises an exception then the finally block accesses "scanner" before it is assigned, raising an UnboundLocalError. --- .../music/management/commands/import_files.py | 28 +++++++++++++------ changes/changelog.d/import-eaccess-fix.bugfix | 1 + 2 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 changes/changelog.d/import-eaccess-fix.bugfix diff --git a/api/funkwhale_api/music/management/commands/import_files.py b/api/funkwhale_api/music/management/commands/import_files.py index e03c9a720..5c9eecda6 100644 --- a/api/funkwhale_api/music/management/commands/import_files.py +++ b/api/funkwhale_api/music/management/commands/import_files.py @@ -3,6 +3,7 @@ import datetime import itertools import os import queue +import sys import threading import time import urllib.parse @@ -29,16 +30,27 @@ def crawl_dir(dir, extensions, recursive=True, ignored=[]): return try: scanner = os.scandir(dir) + except Exception as e: + m = "Error while reading {}: {} {}\n".format(dir, e.__class__.__name__, e) + sys.stderr.write(m) + return + try: for entry in scanner: - if entry.is_file(): - for e in extensions: - if entry.name.lower().endswith(".{}".format(e.lower())): - if entry.path not in ignored: - yield entry.path - elif recursive and entry.is_dir(): - yield from crawl_dir( - entry.path, extensions, recursive=recursive, ignored=ignored + try: + if entry.is_file(): + for e in extensions: + if entry.name.lower().endswith(".{}".format(e.lower())): + if entry.path not in ignored: + yield entry.path + elif recursive and entry.is_dir(): + yield from crawl_dir( + entry.path, extensions, recursive=recursive, ignored=ignored + ) + except Exception as e: + m = "Error while reading {}: {} {}\n".format( + entry.name, e.__class__.__name__, e ) + sys.stderr.write(m) finally: if hasattr(scanner, "close"): scanner.close() diff --git a/changes/changelog.d/import-eaccess-fix.bugfix b/changes/changelog.d/import-eaccess-fix.bugfix new file mode 100644 index 000000000..841a820d9 --- /dev/null +++ b/changes/changelog.d/import-eaccess-fix.bugfix @@ -0,0 +1 @@ +Handle access errors scanning directories when importing files