spatelier 0.3.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.
Files changed (59) hide show
  1. analytics/__init__.py +1 -0
  2. analytics/reporter.py +497 -0
  3. cli/__init__.py +1 -0
  4. cli/app.py +147 -0
  5. cli/audio.py +129 -0
  6. cli/cli_analytics.py +320 -0
  7. cli/cli_utils.py +282 -0
  8. cli/error_handlers.py +122 -0
  9. cli/files.py +299 -0
  10. cli/update.py +325 -0
  11. cli/video.py +823 -0
  12. cli/worker.py +615 -0
  13. core/__init__.py +1 -0
  14. core/analytics_dashboard.py +368 -0
  15. core/base.py +303 -0
  16. core/base_service.py +69 -0
  17. core/config.py +345 -0
  18. core/database_service.py +116 -0
  19. core/decorators.py +263 -0
  20. core/error_handler.py +210 -0
  21. core/file_tracker.py +254 -0
  22. core/interactive_cli.py +366 -0
  23. core/interfaces.py +166 -0
  24. core/job_queue.py +437 -0
  25. core/logger.py +79 -0
  26. core/package_updater.py +469 -0
  27. core/progress.py +228 -0
  28. core/service_factory.py +295 -0
  29. core/streaming.py +299 -0
  30. core/worker.py +765 -0
  31. database/__init__.py +1 -0
  32. database/connection.py +265 -0
  33. database/metadata.py +516 -0
  34. database/models.py +288 -0
  35. database/repository.py +592 -0
  36. database/transcription_storage.py +219 -0
  37. modules/__init__.py +1 -0
  38. modules/audio/__init__.py +5 -0
  39. modules/audio/converter.py +197 -0
  40. modules/video/__init__.py +16 -0
  41. modules/video/converter.py +191 -0
  42. modules/video/fallback_extractor.py +334 -0
  43. modules/video/services/__init__.py +18 -0
  44. modules/video/services/audio_extraction_service.py +274 -0
  45. modules/video/services/download_service.py +852 -0
  46. modules/video/services/metadata_service.py +190 -0
  47. modules/video/services/playlist_service.py +445 -0
  48. modules/video/services/transcription_service.py +491 -0
  49. modules/video/transcription_service.py +385 -0
  50. modules/video/youtube_api.py +397 -0
  51. spatelier/__init__.py +33 -0
  52. spatelier-0.3.0.dist-info/METADATA +260 -0
  53. spatelier-0.3.0.dist-info/RECORD +59 -0
  54. spatelier-0.3.0.dist-info/WHEEL +5 -0
  55. spatelier-0.3.0.dist-info/entry_points.txt +2 -0
  56. spatelier-0.3.0.dist-info/licenses/LICENSE +21 -0
  57. spatelier-0.3.0.dist-info/top_level.txt +7 -0
  58. utils/__init__.py +1 -0
  59. utils/helpers.py +250 -0
cli/update.py ADDED
@@ -0,0 +1,325 @@
1
+ """
2
+ Package update management commands.
3
+
4
+ Provides CLI interface for checking and updating critical packages.
5
+ """
6
+
7
+ from typing import Optional
8
+
9
+ import typer
10
+ from rich.console import Console
11
+ from rich.panel import Panel
12
+ from rich.table import Table
13
+
14
+ from core.config import Config
15
+ from core.package_updater import PackageUpdater
16
+ from core.progress import track_progress
17
+
18
+ console = Console()
19
+ app = typer.Typer(name="update", help="Package update management")
20
+
21
+
22
+ @app.command()
23
+ def check(
24
+ package: Optional[str] = typer.Option(
25
+ None, "--package", "-p", help="Specific package to check"
26
+ ),
27
+ verbose: bool = typer.Option(
28
+ False, "--verbose", "-v", help="Enable verbose output"
29
+ ),
30
+ ):
31
+ """
32
+ 🔍 Check for package updates.
33
+
34
+ Checks if critical packages like yt-dlp have updates available.
35
+ """
36
+ config = Config()
37
+ updater = PackageUpdater(config, verbose=verbose)
38
+
39
+ if package:
40
+ # Check specific package
41
+ result = updater.check_package_updates(package)
42
+
43
+ if "error" in result:
44
+ console.print(
45
+ Panel(
46
+ f"[red]✗[/red] Error checking {package}: {result['error']}",
47
+ title="Error",
48
+ border_style="red",
49
+ )
50
+ )
51
+ raise typer.Exit(1)
52
+
53
+ # Display result
54
+ status = "🔄 Update Available" if result["needs_update"] else "✅ Up to Date"
55
+ color = "yellow" if result["needs_update"] else "green"
56
+
57
+ console.print(
58
+ Panel(
59
+ f"{status}\n"
60
+ f"Package: {result['package']}\n"
61
+ f"Description: {result['description']}\n"
62
+ f"Current: {result['current_version']}\n"
63
+ f"Latest: {result['latest_version']}\n"
64
+ f"Last Checked: {result['last_checked']}",
65
+ title=f"Package Status: {package}",
66
+ border_style=color,
67
+ )
68
+ )
69
+ else:
70
+ # Check all packages
71
+ with track_progress("Checking for updates...", verbose=verbose) as progress:
72
+ summary = updater.get_update_summary()
73
+ progress.update(1, "Update check completed")
74
+
75
+ # Create summary table
76
+ table = Table(title="Package Update Summary")
77
+ table.add_column("Package", style="cyan")
78
+ table.add_column("Status", style="magenta")
79
+ table.add_column("Current", style="green")
80
+ table.add_column("Latest", style="blue")
81
+ table.add_column("Description", style="white")
82
+
83
+ for result in summary["results"]:
84
+ if "error" in result:
85
+ table.add_row(
86
+ result["package"], "[red]Error[/red]", "N/A", "N/A", result["error"]
87
+ )
88
+ else:
89
+ status = (
90
+ "🔄 Update Available" if result["needs_update"] else "✅ Up to Date"
91
+ )
92
+ table.add_row(
93
+ result["package"],
94
+ status,
95
+ result["current_version"],
96
+ result["latest_version"],
97
+ result["description"],
98
+ )
99
+
100
+ console.print(table)
101
+
102
+ # Summary stats
103
+ console.print(
104
+ Panel(
105
+ f"📊 Summary:\n"
106
+ f"Total Packages: {summary['total_packages']}\n"
107
+ f"Need Updates: {summary['packages_needing_update']}\n"
108
+ f"Errors: {summary['packages_with_errors']}\n"
109
+ f"Last Check: {summary['last_check']}",
110
+ title="Update Summary",
111
+ border_style="blue",
112
+ )
113
+ )
114
+
115
+
116
+ @app.command()
117
+ def update(
118
+ package: Optional[str] = typer.Option(
119
+ None, "--package", "-p", help="Specific package to update"
120
+ ),
121
+ auto_confirm: bool = typer.Option(
122
+ False, "--yes", "-y", help="Update without confirmation"
123
+ ),
124
+ verbose: bool = typer.Option(
125
+ False, "--verbose", "-v", help="Enable verbose output"
126
+ ),
127
+ ):
128
+ """
129
+ 🔄 Update packages to latest versions.
130
+
131
+ Updates critical packages like yt-dlp to their latest versions.
132
+ """
133
+ config = Config()
134
+ updater = PackageUpdater(config, verbose=verbose)
135
+
136
+ if package:
137
+ # Update specific package
138
+ if not auto_confirm:
139
+ # Check if update is needed first
140
+ result = updater.check_package_updates(package)
141
+ if "error" in result:
142
+ console.print(
143
+ Panel(
144
+ f"[red]✗[/red] Error checking {package}: {result['error']}",
145
+ title="Error",
146
+ border_style="red",
147
+ )
148
+ )
149
+ raise typer.Exit(1)
150
+
151
+ if not result["needs_update"]:
152
+ console.print(
153
+ Panel(
154
+ f"[green]✓[/green] {package} is already up to date!\n"
155
+ f"Current version: {result['current_version']}",
156
+ title="No Update Needed",
157
+ border_style="green",
158
+ )
159
+ )
160
+ return
161
+
162
+ # Ask for confirmation
163
+ if not typer.confirm(
164
+ f"Update {package} from {result['current_version']} to {result['latest_version']}?"
165
+ ):
166
+ console.print("Update cancelled.")
167
+ return
168
+
169
+ # Perform update
170
+ with track_progress(f"Updating {package}...", verbose=verbose) as progress:
171
+ result = updater.update_package(package, auto_confirm)
172
+ progress.update(1, f"Update completed")
173
+
174
+ if result["success"]:
175
+ console.print(
176
+ Panel(
177
+ f"[green]✓[/green] Successfully updated {package}!\n"
178
+ f"New version: {result['new_version']}\n"
179
+ f"Updated at: {result['updated_at']}",
180
+ title="Update Successful",
181
+ border_style="green",
182
+ )
183
+ )
184
+ else:
185
+ console.print(
186
+ Panel(
187
+ f"[red]✗[/red] Failed to update {package}\n"
188
+ f"Error: {result['error']}\n"
189
+ f"Output: {result.get('output', 'N/A')}",
190
+ title="Update Failed",
191
+ border_style="red",
192
+ )
193
+ )
194
+ raise typer.Exit(1)
195
+ else:
196
+ # Update all packages that need updates
197
+ summary = updater.get_update_summary()
198
+
199
+ if summary["packages_needing_update"] == 0:
200
+ console.print(
201
+ Panel(
202
+ "[green]✓[/green] All packages are up to date!",
203
+ title="No Updates Needed",
204
+ border_style="green",
205
+ )
206
+ )
207
+ return
208
+
209
+ # Show what will be updated
210
+ packages_to_update = [
211
+ r for r in summary["results"] if r.get("needs_update", False)
212
+ ]
213
+
214
+ console.print(
215
+ Panel(
216
+ f"📦 Packages to update:\n"
217
+ + "\n".join(
218
+ [
219
+ f"• {p['package']}: {p['current_version']} → {p['latest_version']}"
220
+ for p in packages_to_update
221
+ ]
222
+ ),
223
+ title="Update Plan",
224
+ border_style="yellow",
225
+ )
226
+ )
227
+
228
+ if not auto_confirm:
229
+ if not typer.confirm(f"Update {len(packages_to_update)} package(s)?"):
230
+ console.print("Update cancelled.")
231
+ return
232
+
233
+ # Perform updates
234
+ success_count = 0
235
+ for package_info in packages_to_update:
236
+ package_name = package_info["package"]
237
+
238
+ with track_progress(
239
+ f"Updating {package_name}...", verbose=verbose
240
+ ) as progress:
241
+ result = updater.update_package(package_name, auto_confirm=True)
242
+ progress.update(1, f"Update completed")
243
+
244
+ if result["success"]:
245
+ success_count += 1
246
+ console.print(
247
+ f"[green]✓[/green] Updated {package_name} to {result['new_version']}"
248
+ )
249
+ else:
250
+ console.print(
251
+ f"[red]✗[/red] Failed to update {package_name}: {result['error']}"
252
+ )
253
+
254
+ # Final summary
255
+ console.print(
256
+ Panel(
257
+ f"📊 Update Results:\n"
258
+ f"Successful: {success_count}/{len(packages_to_update)}\n"
259
+ f"Failed: {len(packages_to_update) - success_count}",
260
+ title="Update Complete",
261
+ border_style="green"
262
+ if success_count == len(packages_to_update)
263
+ else "yellow",
264
+ )
265
+ )
266
+
267
+
268
+ @app.command()
269
+ def status(
270
+ verbose: bool = typer.Option(
271
+ False, "--verbose", "-v", help="Enable verbose output"
272
+ ),
273
+ ):
274
+ """
275
+ 📊 Show package update status.
276
+
277
+ Displays the current status of all critical packages.
278
+ """
279
+ config = Config()
280
+ updater = PackageUpdater(config, verbose=verbose)
281
+
282
+ summary = updater.get_update_summary()
283
+
284
+ # Create detailed status table
285
+ table = Table(title="Package Status Overview")
286
+ table.add_column("Package", style="cyan", no_wrap=True)
287
+ table.add_column("Current Version", style="green")
288
+ table.add_column("Status", style="magenta")
289
+ table.add_column("Last Checked", style="blue")
290
+ table.add_column("Description", style="white")
291
+
292
+ for result in summary["results"]:
293
+ if "error" in result:
294
+ table.add_row(
295
+ result["package"],
296
+ "Unknown",
297
+ "[red]Error[/red]",
298
+ "Never",
299
+ result["error"],
300
+ )
301
+ else:
302
+ status = "🔄 Update Available" if result["needs_update"] else "✅ Up to Date"
303
+ table.add_row(
304
+ result["package"],
305
+ result["current_version"],
306
+ status,
307
+ result["last_checked"],
308
+ result["description"],
309
+ )
310
+
311
+ console.print(table)
312
+
313
+ # Summary stats
314
+ console.print(
315
+ Panel(
316
+ f"📈 Statistics:\n"
317
+ f"Total Packages: {summary['total_packages']}\n"
318
+ f"Need Updates: {summary['packages_needing_update']}\n"
319
+ f"Up to Date: {summary['total_packages'] - summary['packages_needing_update'] - summary['packages_with_errors']}\n"
320
+ f"Errors: {summary['packages_with_errors']}\n"
321
+ f"Last Check: {summary['last_check']}",
322
+ title="Status Summary",
323
+ border_style="blue",
324
+ )
325
+ )