From f54038ca837e98e264b97685d1c3fbc98e53a0ad Mon Sep 17 00:00:00 2001
From: Agate <me@agate.blue>
Date: Fri, 5 Jun 2020 10:42:56 +0200
Subject: [PATCH] Resolve "CLI in-place import impossible with virtualenv with
 python3.5"

---
 .../music/management/commands/import_files.py    |   6 +++++-
 api/tests/files/nested/valid.ogg                 | Bin 0 -> 5158 bytes
 api/tests/test_import_audio_file.py              |  14 ++++++++++++++
 changes/changelog.d/1048.bugfix                  |   1 +
 4 files changed, 20 insertions(+), 1 deletion(-)
 create mode 100644 api/tests/files/nested/valid.ogg
 create mode 100644 changes/changelog.d/1048.bugfix

diff --git a/api/funkwhale_api/music/management/commands/import_files.py b/api/funkwhale_api/music/management/commands/import_files.py
index fab980510d..ddc598d06f 100644
--- a/api/funkwhale_api/music/management/commands/import_files.py
+++ b/api/funkwhale_api/music/management/commands/import_files.py
@@ -27,7 +27,8 @@ def crawl_dir(dir, extensions, recursive=True, ignored=[]):
     if os.path.isfile(dir):
         yield dir
         return
-    with os.scandir(dir) as scanner:
+    try:
+        scanner = os.scandir(dir)
         for entry in scanner:
             if entry.is_file():
                 for e in extensions:
@@ -38,6 +39,9 @@ def crawl_dir(dir, extensions, recursive=True, ignored=[]):
                 yield from crawl_dir(
                     entry, extensions, recursive=recursive, ignored=ignored
                 )
+    finally:
+        if hasattr(scanner, "close"):
+            scanner.close()
 
 
 def batch(iterable, n=1):
diff --git a/api/tests/files/nested/valid.ogg b/api/tests/files/nested/valid.ogg
new file mode 100644
index 0000000000000000000000000000000000000000..e1643848a07a548e55d53726d4e4fe168a8ab2cd
GIT binary patch
literal 5158
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
PjMSJoeW_!T=UEv5m3TPm

literal 0
HcmV?d00001

diff --git a/api/tests/test_import_audio_file.py b/api/tests/test_import_audio_file.py
index 04c06a8f46..7ee1028c8f 100644
--- a/api/tests/test_import_audio_file.py
+++ b/api/tests/test_import_audio_file.py
@@ -352,3 +352,17 @@ def test_handle_modified_update_existing_path_if_found_and_attributed_to(
         event=event, stdout=stdout, library=library, in_place=True,
     )
     update_track_metadata.assert_not_called()
+
+
+def test_import_files(factories, capsys):
+    # smoke test to ensure the command run properly
+    library = factories["music.Library"](actor__local=True)
+    call_command(
+        "import_files", str(library.uuid), DATA_DIR, interactive=False, recursive=True
+    )
+    captured = capsys.readouterr()
+
+    imported = library.uploads.filter(import_status="finished").count()
+    assert imported > 0
+    assert "Successfully imported {} new tracks".format(imported) in captured.out
+    assert "For details, please refer to import reference" in captured.out
diff --git a/changes/changelog.d/1048.bugfix b/changes/changelog.d/1048.bugfix
new file mode 100644
index 0000000000..0f19734441
--- /dev/null
+++ b/changes/changelog.d/1048.bugfix
@@ -0,0 +1 @@
+Fixed recursive CLI importing crashing under Python 3.5 (#1148, #1147)
-- 
GitLab