Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import os | |
| import json | |
| from Pdf_utils import extract_text_from_pdf | |
| from ocr_utils import extract_text_from_image | |
| from Prompt_Builder import build_prompt | |
| from openai import OpenAI | |
| # ---------------------------- | |
| # CONFIG & SECRETS | |
| # ---------------------------- | |
| GROQ_API_KEY = os.environ.get("GROQ_API_KEY") | |
| OCR_API_KEY = os.environ.get("OCR_API_KEY") | |
| client = OpenAI( | |
| api_key=GROQ_API_KEY, | |
| base_url="https://api.groq.com/openai/v1", | |
| ) | |
| # ---------------------------- | |
| # UI CUSTOMIZATION (Vanta.js + Glassmorphism) | |
| # ---------------------------- | |
| css = """ | |
| footer {visibility: hidden} | |
| .gradio-container { | |
| background: rgba(10, 25, 47, 0.7) !important; | |
| backdrop-filter: blur(15px) !important; | |
| border: 1px solid rgba(255, 255, 255, 0.1) !important; | |
| border-radius: 20px !important; | |
| color: white !important; | |
| } | |
| #vanta-canvas { | |
| position: fixed; | |
| top: 0; left: 0; width: 100vw; height: 100vh; | |
| z-index: -1; | |
| } | |
| #output-box { | |
| background: rgba(0, 0, 0, 0.3) !important; | |
| padding: 20px; | |
| border-radius: 10px; | |
| } | |
| """ | |
| vanta_head = """ | |
| <div id="vanta-canvas"></div> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.net.min.js"></script> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| VANTA.NET({ | |
| el: "#vanta-canvas", | |
| mouseControls: true, | |
| touchControls: true, | |
| gyroControls: false, | |
| minHeight: 200.00, | |
| minWidth: 200.00, | |
| scale: 1.00, | |
| scaleMobile: 1.00, | |
| color: 0x3fbbee, | |
| backgroundColor: 0x0a192f, | |
| points: 15.00, | |
| maxDistance: 20.00, | |
| spacing: 16.00 | |
| }) | |
| }); | |
| </script> | |
| """ | |
| # ---------------------------- | |
| # CORE LOGIC WITH UX ALERTS | |
| # ---------------------------- | |
| def generate_nexus_post(file, user_text, url, url_desc, hashtags, custom_p, suggestions, model_name): | |
| # Validation Check | |
| if not file and not user_text.strip(): | |
| raise gr.Error("Bhai, kam az kam kuch text ya file toh do! Input empty hai.") | |
| # User Feedback Notification | |
| gr.Info("🚀 Processing your request... Sit tight!") | |
| file_text = "" | |
| if file: | |
| try: | |
| if file.name.lower().endswith(".pdf"): | |
| gr.Info("📄 Reading PDF...") | |
| file_text = extract_text_from_pdf(file.name) | |
| else: | |
| gr.Info("🖼️ Running OCR on Image...") | |
| file_text = extract_text_from_image(file.name, OCR_API_KEY) | |
| except Exception as e: | |
| raise gr.Error(f"File processing error: {str(e)}") | |
| # Prompt Building | |
| final_prompt = build_prompt(user_text, file_text, {"url": url, "description": url_desc}, [], hashtags.split(","), custom_p, suggestions) | |
| try: | |
| gr.Info("🤖 AI is ghostwriting your post...") | |
| completion = client.chat.completions.create( | |
| model=model_name, | |
| messages=[{"role": "user", "content": final_prompt}], | |
| temperature=0.7, | |
| timeout=45.0 # Pre-emptively stop if API is stuck | |
| ) | |
| gr.Info("✅ Done! Post generated.") | |
| return completion.choices[0].message.content | |
| except Exception as e: | |
| raise gr.Error(f"API Error: {str(e)}") | |
| # ---------------------------- | |
| # GRADIO INTERFACE | |
| # ---------------------------- | |
| with gr.Blocks(theme=gr.themes.Default(), css=css) as demo: | |
| gr.HTML(vanta_head) | |
| with gr.Column(): | |
| gr.Markdown("# 🚀 Nexus Post AI\n### Professional LinkedIn Ghostwriter") | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| file_input = gr.File(label="Upload Context (PDF/Image)") | |
| user_msg = gr.Textbox(label="Core Idea", placeholder="What's this post about?", lines=3) | |
| with gr.Accordion("🔗 Links & Tags", open=False): | |
| link_url = gr.Textbox(label="Reference URL") | |
| link_d = gr.Textbox(label="Link Description") | |
| tags = gr.Textbox(label="Hashtags (comma separated)") | |
| with gr.Column(scale=1): | |
| model_drop = gr.Dropdown( | |
| choices=["llama-3.3-70b-versatile", "mixtral-8x7b-32768"], | |
| value="llama-3.3-70b-versatile", | |
| label="AI Model" | |
| ) | |
| ai_adds = gr.CheckboxGroup( | |
| label="Enhancements", | |
| choices=["Strong Hook", "Storytelling", "Bullet Points", "Emojis", "Call-to-Action"] | |
| ) | |
| custom_inst = gr.Textbox(label="Custom Instructions", placeholder="e.g. 'Make it professional'") | |
| # Button with explicit loading | |
| submit_btn = gr.Button("🔥 GENERATE POST", variant="primary") | |
| output_display = gr.Markdown(label="Generated Drafts", elem_id="output-box") | |
| # The Logic Trigger | |
| submit_btn.click( | |
| fn=generate_nexus_post, | |
| inputs=[file_input, user_msg, link_url, link_d, tags, custom_inst, ai_adds, model_drop], | |
| outputs=output_display, | |
| show_progress="full", # Full screen overlay for clear status | |
| scroll_to_output=True | |
| ) | |
| demo.launch() |