Skip to content

Commit 008e802

Browse files
authored
Merge pull request #720 from OpenTrafficCam/task/8172-can-not-add-multiple-videos-folder-with-videos3
Task/8172 can not add multiple videos folder with videos3
2 parents 4084a1a + 711a99d commit 008e802

6 files changed

Lines changed: 56 additions & 21 deletions

File tree

‎OTAnalytics/adapter_ui/dummy_viewmodel.py‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -563,16 +563,15 @@ async def add_video(self) -> None:
563563
for ext in clean_extensions:
564564
extension_options[ext] = [ext]
565565

566-
track_files = await self._ui_factory.askopenfilenames(
566+
video_files = await self._ui_factory.askopenfilenames(
567567
title="Load video files",
568568
filetypes=[("video file", SUPPORTED_VIDEO_FILE_TYPES)],
569569
extension_options=extension_options,
570570
)
571-
if not track_files:
571+
if not video_files:
572572
return
573-
logger().info(f"Video files to load: {track_files}")
574-
paths = [Path(file) for file in track_files]
575-
self._application.add_videos(files=paths)
573+
logger().info(f"Video files to load: {video_files}")
574+
self._application.add_videos(files=video_files)
576575

577576
def remove_videos(self) -> None:
578577
self._application.remove_videos()

‎OTAnalytics/adapter_ui/ui_factory.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from abc import ABC, abstractmethod
22
from datetime import datetime
33
from pathlib import Path
4-
from typing import Iterable, Literal
4+
from typing import Iterable
55

66
from OTAnalytics.adapter_ui.file_export_dto import ExportFileDto
77
from OTAnalytics.adapter_ui.flow_dto import FlowDto
@@ -45,7 +45,7 @@ async def askopenfilenames(
4545
title: str,
4646
filetypes: Iterable[tuple[str, str | list[str] | tuple[str, ...]]],
4747
extension_options: dict[str, list[str] | None] | None = None,
48-
) -> Literal[""] | tuple[str, ...]:
48+
) -> list[Path]:
4949
raise NotImplementedError
5050

5151
@abstractmethod
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from pathlib import Path
2+
from typing import Iterable
3+
4+
from OTAnalytics.application.logger import logger
5+
6+
7+
def get_all_files_with_correct_file_ending_in_directory(
8+
files: Iterable[Path], file_types: list[str]
9+
) -> list[Path]:
10+
files_to_save: set[Path] = set()
11+
for file_type in file_types:
12+
for file in files:
13+
file_to_save = file.expanduser()
14+
if file_to_save.is_dir():
15+
files_in_directory = file_to_save.rglob(file_type)
16+
files_to_save.update(files_in_directory)
17+
continue
18+
19+
if not file_to_save.exists() or file_to_save.suffix != file_type:
20+
logger().warning(
21+
f"Ottrk file'{file_to_save}' does not exist. Skipping file."
22+
)
23+
continue
24+
25+
files_to_save.add(file_to_save)
26+
return list(files_to_save)

‎OTAnalytics/plugin_ui/customtkinter_gui/ctk_ui_factory.py‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from datetime import datetime
22
from pathlib import Path
33
from tkinter.filedialog import askopenfilename, askopenfilenames
4-
from typing import Iterable, Literal
4+
from typing import Iterable
55

66
from OTAnalytics.adapter_ui.file_export_dto import ExportFileDto
77
from OTAnalytics.adapter_ui.flow_dto import FlowDto
@@ -57,8 +57,9 @@ async def askopenfilenames(
5757
title: str,
5858
filetypes: Iterable[tuple[str, str | list[str] | tuple[str, ...]]],
5959
extension_options: dict[str, list[str] | None] | None = None,
60-
) -> Literal[""] | tuple[str, ...]:
61-
return askopenfilenames(title=title, filetypes=filetypes)
60+
) -> list[Path]:
61+
video_files = askopenfilenames(title=title, filetypes=filetypes)
62+
return [Path(file) for file in video_files]
6263

6364
async def askopenfilename(
6465
self,

‎OTAnalytics/plugin_ui/nicegui_gui/dialogs/file_picker.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def __init__(
5151
extensions or None for "All Files". If None, uses default options.
5252
"""
5353
super().__init__()
54-
54+
self.multiple = multiple
5555
self.path: Path = directory.expanduser()
5656
self.upper_limit: Path = directory.expanduser()
5757
self.show_hidden_files: bool = show_hidden_files
@@ -240,7 +240,7 @@ async def _handle_ok(self) -> None:
240240
paths: List[Path] = [self._map_to_domain(r[PATH]) for r in rows]
241241

242242
# If no rows are selected and we're in directory-only mode, use the current directory # noqa
243-
if not paths and self.show_only_directories:
243+
if not paths and (self.show_only_directories or self.multiple):
244244
paths = [self.path]
245245

246246
self.submit(paths)

‎OTAnalytics/plugin_ui/nicegui_gui/ui_factory.py‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import asyncio
22
from datetime import datetime
33
from pathlib import Path
4-
from typing import Any, Iterable, Literal
4+
from typing import Any, Iterable
55

66
from OTAnalytics.adapter_ui.file_export_dto import ExportFileDto
77
from OTAnalytics.adapter_ui.flow_dto import FlowDto
@@ -17,6 +17,9 @@
1717
from OTAnalytics.application.resources.resource_manager import ResourceManager
1818
from OTAnalytics.application.use_cases.generate_flows import FlowNameGenerator
1919
from OTAnalytics.domain.geometry import RelativeOffsetCoordinate
20+
from OTAnalytics.helpers.file_helpers import (
21+
get_all_files_with_correct_file_ending_in_directory,
22+
)
2023
from OTAnalytics.plugin_ui.nicegui_gui.dialogs.edit_flow_dialog import EditFlowDialog
2124
from OTAnalytics.plugin_ui.nicegui_gui.dialogs.edit_section_dialog import (
2225
EditSectionDialog,
@@ -27,6 +30,7 @@
2730
from OTAnalytics.plugin_ui.nicegui_gui.dialogs.file_chooser_dialog import (
2831
FileChooserDialog,
2932
)
33+
from OTAnalytics.plugin_ui.nicegui_gui.dialogs.file_picker import LocalFilePicker
3034
from OTAnalytics.plugin_ui.nicegui_gui.nicegui.elements.dialog import DialogResult
3135

3236

@@ -88,24 +92,29 @@ async def askopenfilenames(
8892
title: str,
8993
filetypes: Iterable[tuple[str, str | list[str] | tuple[str, ...]]],
9094
extension_options: dict[str, list[str] | None] | None = None,
91-
) -> Literal[""] | tuple[str, ...]:
95+
) -> list[Path]:
9296
# For now, we'll just support selecting a single file
9397
# In a real implementation, this would allow selecting multiple files
9498
# Convert list/tuple of extensions to individual (desc, ext) pairs
9599
converted_filetypes = []
96100
for desc, ext in filetypes:
97101
if isinstance(ext, str):
98-
converted_filetypes.append((desc, ext))
102+
converted_filetypes.append(ext)
99103
elif isinstance(ext, (list, tuple)) and ext:
100104
# Use the first extension from the list/tuple
101-
converted_filetypes.append((desc, ext[0]))
105+
converted_filetypes.append(ext[0])
102106

103-
file_path = await self.askopenfilename(
104-
title, converted_filetypes, "", extension_options
107+
file_paths = await LocalFilePicker(
108+
directory=Path.home(),
109+
show_hidden_files=False,
110+
show_files_only_of_type=None, # Show all files
111+
show_only_directories=False,
112+
extension_options=extension_options,
113+
multiple=True,
114+
)
115+
return get_all_files_with_correct_file_ending_in_directory(
116+
file_paths, converted_filetypes
105117
)
106-
if file_path:
107-
return (file_path,)
108-
return ""
109118

110119
async def ask_for_save_file_path(
111120
self,

0 commit comments

Comments
 (0)