Repository: CS-SI/eodag
Pull request #635 (2023-02-07 16:08:15)

fix: not-downloaded products warning
Fixes issue in the warning message following a download timeout (that could be caused by a network issue):
```
File /path/to/lib/python3.9/site-packages/eodag/plugins/download/base.py:517, in Download.download_all(self, products, auth, downloaded_callback, progress_callback, wait, timeout, **kwargs)
513 sleep(wait_seconds + 1)
514 elif len(products) > 0 and datetime.now() >= stop_time:
515 logger.warning(
516 f"{len(products)} products could not be downloaded:"
--> 517 f"{' ' + [prod.properties['title'] for prod in products]}",
518 )
TypeError: can only concatenate str (not "list") to str
```


Patch:
diff --git a/eodag/plugins/download/base.py b/eodag/plugins/download/base.py
index 7ec2cbea..a89c0b52 100644
--- a/eodag/plugins/download/base.py
+++ b/eodag/plugins/download/base.py
@@ -513,8 +513,8 @@ class Download(PluginTopic):
                     sleep(wait_seconds + 1)
                 elif len(products) > 0 and datetime.now() >= stop_time:
                     logger.warning(
-                        f"{len(products)} products could not be downloaded:"
-                        f"{' ' + [prod.properties['title'] for prod in products]}",
+                        f"{len(products)} products could not be downloaded: "
+                        + str([prod.properties["title"] for prod in products])
                     )
                     break
                 elif len(products) == 0:
diff --git a/eodag/utils/__init__.py b/eodag/utils/__init__.py
index 35841aaf..d968c733 100644
--- a/eodag/utils/__init__.py
+++ b/eodag/utils/__init__.py
@@ -1148,6 +1148,9 @@ def flatten_top_directories(nested_dir_root, common_subdirs_path=None):
         subpaths_list = [p for p in Path(nested_dir_root).glob("**/*") if p.is_file()]
         common_subdirs_path = os.path.commonpath(subpaths_list)
 
+    if Path(common_subdirs_path).is_file():
+        common_subdirs_path = os.path.dirname(common_subdirs_path)
+
     if nested_dir_root != common_subdirs_path:
         logger.debug(f"Flatten {common_subdirs_path} to {nested_dir_root}")
         tmp_path = mkdtemp()


Test patch:
diff --git a/tests/units/test_download_plugins.py b/tests/units/test_download_plugins.py
index b3514aec..e15a565b 100644
--- a/tests/units/test_download_plugins.py
+++ b/tests/units/test_download_plugins.py
@@ -487,7 +487,7 @@ class TestDownloadPluginHttpRetry(BaseDownloadPluginTest):
                 self.plugin.download(
                     self.product,
                     outputs_prefix=self.output_dir,
-                    wait=0.1 / 60,
+                    wait=0.01 / 60,
                     timeout=0.2 / 60,
                 )
 
diff --git a/tests/units/test_utils.py b/tests/units/test_utils.py
index 04b4ad9b..90697d31 100644
--- a/tests/units/test_utils.py
+++ b/tests/units/test_utils.py
@@ -241,6 +241,20 @@ class TestUtils(unittest.TestCase):
             self.assertIn(Path(nested_dir_root) / "c2" / "bar", dir_content)
             self.assertIn(Path(nested_dir_root) / "c2" / "baz", dir_content)
 
+    def test_flatten_top_dirs_single_file(self):
+        """flatten_top_dirs must flatten directory structure containing a single file"""
+        with TemporaryDirectory() as nested_dir_root:
+            os.makedirs(os.path.join(nested_dir_root, "a", "b", "c1"))
+            # create empty file
+            open(os.path.join(nested_dir_root, "a", "b", "c1", "foo"), "a").close()
+
+            flatten_top_directories(nested_dir_root)
+
+            dir_content = list(Path(nested_dir_root).glob("**/*"))
+
+            self.assertEqual(len(dir_content), 1)
+            self.assertIn(Path(nested_dir_root) / "foo", dir_content)
+
     def test_flatten_top_dirs_given_subdir(self):
         """flatten_top_dirs must flatten directory structure using given subdirectory"""
         with TemporaryDirectory() as nested_dir_root: