karaoke-gen 0.99.3__py3-none-any.whl → 0.103.1__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 (55) hide show
  1. backend/api/routes/admin.py +512 -1
  2. backend/api/routes/audio_search.py +17 -34
  3. backend/api/routes/file_upload.py +60 -84
  4. backend/api/routes/internal.py +6 -0
  5. backend/api/routes/jobs.py +11 -3
  6. backend/api/routes/rate_limits.py +428 -0
  7. backend/api/routes/review.py +13 -6
  8. backend/api/routes/tenant.py +120 -0
  9. backend/api/routes/users.py +229 -247
  10. backend/config.py +16 -0
  11. backend/exceptions.py +66 -0
  12. backend/main.py +30 -1
  13. backend/middleware/__init__.py +7 -1
  14. backend/middleware/tenant.py +192 -0
  15. backend/models/job.py +19 -3
  16. backend/models/tenant.py +208 -0
  17. backend/models/user.py +18 -0
  18. backend/services/email_service.py +253 -6
  19. backend/services/email_validation_service.py +646 -0
  20. backend/services/firestore_service.py +27 -0
  21. backend/services/job_defaults_service.py +113 -0
  22. backend/services/job_manager.py +73 -3
  23. backend/services/rate_limit_service.py +641 -0
  24. backend/services/stripe_service.py +61 -35
  25. backend/services/tenant_service.py +285 -0
  26. backend/services/user_service.py +85 -7
  27. backend/tests/conftest.py +7 -1
  28. backend/tests/emulator/test_made_for_you_integration.py +167 -0
  29. backend/tests/test_admin_job_files.py +337 -0
  30. backend/tests/test_admin_job_reset.py +384 -0
  31. backend/tests/test_admin_job_update.py +326 -0
  32. backend/tests/test_audio_search.py +12 -8
  33. backend/tests/test_email_service.py +233 -0
  34. backend/tests/test_email_validation_service.py +298 -0
  35. backend/tests/test_file_upload.py +8 -6
  36. backend/tests/test_impersonation.py +223 -0
  37. backend/tests/test_job_creation_regression.py +4 -0
  38. backend/tests/test_job_manager.py +146 -1
  39. backend/tests/test_made_for_you.py +2088 -0
  40. backend/tests/test_models.py +139 -0
  41. backend/tests/test_rate_limit_service.py +396 -0
  42. backend/tests/test_rate_limits_api.py +392 -0
  43. backend/tests/test_tenant_api.py +350 -0
  44. backend/tests/test_tenant_middleware.py +345 -0
  45. backend/tests/test_tenant_models.py +406 -0
  46. backend/tests/test_tenant_service.py +418 -0
  47. backend/workers/video_worker.py +8 -3
  48. backend/workers/video_worker_orchestrator.py +26 -0
  49. {karaoke_gen-0.99.3.dist-info → karaoke_gen-0.103.1.dist-info}/METADATA +1 -1
  50. {karaoke_gen-0.99.3.dist-info → karaoke_gen-0.103.1.dist-info}/RECORD +55 -33
  51. lyrics_transcriber/frontend/src/api.ts +13 -5
  52. lyrics_transcriber/frontend/src/components/PreviewVideoSection.tsx +90 -57
  53. {karaoke_gen-0.99.3.dist-info → karaoke_gen-0.103.1.dist-info}/WHEEL +0 -0
  54. {karaoke_gen-0.99.3.dist-info → karaoke_gen-0.103.1.dist-info}/entry_points.txt +0 -0
  55. {karaoke_gen-0.99.3.dist-info → karaoke_gen-0.103.1.dist-info}/licenses/LICENSE +0 -0
@@ -7,25 +7,30 @@ backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  backend/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  backend/api/dependencies.py,sha256=-61nHBhiihUDSVMQd3VuHLP7uvKrUbm1y-j9RmV6_zc,16871
9
9
  backend/api/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- backend/api/routes/admin.py,sha256=r9Q7cOnDJjLnQVQ5ql3S6eUOXiVss9hEanHMz6I0Mp4,30499
11
- backend/api/routes/audio_search.py,sha256=r8VPlyA40DUoFPcvNVM_p4faJsjv_Ta_qsY7PhvAzfw,39678
10
+ backend/api/routes/admin.py,sha256=GI4ANzshBUfAzMdRH3M8cUBnzsCbrL1owRXmIY5HK8A,46506
11
+ backend/api/routes/audio_search.py,sha256=QxV3kIm_QYGFzrEdv0nrDIsC-X8ms-3ldOyvMwJ93RM,39267
12
12
  backend/api/routes/auth.py,sha256=G1U2KwS3uqBJpgvg2PIe_mZOWCJKPFhhewrmKbW3Z_s,11531
13
- backend/api/routes/file_upload.py,sha256=GQ_m1ZQxFOxxkrjPY6a-9K3jvBC-Jwo_1mRYjZ6cxic,94156
13
+ backend/api/routes/file_upload.py,sha256=dGLWC7n3g9bUxwZ1UNxhW4gCEF-sogcIxYP0vByI-e4,93539
14
14
  backend/api/routes/health.py,sha256=iZlhJpmz4vminUy_qrzkyk_1tgG1gmITz4jEWaCWJnM,14010
15
- backend/api/routes/internal.py,sha256=N_Fv0hYQ9gleYNehjHaZb1OKzM78PXDbcqTmHasll2w,15276
16
- backend/api/routes/jobs.py,sha256=L0Aot-BEgOlNv-_AqEVIkO5Uv4BTP5gjmBvPzjWmlR8,60866
17
- backend/api/routes/review.py,sha256=hEvLUcb07DWcBc6E4fTa91zam3Z_a-x2vIvLP_OKR9o,28256
15
+ backend/api/routes/internal.py,sha256=yqzd5V8xGJQ_vTZL85vKIMwmBXf1MIp1nhder-kQEuA,15683
16
+ backend/api/routes/jobs.py,sha256=FBf5_YojNMFamd51lOd3MDdevfOZefGTyMrtZ9Q8BSU,61241
17
+ backend/api/routes/rate_limits.py,sha256=lda7gwQdT9-U80XKsRiXkdYtB1HfpSfH5EskbB1kCQI,13806
18
+ backend/api/routes/review.py,sha256=BiaXZs-NXl7AVzGiwBzIhzm60fUslcQagSw4XuUByhU,28842
19
+ backend/api/routes/tenant.py,sha256=sM0WVXWGKJeyBNMbPDnAKOD9-SkJBmH4RkMXVWz4dlM,4038
18
20
  backend/api/routes/themes.py,sha256=_fPZg9N2KN-yyr1YR2vAy8FIm8PqVowboQ4WEpFTYiQ,4721
19
- backend/api/routes/users.py,sha256=9ffodZUGzxjoHXLQdOZ-PLEqK0k-wd4zK4xp_GD2wZk,56781
20
- backend/config.py,sha256=-HsMaacaKuRftYXUXZJr8GBHPdmacFbrNnFDMk7DHNI,8187
21
- backend/main.py,sha256=xYxdM9GT0vLVPmyXGgoa0_BW1JQMGEX5m7lXm_xYnaw,5666
22
- backend/middleware/__init__.py,sha256=lUSMQqQc4UxPazrE1XmyNNEvTKRk7tddAdFmxbTzz7M,157
21
+ backend/api/routes/users.py,sha256=9RSZyQPBF2Zx8rYMp6cJZoZ4zQ2vskcW90lFx4FSegA,55339
22
+ backend/config.py,sha256=Nb0-l0w59ZpWk_SXpLuqCm5ccUAU-ycEtENdv6wl74k,9293
23
+ backend/exceptions.py,sha256=tKu1YeAj0fmZsmGU_ZebHol-JqaGrGfauom8_DCrVys,1944
24
+ backend/main.py,sha256=C-eAFYUPsrO9W5y17AnVlIz_iRZiAz8XBQ4l-o1IiJY,6782
25
+ backend/middleware/__init__.py,sha256=usnVRHqfGW56bWJFqaIXz49pSW91uyciBfwO7ANCpIk,369
23
26
  backend/middleware/audit_logging.py,sha256=oGdgbfH_M_3hIMAGrS5HpRvri2jjLxGFnFuA6IiU9BU,4170
27
+ backend/middleware/tenant.py,sha256=a-HEAhyvMUC4uFF6VptaNOO9O6YP64-ZoUitppl79PQ,6373
24
28
  backend/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- backend/models/job.py,sha256=Aw5pl6uwJpvnqr61HIKmxMB4h7moX4DqcyRoR46zRzw,24683
29
+ backend/models/job.py,sha256=B1Q12F6448okCOkmLmpBnlwGIKi16TqBjVkRttTmqi0,25663
26
30
  backend/models/requests.py,sha256=tCX7ss4to3rKAR_Wu92CZ8uPqNb2nnmCp1XepD4VR5s,4152
31
+ backend/models/tenant.py,sha256=rhj6n7bsX8ClstoHQKCVcLWALI31l5Tepcf_N8IXDdM,7403
27
32
  backend/models/theme.py,sha256=cfNSHIigoAV4P41Jku6Sa1okHSRhUHjFpl1XBVF3kCY,4628
28
- backend/models/user.py,sha256=5kUqfAMQU26DjCvCgjyoP0f07QbOypAnSgpuGhGcMg0,7377
33
+ backend/models/user.py,sha256=2Dl81Sa8_c0cuPJ3uddsLSOAN40mtv-5aUETtFZZK8c,8022
29
34
  backend/models/worker_log.py,sha256=QDgpdRarm00N1TdFoGhKJxZjP9GmiMjrTJb6msw7pHA,5547
30
35
  backend/pyproject.toml,sha256=LAvEXxQSRI94XQcwpBmuSoEu36341HOu53iigsN6dVs,577
31
36
  backend/quick-check.sh,sha256=PUvH0wXaGzWrgWwwJG5M4Bxxt3vVA4mmdEdL6VepVHY,2382
@@ -39,18 +44,20 @@ backend/services/auth_service.py,sha256=rEpb4O9YSTOQaEoP2XXKXRpppWI5sG10AsueQSVc
39
44
  backend/services/credential_manager.py,sha256=VA--PwvL3gboJ21orQb7MIUiovX8n66FohD6w84exX8,31682
40
45
  backend/services/discord_service.py,sha256=LnEasOgaSRlmebDKsVT2yKCdWNDmskUToP3o2wPmdus,5082
41
46
  backend/services/dropbox_service.py,sha256=R47MUKCqK2BEXXmQxMLG6zkPWw02htFoES9q9xiaYAw,10717
42
- backend/services/email_service.py,sha256=fxwcL-n6ZRGLQ7SHXhxUQK1MkprtgE3GcuL5ulUR-90,44699
47
+ backend/services/email_service.py,sha256=gpufwXhNWmdElpWCmKrTLtm2LB8S-0Y5wcyJ3n1i6Jg,52868
48
+ backend/services/email_validation_service.py,sha256=xblVdzieoNTDbkB8MJLOgV_hPsHP_iwO0m36l42QmQw,19102
43
49
  backend/services/encoding_interface.py,sha256=Y8hPskDyX9DOyAD557F3-SdHjymaBkGXcoC9E_OW7SE,15825
44
50
  backend/services/encoding_service.py,sha256=XAX4hyL2wIHdpBCTc8yglcjVJboZxRVAjc07lUTxgFg,18025
45
- backend/services/firestore_service.py,sha256=XOuXUNd91eVeyEx82uh-A-WMwcyUa2HVxqTfYnGPw-Q,18512
51
+ backend/services/firestore_service.py,sha256=SQWwIelerFOADRG_ZMVqk8zPPR0-utwWhGXwkjtaPIo,19416
46
52
  backend/services/flacfetch_client.py,sha256=zj4VToKamR8bShXZifLvjDmUVa1HHvDhZuaw_b7g4lU,19901
47
53
  backend/services/gce_encoding/README.md,sha256=frTFrp7-ugFAvUd_K9EgE4ud8Xu4Qf1V7BNirQn6qJk,2515
48
54
  backend/services/gce_encoding/__init__.py,sha256=d2H6zM207NSc5afnfgkd3kwOXUu2gFBYjxBSS7tvX_s,571
49
55
  backend/services/gce_encoding/main.py,sha256=2A0Bd3zYzbV66ikShB3avpqfNoDFBxr8Ja6c36qJhRI,22203
50
56
  backend/services/gce_encoding/requirements.txt,sha256=-hW5ot-PnVoKkxrpY3yV6l68wx7AvzgnLYAWEgDGWNc,408
51
57
  backend/services/gdrive_service.py,sha256=3JTXmPBuxpKopAbWDrh6YhqR5L9BLop1R7caXBnIk2A,13266
58
+ backend/services/job_defaults_service.py,sha256=GHWkBeEsx97K86ffAdkDvw8PunpyIFuT2_ezgEoGbBM,4446
52
59
  backend/services/job_logging.py,sha256=theCkAlwMbqyqAbu7vCCRpVRscaIpkam3UrCs_4Yi1g,8052
53
- backend/services/job_manager.py,sha256=y7TCwJal7rPJm4QRuOEviv_SE9RvDiNGHz33MSgGY3M,31701
60
+ backend/services/job_manager.py,sha256=8kmGIsYUg40HO9CG_zxdLqpOgRZno39O55kAlSAeNL0,35192
54
61
  backend/services/job_notification_service.py,sha256=ywGJUMUDqV23OSDsugOUufpXO6N_24bM9YVaPp8bOk4,9557
55
62
  backend/services/langfuse_preloader.py,sha256=t-Rt_ThjZm4K8W3jlyLn2H3cEy7KNUlhrvOPmdg-gYM,3100
56
63
  backend/services/local_encoding_service.py,sha256=Q6yK2-QL9tHM_pUBoxdyfT7ln2L5xMx82JB2nC5OfNQ,20680
@@ -59,35 +66,41 @@ backend/services/lyrics_cache_service.py,sha256=53EIZuDs5jIKr6QiOhIKJjE2mx1Jd1_x
59
66
  backend/services/metrics.py,sha256=hlEeLG4jOR1i_QbWaNQthoko9CSpe-Zn_LHJ2huEFeY,12728
60
67
  backend/services/nltk_preloader.py,sha256=TZFghQrpDTi6COcW_rkjL15SlzdRNvPmrdy690fq0hw,3579
61
68
  backend/services/packaging_service.py,sha256=MUuBk0jtG3vGQhuOWbDv9u1uIMwbBC4NknLpJYFcWhs,10259
69
+ backend/services/rate_limit_service.py,sha256=KuLF9oWO44v-0zKYL3bFBwVq-_HejsQKbc0ojKJ1JSw,22907
62
70
  backend/services/rclone_service.py,sha256=Q6wRAjlBiMMh9FBbbFRp4SHK1ljOQBed9zUJaJgAuhU,3646
63
71
  backend/services/spacy_preloader.py,sha256=rpsMZB0CQWcoXjq8nyZCwJBkyjGheKaCFrfhxCOln5w,1836
64
72
  backend/services/storage_service.py,sha256=gA7Snz1pihzYpRKZjEZx3eDwyMUBezl3ccLuBdpTwE4,8573
65
- backend/services/stripe_service.py,sha256=154TbTuysOiuUFKEmIG3RFZYKYEYhLJR2Weyb4xAhxs,13243
73
+ backend/services/stripe_service.py,sha256=YPBVE2_ZeBYWklcFCTGoRWOuO1UTI16_Un2NKAE-sqE,14825
66
74
  backend/services/structured_logging.py,sha256=daGgZUdc1xIiOdxL9-YtWHDy51hwZqd8ELpomkh2QH4,9063
67
75
  backend/services/template_service.py,sha256=5CdSxBGhdBtxIUz24AhvltUfSWcFqZzBIxb9MjlN4YU,11212
76
+ backend/services/tenant_service.py,sha256=AlG5acJww-rpxGEQbw7eOWe1KaHLOcCn3fM95qDZMGw,9709
68
77
  backend/services/theme_service.py,sha256=6lJqMpFjmRY09CMJcW9IJ6DVPffLmwE0DnpXDUKaJ0U,17374
69
78
  backend/services/tracing.py,sha256=MNpJNMmSOw-9TRlb3dJk7pA8JTmSjAFHj9bSuyM5cOY,17210
70
- backend/services/user_service.py,sha256=TSVuIfM2rF4Acw1ic5TQ-QIjgeKU-Q8r93-PQdd4cwA,26215
79
+ backend/services/user_service.py,sha256=0_ztVqXKNH1jqKiZwqgStEfW95YowJbvYOL-eaBw2oY,29339
71
80
  backend/services/worker_service.py,sha256=WRgh3kconWYmvraEIsx6eUto2frKacauKApFU1wIEiQ,21093
72
81
  backend/services/youtube_service.py,sha256=L2jqcWkw6qIaKh4wEfX894mHaTU0m5qtgIX6TPi6uiQ,3828
73
82
  backend/services/youtube_upload_service.py,sha256=fvo4WxLQaKY_I75ViBMLk6vm87ym2ABHK0Fn_StYN6g,16694
74
83
  backend/tests/__init__.py,sha256=jTjELMqIzpgHG9dcXwwkszTAAC4Wf-c93C6D1k-toZg,44
75
- backend/tests/conftest.py,sha256=c4_jH0FIHsiKeUfo3ECPN78MlbW_IARTWwKr9RKLOSM,7843
84
+ backend/tests/conftest.py,sha256=hsUOHf3VZKX-fMorjjUY6gyTIYzdb9ICrdosYW9yAZI,8122
76
85
  backend/tests/emulator/__init__.py,sha256=yOGPU5e0JPNYyUpy-u13jW4gEfWQs3dCJxfincptaCY,156
77
86
  backend/tests/emulator/conftest.py,sha256=VXhoJ3NZg3uiLzSAsushQtozFS7Lt6lmjk7ym-k6V8o,3844
78
87
  backend/tests/emulator/test_e2e_cli_backend.py,sha256=BTrWDv4sRTeOlheZ-d4R37tZsvJ2MhdFLbDb9tjbF08,41018
79
88
  backend/tests/emulator/test_emulator_integration.py,sha256=pm_JzgA2bmjcnHmGA-mZfJhUAYwGx10jv48A2deujRs,11822
89
+ backend/tests/emulator/test_made_for_you_integration.py,sha256=EYWZrYrQdoYk4Eb8G4M7Cyzq5ncAWqeYLuG8a31EAqc,5470
80
90
  backend/tests/emulator/test_style_loading_direct.py,sha256=e-FzlCVW_-ealM9hTGa2qgpwoVRiYKrcXDWB1FjkwXc,16842
81
91
  backend/tests/emulator/test_worker_logs_direct.py,sha256=96EeaSxeNQBtDiZ9ky1-CGE6Lv6ZV3dKuoF3inHxO8A,8158
82
92
  backend/tests/emulator/test_worker_logs_subcollection.py,sha256=whwUXW_-fF-nQp2Z791PNxi0nnvlRwLo87QacF-yMUI,16834
83
93
  backend/tests/requirements-test.txt,sha256=1ixGqdsXFG0hbqUPWUjNGPlKdQgYxo1GajXOiLhs66M,193
84
94
  backend/tests/requirements.txt,sha256=1526vDy39B1ZjJ5URZtoiDGnjvwuxiD9dNrjOLd6-gA,95
85
95
  backend/tests/test_admin_email_endpoints.py,sha256=C1mOX3K4P-_QqSWa8ZSH4gtMnUJ7hqq5rOi00zSKR8g,16592
96
+ backend/tests/test_admin_job_files.py,sha256=LXeV08a4XuaipM-QFFVJKE02e83Muj-JrjtCPlgExuM,13348
97
+ backend/tests/test_admin_job_reset.py,sha256=PsM6cBPeN5d6HO4pejaOQNyTh7OHTOFNPMTPuulcZCI,14292
98
+ backend/tests/test_admin_job_update.py,sha256=19NFazBk-fU8vrKKOoJV9c7pAvskNcAhihpmdQFZNIk,12157
86
99
  backend/tests/test_api_integration.py,sha256=ps4dFoW69NCKJAWvPSr410fEILPxfQNME_YmLPdNqxo,14886
87
100
  backend/tests/test_api_routes.py,sha256=j6alBwXgtKspXxbOiDuNCCVMENk6yxdFJkakbife-rM,3193
88
101
  backend/tests/test_audio_analysis_service.py,sha256=bKIAgyxfdbUOr7atHH-WCbZcZFkWGmGOOn7IfvRF2ms,11373
89
102
  backend/tests/test_audio_editing_service.py,sha256=wXs82PRaxFQIji0CO1eKKYD2skHS4_VLK4aBnfj8CLE,15541
90
- backend/tests/test_audio_search.py,sha256=ukZjzsw7XjVM6jPoJRiLp98TDiBbdYCp22-7v0hqeMU,54285
103
+ backend/tests/test_audio_search.py,sha256=VKVqh52to01AdQp1I1sAIkHIdhSOXgk82utc-oKdheg,54505
91
104
  backend/tests/test_audio_services.py,sha256=mOF15i7IMtjM3mV-BNG0QBoMxW58cNPviEE6wka1pjQ,14607
92
105
  backend/tests/test_auth_firestore.py,sha256=2etzuL47Pu-xOtR1CpCxi075OTFsftqneHa09yNJKEk,10063
93
106
  backend/tests/test_config_extended.py,sha256=U2l9-wF28PmSllmRW5zNqRCNoYbBl3Nixb2SrmfGUOA,2475
@@ -96,24 +109,29 @@ backend/tests/test_dependencies.py,sha256=kWiOQEMQWFPIbAM8FEMYI921n3dLOQFJ7HXyRH
96
109
  backend/tests/test_discord_service.py,sha256=OU5mVzjukFtJd_H5e_HxJqSsf78B0TrNfjxhwypbV34,8902
97
110
  backend/tests/test_distribution_services.py,sha256=8oB2vMq5T_4rvOs6BURoLLTQiDf0kUJ-jF8dzJzDYRk,33699
98
111
  backend/tests/test_dropbox_service.py,sha256=nDN1NjiCMS_f1bICWfe3maqbKT5FbhNuKCb1zjyjKq0,19198
99
- backend/tests/test_email_service.py,sha256=jj4EQwbJ2iOiL_-jFR-2t9YJv7KnGP99HcFjZHAq2-I,16754
112
+ backend/tests/test_email_service.py,sha256=u1VSTBCZl7m3GYR-vKV84tu3q7zhMuIhNA5a4OiCDlE,25290
113
+ backend/tests/test_email_validation_service.py,sha256=AGtusq5fUiNQz4gpiT8DXmroNPD5bcYij0R787NDooE,12472
100
114
  backend/tests/test_emulator_integration.py,sha256=m4teGnKLBKQNe9UdFi0-0iR_unnotWs07VWgSd_atuw,10387
101
115
  backend/tests/test_encoding_interface.py,sha256=7q9mKX4QG8-bfkxQgZkmeirK_ynfL88UTbgWS0f097U,14609
102
- backend/tests/test_file_upload.py,sha256=mWEIVj6cK6ZzKf4X0D0JhSk6pmJeCO0dOawV2GED7tc,68038
116
+ backend/tests/test_file_upload.py,sha256=seFF8viLNTEqiuChRolD5gIiMevhhkawvcXMFPcmCHw,68226
103
117
  backend/tests/test_flacfetch_client.py,sha256=ZquMDLFVgORr9GoNfybOV9Z3eruborRgCvBRY6l-V8A,22614
104
118
  backend/tests/test_gdrive_service.py,sha256=fh02KPaFqLEWfPaDQvSehn6r6RLq0bgt6MdXenF1kxA,19762
119
+ backend/tests/test_impersonation.py,sha256=vuCJaYmPOObLvFWuzxRvqadeRtFXgsbQxyOKd4TaxHg,9087
105
120
  backend/tests/test_instrumental_api.py,sha256=2eWaoEAYVY02HZgY4esn5echuWGv_sznoO6FYWIgTbQ,17210
106
121
  backend/tests/test_internal_api.py,sha256=qMGSDCkYd5OY_Z85vQu10xjqJn1JtaQcaKSnSBpVijw,12980
107
- backend/tests/test_job_creation_regression.py,sha256=C1KgyNhpJzchl10QK8trfmACs2BrEwYd-WK1YMMS-7I,22602
108
- backend/tests/test_job_manager.py,sha256=Y5De6L0BvK4yk6D4w-pDBKBk2R7w89SfSyUz5krgphE,13187
122
+ backend/tests/test_job_creation_regression.py,sha256=ydd97391bMq40MSTlTlvMn3_zjtFDWzSQLjYczoqR_U,22826
123
+ backend/tests/test_job_manager.py,sha256=9SvwVkgN5VoyaJH-vzVN3VRoXpMJf4YAluLmspZrhzs,18862
109
124
  backend/tests/test_job_manager_notifications.py,sha256=WlzXXxTCmHHCrD4XWu2j2fDYODlHGKThOQpZQeyhPXM,12996
110
125
  backend/tests/test_job_notification_service.py,sha256=YbXqCWbsK8O5WICItb3VCrEY8qKqoJ3NBEZtwCs7AYM,17892
111
126
  backend/tests/test_jobs_api.py,sha256=z3pGTawTpt75a1bQ5x4ynw3pTlNihLA6vqktTc6mBAU,11092
112
127
  backend/tests/test_local_encoding_service.py,sha256=TbBaFOB-8Re09G-qXIQCl8mS9WlQMFNQF01V64IekyI,14638
113
128
  backend/tests/test_local_preview_encoding_service.py,sha256=VwxpcAjDdYaVauSsrJ609U575VWRZbLsXew8BqBXpJY,20228
129
+ backend/tests/test_made_for_you.py,sha256=Eanhp4v_dOgpQTxKQPHxHdLG4XiJ-kruVPWkR0iUnsg,87806
114
130
  backend/tests/test_main.py,sha256=BvzcadLUV0SEUO1ViKm0djgy_TEKXm8PPvgfcCCEJAY,3348
115
- backend/tests/test_models.py,sha256=3qmuI-GmOXzhPTSLO2jlAl9E1hqtT057SkH4t4Dbchk,34435
131
+ backend/tests/test_models.py,sha256=buUjtm3TaiIff58SCpG0Du1Bnm-S9X8LyaW64zEhb4U,39606
116
132
  backend/tests/test_packaging_service.py,sha256=v4Bj8R61Fx0Kng6RoTj3SRN9jmxow5qCVtTJstTWNfE,13916
133
+ backend/tests/test_rate_limit_service.py,sha256=1G-kskzv-5hcG_px78vZ9_J_X2Jj21s7l_wuUOWAOkY,16905
134
+ backend/tests/test_rate_limits_api.py,sha256=eFtdMzDMxhvI3MPhm60nRIWh-MVFCdpG0e-FwIVLn9I,14822
117
135
  backend/tests/test_requests.py,sha256=DI2IG67hHk2rhuzUfz_QNJCLRTy1NZPLsnSdZbIfPA8,6817
118
136
  backend/tests/test_routes_jobs.py,sha256=iqOZ93ACKpizSzLEJUx5hIo0vkKe2oIT7s7iZqQUJaE,11258
119
137
  backend/tests/test_routes_review.py,sha256=ENo6_wFUDcyXZhRy_NBqajan9dvqV_7f1rIQ7LLLS-U,14334
@@ -123,6 +141,10 @@ backend/tests/test_spacy_preloader.py,sha256=uWpkrOPUOOcW1-fWClKMKVhXHGk30FXq537
123
141
  backend/tests/test_storage_service.py,sha256=gorn3aFwKSr8lihxcG7kza7fYvDsTvxJhOxzuTtPK_o,19069
124
142
  backend/tests/test_style_upload.py,sha256=8G2dGgvyMGXsh1jk8PcGpTlSdBQAlHn13kpZcKn6rTY,10491
125
143
  backend/tests/test_template_service.py,sha256=BKURQ1M-hXXgdBl9LqhPQKfpItWOYDRBSt1y5FXQzaM,10431
144
+ backend/tests/test_tenant_api.py,sha256=P4395WYGldJIX7hYcbk96bIDW0Hogcj2McUG6iApNmc,13441
145
+ backend/tests/test_tenant_middleware.py,sha256=0WflieACxT1c_k-C2-yQ5sap_xm6z6w3p3ys09B8iMA,12577
146
+ backend/tests/test_tenant_models.py,sha256=NwNz197f5IPuhNU8f0d2OGBTeE7y7K2oulHfOJRo1EQ,15228
147
+ backend/tests/test_tenant_service.py,sha256=39bL1B0poa1LyxHDwFdQgSVu-QJ96rpe7Occ_ItC1Zc,16494
126
148
  backend/tests/test_theme_service.py,sha256=I_BrXjDAwmqGhxClJA8kE9FDYdQmtdYQINjIwyI3NTs,20454
127
149
  backend/tests/test_unicode_sanitization.py,sha256=M4QfJmHGZ8WrhTfg7QPljPj2kUkN5QUNThtofzZhQiE,22930
128
150
  backend/tests/test_upload_api.py,sha256=oWXPunON3pSTEnE3oE9vIQk63GC6lKM5RgTmaKKQths,10127
@@ -144,8 +166,8 @@ backend/workers/lyrics_worker.py,sha256=nsy90pb0BPAl_lbZ0E7d7jIclcXK7W8d9RxxEdJa
144
166
  backend/workers/render_video_worker.py,sha256=L6-VCxSBY6MbXBBm0-wu_DXxcIWKfW6ynTv9K03WCjY,25163
145
167
  backend/workers/screens_worker.py,sha256=vCS7j4dQRQ_tsWNhz-XH5nau7kGyUSzSp-dzyZpeJEo,21402
146
168
  backend/workers/style_helper.py,sha256=7-PM79dAUAZHTj-bnATy43ImqNdl_00E9pm94CYg1BM,6906
147
- backend/workers/video_worker.py,sha256=49Q7D3bNg38iJk26q2k8y3v-oUscUtE50qaUymlFQbk,55292
148
- backend/workers/video_worker_orchestrator.py,sha256=NInZjFwztqcYneuxrkDqEFWV7z5BzGlaaoJxj812KA4,27510
169
+ backend/workers/video_worker.py,sha256=5r3PcYdoca16fjZtFzCwfKm-G7QjL98ZLMhw6qGVDNE,55670
170
+ backend/workers/video_worker_orchestrator.py,sha256=kmkEFUVlcWxuGXXwGmhV8A7NFfu4KfdO2LEhxSYc3RA,28779
149
171
  backend/workers/worker_logging.py,sha256=nlbGsjDjdkv28Fm-95vKBumy6P47dGiNN5Zf3r0A480,9928
150
172
  karaoke_gen/__init__.py,sha256=wHpDbURJxmJAMNZ0uQjISv5MIT7KD9RWYi15xlYgEhU,1351
151
173
  karaoke_gen/audio_fetcher.py,sha256=EuMSO_wG0z0ldfQQ_xGC8kdoUCDB1Rr2_IuWIZ218lA,71380
@@ -287,7 +309,7 @@ lyrics_transcriber/frontend/public/favicon.ico,sha256=ZK7QvdBuZp0QxPkluCW4IKxfle
287
309
  lyrics_transcriber/frontend/public/nomad-karaoke-logo.png,sha256=jTTBFXV6hGJGolZYQ-dIjgQQbMsehk5XGtsllhLrdzg,212641
288
310
  lyrics_transcriber/frontend/public/nomad-karaoke-logo.svg,sha256=0LOH346_a-1JeYquMWd1v2A3XMN8zLDBeujfWAOeNYk,9185
289
311
  lyrics_transcriber/frontend/src/App.tsx,sha256=STVmqN3xtXambV_5X4M0MNuwYjARHBQfn1cuCqxNGkw,7979
290
- lyrics_transcriber/frontend/src/api.ts,sha256=GcjbOrlU7EdUpZ7MUPFqE1rtH-ckdw8wHtgyQxWateY,8648
312
+ lyrics_transcriber/frontend/src/api.ts,sha256=MDTKq1rZUXKdRHb1YFDKaGuFOK-LO2wC3yvladlWjeY,9085
291
313
  lyrics_transcriber/frontend/src/components/AIFeedbackModal.tsx,sha256=YvJlBP-3udqrOmvwKuMR7FxfIozZq5pVfTYvmhzbnHo,5602
292
314
  lyrics_transcriber/frontend/src/components/AddLyricsModal.tsx,sha256=ubJwQewryjUrXwpBkITQNu4POhoUtDbNA93cqa-yJKY,3416
293
315
  lyrics_transcriber/frontend/src/components/AgenticCorrectionMetrics.tsx,sha256=Yg6FG0LtrneRfAYeBu3crt_RdN-_o7FojtYhDMDKi0o,8595
@@ -314,7 +336,7 @@ lyrics_transcriber/frontend/src/components/MetricsDashboard.tsx,sha256=33XpyHj0s
314
336
  lyrics_transcriber/frontend/src/components/ModeSelectionModal.tsx,sha256=eihGI49r9tKq-AaEtnmVrbiBOoJApWvabaZW4ydmg-4,5302
315
337
  lyrics_transcriber/frontend/src/components/ModeSelector.tsx,sha256=HnBAK_gFgNBJLtMC_ESMVdUapDjmqmoLX8pQeyHfpOw,2651
316
338
  lyrics_transcriber/frontend/src/components/ModelSelector.tsx,sha256=lfG_B5VAzSfrU0FqJl8XptN6DVt2kSljU96HMXo8mf4,559
317
- lyrics_transcriber/frontend/src/components/PreviewVideoSection.tsx,sha256=59ZhG5XsxUZ_dkK8BjTQhYmYP5Wv86uRR-xtuwFRK8c,5582
339
+ lyrics_transcriber/frontend/src/components/PreviewVideoSection.tsx,sha256=zKR_S1AyYAEmr1hnr2IN14mw1igpYbJB12HjaUrXbH4,6803
318
340
  lyrics_transcriber/frontend/src/components/ReferenceView.tsx,sha256=a3CFpbJ8M-kFV3K79xyuo-sfOoC9He_IuXwhIcAOImo,10510
319
341
  lyrics_transcriber/frontend/src/components/ReplaceAllLyricsModal.tsx,sha256=pVlqHrSloxXZV_Ib8cbk1invF7WA3uge5b7pnFPe9Pc,12290
320
342
  lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx,sha256=VQg_gBFViAxQu9Z75o6rOsvmH5DZBjKq9FkU8aB_7mI,13790
@@ -436,8 +458,8 @@ lyrics_transcriber/transcribers/whisper.py,sha256=YcCB1ic9H6zL1GS0jD0emu8-qlcH0Q
436
458
  lyrics_transcriber/types.py,sha256=UJjaxhVd2o14AG4G8ToU598p0JeYdiTFjpG38jGCoYQ,27917
437
459
  lyrics_transcriber/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
438
460
  lyrics_transcriber/utils/word_utils.py,sha256=-cMGpj9UV4F6IsoDKAV2i1aiqSO8eI91HMAm_igtVMk,958
439
- karaoke_gen-0.99.3.dist-info/METADATA,sha256=unsN1sCERd0RAJ-G2KFKw1UI_1sUpM-ZG6Sl3FODVJ8,23115
440
- karaoke_gen-0.99.3.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
441
- karaoke_gen-0.99.3.dist-info/entry_points.txt,sha256=xIyLe7K84ZyjO8L0_AmNectz93QjGSs5AkApMtlAd4g,160
442
- karaoke_gen-0.99.3.dist-info/licenses/LICENSE,sha256=81R_4XwMZDODHD7JcZeUR8IiCU8AD7Ajl6bmwR9tYDk,1074
443
- karaoke_gen-0.99.3.dist-info/RECORD,,
461
+ karaoke_gen-0.103.1.dist-info/METADATA,sha256=EMLjE5yyOq75ZCqVMPagcYppdJYukM-wmX9hgQe56Mg,23116
462
+ karaoke_gen-0.103.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
463
+ karaoke_gen-0.103.1.dist-info/entry_points.txt,sha256=xIyLe7K84ZyjO8L0_AmNectz93QjGSs5AkApMtlAd4g,160
464
+ karaoke_gen-0.103.1.dist-info/licenses/LICENSE,sha256=81R_4XwMZDODHD7JcZeUR8IiCU8AD7Ajl6bmwR9tYDk,1074
465
+ karaoke_gen-0.103.1.dist-info/RECORD,,
@@ -6,7 +6,7 @@ export interface ApiClient {
6
6
  getCorrectionData: () => Promise<CorrectionData>;
7
7
  submitCorrections: (data: CorrectionData) => Promise<void>;
8
8
  getAudioUrl: (audioHash: string) => string;
9
- generatePreviewVideo: (data: CorrectionData) => Promise<PreviewVideoResponse>;
9
+ generatePreviewVideo: (data: CorrectionData, options?: PreviewOptions) => Promise<PreviewVideoResponse>;
10
10
  getPreviewVideoUrl: (previewHash: string) => string;
11
11
  updateHandlers: (enabledHandlers: string[]) => Promise<CorrectionData>;
12
12
  isUpdatingHandlers?: boolean;
@@ -21,6 +21,11 @@ interface CorrectionUpdate {
21
21
  corrected_segments: CorrectionData['corrected_segments'];
22
22
  }
23
23
 
24
+ // Add interface for preview generation options
25
+ export interface PreviewOptions {
26
+ use_background_image?: boolean;
27
+ }
28
+
24
29
  // Add new interface for preview response
25
30
  interface PreviewVideoResponse {
26
31
  status: "success" | "error";
@@ -96,11 +101,13 @@ export class LiveApiClient implements ApiClient {
96
101
  return this.buildUrl(`/audio/${audioHash}`)
97
102
  }
98
103
 
99
- async generatePreviewVideo(data: CorrectionData): Promise<PreviewVideoResponse> {
104
+ async generatePreviewVideo(data: CorrectionData, options?: PreviewOptions): Promise<PreviewVideoResponse> {
100
105
  // Extract only the needed fields, just like in submitCorrections
101
- const updatePayload: CorrectionUpdate = {
106
+ // Include use_background_image option (defaults to false for fast black background)
107
+ const updatePayload = {
102
108
  corrections: data.corrections,
103
- corrected_segments: data.corrected_segments
109
+ corrected_segments: data.corrected_segments,
110
+ use_background_image: options?.use_background_image ?? false,
104
111
  };
105
112
 
106
113
  const response = await fetch(this.buildUrl('/preview-video'), {
@@ -224,7 +231,8 @@ export class FileOnlyClient implements ApiClient {
224
231
  throw new Error('Not supported in file-only mode');
225
232
  }
226
233
 
227
- async generatePreviewVideo(): Promise<PreviewVideoResponse> {
234
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
235
+ async generatePreviewVideo(_data: CorrectionData, _options?: PreviewOptions): Promise<PreviewVideoResponse> {
228
236
  throw new Error('Not supported in file-only mode');
229
237
  }
230
238
 
@@ -1,5 +1,5 @@
1
- import { Box, Typography, CircularProgress, Alert, Button } from '@mui/material'
2
- import { useState, useEffect } from 'react'
1
+ import { Box, Typography, CircularProgress, Alert, Button, FormControlLabel, Checkbox } from '@mui/material'
2
+ import { useState, useEffect, useCallback } from 'react'
3
3
  import { ApiClient } from '../api'
4
4
  import { CorrectionData } from '../types'
5
5
  import { applyOffsetToCorrectionData } from './shared/utils/timingUtils'
@@ -25,75 +25,108 @@ export default function PreviewVideoSection({
25
25
  error?: string;
26
26
  }>({ status: 'loading' });
27
27
 
28
- // Generate preview when modal opens
29
- useEffect(() => {
30
- if (isModalOpen && apiClient) {
31
- const generatePreview = async () => {
32
- setPreviewState({ status: 'loading' });
33
- try {
34
- // Debug logging for timing offset
35
- console.log(`[TIMING] PreviewVideoSection - Current timing offset: ${timingOffsetMs}ms`);
36
-
37
- // Apply timing offset if needed
38
- const dataToPreview = timingOffsetMs !== 0
39
- ? applyOffsetToCorrectionData(updatedData, timingOffsetMs)
40
- : updatedData;
41
-
42
- // Log some example timestamps after potential offset application
43
- if (dataToPreview.corrected_segments.length > 0) {
44
- const firstSegment = dataToPreview.corrected_segments[0];
45
- console.log(`[TIMING] Preview - First segment id: ${firstSegment.id}`);
46
- console.log(`[TIMING] - start_time: ${firstSegment.start_time}, end_time: ${firstSegment.end_time}`);
47
-
48
- if (firstSegment.words.length > 0) {
49
- const firstWord = firstSegment.words[0];
50
- console.log(`[TIMING] - first word "${firstWord.text}" time: ${firstWord.start_time} -> ${firstWord.end_time}`);
51
- }
52
- }
53
-
54
- const response = await apiClient.generatePreviewVideo(dataToPreview);
55
-
56
- if (response.status === 'error') {
57
- setPreviewState({
58
- status: 'error',
59
- error: response.message || 'Failed to generate preview video'
60
- });
61
- return;
62
- }
28
+ // Toggle for rendering with theme background image (slower) vs black background (faster)
29
+ const [useBackgroundImage, setUseBackgroundImage] = useState(false);
63
30
 
64
- if (!response.preview_hash) {
65
- setPreviewState({
66
- status: 'error',
67
- error: 'No preview hash received from server'
68
- });
69
- return;
70
- }
31
+ // Memoized function to generate preview
32
+ const generatePreview = useCallback(async () => {
33
+ if (!apiClient) return;
34
+
35
+ setPreviewState({ status: 'loading' });
36
+ try {
37
+ // Debug logging for timing offset
38
+ console.log(`[TIMING] PreviewVideoSection - Current timing offset: ${timingOffsetMs}ms`);
39
+ console.log(`[PREVIEW] Using background image: ${useBackgroundImage}`);
40
+
41
+ // Apply timing offset if needed
42
+ const dataToPreview = timingOffsetMs !== 0
43
+ ? applyOffsetToCorrectionData(updatedData, timingOffsetMs)
44
+ : updatedData;
71
45
 
72
- const videoUrl = apiClient.getPreviewVideoUrl(response.preview_hash);
73
- setPreviewState({
74
- status: 'ready',
75
- videoUrl
76
- });
77
- } catch (error) {
78
- setPreviewState({
79
- status: 'error',
80
- error: (error as Error).message || 'Failed to generate preview video'
81
- });
46
+ // Log some example timestamps after potential offset application
47
+ if (dataToPreview.corrected_segments.length > 0) {
48
+ const firstSegment = dataToPreview.corrected_segments[0];
49
+ console.log(`[TIMING] Preview - First segment id: ${firstSegment.id}`);
50
+ console.log(`[TIMING] - start_time: ${firstSegment.start_time}, end_time: ${firstSegment.end_time}`);
51
+
52
+ if (firstSegment.words.length > 0) {
53
+ const firstWord = firstSegment.words[0];
54
+ console.log(`[TIMING] - first word "${firstWord.text}" time: ${firstWord.start_time} -> ${firstWord.end_time}`);
82
55
  }
83
- };
56
+ }
57
+
58
+ const response = await apiClient.generatePreviewVideo(dataToPreview, {
59
+ use_background_image: useBackgroundImage
60
+ });
84
61
 
62
+ if (response.status === 'error') {
63
+ setPreviewState({
64
+ status: 'error',
65
+ error: response.message || 'Failed to generate preview video'
66
+ });
67
+ return;
68
+ }
69
+
70
+ if (!response.preview_hash) {
71
+ setPreviewState({
72
+ status: 'error',
73
+ error: 'No preview hash received from server'
74
+ });
75
+ return;
76
+ }
77
+
78
+ const videoUrl = apiClient.getPreviewVideoUrl(response.preview_hash);
79
+ setPreviewState({
80
+ status: 'ready',
81
+ videoUrl
82
+ });
83
+ } catch (error) {
84
+ setPreviewState({
85
+ status: 'error',
86
+ error: (error as Error).message || 'Failed to generate preview video'
87
+ });
88
+ }
89
+ }, [apiClient, updatedData, timingOffsetMs, useBackgroundImage]);
90
+
91
+ // Generate preview when modal opens or when background toggle changes
92
+ useEffect(() => {
93
+ if (isModalOpen && apiClient) {
85
94
  generatePreview();
86
95
  }
87
- }, [isModalOpen, apiClient, updatedData, timingOffsetMs]);
96
+ }, [isModalOpen, apiClient, generatePreview]);
88
97
 
89
98
  if (!apiClient) return null;
90
99
 
91
100
  return (
92
101
  <Box sx={{ mb: 2 }}>
102
+ {/* Background image toggle */}
103
+ <Box sx={{ px: 2, pt: 2, pb: 1 }}>
104
+ <FormControlLabel
105
+ control={
106
+ <Checkbox
107
+ checked={useBackgroundImage}
108
+ onChange={(e) => setUseBackgroundImage(e.target.checked)}
109
+ disabled={previewState.status === 'loading'}
110
+ size="small"
111
+ />
112
+ }
113
+ label={
114
+ <Box>
115
+ <Typography variant="body2" component="span">
116
+ Render with theme background
117
+ </Typography>
118
+ <Typography variant="caption" color="text.secondary" display="block">
119
+ Preview uses black background for speed (~10s). Enable for theme background (~30-60s).
120
+ </Typography>
121
+ </Box>
122
+ }
123
+ />
124
+ </Box>
125
+
93
126
  {previewState.status === 'loading' && (
94
127
  <Box sx={{ display: 'flex', alignItems: 'center', gap: 2, p: 2 }}>
95
128
  <CircularProgress size={24} />
96
- <Typography>Generating preview video...</Typography>
129
+ <Typography>Generating preview video{useBackgroundImage ? ' with theme background' : ''}...</Typography>
97
130
  </Box>
98
131
  )}
99
132