liveflowai 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
liveflowai/__init__.py ADDED
File without changes
liveflowai/__main__.py ADDED
@@ -0,0 +1,5 @@
1
+ # src/liveflowai/__main__.py
2
+ from . import main
3
+
4
+ if __name__ == "__main__":
5
+ main()
File without changes
@@ -0,0 +1,153 @@
1
+ # src/liveflowai/audio/audio_file_selector.py
2
+
3
+ from pathlib import Path
4
+
5
+
6
+ class AudioFileSelector:
7
+ """
8
+ Interactive selector for audio files stored in data/songs/.
9
+ """
10
+
11
+ SUPPORTED_EXTENSIONS = {
12
+ ".mp3",
13
+ ".wav",
14
+ ".flac",
15
+ ".m4a",
16
+ ".aac",
17
+ ".ogg",
18
+ ".wma",
19
+ }
20
+
21
+ def __init__(self, base_dir=None):
22
+ """
23
+ Args:
24
+ base_dir: Project root directory. If None, automatically
25
+ determines the project root.
26
+ """
27
+
28
+ if base_dir is None:
29
+ self.project_root = Path(__file__).resolve().parents[3]
30
+ else:
31
+ self.project_root = Path(base_dir).resolve()
32
+
33
+ self.audio_dir = self.project_root / "data" / "songs"
34
+
35
+ def get_audio_files(self):
36
+ """
37
+ Return all supported audio files in data/songs/.
38
+ """
39
+
40
+ if not self.audio_dir.exists():
41
+ print(f"\nAudio directory does not exist:")
42
+ print(f" {self.audio_dir}")
43
+ return []
44
+
45
+ audio_files = [
46
+ file
47
+ for file in self.audio_dir.iterdir()
48
+ if file.is_file()
49
+ and file.suffix.lower() in self.SUPPORTED_EXTENSIONS
50
+ ]
51
+
52
+ return sorted(audio_files, key=lambda path: path.name.lower())
53
+
54
+ def display_audio_files(self, audio_files):
55
+ """
56
+ Display all available audio files with numbers.
57
+ """
58
+
59
+ print("\n=== Available Audio Files ===")
60
+
61
+ for index, file_path in enumerate(audio_files, start=1):
62
+ print(f"{index}. {file_path.name}")
63
+
64
+ print("=============================")
65
+
66
+ def select_file(self):
67
+ """
68
+ Show all available audio files and let the user select one.
69
+
70
+ Returns:
71
+ Path or None
72
+ """
73
+
74
+ audio_files = self.get_audio_files()
75
+
76
+ if not audio_files:
77
+ print("\nNo supported audio files found in:")
78
+ print(f" {self.audio_dir}")
79
+ return None
80
+
81
+ self.display_audio_files(audio_files)
82
+
83
+ while True:
84
+ choice = input(
85
+ f"\nSelect an audio file (1-{len(audio_files)}) "
86
+ "or 'q' to cancel: "
87
+ ).strip()
88
+
89
+ if choice.lower() == "q":
90
+ return None
91
+
92
+ try:
93
+ index = int(choice) - 1
94
+ except ValueError:
95
+ print("Invalid input. Please enter a number.")
96
+ continue
97
+
98
+ if 0 <= index < len(audio_files):
99
+ selected_file = audio_files[index]
100
+
101
+ print(f"\nSelected: {selected_file.name}")
102
+
103
+ return selected_file
104
+
105
+ print(
106
+ f"Invalid selection. "
107
+ f"Please enter a number between 1 and {len(audio_files)}."
108
+ )
109
+
110
+ def ask_continue(self):
111
+ """
112
+ Ask whether the user wants to select another audio file.
113
+
114
+ Returns:
115
+ True -> select another file
116
+ False -> return to startup menu
117
+ """
118
+
119
+ while True:
120
+ choice = input(
121
+ "\nDo you want to select another audio file? (y/n): "
122
+ ).strip().lower()
123
+
124
+ if choice in {"y", "yes"}:
125
+ return True
126
+
127
+ if choice in {"n", "no"}:
128
+ return False
129
+
130
+ print("Please enter 'y' or 'n'.")
131
+
132
+ def select_multiple(self):
133
+ """
134
+ Allow the user to repeatedly select audio files.
135
+
136
+ Returns:
137
+ list[Path]: Selected audio files.
138
+ """
139
+
140
+ selected_files = []
141
+
142
+ while True:
143
+ selected_file = self.select_file()
144
+
145
+ if selected_file is None:
146
+ break
147
+
148
+ selected_files.append(selected_file)
149
+
150
+ if not self.ask_continue():
151
+ break
152
+
153
+ return selected_files