Natwar commited on
Commit
73351e0
Β·
verified Β·
1 Parent(s): 8ee7fe3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +128 -129
app.py CHANGED
@@ -993,7 +993,6 @@ def process_excel_to_word(excel_file_path):
993
 
994
  # ======================== GRADIO INTERFACE ========================
995
  def create_interface():
996
- # ... (Your entire Gradio interface layout remains here, unchanged)
997
  generator = BlogGenerator()
998
  with gr.Blocks(title="🎯 Digiworks Unified Blog Generator", theme=gr.themes.Soft()) as interface:
999
  gr.HTML("""<div style='text-align: center; padding: 25px; background: linear-gradient(135deg, #1a365d 0%, #2d3748 100%); color: white; margin-bottom: 25px; border-radius: 15px;'><h1 style='margin: 0; font-size: 2.5em; font-weight: 900;'>🎯 Digiworks Unified Blog Generator</h1><p style='margin: 15px 0 0 0; font-size: 1.2em;'>Idea Generation β†’ Blog Post Creation β†’ Word Document Formatting</p></div>""")
@@ -1047,134 +1046,134 @@ def create_interface():
1047
  with gr.Row():
1048
  download_word_btn = gr.File(label="πŸ“₯ Download Formatted Word Document", visible=False)
1049
  gr.HTML("""<div style='background: #065f46; color: white; padding: 15px; border-radius: 8px; text-align: center; margin-left: 15px; border: 1px solid #10b981;'><strong style='color: #6ee7b7;'>πŸ’‘ WordPress Tip:</strong><span style='color: white;'>Copy sections directly from Word to WordPress editor!</span></div>""")
1050
-
1051
- # --- HANDLER FUNCTIONS (MODIFIED for Incremental Save) ---
1052
- def toggle_content_type(mode): return gr.update(visible=(mode == "Single Type"))
1053
- def handle_idea_generation(mode, content_type_val, num_topics_val):
1054
- try:
1055
- if mode == "Single Type": result, df, status = generate_blog_topics(content_type_val, num_topics_val)
1056
- else: result, df, status = generate_all_types(num_topics_val)
1057
- download_file, download_visible = None, False
1058
- if not df.empty:
1059
- timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
1060
- filename = f"digiworks_blog_ideas_{timestamp}.xlsx"
1061
- temp_path = os.path.join(tempfile.gettempdir(), filename)
1062
- with pd.ExcelWriter(temp_path, engine='openpyxl') as writer: df.to_excel(writer, sheet_name='Blog Ideas', index=False)
1063
- download_file, download_visible = temp_path, True
1064
- return status, result, df, gr.update(value=download_file, visible=download_visible)
1065
- except Exception as e: return f"❌ Error: {str(e)}", f"❌ Generation failed: {str(e)}", pd.DataFrame(), gr.update(visible=False)
1066
- def load_excel_and_create_checklist(file_path):
1067
- if not file_path: return gr.update(choices=[], value=[]), pd.DataFrame(), "Please upload an Excel file"
1068
- try:
1069
- df = pd.read_excel(file_path)
1070
- required_cols = ['Content Type', 'Headline']
1071
- if missing_cols := [col for col in required_cols if col not in df.columns]: return gr.update(choices=[], value=[]), pd.DataFrame(), f"Missing columns: {', '.join(missing_cols)}"
1072
- choices = []
1073
- for i, row in df.iterrows():
1074
- content_type = row.get('Content Type', '').replace(' πŸ“š', '').replace(' πŸ“‹', '').replace(' βš–οΈ', '').replace(' πŸ“ˆ', '').replace(' πŸ“Š', '').replace(' πŸ’‘', '')
1075
- headline = row.get('Headline', '')[:60]; keywords = row.get('Keywords', '')[:50]
1076
- choices.append(f"#{i+1} [{content_type}] {headline}... | Keywords: {keywords}...")
1077
- return gr.update(choices=choices, value=choices), df, f"βœ… Loaded {len(df)} topics. Select topics to generate blog posts."
1078
- except Exception as e: return gr.update(choices=[], value=[]), pd.DataFrame(), f"❌ Error: {str(e)}"
1079
- def reset_topic_counter():
1080
- generator.reset_counter()
1081
- return "πŸ”„ Topic counter reset to 0. Next generation will start from Topic #1."
1082
-
1083
- def generate_selected_posts(file_path, selected_choices, df):
1084
- if not file_path or not selected_choices:
1085
- yield "Please upload an Excel file and select at least one topic to generate.", pd.DataFrame(), gr.update(visible=False)
1086
- return
1087
- all_sections_data, status_log = [], ["πŸš€ Starting blog post generation..."]
1088
- latest_file_path = None
1089
- yield "\n".join(status_log), pd.DataFrame(), gr.update(value=None, visible=False)
1090
- try:
1091
- for topic_counter, choice in enumerate(selected_choices, 1):
1092
- choice_index = int(choice.split('#')[1].split(' ')[0]) - 1
1093
- if choice_index < len(df):
1094
- topic_data = df.iloc[choice_index].to_dict()
1095
- generation_iterator = generator.generate_blog_from_topic_data(topic_data, topic_index=topic_counter)
1096
-
1097
- topic_sections = []
1098
- for update_type, update_value, *rest in generation_iterator:
1099
- if update_type == 'status':
1100
- message = update_value
1101
- status_log.append(message)
1102
- yield "\n".join(status_log), pd.DataFrame(all_sections_data), gr.update(value=latest_file_path, visible=bool(latest_file_path))
1103
- elif update_type == 'result':
1104
- sections, msg = update_value, rest[0]
1105
- if sections:
1106
- topic_sections.extend(sections)
1107
- status_log.append(msg)
1108
-
1109
- if topic_sections:
1110
- all_sections_data.extend(topic_sections)
1111
- intermediate_df = pd.DataFrame(all_sections_data)
1112
- intermediate_file = create_excel_export(all_sections_data)
1113
- latest_file_path = intermediate_file
1114
- status_log.append(f"πŸ“¦ Intermediate file for Topic #{topic_counter} ready.")
1115
- yield "\n".join(status_log), intermediate_df, gr.update(value=latest_file_path, visible=True)
1116
-
1117
- if all_sections_data:
1118
- final_df = pd.DataFrame(all_sections_data)
1119
- total_topics, total_sections = len(selected_choices), len(all_sections_data)
1120
- successful_sections = len([s for s in all_sections_data if s['Word Count'] > 0])
1121
- total_words = sum(s['Word Count'] for s in all_sections_data if s['Word Count'] > 0)
1122
- final_status = f"""πŸŽ‰ ALL TOPICS COMPLETE!\n--------------------\nπŸ“Š Generated {total_sections} sections across {total_topics} topics\nβœ… Successful sections: {successful_sections}/{total_sections}\nπŸ“ Total words generated: {total_words:,}\nπŸ”’ Topics indexed: 1-{total_topics}\n\nFull Log:\n""" + "\n".join(status_log)
1123
- yield final_status, final_df, gr.update(value=latest_file_path, visible=True)
1124
- else:
1125
- yield "❌ No sections were generated.", pd.DataFrame(), gr.update(visible=False)
1126
- except Exception as e:
1127
- import traceback
1128
- tb_str = traceback.format_exc()
1129
- yield f"❌ An unexpected error occurred: {str(e)}\n\nTraceback:\n{tb_str}", pd.DataFrame(), gr.update(visible=False)
1130
-
1131
- def process_excel_file(excel_file):
1132
- if not excel_file: return "Please upload an Excel file", "", gr.update(visible=False)
1133
- try:
1134
- df = pd.read_excel(excel_file); preview = "No content preview available"
1135
- if not df.empty and 'Section Content' in df.columns:
1136
- cleaned_sample = clean_blog_content(df.iloc[0]['Section Content'])
1137
- preview = cleaned_sample[:500] + "..." if len(cleaned_sample) > 500 else cleaned_sample
1138
- status = f"βœ… Excel loaded: {len(df)} sections found\nπŸ“Š Topics: {df['Topic Number'].nunique() if 'Topic Number' in df.columns else 'Unknown'}\nπŸ”„ Ready to generate Word document"
1139
- return status, preview, gr.update(visible=False)
1140
- except Exception as e: return f"❌ Error reading Excel: {str(e)}", "", gr.update(visible=False)
1141
-
1142
- def generate_word_document(excel_file):
1143
- if not excel_file:
1144
- yield "Please upload an Excel file.", "", gr.update(visible=False)
1145
- return
1146
- status_log = ["πŸš€ Starting Word document generation..."]
1147
- yield "\n".join(status_log), "", gr.update(visible=False)
1148
- try:
1149
- processing_generator = process_excel_to_word(excel_file)
1150
- for type, val1, *val2 in processing_generator:
1151
- if type == 'status':
1152
- status_log.append(val1)
1153
- yield "\n".join(status_log), "", gr.update(visible=False)
1154
- elif type == 'complete':
1155
- word_file_path, result_message = val1, val2[0]
1156
- df = pd.read_excel(excel_file)
1157
- preview = "Document generated successfully"
1158
- if not df.empty and 'Section Content' in df.columns:
1159
- cleaned_sample = clean_blog_content(df.iloc[0]['Section Content'])
1160
- preview = cleaned_sample[:500] + "..." if len(cleaned_sample) > 500 else cleaned_sample
1161
- yield result_message, preview, gr.update(value=word_file_path, visible=True)
1162
- elif type == 'error':
1163
- yield val1, "", gr.update(visible=False)
1164
- except Exception as e:
1165
- import traceback
1166
- yield f"❌ An unexpected error occurred: {str(e)}\n{traceback.format_exc()}", "", gr.update(visible=False)
1167
-
1168
- # --- EVENT LISTENERS ---
1169
- mode_choice.change(fn=toggle_content_type, inputs=[mode_choice], outputs=[content_type])
1170
- generate_ideas_btn.click(fn=handle_idea_generation, inputs=[mode_choice, content_type, num_topics], outputs=[ideas_status, ideas_results, ideas_df, download_ideas_btn])
1171
- excel_upload.change(fn=load_excel_and_create_checklist, inputs=[excel_upload], outputs=[topics_checklist, loaded_data, posts_status])
1172
- reset_counter_btn.click(fn=reset_topic_counter, inputs=[], outputs=[posts_status])
1173
- generate_posts_btn.click(fn=generate_selected_posts, inputs=[excel_upload, topics_checklist, loaded_data], outputs=[posts_status, posts_dataframe, download_posts_btn])
1174
- word_excel_input.change(fn=process_excel_file, inputs=[word_excel_input], outputs=[word_status, word_preview, download_word_btn])
1175
- generate_word_btn.click(fn=generate_word_document, inputs=[word_excel_input], outputs=[word_status, word_preview, download_word_btn])
1176
- gr.HTML("""<div style='text-align: center; padding: 20px; margin-top: 25px; border-top: 1px solid #e0e0e0;'><p style='color: #666; margin: 0;'>🎯 <strong>Digiworks Unified Blog Generator</strong> | Idea Generation β†’ Blog Post Creation β†’ Word Document Formatting<br><small>Perfect for content teams and marketers</small></p></div>""")
1177
-
1178
  return interface
1179
 
1180
 
 
993
 
994
  # ======================== GRADIO INTERFACE ========================
995
  def create_interface():
 
996
  generator = BlogGenerator()
997
  with gr.Blocks(title="🎯 Digiworks Unified Blog Generator", theme=gr.themes.Soft()) as interface:
998
  gr.HTML("""<div style='text-align: center; padding: 25px; background: linear-gradient(135deg, #1a365d 0%, #2d3748 100%); color: white; margin-bottom: 25px; border-radius: 15px;'><h1 style='margin: 0; font-size: 2.5em; font-weight: 900;'>🎯 Digiworks Unified Blog Generator</h1><p style='margin: 15px 0 0 0; font-size: 1.2em;'>Idea Generation β†’ Blog Post Creation β†’ Word Document Formatting</p></div>""")
 
1046
  with gr.Row():
1047
  download_word_btn = gr.File(label="πŸ“₯ Download Formatted Word Document", visible=False)
1048
  gr.HTML("""<div style='background: #065f46; color: white; padding: 15px; border-radius: 8px; text-align: center; margin-left: 15px; border: 1px solid #10b981;'><strong style='color: #6ee7b7;'>πŸ’‘ WordPress Tip:</strong><span style='color: white;'>Copy sections directly from Word to WordPress editor!</span></div>""")
1049
+ gr.HTML("""<div style='text-align: center; padding: 20px; margin-top: 25px; border-top: 1px solid #e0e0e0;'><p style='color: #666; margin: 0;'>🎯 <strong>Digiworks Unified Blog Generator</strong> | Idea Generation β†’ Blog Post Creation β†’ Word Document Formatting<br><small>Perfect for content teams and marketers</small></p></div>""")
1050
+
1051
+ # --- HANDLER FUNCTIONS (MODIFIED for Incremental Save) ---
1052
+ def toggle_content_type(mode): return gr.update(visible=(mode == "Single Type"))
1053
+ def handle_idea_generation(mode, content_type_val, num_topics_val):
1054
+ try:
1055
+ if mode == "Single Type": result, df, status = generate_blog_topics(content_type_val, num_topics_val)
1056
+ else: result, df, status = generate_all_types(num_topics_val)
1057
+ download_file, download_visible = None, False
1058
+ if not df.empty:
1059
+ timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
1060
+ filename = f"digiworks_blog_ideas_{timestamp}.xlsx"
1061
+ temp_path = os.path.join(tempfile.gettempdir(), filename)
1062
+ with pd.ExcelWriter(temp_path, engine='openpyxl') as writer: df.to_excel(writer, sheet_name='Blog Ideas', index=False)
1063
+ download_file, download_visible = temp_path, True
1064
+ return status, result, df, gr.update(value=download_file, visible=download_visible)
1065
+ except Exception as e: return f"❌ Error: {str(e)}", f"❌ Generation failed: {str(e)}", pd.DataFrame(), gr.update(visible=False)
1066
+ def load_excel_and_create_checklist(file_path):
1067
+ if not file_path: return gr.update(choices=[], value=[]), pd.DataFrame(), "Please upload an Excel file"
1068
+ try:
1069
+ df = pd.read_excel(file_path)
1070
+ required_cols = ['Content Type', 'Headline']
1071
+ if missing_cols := [col for col in required_cols if col not in df.columns]: return gr.update(choices=[], value=[]), pd.DataFrame(), f"Missing columns: {', '.join(missing_cols)}"
1072
+ choices = []
1073
+ for i, row in df.iterrows():
1074
+ content_type = row.get('Content Type', '').replace(' πŸ“š', '').replace(' πŸ“‹', '').replace(' βš–οΈ', '').replace(' πŸ“ˆ', '').replace(' πŸ“Š', '').replace(' πŸ’‘', '')
1075
+ headline = row.get('Headline', '')[:60]; keywords = row.get('Keywords', '')[:50]
1076
+ choices.append(f"#{i+1} [{content_type}] {headline}... | Keywords: {keywords}...")
1077
+ return gr.update(choices=choices, value=choices), df, f"βœ… Loaded {len(df)} topics. Select topics to generate blog posts."
1078
+ except Exception as e: return gr.update(choices=[], value=[]), pd.DataFrame(), f"❌ Error: {str(e)}"
1079
+ def reset_topic_counter():
1080
+ generator.reset_counter()
1081
+ return "πŸ”„ Topic counter reset to 0. Next generation will start from Topic #1."
1082
+
1083
+ def generate_selected_posts(file_path, selected_choices, df):
1084
+ if not file_path or not selected_choices:
1085
+ yield "Please upload an Excel file and select at least one topic to generate.", pd.DataFrame(), gr.update(visible=False)
1086
+ return
1087
+ all_sections_data, status_log = [], ["πŸš€ Starting blog post generation..."]
1088
+ latest_file_path = None
1089
+ yield "\n".join(status_log), pd.DataFrame(), gr.update(value=None, visible=False)
1090
+ try:
1091
+ for topic_counter, choice in enumerate(selected_choices, 1):
1092
+ choice_index = int(choice.split('#')[1].split(' ')[0]) - 1
1093
+ if choice_index < len(df):
1094
+ topic_data = df.iloc[choice_index].to_dict()
1095
+ generation_iterator = generator.generate_blog_from_topic_data(topic_data, topic_index=topic_counter)
1096
+
1097
+ topic_sections = []
1098
+ for update_type, update_value, *rest in generation_iterator:
1099
+ if update_type == 'status':
1100
+ message = update_value
1101
+ status_log.append(message)
1102
+ yield "\n".join(status_log), pd.DataFrame(all_sections_data), gr.update(value=latest_file_path, visible=bool(latest_file_path))
1103
+ elif update_type == 'result':
1104
+ sections, msg = update_value, rest[0]
1105
+ if sections:
1106
+ topic_sections.extend(sections)
1107
+ status_log.append(msg)
1108
+
1109
+ if topic_sections:
1110
+ all_sections_data.extend(topic_sections)
1111
+ intermediate_df = pd.DataFrame(all_sections_data)
1112
+ intermediate_file = create_excel_export(all_sections_data)
1113
+ latest_file_path = intermediate_file
1114
+ status_log.append(f"πŸ“¦ Intermediate file for Topic #{topic_counter} ready.")
1115
+ yield "\n".join(status_log), intermediate_df, gr.update(value=latest_file_path, visible=True)
1116
+
1117
+ if all_sections_data:
1118
+ final_df = pd.DataFrame(all_sections_data)
1119
+ total_topics, total_sections = len(selected_choices), len(all_sections_data)
1120
+ successful_sections = len([s for s in all_sections_data if s['Word Count'] > 0])
1121
+ total_words = sum(s['Word Count'] for s in all_sections_data if s['Word Count'] > 0)
1122
+ final_status = f"""πŸŽ‰ ALL TOPICS COMPLETE!\n--------------------\nπŸ“Š Generated {total_sections} sections across {total_topics} topics\nβœ… Successful sections: {successful_sections}/{total_sections}\nπŸ“ Total words generated: {total_words:,}\nπŸ”’ Topics indexed: 1-{total_topics}\n\nFull Log:\n""" + "\n".join(status_log)
1123
+ yield final_status, final_df, gr.update(value=latest_file_path, visible=True)
1124
+ else:
1125
+ yield "❌ No sections were generated.", pd.DataFrame(), gr.update(visible=False)
1126
+ except Exception as e:
1127
+ import traceback
1128
+ tb_str = traceback.format_exc()
1129
+ yield f"❌ An unexpected error occurred: {str(e)}\n\nTraceback:\n{tb_str}", pd.DataFrame(), gr.update(visible=False)
1130
+
1131
+ def process_excel_file(excel_file):
1132
+ if not excel_file: return "Please upload an Excel file", "", gr.update(visible=False)
1133
+ try:
1134
+ df = pd.read_excel(excel_file); preview = "No content preview available"
1135
+ if not df.empty and 'Section Content' in df.columns:
1136
+ cleaned_sample = clean_blog_content(df.iloc[0]['Section Content'])
1137
+ preview = cleaned_sample[:500] + "..." if len(cleaned_sample) > 500 else cleaned_sample
1138
+ status = f"βœ… Excel loaded: {len(df)} sections found\nπŸ“Š Topics: {df['Topic Number'].nunique() if 'Topic Number' in df.columns else 'Unknown'}\nπŸ”„ Ready to generate Word document"
1139
+ return status, preview, gr.update(visible=False)
1140
+ except Exception as e: return f"❌ Error reading Excel: {str(e)}", "", gr.update(visible=False)
1141
+
1142
+ def generate_word_document(excel_file):
1143
+ if not excel_file:
1144
+ yield "Please upload an Excel file.", "", gr.update(visible=False)
1145
+ return
1146
+ status_log = ["πŸš€ Starting Word document generation..."]
1147
+ yield "\n".join(status_log), "", gr.update(visible=False)
1148
+ try:
1149
+ processing_generator = process_excel_to_word(excel_file)
1150
+ for type, val1, *val2 in processing_generator:
1151
+ if type == 'status':
1152
+ status_log.append(val1)
1153
+ yield "\n".join(status_log), "", gr.update(visible=False)
1154
+ elif type == 'complete':
1155
+ word_file_path, result_message = val1, val2[0]
1156
+ df = pd.read_excel(excel_file)
1157
+ preview = "Document generated successfully"
1158
+ if not df.empty and 'Section Content' in df.columns:
1159
+ cleaned_sample = clean_blog_content(df.iloc[0]['Section Content'])
1160
+ preview = cleaned_sample[:500] + "..." if len(cleaned_sample) > 500 else cleaned_sample
1161
+ yield result_message, preview, gr.update(value=word_file_path, visible=True)
1162
+ elif type == 'error':
1163
+ yield val1, "", gr.update(visible=False)
1164
+ except Exception as e:
1165
+ import traceback
1166
+ yield f"❌ An unexpected error occurred: {str(e)}\n{traceback.format_exc()}", "", gr.update(visible=False)
1167
+
1168
+ # --- EVENT LISTENERS ---
1169
+ mode_choice.change(fn=toggle_content_type, inputs=[mode_choice], outputs=[content_type])
1170
+ generate_ideas_btn.click(fn=handle_idea_generation, inputs=[mode_choice, content_type, num_topics], outputs=[ideas_status, ideas_results, ideas_df, download_ideas_btn])
1171
+ excel_upload.change(fn=load_excel_and_create_checklist, inputs=[excel_upload], outputs=[topics_checklist, loaded_data, posts_status])
1172
+ reset_counter_btn.click(fn=reset_topic_counter, inputs=[], outputs=[posts_status])
1173
+ generate_posts_btn.click(fn=generate_selected_posts, inputs=[excel_upload, topics_checklist, loaded_data], outputs=[posts_status, posts_dataframe, download_posts_btn])
1174
+ word_excel_input.change(fn=process_excel_file, inputs=[word_excel_input], outputs=[word_status, word_preview, download_word_btn])
1175
+ generate_word_btn.click(fn=generate_word_document, inputs=[word_excel_input], outputs=[word_status, word_preview, download_word_btn])
1176
+
1177
  return interface
1178
 
1179