karaoke-gen 0.90.1__py3-none-any.whl → 0.96.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.
- backend/.coveragerc +20 -0
- backend/.gitignore +37 -0
- backend/Dockerfile +43 -0
- backend/Dockerfile.base +74 -0
- backend/README.md +242 -0
- backend/__init__.py +0 -0
- backend/api/__init__.py +0 -0
- backend/api/dependencies.py +457 -0
- backend/api/routes/__init__.py +0 -0
- backend/api/routes/admin.py +742 -0
- backend/api/routes/audio_search.py +903 -0
- backend/api/routes/auth.py +348 -0
- backend/api/routes/file_upload.py +2076 -0
- backend/api/routes/health.py +344 -0
- backend/api/routes/internal.py +435 -0
- backend/api/routes/jobs.py +1610 -0
- backend/api/routes/review.py +652 -0
- backend/api/routes/themes.py +162 -0
- backend/api/routes/users.py +1014 -0
- backend/config.py +172 -0
- backend/main.py +133 -0
- backend/middleware/__init__.py +5 -0
- backend/middleware/audit_logging.py +124 -0
- backend/models/__init__.py +0 -0
- backend/models/job.py +519 -0
- backend/models/requests.py +123 -0
- backend/models/theme.py +153 -0
- backend/models/user.py +254 -0
- backend/models/worker_log.py +164 -0
- backend/pyproject.toml +29 -0
- backend/quick-check.sh +93 -0
- backend/requirements.txt +29 -0
- backend/run_tests.sh +60 -0
- backend/services/__init__.py +0 -0
- backend/services/audio_analysis_service.py +243 -0
- backend/services/audio_editing_service.py +278 -0
- backend/services/audio_search_service.py +702 -0
- backend/services/auth_service.py +630 -0
- backend/services/credential_manager.py +792 -0
- backend/services/discord_service.py +172 -0
- backend/services/dropbox_service.py +301 -0
- backend/services/email_service.py +1093 -0
- backend/services/encoding_interface.py +454 -0
- backend/services/encoding_service.py +405 -0
- backend/services/firestore_service.py +512 -0
- backend/services/flacfetch_client.py +573 -0
- backend/services/gce_encoding/README.md +72 -0
- backend/services/gce_encoding/__init__.py +22 -0
- backend/services/gce_encoding/main.py +589 -0
- backend/services/gce_encoding/requirements.txt +16 -0
- backend/services/gdrive_service.py +356 -0
- backend/services/job_logging.py +258 -0
- backend/services/job_manager.py +842 -0
- backend/services/job_notification_service.py +271 -0
- backend/services/local_encoding_service.py +590 -0
- backend/services/local_preview_encoding_service.py +407 -0
- backend/services/lyrics_cache_service.py +216 -0
- backend/services/metrics.py +413 -0
- backend/services/packaging_service.py +287 -0
- backend/services/rclone_service.py +106 -0
- backend/services/storage_service.py +209 -0
- backend/services/stripe_service.py +275 -0
- backend/services/structured_logging.py +254 -0
- backend/services/template_service.py +330 -0
- backend/services/theme_service.py +469 -0
- backend/services/tracing.py +543 -0
- backend/services/user_service.py +721 -0
- backend/services/worker_service.py +558 -0
- backend/services/youtube_service.py +112 -0
- backend/services/youtube_upload_service.py +445 -0
- backend/tests/__init__.py +4 -0
- backend/tests/conftest.py +224 -0
- backend/tests/emulator/__init__.py +7 -0
- backend/tests/emulator/conftest.py +88 -0
- backend/tests/emulator/test_e2e_cli_backend.py +1053 -0
- backend/tests/emulator/test_emulator_integration.py +356 -0
- backend/tests/emulator/test_style_loading_direct.py +436 -0
- backend/tests/emulator/test_worker_logs_direct.py +229 -0
- backend/tests/emulator/test_worker_logs_subcollection.py +443 -0
- backend/tests/requirements-test.txt +10 -0
- backend/tests/requirements.txt +6 -0
- backend/tests/test_admin_email_endpoints.py +411 -0
- backend/tests/test_api_integration.py +460 -0
- backend/tests/test_api_routes.py +93 -0
- backend/tests/test_audio_analysis_service.py +294 -0
- backend/tests/test_audio_editing_service.py +386 -0
- backend/tests/test_audio_search.py +1398 -0
- backend/tests/test_audio_services.py +378 -0
- backend/tests/test_auth_firestore.py +231 -0
- backend/tests/test_config_extended.py +68 -0
- backend/tests/test_credential_manager.py +377 -0
- backend/tests/test_dependencies.py +54 -0
- backend/tests/test_discord_service.py +244 -0
- backend/tests/test_distribution_services.py +820 -0
- backend/tests/test_dropbox_service.py +472 -0
- backend/tests/test_email_service.py +492 -0
- backend/tests/test_emulator_integration.py +322 -0
- backend/tests/test_encoding_interface.py +412 -0
- backend/tests/test_file_upload.py +1739 -0
- backend/tests/test_flacfetch_client.py +632 -0
- backend/tests/test_gdrive_service.py +524 -0
- backend/tests/test_instrumental_api.py +431 -0
- backend/tests/test_internal_api.py +343 -0
- backend/tests/test_job_creation_regression.py +583 -0
- backend/tests/test_job_manager.py +339 -0
- backend/tests/test_job_manager_notifications.py +329 -0
- backend/tests/test_job_notification_service.py +443 -0
- backend/tests/test_jobs_api.py +273 -0
- backend/tests/test_local_encoding_service.py +423 -0
- backend/tests/test_local_preview_encoding_service.py +567 -0
- backend/tests/test_main.py +87 -0
- backend/tests/test_models.py +918 -0
- backend/tests/test_packaging_service.py +382 -0
- backend/tests/test_requests.py +201 -0
- backend/tests/test_routes_jobs.py +282 -0
- backend/tests/test_routes_review.py +337 -0
- backend/tests/test_services.py +556 -0
- backend/tests/test_services_extended.py +112 -0
- backend/tests/test_storage_service.py +448 -0
- backend/tests/test_style_upload.py +261 -0
- backend/tests/test_template_service.py +295 -0
- backend/tests/test_theme_service.py +516 -0
- backend/tests/test_unicode_sanitization.py +522 -0
- backend/tests/test_upload_api.py +256 -0
- backend/tests/test_validate.py +156 -0
- backend/tests/test_video_worker_orchestrator.py +847 -0
- backend/tests/test_worker_log_subcollection.py +509 -0
- backend/tests/test_worker_logging.py +365 -0
- backend/tests/test_workers.py +1116 -0
- backend/tests/test_workers_extended.py +178 -0
- backend/tests/test_youtube_service.py +247 -0
- backend/tests/test_youtube_upload_service.py +568 -0
- backend/validate.py +173 -0
- backend/version.py +27 -0
- backend/workers/README.md +597 -0
- backend/workers/__init__.py +11 -0
- backend/workers/audio_worker.py +618 -0
- backend/workers/lyrics_worker.py +683 -0
- backend/workers/render_video_worker.py +483 -0
- backend/workers/screens_worker.py +525 -0
- backend/workers/style_helper.py +198 -0
- backend/workers/video_worker.py +1277 -0
- backend/workers/video_worker_orchestrator.py +701 -0
- backend/workers/worker_logging.py +278 -0
- karaoke_gen/instrumental_review/static/index.html +7 -4
- karaoke_gen/karaoke_finalise/karaoke_finalise.py +6 -1
- karaoke_gen/utils/__init__.py +163 -8
- karaoke_gen/video_background_processor.py +9 -4
- {karaoke_gen-0.90.1.dist-info → karaoke_gen-0.96.0.dist-info}/METADATA +1 -1
- {karaoke_gen-0.90.1.dist-info → karaoke_gen-0.96.0.dist-info}/RECORD +186 -41
- lyrics_transcriber/correction/agentic/providers/config.py +9 -5
- lyrics_transcriber/correction/agentic/providers/langchain_bridge.py +1 -51
- lyrics_transcriber/correction/corrector.py +192 -130
- lyrics_transcriber/correction/operations.py +24 -9
- lyrics_transcriber/frontend/package-lock.json +2 -2
- lyrics_transcriber/frontend/package.json +1 -1
- lyrics_transcriber/frontend/src/components/AIFeedbackModal.tsx +1 -1
- lyrics_transcriber/frontend/src/components/CorrectedWordWithActions.tsx +11 -7
- lyrics_transcriber/frontend/src/components/EditActionBar.tsx +31 -5
- lyrics_transcriber/frontend/src/components/EditModal.tsx +28 -10
- lyrics_transcriber/frontend/src/components/EditTimelineSection.tsx +123 -27
- lyrics_transcriber/frontend/src/components/EditWordList.tsx +112 -60
- lyrics_transcriber/frontend/src/components/Header.tsx +90 -76
- lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +53 -31
- lyrics_transcriber/frontend/src/components/LyricsSynchronizer/SyncControls.tsx +44 -13
- lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx +66 -50
- lyrics_transcriber/frontend/src/components/LyricsSynchronizer/index.tsx +124 -30
- lyrics_transcriber/frontend/src/components/ReferenceView.tsx +1 -1
- lyrics_transcriber/frontend/src/components/TimelineEditor.tsx +12 -5
- lyrics_transcriber/frontend/src/components/TimingOffsetModal.tsx +3 -3
- lyrics_transcriber/frontend/src/components/TranscriptionView.tsx +1 -1
- lyrics_transcriber/frontend/src/components/WordDivider.tsx +11 -7
- lyrics_transcriber/frontend/src/components/shared/components/Word.tsx +4 -2
- lyrics_transcriber/frontend/src/hooks/useManualSync.ts +103 -1
- lyrics_transcriber/frontend/src/theme.ts +42 -15
- lyrics_transcriber/frontend/tsconfig.tsbuildinfo +1 -1
- lyrics_transcriber/frontend/vite.config.js +5 -0
- lyrics_transcriber/frontend/web_assets/assets/{index-BECn1o8Q.js → index-BSMgOq4Z.js} +6959 -5782
- lyrics_transcriber/frontend/web_assets/assets/index-BSMgOq4Z.js.map +1 -0
- lyrics_transcriber/frontend/web_assets/index.html +6 -2
- lyrics_transcriber/frontend/web_assets/nomad-karaoke-logo.svg +5 -0
- lyrics_transcriber/output/generator.py +17 -3
- lyrics_transcriber/output/video.py +60 -95
- lyrics_transcriber/frontend/web_assets/assets/index-BECn1o8Q.js.map +0 -1
- {karaoke_gen-0.90.1.dist-info → karaoke_gen-0.96.0.dist-info}/WHEEL +0 -0
- {karaoke_gen-0.90.1.dist-info → karaoke_gen-0.96.0.dist-info}/entry_points.txt +0 -0
- {karaoke_gen-0.90.1.dist-info → karaoke_gen-0.96.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Theme API routes for listing and retrieving theme information.
|
|
3
|
+
|
|
4
|
+
Themes are pre-created style configurations that users can select when creating jobs.
|
|
5
|
+
These endpoints are public (no authentication required) to allow theme selection
|
|
6
|
+
before job creation.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
from typing import Optional
|
|
11
|
+
|
|
12
|
+
from fastapi import APIRouter, HTTPException
|
|
13
|
+
|
|
14
|
+
from backend.models.theme import ThemeDetailResponse, ThemesListResponse
|
|
15
|
+
from backend.services.theme_service import get_theme_service
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
router = APIRouter(prefix="/themes", tags=["themes"])
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@router.get("", response_model=ThemesListResponse)
|
|
23
|
+
async def list_themes() -> ThemesListResponse:
|
|
24
|
+
"""
|
|
25
|
+
List all available themes.
|
|
26
|
+
|
|
27
|
+
Returns a list of themes with their metadata and preview image URLs.
|
|
28
|
+
Preview URLs are signed and valid for 60 minutes.
|
|
29
|
+
|
|
30
|
+
This endpoint is public and does not require authentication.
|
|
31
|
+
"""
|
|
32
|
+
try:
|
|
33
|
+
theme_service = get_theme_service()
|
|
34
|
+
themes = theme_service.list_themes()
|
|
35
|
+
return ThemesListResponse(themes=themes)
|
|
36
|
+
except Exception as e:
|
|
37
|
+
logger.error(f"Error listing themes: {e}")
|
|
38
|
+
raise HTTPException(
|
|
39
|
+
status_code=500,
|
|
40
|
+
detail="Failed to load themes"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@router.get("/{theme_id}", response_model=ThemeDetailResponse)
|
|
45
|
+
async def get_theme(theme_id: str) -> ThemeDetailResponse:
|
|
46
|
+
"""
|
|
47
|
+
Get detailed information about a specific theme.
|
|
48
|
+
|
|
49
|
+
Returns the full theme details including style parameters.
|
|
50
|
+
This can be used to preview theme settings or inspect configuration.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
theme_id: The unique identifier of the theme
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
ThemeDetailResponse with full theme details
|
|
57
|
+
|
|
58
|
+
Raises:
|
|
59
|
+
404: Theme not found
|
|
60
|
+
"""
|
|
61
|
+
try:
|
|
62
|
+
theme_service = get_theme_service()
|
|
63
|
+
theme = theme_service.get_theme(theme_id)
|
|
64
|
+
|
|
65
|
+
if theme is None:
|
|
66
|
+
raise HTTPException(
|
|
67
|
+
status_code=404,
|
|
68
|
+
detail=f"Theme not found: {theme_id}"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
return ThemeDetailResponse(theme=theme)
|
|
72
|
+
except HTTPException:
|
|
73
|
+
raise
|
|
74
|
+
except Exception as e:
|
|
75
|
+
logger.error(f"Error getting theme {theme_id}: {e}")
|
|
76
|
+
raise HTTPException(
|
|
77
|
+
status_code=500,
|
|
78
|
+
detail="Failed to load theme"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@router.get("/{theme_id}/preview")
|
|
83
|
+
async def get_theme_preview(theme_id: str) -> dict:
|
|
84
|
+
"""
|
|
85
|
+
Get a signed URL for the theme's preview image.
|
|
86
|
+
|
|
87
|
+
This endpoint is useful when you need just the preview URL
|
|
88
|
+
without loading the full theme details.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
theme_id: The unique identifier of the theme
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
Object with preview_url field
|
|
95
|
+
|
|
96
|
+
Raises:
|
|
97
|
+
404: Theme not found or no preview available
|
|
98
|
+
"""
|
|
99
|
+
try:
|
|
100
|
+
theme_service = get_theme_service()
|
|
101
|
+
|
|
102
|
+
if not theme_service.theme_exists(theme_id):
|
|
103
|
+
raise HTTPException(
|
|
104
|
+
status_code=404,
|
|
105
|
+
detail=f"Theme not found: {theme_id}"
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
theme = theme_service.get_theme(theme_id)
|
|
109
|
+
if theme is None or theme.preview_url is None:
|
|
110
|
+
raise HTTPException(
|
|
111
|
+
status_code=404,
|
|
112
|
+
detail=f"No preview available for theme: {theme_id}"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
return {"preview_url": theme.preview_url}
|
|
116
|
+
except HTTPException:
|
|
117
|
+
raise
|
|
118
|
+
except Exception as e:
|
|
119
|
+
logger.error(f"Error getting preview for theme {theme_id}: {e}")
|
|
120
|
+
raise HTTPException(
|
|
121
|
+
status_code=500,
|
|
122
|
+
detail="Failed to load theme preview"
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@router.get("/{theme_id}/youtube-description")
|
|
127
|
+
async def get_theme_youtube_description(theme_id: str) -> dict:
|
|
128
|
+
"""
|
|
129
|
+
Get the YouTube description template for a theme.
|
|
130
|
+
|
|
131
|
+
Some themes include a default YouTube video description template
|
|
132
|
+
that can be used when uploading videos.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
theme_id: The unique identifier of the theme
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
Object with description field containing the template text,
|
|
139
|
+
or null if no template is available
|
|
140
|
+
|
|
141
|
+
Raises:
|
|
142
|
+
404: Theme not found
|
|
143
|
+
"""
|
|
144
|
+
try:
|
|
145
|
+
theme_service = get_theme_service()
|
|
146
|
+
|
|
147
|
+
if not theme_service.theme_exists(theme_id):
|
|
148
|
+
raise HTTPException(
|
|
149
|
+
status_code=404,
|
|
150
|
+
detail=f"Theme not found: {theme_id}"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
description = theme_service.get_youtube_description(theme_id)
|
|
154
|
+
return {"description": description}
|
|
155
|
+
except HTTPException:
|
|
156
|
+
raise
|
|
157
|
+
except Exception as e:
|
|
158
|
+
logger.error(f"Error getting YouTube description for theme {theme_id}: {e}")
|
|
159
|
+
raise HTTPException(
|
|
160
|
+
status_code=500,
|
|
161
|
+
detail="Failed to load YouTube description"
|
|
162
|
+
)
|