import os import warnings import logging # Suppress technical initialization warnings from Torch/Transformers/HF os.environ["TORCH_LOGS"] = "-all" os.environ["TORCH_CPP_LOG_LEVEL"] = "3" os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3" os.environ["HUGGINGFACE_HUB_VERBOSITY"] = "error" warnings.filterwarnings("ignore", message=".*torch.classes.*") logging.getLogger("torch").setLevel(logging.ERROR) import streamlit as st # Page Config must be first Streamlit command st.set_page_config( page_title="AutoContentForge AI", page_icon="⚒️", layout="wide", initial_sidebar_state="expanded", ) from streamlit_calendar import calendar from forge_utils import ContentExtractor, ForgeAI # Initialize ForgeAI with caching @st.cache_resource def get_forge(): return ForgeAI() forge = get_forge() # Session State for Content if 'forge_results' not in st.session_state: st.session_state.forge_results = None if 'extracted_content' not in st.session_state: st.session_state.extracted_content = None # Custom CSS for Premium Look st.markdown(""" """, unsafe_allow_html=True) # Sidebar Branding & Pro CTA with st.sidebar: st.title("⚒️ AutoContentForge AI") st.caption("Automate Your Content. Forge Every Platform.") st.markdown("---") st.markdown("""
""", unsafe_allow_html=True) if st.button("Contact for Pro Version", use_container_width=True): st.info("Email: rajue@smackcoders.com with subject 'AutoContentForge AI Pro Inquiry'") st.markdown("---") st.markdown("### Resources") st.markdown("[Documentation](#)") st.markdown("[Pricing](#)") st.markdown("[YouTube Channel](#)") # Main Navigation Tabs tab1, tab2, tab3 = st.tabs([ "📝 Single Post", "📦 Bulk Posting", "⚙️ Admin Settings" ]) # Initialize session states for the new workflow if 'master_variations' not in st.session_state: st.session_state.master_variations = None if 'selected_variation' not in st.session_state: st.session_state.selected_variation = None if 'current_hashtags' not in st.session_state: st.session_state.current_hashtags = "" # Module 1: Single Post with tab1: st.header("📝 Create Single Social Post") st.write("Fetch from a URL or use the manual editor to forge your master variations.") col_in, col_out = st.columns([1, 1.2]) with col_in: st.subheader("1. Source Content") input_mode = st.radio( "Input Mode", ["URL Fetch", "Manual Editor"], horizontal=True, help="Choose 'URL Fetch' to extract content from a website, or 'Manual Editor' to paste your own text directly." ) if input_mode == "URL Fetch": source_url = st.text_input( "Enter Content URL", placeholder="https://example.com/blog-post", help="Paste the full link (including https://) of the article or blog post you want to repurpose." ) if st.button("🚀 Fetch & Analyze"): if not source_url or "://" not in source_url: st.error("Please enter a valid URL (including https://)") else: with st.spinner("Forging 3 master variations..."): extracted = ContentExtractor.from_url(source_url) if "error" in extracted: st.error(extracted["error"]) else: st.session_state.extracted_content = extracted st.session_state.master_variations = forge.generate_master_variations(extracted['text']) st.session_state.current_hashtags = forge.extract_hashtags(extracted['text']) st.session_state.selected_variation = None # Reset selection st.success("Successfully generated 3 variations!") else: pasted_title = st.text_input("Post Title (Optional)", help="Give your post a title for easier tracking.") pasted_text = st.text_area( "Master Content / Article Text", height=200, help="Paste the core content you want to turn into social posts. Aim for at least 50 words for the best AI results." ) if st.button("✨ Generate Variations"): if len(pasted_text) < 50: st.warning("Please provide more content for better AI results.") else: with st.spinner("Processing..."): st.session_state.extracted_content = {"title": pasted_title or "Manual Input", "text": pasted_text} st.session_state.master_variations = forge.generate_master_variations(pasted_text) st.session_state.current_hashtags = forge.extract_hashtags(pasted_text) st.session_state.selected_variation = None st.success("Variations generated!") if st.session_state.master_variations: st.markdown("---") st.subheader("2. Choose Master Variation") st.info("💡 **Tip:** Each variation has a different tone. Expand them to see which one fits your brand voice best.") for var in st.session_state.master_variations: with st.expander(f"🔹 {var['type']}", expanded=(st.session_state.selected_variation == var['id'])): st.write(var['text']) if st.button(f"Select {var['type']}", key=f"sel_{var['id']}", help=f"Choose the {var['type']} to be adapted for your social networks."): st.session_state.selected_variation = var['id'] st.rerun() with col_out: st.subheader("3. Preview & Adapt") if not st.session_state.selected_variation: st.info("Select a master variation on the left to see platform-specific previews.") else: selected_var_obj = next(v for v in st.session_state.master_variations if v['id'] == st.session_state.selected_variation) platforms = st.multiselect( "Select Social Networks", ["LinkedIn", "Twitter/X", "Instagram", "Facebook", "YouTube", "Bluesky"], default=["LinkedIn", "Twitter/X"], help="Choose which platforms you want to generate previews for. The AI will format your selected variation for each." ) if st.session_state.extracted_content.get("images"): st.image(st.session_state.extracted_content['images'][0], caption="Extracted Media", width=300) else: st.write("📸 *No media found. You can add media in the Pro version or manual editor.*") st.markdown("---") for platform in platforms: adapted_text = forge.adapt_for_platform(selected_var_obj['text'], platform, st.session_state.current_hashtags) with st.container(): st.markdown(f"""{adapted_text if isinstance(adapted_text, str) else adapted_text.get('title')}