karaoke-gen 0.90.1__py3-none-any.whl → 0.99.3__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 +835 -0
- backend/api/routes/audio_search.py +913 -0
- backend/api/routes/auth.py +348 -0
- backend/api/routes/file_upload.py +2112 -0
- backend/api/routes/health.py +409 -0
- backend/api/routes/internal.py +435 -0
- backend/api/routes/jobs.py +1629 -0
- backend/api/routes/review.py +652 -0
- backend/api/routes/themes.py +162 -0
- backend/api/routes/users.py +1513 -0
- backend/config.py +172 -0
- backend/main.py +157 -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 +502 -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 +853 -0
- backend/services/job_notification_service.py +271 -0
- backend/services/langfuse_preloader.py +98 -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/nltk_preloader.py +122 -0
- backend/services/packaging_service.py +287 -0
- backend/services/rclone_service.py +106 -0
- backend/services/spacy_preloader.py +65 -0
- backend/services/storage_service.py +209 -0
- backend/services/stripe_service.py +371 -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 +109 -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 +356 -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 +283 -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_spacy_preloader.py +119 -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/utils/test_data.py +27 -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 +535 -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.99.3.dist-info}/METADATA +1 -1
- {karaoke_gen-0.90.1.dist-info → karaoke_gen-0.99.3.dist-info}/RECORD +196 -46
- lyrics_transcriber/correction/agentic/agent.py +17 -6
- lyrics_transcriber/correction/agentic/providers/config.py +9 -5
- lyrics_transcriber/correction/agentic/providers/langchain_bridge.py +96 -93
- lyrics_transcriber/correction/agentic/providers/model_factory.py +27 -6
- lyrics_transcriber/correction/anchor_sequence.py +151 -37
- lyrics_transcriber/correction/corrector.py +192 -130
- lyrics_transcriber/correction/handlers/syllables_match.py +44 -2
- lyrics_transcriber/correction/operations.py +24 -9
- lyrics_transcriber/correction/phrase_analyzer.py +18 -0
- 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.99.3.dist-info}/WHEEL +0 -0
- {karaoke_gen-0.90.1.dist-info → karaoke_gen-0.99.3.dist-info}/entry_points.txt +0 -0
- {karaoke_gen-0.90.1.dist-info → karaoke_gen-0.99.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Style configuration helper for workers.
|
|
3
|
+
|
|
4
|
+
Downloads and processes style assets from GCS, making them available
|
|
5
|
+
for screen generation, video rendering, and CDG generation.
|
|
6
|
+
|
|
7
|
+
This module uses the unified style_loader from karaoke_gen for
|
|
8
|
+
consistent style handling across local CLI and cloud backend.
|
|
9
|
+
"""
|
|
10
|
+
import json
|
|
11
|
+
import logging
|
|
12
|
+
import os
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Dict, Any, Optional
|
|
15
|
+
|
|
16
|
+
from backend.services.storage_service import StorageService
|
|
17
|
+
|
|
18
|
+
# Import from the unified style loader module
|
|
19
|
+
from karaoke_gen.style_loader import (
|
|
20
|
+
# Defaults
|
|
21
|
+
DEFAULT_INTRO_STYLE,
|
|
22
|
+
DEFAULT_END_STYLE,
|
|
23
|
+
DEFAULT_KARAOKE_STYLE,
|
|
24
|
+
DEFAULT_CDG_STYLE,
|
|
25
|
+
# Functions
|
|
26
|
+
load_styles_from_gcs,
|
|
27
|
+
update_asset_paths,
|
|
28
|
+
save_style_params,
|
|
29
|
+
get_intro_format,
|
|
30
|
+
get_end_format,
|
|
31
|
+
get_karaoke_format,
|
|
32
|
+
get_cdg_format,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger(__name__)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# Re-export defaults for backwards compatibility with existing code
|
|
40
|
+
DEFAULT_INTRO_FORMAT = DEFAULT_INTRO_STYLE
|
|
41
|
+
DEFAULT_END_FORMAT = DEFAULT_END_STYLE
|
|
42
|
+
DEFAULT_KARAOKE_FORMAT = DEFAULT_KARAOKE_STYLE
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class StyleConfig:
|
|
46
|
+
"""
|
|
47
|
+
Manages style configuration for a job.
|
|
48
|
+
|
|
49
|
+
Downloads style assets from GCS and provides processed style parameters
|
|
50
|
+
with local file paths for use by video generators.
|
|
51
|
+
|
|
52
|
+
This class wraps the unified style_loader module to provide an
|
|
53
|
+
object-oriented interface for backend workers.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def __init__(self, job, storage: StorageService, temp_dir: str):
|
|
57
|
+
"""
|
|
58
|
+
Initialize style configuration.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
job: Job object with style_assets and style_params_gcs_path
|
|
62
|
+
storage: Storage service for downloading files
|
|
63
|
+
temp_dir: Temporary directory for downloaded assets
|
|
64
|
+
"""
|
|
65
|
+
self.job = job
|
|
66
|
+
self.storage = storage
|
|
67
|
+
self.temp_dir = temp_dir
|
|
68
|
+
self.style_dir = os.path.join(temp_dir, "style")
|
|
69
|
+
os.makedirs(self.style_dir, exist_ok=True)
|
|
70
|
+
|
|
71
|
+
self._style_params: Optional[Dict[str, Any]] = None
|
|
72
|
+
self._local_assets: Dict[str, str] = {}
|
|
73
|
+
self._styles_path: Optional[str] = None
|
|
74
|
+
self._loaded = False
|
|
75
|
+
self._has_custom_styles = False # Track if custom styles were loaded
|
|
76
|
+
|
|
77
|
+
async def load(self) -> None:
|
|
78
|
+
"""
|
|
79
|
+
Download and parse style configuration from GCS.
|
|
80
|
+
|
|
81
|
+
Downloads:
|
|
82
|
+
- style_params.json (if exists)
|
|
83
|
+
- All style assets (backgrounds, fonts)
|
|
84
|
+
|
|
85
|
+
After loading, style params will have local file paths.
|
|
86
|
+
"""
|
|
87
|
+
if self._loaded:
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
logger.info(f"Loading style configuration for job {self.job.job_id}")
|
|
91
|
+
|
|
92
|
+
# Get style assets from job
|
|
93
|
+
style_assets = getattr(self.job, 'style_assets', {}) or {}
|
|
94
|
+
style_params_gcs_path = getattr(self.job, 'style_params_gcs_path', None)
|
|
95
|
+
|
|
96
|
+
logger.info(f"Job has {len(style_assets)} style assets defined")
|
|
97
|
+
for key, path in style_assets.items():
|
|
98
|
+
logger.info(f" Style asset '{key}': {path}")
|
|
99
|
+
|
|
100
|
+
# Check if we have custom styles before loading
|
|
101
|
+
self._has_custom_styles = bool(style_params_gcs_path)
|
|
102
|
+
|
|
103
|
+
# Use the unified style loader
|
|
104
|
+
self._styles_path, self._style_params = load_styles_from_gcs(
|
|
105
|
+
style_params_gcs_path=style_params_gcs_path,
|
|
106
|
+
style_assets=style_assets,
|
|
107
|
+
temp_dir=self.temp_dir,
|
|
108
|
+
download_func=self.storage.download_file,
|
|
109
|
+
logger=logger,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Track local assets for get_local_asset_path()
|
|
113
|
+
if style_assets:
|
|
114
|
+
for asset_key in style_assets.keys():
|
|
115
|
+
if asset_key == 'style_params':
|
|
116
|
+
self._local_assets['style_params'] = self._styles_path
|
|
117
|
+
else:
|
|
118
|
+
ext = os.path.splitext(style_assets[asset_key])[1] or '.png'
|
|
119
|
+
local_path = os.path.join(self.style_dir, f"{asset_key}{ext}")
|
|
120
|
+
if os.path.exists(local_path):
|
|
121
|
+
self._local_assets[asset_key] = local_path
|
|
122
|
+
|
|
123
|
+
self._loaded = True
|
|
124
|
+
logger.info(f"Successfully loaded style configuration")
|
|
125
|
+
|
|
126
|
+
def get_intro_format(self) -> Dict[str, Any]:
|
|
127
|
+
"""Get title/intro screen format, with custom styles if available."""
|
|
128
|
+
if self._style_params:
|
|
129
|
+
return get_intro_format(self._style_params)
|
|
130
|
+
return DEFAULT_INTRO_STYLE.copy()
|
|
131
|
+
|
|
132
|
+
def get_end_format(self) -> Dict[str, Any]:
|
|
133
|
+
"""Get end screen format, with custom styles if available."""
|
|
134
|
+
if self._style_params:
|
|
135
|
+
return get_end_format(self._style_params)
|
|
136
|
+
return DEFAULT_END_STYLE.copy()
|
|
137
|
+
|
|
138
|
+
def get_karaoke_format(self) -> Dict[str, Any]:
|
|
139
|
+
"""Get karaoke video format, with custom styles if available."""
|
|
140
|
+
if self._style_params:
|
|
141
|
+
return get_karaoke_format(self._style_params)
|
|
142
|
+
return DEFAULT_KARAOKE_STYLE.copy()
|
|
143
|
+
|
|
144
|
+
def get_cdg_styles(self) -> Optional[Dict[str, Any]]:
|
|
145
|
+
"""Get CDG generation styles if available, falling back to defaults."""
|
|
146
|
+
if self._style_params:
|
|
147
|
+
cdg_styles = get_cdg_format(self._style_params)
|
|
148
|
+
if cdg_styles:
|
|
149
|
+
return cdg_styles
|
|
150
|
+
# Return default CDG styles if no custom styles
|
|
151
|
+
return DEFAULT_CDG_STYLE.copy()
|
|
152
|
+
|
|
153
|
+
def get_style_params_path(self) -> Optional[str]:
|
|
154
|
+
"""
|
|
155
|
+
Get local path to style_params.json with updated asset paths.
|
|
156
|
+
|
|
157
|
+
Returns the styles JSON file path, or None if not loaded.
|
|
158
|
+
"""
|
|
159
|
+
return self._styles_path
|
|
160
|
+
|
|
161
|
+
def get_local_asset_path(self, asset_key: str) -> Optional[str]:
|
|
162
|
+
"""Get local path for a specific asset."""
|
|
163
|
+
return self._local_assets.get(asset_key)
|
|
164
|
+
|
|
165
|
+
def has_custom_styles(self) -> bool:
|
|
166
|
+
"""Check if custom styles were provided (not using defaults)."""
|
|
167
|
+
return self._has_custom_styles
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
def intro_video_duration(self) -> int:
|
|
171
|
+
"""Get intro video duration in seconds."""
|
|
172
|
+
if self._style_params and 'intro' in self._style_params:
|
|
173
|
+
return self._style_params['intro'].get('video_duration', 5)
|
|
174
|
+
return 5
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def end_video_duration(self) -> int:
|
|
178
|
+
"""Get end video duration in seconds."""
|
|
179
|
+
if self._style_params and 'end' in self._style_params:
|
|
180
|
+
return self._style_params['end'].get('video_duration', 5)
|
|
181
|
+
return 5
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
async def load_style_config(job, storage: StorageService, temp_dir: str) -> StyleConfig:
|
|
185
|
+
"""
|
|
186
|
+
Helper function to load style configuration for a job.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
job: Job object
|
|
190
|
+
storage: Storage service
|
|
191
|
+
temp_dir: Temporary directory
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
Loaded StyleConfig instance
|
|
195
|
+
"""
|
|
196
|
+
config = StyleConfig(job, storage, temp_dir)
|
|
197
|
+
await config.load()
|
|
198
|
+
return config
|