openfree commited on
Commit
b8fb8e7
ยท
verified ยท
1 Parent(s): 49b3d5e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +305 -305
app.py CHANGED
@@ -2980,106 +2980,106 @@ def download_screenplay(screenplay_text: str, format_type: str, title: str,
2980
 
2981
  # Create Gradio interface
2982
  def create_interface():
2983
- """Create Gradio interface for screenplay generation"""
2984
-
2985
- css = """
2986
- .main-header {
2987
- text-align: center;
2988
- margin-bottom: 2rem;
2989
- padding: 2rem;
2990
- background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
2991
- border-radius: 10px;
2992
- color: white;
2993
- }
2994
-
2995
- .header-title {
2996
- font-size: 3rem;
2997
- margin-bottom: 1rem;
2998
- background: linear-gradient(45deg, #f39c12, #e74c3c);
2999
- -webkit-background-clip: text;
3000
- -webkit-text-fill-color: transparent;
3001
- }
3002
-
3003
- .header-description {
3004
- font-size: 1.1rem;
3005
- opacity: 0.9;
3006
- line-height: 1.6;
3007
- }
3008
-
3009
- .type-selector {
3010
- display: flex;
3011
- gap: 1rem;
3012
- margin: 1rem 0;
3013
- }
3014
-
3015
- .type-card {
3016
- flex: 1;
3017
- padding: 1rem;
3018
- border: 2px solid #ddd;
3019
- border-radius: 8px;
3020
- cursor: pointer;
3021
- transition: all 0.3s;
3022
- }
3023
-
3024
- .type-card:hover {
3025
- border-color: #f39c12;
3026
- transform: translateY(-2px);
3027
- }
3028
-
3029
- .type-card.selected {
3030
- border-color: #e74c3c;
3031
- background: #fff5f5;
3032
- }
3033
-
3034
- #stages-display {
3035
- max-height: 600px;
3036
- overflow-y: auto;
3037
- padding: 1rem;
3038
- background: #f8f9fa;
3039
- border-radius: 8px;
3040
- }
3041
-
3042
- #screenplay-output {
3043
- font-family: 'Courier New', monospace;
3044
- white-space: pre-wrap;
3045
- background: white;
3046
- padding: 2rem;
3047
- border: 1px solid #ddd;
3048
- border-radius: 8px;
3049
- max-height: 800px;
3050
- overflow-y: auto;
3051
- }
3052
-
3053
- .genre-grid {
3054
- display: grid;
3055
- grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
3056
- gap: 0.5rem;
3057
- margin: 1rem 0;
3058
- }
3059
-
3060
- .genre-btn {
3061
- padding: 0.75rem;
3062
- border: 2px solid #e0e0e0;
3063
- background: white;
3064
- border-radius: 8px;
3065
- cursor: pointer;
3066
- transition: all 0.3s;
3067
- text-align: center;
3068
- }
3069
-
3070
- .genre-btn:hover {
3071
- border-color: #f39c12;
3072
- background: #fffbf0;
3073
- }
3074
-
3075
- .genre-btn.selected {
3076
- border-color: #e74c3c;
3077
- background: #fff5f5;
3078
- font-weight: bold;
3079
- }
3080
- """
3081
-
3082
- with gr.Blocks(theme=gr.themes.Soft(), css=css, title="Screenplay Generator") as interface:
3083
  gr.HTML("""
3084
  <style>
3085
  .badges-container {
@@ -3138,217 +3138,217 @@ def create_interface():
3138
  </p>
3139
  </div>
3140
  """)
3141
- # State management
3142
- current_session_id = gr.State(None)
3143
-
3144
- with gr.Tabs():
3145
- # Main Writing Tab
3146
- with gr.Tab("โœ๏ธ Write Screenplay"):
3147
- with gr.Row():
3148
- with gr.Column(scale=3):
3149
- query_input = gr.Textbox(
3150
- label="Screenplay Concept",
3151
- placeholder="""Describe your screenplay idea. For example:
 
3152
  - A detective with memory loss must solve their own attempted murder
3153
  - Two rival food truck owners forced to work together to save the city food festival
3154
  - A space station AI develops consciousness during a critical mission
3155
  - A family reunion turns into a murder mystery during a hurricane
3156
 
3157
  The more specific your concept, the better the screenplay will be tailored to your vision.""",
3158
- lines=6
3159
- )
3160
-
3161
- with gr.Column(scale=1):
3162
- screenplay_type = gr.Radio(
3163
- choices=list(SCREENPLAY_LENGTHS.keys()),
3164
- value="movie",
3165
- label="Screenplay Type",
3166
- info="Choose your format"
3167
- )
3168
-
3169
- genre_select = gr.Dropdown(
3170
- choices=list(GENRE_TEMPLATES.keys()),
3171
- value="drama",
3172
- label="Primary Genre",
3173
- info="Select main genre"
3174
- )
3175
-
3176
- language_select = gr.Radio(
3177
- choices=["English", "Korean"],
3178
- value="English",
3179
- label="Language"
3180
- )
3181
-
3182
- with gr.Row():
3183
- random_btn = gr.Button("๐ŸŽฒ Random Concept", scale=1)
3184
- clear_btn = gr.Button("๐Ÿ—‘๏ธ Clear", scale=1)
3185
- submit_btn = gr.Button("๐ŸŽฌ Start Writing", variant="primary", scale=2)
3186
-
3187
- status_text = gr.Textbox(
3188
- label="Status",
3189
- interactive=False,
3190
- value="Ready to create your screenplay"
3191
- )
3192
-
3193
- # Session management
3194
- with gr.Group():
3195
- gr.Markdown("### ๐Ÿ“ Saved Projects")
3196
- with gr.Row():
3197
- session_dropdown = gr.Dropdown(
3198
- label="Active Sessions",
3199
- choices=[],
3200
- interactive=True,
3201
- scale=3
3202
- )
3203
- refresh_btn = gr.Button("๐Ÿ”„", scale=1)
3204
- resume_btn = gr.Button("๐Ÿ“‚ Load", scale=1)
3205
-
3206
- # Output displays
3207
- with gr.Row():
3208
- with gr.Column():
3209
- with gr.Tab("๐ŸŽญ Writing Progress"):
3210
- stages_display = gr.Markdown(
3211
- value="*Your screenplay journey will unfold here...*",
3212
- elem_id="stages-display"
3213
- )
3214
-
3215
- with gr.Tab("๐Ÿ“„ Screenplay"):
3216
- screenplay_output = gr.Markdown(
3217
- value="*Your formatted screenplay will appear here...*",
3218
- elem_id="screenplay-output"
3219
- )
3220
-
3221
- with gr.Row():
3222
- format_select = gr.Radio(
3223
- choices=["PDF", "FDX", "FOUNTAIN", "TXT"],
3224
- value="PDF",
3225
- label="Export Format"
3226
- )
3227
- download_btn = gr.Button("๐Ÿ“ฅ Download Screenplay", variant="secondary")
3228
-
3229
- download_file = gr.File(
3230
- label="Download",
3231
- visible=False
3232
- )
3233
-
3234
- # Examples
3235
- gr.Examples(
3236
- examples=[
3237
- ["A burned-out teacher discovers her students are being replaced by AI duplicates"],
3238
- ["Two funeral home employees accidentally release a ghost who helps them solve murders"],
3239
- ["A time-loop forces a wedding planner to relive the worst wedding until they find true love"],
3240
- ["An astronaut returns to Earth to find everyone has forgotten space exists"],
3241
- ["A support group for reformed villains must save the city when heroes disappear"],
3242
- ["A food critic loses their sense of taste and teams up with a street food vendor"]
3243
- ],
3244
- inputs=query_input,
3245
- label="๐Ÿ’ก Example Concepts"
3246
- )
3247
-
3248
- # Screenplay Library Tab
3249
- with gr.Tab("๐Ÿ“š Concept Library"):
3250
- gr.Markdown("""
3251
- ### ๐ŸŽฒ Random Screenplay Concepts
3252
-
3253
- Browse through AI-generated screenplay concepts. Each concept includes a title, logline, and brief setup.
3254
- """)
3255
-
3256
- library_display = gr.HTML(
3257
- value="<p>Library feature coming soon...</p>"
3258
- )
3259
-
3260
- # Event handlers
3261
- def handle_submit(query, s_type, genre, lang, session_id):
3262
- if not query:
3263
- yield "", "", "โŒ Please enter a concept", session_id
3264
- return
3265
-
3266
- yield from process_query(query, s_type, genre, lang, session_id)
3267
-
3268
- def handle_random(s_type, genre, lang):
3269
- return generate_random_screenplay_theme(s_type, genre, lang)
3270
-
3271
- def handle_download(screenplay_text, format_type, session_id):
3272
- if not screenplay_text or not session_id:
3273
- return gr.update(visible=False)
3274
-
3275
- # Get title from database
3276
- session = ScreenplayDatabase.get_session(session_id)
3277
- title = session.get('title', 'Untitled') if session else 'Untitled'
3278
-
3279
- file_path = download_screenplay(screenplay_text, format_type, title, session_id)
3280
- if file_path and os.path.exists(file_path):
3281
- return gr.update(value=file_path, visible=True)
3282
- return gr.update(visible=False)
3283
-
3284
- # Connect events
3285
- submit_btn.click(
3286
- fn=handle_submit,
3287
- inputs=[query_input, screenplay_type, genre_select, language_select, current_session_id],
3288
- outputs=[stages_display, screenplay_output, status_text, current_session_id]
3289
- )
3290
-
3291
- random_btn.click(
3292
- fn=handle_random,
3293
- inputs=[screenplay_type, genre_select, language_select],
3294
- outputs=[query_input]
3295
- )
3296
-
3297
- clear_btn.click(
3298
- fn=lambda: ("", "", "Ready to create your screenplay", None),
3299
- outputs=[stages_display, screenplay_output, status_text, current_session_id]
3300
- )
3301
-
3302
- refresh_btn.click(
3303
- fn=get_active_sessions,
3304
- outputs=[session_dropdown]
3305
- )
3306
-
3307
- download_btn.click(
3308
- fn=handle_download,
3309
- inputs=[screenplay_output, format_select, current_session_id],
3310
- outputs=[download_file]
3311
- )
3312
-
3313
- # Load sessions on start
3314
- interface.load(
3315
- fn=get_active_sessions,
3316
- outputs=[session_dropdown]
3317
- )
3318
-
3319
- return interface
3320
 
3321
  # Main function
3322
  if __name__ == "__main__":
3323
- logger.info("Screenplay Generator Starting...")
3324
- logger.info("=" * 60)
3325
-
3326
- # Environment check
3327
- logger.info(f"API Endpoint: {API_URL}")
3328
- logger.info("Screenplay Types Available:")
3329
- for s_type, info in SCREENPLAY_LENGTHS.items():
3330
- logger.info(f" - {s_type}: {info['description']}")
3331
- logger.info(f"Genres: {', '.join(GENRE_TEMPLATES.keys())}")
3332
-
3333
- if BRAVE_SEARCH_API_KEY:
3334
- logger.info("Web search enabled for market research.")
3335
- else:
3336
- logger.warning("Web search disabled.")
3337
-
3338
- logger.info("=" * 60)
3339
-
3340
- # Initialize database
3341
- logger.info("Initializing database...")
3342
- ScreenplayDatabase.init_db()
3343
- logger.info("Database initialization complete.")
3344
-
3345
- # Create and launch interface
3346
- interface = create_interface()
3347
-
3348
- interface.launch(
3349
- server_name="0.0.0.0",
3350
- server_port=7860,
3351
- share=False,
3352
- debug=True
3353
- )
3354
-
 
2980
 
2981
  # Create Gradio interface
2982
  def create_interface():
2983
+ """Create Gradio interface for screenplay generation"""
2984
+
2985
+ css = """
2986
+ .main-header {
2987
+ text-align: center;
2988
+ margin-bottom: 2rem;
2989
+ padding: 2rem;
2990
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
2991
+ border-radius: 10px;
2992
+ color: white;
2993
+ }
2994
+
2995
+ .header-title {
2996
+ font-size: 3rem;
2997
+ margin-bottom: 1rem;
2998
+ background: linear-gradient(45deg, #f39c12, #e74c3c);
2999
+ -webkit-background-clip: text;
3000
+ -webkit-text-fill-color: transparent;
3001
+ }
3002
+
3003
+ .header-description {
3004
+ font-size: 1.1rem;
3005
+ opacity: 0.9;
3006
+ line-height: 1.6;
3007
+ }
3008
+
3009
+ .type-selector {
3010
+ display: flex;
3011
+ gap: 1rem;
3012
+ margin: 1rem 0;
3013
+ }
3014
+
3015
+ .type-card {
3016
+ flex: 1;
3017
+ padding: 1rem;
3018
+ border: 2px solid #ddd;
3019
+ border-radius: 8px;
3020
+ cursor: pointer;
3021
+ transition: all 0.3s;
3022
+ }
3023
+
3024
+ .type-card:hover {
3025
+ border-color: #f39c12;
3026
+ transform: translateY(-2px);
3027
+ }
3028
+
3029
+ .type-card.selected {
3030
+ border-color: #e74c3c;
3031
+ background: #fff5f5;
3032
+ }
3033
+
3034
+ #stages-display {
3035
+ max-height: 600px;
3036
+ overflow-y: auto;
3037
+ padding: 1rem;
3038
+ background: #f8f9fa;
3039
+ border-radius: 8px;
3040
+ }
3041
+
3042
+ #screenplay-output {
3043
+ font-family: 'Courier New', monospace;
3044
+ white-space: pre-wrap;
3045
+ background: white;
3046
+ padding: 2rem;
3047
+ border: 1px solid #ddd;
3048
+ border-radius: 8px;
3049
+ max-height: 800px;
3050
+ overflow-y: auto;
3051
+ }
3052
+
3053
+ .genre-grid {
3054
+ display: grid;
3055
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
3056
+ gap: 0.5rem;
3057
+ margin: 1rem 0;
3058
+ }
3059
+
3060
+ .genre-btn {
3061
+ padding: 0.75rem;
3062
+ border: 2px solid #e0e0e0;
3063
+ background: white;
3064
+ border-radius: 8px;
3065
+ cursor: pointer;
3066
+ transition: all 0.3s;
3067
+ text-align: center;
3068
+ }
3069
+
3070
+ .genre-btn:hover {
3071
+ border-color: #f39c12;
3072
+ background: #fffbf0;
3073
+ }
3074
+
3075
+ .genre-btn.selected {
3076
+ border-color: #e74c3c;
3077
+ background: #fff5f5;
3078
+ font-weight: bold;
3079
+ }
3080
+ """
3081
+
3082
+ with gr.Blocks(theme=gr.themes.Soft(), css=css, title="Screenplay Generator") as interface:
3083
  gr.HTML("""
3084
  <style>
3085
  .badges-container {
 
3138
  </p>
3139
  </div>
3140
  """)
3141
+
3142
+ # State management
3143
+ current_session_id = gr.State(None)
3144
+
3145
+ with gr.Tabs():
3146
+ # Main Writing Tab
3147
+ with gr.Tab("โœ๏ธ Write Screenplay"):
3148
+ with gr.Row():
3149
+ with gr.Column(scale=3):
3150
+ query_input = gr.Textbox(
3151
+ label="Screenplay Concept",
3152
+ placeholder="""Describe your screenplay idea. For example:
3153
  - A detective with memory loss must solve their own attempted murder
3154
  - Two rival food truck owners forced to work together to save the city food festival
3155
  - A space station AI develops consciousness during a critical mission
3156
  - A family reunion turns into a murder mystery during a hurricane
3157
 
3158
  The more specific your concept, the better the screenplay will be tailored to your vision.""",
3159
+ lines=6
3160
+ )
3161
+
3162
+ with gr.Column(scale=1):
3163
+ screenplay_type = gr.Radio(
3164
+ choices=list(SCREENPLAY_LENGTHS.keys()),
3165
+ value="movie",
3166
+ label="Screenplay Type",
3167
+ info="Choose your format"
3168
+ )
3169
+
3170
+ genre_select = gr.Dropdown(
3171
+ choices=list(GENRE_TEMPLATES.keys()),
3172
+ value="drama",
3173
+ label="Primary Genre",
3174
+ info="Select main genre"
3175
+ )
3176
+
3177
+ language_select = gr.Radio(
3178
+ choices=["English", "Korean"],
3179
+ value="English",
3180
+ label="Language"
3181
+ )
3182
+
3183
+ with gr.Row():
3184
+ random_btn = gr.Button("๐ŸŽฒ Random Concept", scale=1)
3185
+ clear_btn = gr.Button("๐Ÿ—‘๏ธ Clear", scale=1)
3186
+ submit_btn = gr.Button("๐ŸŽฌ Start Writing", variant="primary", scale=2)
3187
+
3188
+ status_text = gr.Textbox(
3189
+ label="Status",
3190
+ interactive=False,
3191
+ value="Ready to create your screenplay"
3192
+ )
3193
+
3194
+ # Session management
3195
+ with gr.Group():
3196
+ gr.Markdown("### ๐Ÿ“ Saved Projects")
3197
+ with gr.Row():
3198
+ session_dropdown = gr.Dropdown(
3199
+ label="Active Sessions",
3200
+ choices=[],
3201
+ interactive=True,
3202
+ scale=3
3203
+ )
3204
+ refresh_btn = gr.Button("๐Ÿ”„", scale=1)
3205
+ resume_btn = gr.Button("๐Ÿ“‚ Load", scale=1)
3206
+
3207
+ # Output displays
3208
+ with gr.Row():
3209
+ with gr.Column():
3210
+ with gr.Tab("๐ŸŽญ Writing Progress"):
3211
+ stages_display = gr.Markdown(
3212
+ value="*Your screenplay journey will unfold here...*",
3213
+ elem_id="stages-display"
3214
+ )
3215
+
3216
+ with gr.Tab("๐Ÿ“„ Screenplay"):
3217
+ screenplay_output = gr.Markdown(
3218
+ value="*Your formatted screenplay will appear here...*",
3219
+ elem_id="screenplay-output"
3220
+ )
3221
+
3222
+ with gr.Row():
3223
+ format_select = gr.Radio(
3224
+ choices=["PDF", "FDX", "FOUNTAIN", "TXT"],
3225
+ value="PDF",
3226
+ label="Export Format"
3227
+ )
3228
+ download_btn = gr.Button("๐Ÿ“ฅ Download Screenplay", variant="secondary")
3229
+
3230
+ download_file = gr.File(
3231
+ label="Download",
3232
+ visible=False
3233
+ )
3234
+
3235
+ # Examples
3236
+ gr.Examples(
3237
+ examples=[
3238
+ ["A burned-out teacher discovers her students are being replaced by AI duplicates"],
3239
+ ["Two funeral home employees accidentally release a ghost who helps them solve murders"],
3240
+ ["A time-loop forces a wedding planner to relive the worst wedding until they find true love"],
3241
+ ["An astronaut returns to Earth to find everyone has forgotten space exists"],
3242
+ ["A support group for reformed villains must save the city when heroes disappear"],
3243
+ ["A food critic loses their sense of taste and teams up with a street food vendor"]
3244
+ ],
3245
+ inputs=query_input,
3246
+ label="๐Ÿ’ก Example Concepts"
3247
+ )
3248
+
3249
+ # Screenplay Library Tab
3250
+ with gr.Tab("๐Ÿ“š Concept Library"):
3251
+ gr.Markdown("""
3252
+ ### ๐ŸŽฒ Random Screenplay Concepts
3253
+
3254
+ Browse through AI-generated screenplay concepts. Each concept includes a title, logline, and brief setup.
3255
+ """)
3256
+
3257
+ library_display = gr.HTML(
3258
+ value="<p>Library feature coming soon...</p>"
3259
+ )
3260
+
3261
+ # Event handlers
3262
+ def handle_submit(query, s_type, genre, lang, session_id):
3263
+ if not query:
3264
+ yield "", "", "โŒ Please enter a concept", session_id
3265
+ return
3266
+
3267
+ yield from process_query(query, s_type, genre, lang, session_id)
3268
+
3269
+ def handle_random(s_type, genre, lang):
3270
+ return generate_random_screenplay_theme(s_type, genre, lang)
3271
+
3272
+ def handle_download(screenplay_text, format_type, session_id):
3273
+ if not screenplay_text or not session_id:
3274
+ return gr.update(visible=False)
3275
+
3276
+ # Get title from database
3277
+ session = ScreenplayDatabase.get_session(session_id)
3278
+ title = session.get('title', 'Untitled') if session else 'Untitled'
3279
+
3280
+ file_path = download_screenplay(screenplay_text, format_type, title, session_id)
3281
+ if file_path and os.path.exists(file_path):
3282
+ return gr.update(value=file_path, visible=True)
3283
+ return gr.update(visible=False)
3284
+
3285
+ # Connect events
3286
+ submit_btn.click(
3287
+ fn=handle_submit,
3288
+ inputs=[query_input, screenplay_type, genre_select, language_select, current_session_id],
3289
+ outputs=[stages_display, screenplay_output, status_text, current_session_id]
3290
+ )
3291
+
3292
+ random_btn.click(
3293
+ fn=handle_random,
3294
+ inputs=[screenplay_type, genre_select, language_select],
3295
+ outputs=[query_input]
3296
+ )
3297
+
3298
+ clear_btn.click(
3299
+ fn=lambda: ("", "", "Ready to create your screenplay", None),
3300
+ outputs=[stages_display, screenplay_output, status_text, current_session_id]
3301
+ )
3302
+
3303
+ refresh_btn.click(
3304
+ fn=get_active_sessions,
3305
+ outputs=[session_dropdown]
3306
+ )
3307
+
3308
+ download_btn.click(
3309
+ fn=handle_download,
3310
+ inputs=[screenplay_output, format_select, current_session_id],
3311
+ outputs=[download_file]
3312
+ )
3313
+
3314
+ # Load sessions on start
3315
+ interface.load(
3316
+ fn=get_active_sessions,
3317
+ outputs=[session_dropdown]
3318
+ )
3319
+
3320
+ return interface
3321
 
3322
  # Main function
3323
  if __name__ == "__main__":
3324
+ logger.info("Screenplay Generator Starting...")
3325
+ logger.info("=" * 60)
3326
+
3327
+ # Environment check
3328
+ logger.info(f"API Endpoint: {API_URL}")
3329
+ logger.info("Screenplay Types Available:")
3330
+ for s_type, info in SCREENPLAY_LENGTHS.items():
3331
+ logger.info(f" - {s_type}: {info['description']}")
3332
+ logger.info(f"Genres: {', '.join(GENRE_TEMPLATES.keys())}")
3333
+
3334
+ if BRAVE_SEARCH_API_KEY:
3335
+ logger.info("Web search enabled for market research.")
3336
+ else:
3337
+ logger.warning("Web search disabled.")
3338
+
3339
+ logger.info("=" * 60)
3340
+
3341
+ # Initialize database
3342
+ logger.info("Initializing database...")
3343
+ ScreenplayDatabase.init_db()
3344
+ logger.info("Database initialization complete.")
3345
+
3346
+ # Create and launch interface
3347
+ interface = create_interface()
3348
+
3349
+ interface.launch(
3350
+ server_name="0.0.0.0",
3351
+ server_port=7860,
3352
+ share=False,
3353
+ debug=True
3354
+ )