| import streamlit as st |
| import streamlit.components.v1 as components |
| import re |
| from bs4 import BeautifulSoup |
| import markdown |
| from PIL import Image |
| import io |
|
|
| |
| st.set_page_config( |
| page_title="Lexical Tools", |
| page_icon="⚡", |
| layout="centered", |
| initial_sidebar_state="expanded" |
| ) |
|
|
| |
| st.sidebar.title("Navigation") |
| query_params = st.query_params |
| default_index = 1 if query_params.get("mode") == "downloader" else 0 |
|
|
| app_mode = st.sidebar.radio( |
| "Choose Tool:", |
| ["Webmaster Toolkit", "YouTube Downloader"], |
| index=default_index |
| ) |
|
|
| |
| |
| |
| if app_mode == "YouTube Downloader": |
| st.title("🎥 YouTube Media Extractor") |
| st.caption("🚀 Client-Side Mode: Runs on your browser (No Server Blocks)") |
|
|
| |
| url = st.text_input("Paste YouTube URL", placeholder="https://youtube.com/watch?v=...") |
| |
| col1, col2 = st.columns(2) |
| with col1: |
| is_audio = st.toggle("Audio Only (MP3)", value=False) |
| |
| |
| mode_str = "audio" if is_audio else "auto" |
| |
| if url: |
| st.info("👇 Click the button below to process.") |
| |
| |
| |
| html_code = f""" |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <style> |
| body {{ font-family: sans-serif; color: white; background: transparent; }} |
| .btn {{ |
| background: #FF4B4B; color: white; border: none; padding: 12px 24px; |
| border-radius: 8px; font-size: 16px; cursor: pointer; width: 100%; |
| transition: 0.3s; font-weight: bold; |
| }} |
| .btn:hover {{ background: #FF2B2B; }} |
| .btn:disabled {{ background: #555; cursor: not-allowed; }} |
| .result {{ margin-top: 15px; padding: 10px; border-radius: 5px; display: none; }} |
| .success {{ background: #1E3A2F; border: 1px solid #2ecc71; color: #2ecc71; }} |
| .error {{ background: #3A1E1E; border: 1px solid #e74c3c; color: #e74c3c; }} |
| a {{ color: white; text-decoration: none; display: block; padding: 10px; background: #2ecc71; border-radius: 5px; text-align: center; }} |
| </style> |
| </head> |
| <body> |
| <button id="procBtn" class="btn" onclick="fetchMedia()">🚀 Process Media</button> |
| <div id="status" class="result"></div> |
| |
| <script> |
| async function fetchMedia() {{ |
| const btn = document.getElementById('procBtn'); |
| const status = document.getElementById('status'); |
| |
| btn.disabled = true; |
| btn.innerText = "⏳ Processing..."; |
| status.style.display = "none"; |
| |
| // The Payload |
| const data = {{ |
| url: "{url}", |
| downloadMode: "{mode_str}", |
| videoQuality: "1080" |
| }}; |
| |
| try {{ |
| // We use a public instance that allows CORS (Browser access) |
| const response = await fetch("https://co.wuk.sh/api/json", {{ |
| method: "POST", |
| headers: {{ |
| "Accept": "application/json", |
| "Content-Type": "application/json" |
| }}, |
| body: JSON.stringify(data) |
| }}); |
| |
| const result = await response.json(); |
| |
| if (result.url) {{ |
| status.className = "result success"; |
| status.innerHTML = ` |
| <strong>✅ Success!</strong><br><br> |
| <a href="${{result.url}}" target="_blank">⬇️ Click to Download</a> |
| `; |
| status.style.display = "block"; |
| btn.innerText = "🚀 Process Another"; |
| }} else {{ |
| throw new Error(result.text || "Unknown error"); |
| }} |
| |
| }} catch (err) {{ |
| status.className = "result error"; |
| status.innerText = "Error: " + err.message; |
| status.style.display = "block"; |
| btn.innerText = "❌ Retry"; |
| }} |
| btn.disabled = false; |
| }} |
| </script> |
| </body> |
| </html> |
| """ |
| |
| |
| components.html(html_code, height=250) |
|
|
|
|
| |
| |
| |
| elif app_mode == "Webmaster Toolkit": |
| st.title("⚡ Webmaster's Toolkit") |
| |
| tab1, tab2 = st.tabs(["📝 Text Cleaner & SEO", "🖼️ Media Optimizer"]) |
| |
| with tab1: |
| st.write("Paste your raw text or messy HTML below.") |
| raw_text = st.text_area("Input Text", height=200) |
| c1, c2, c3 = st.columns(3) |
| processed_text = "" |
| |
| if c1.button("Strip HTML"): |
| soup = BeautifulSoup(raw_text, "html.parser") |
| processed_text = soup.get_text(separator=" ") |
| if c2.button("Fix Spacing"): |
| processed_text = re.sub(r'\s+', ' ', raw_text).strip() |
| if c3.button("MD to HTML"): |
| processed_text = markdown.markdown(raw_text) |
|
|
| if processed_text: |
| st.success("Done!") |
| st.text_area("Result", value=processed_text, height=200) |
|
|
| with tab2: |
| st.write("Convert heavy images to WebP.") |
| uploaded_file = st.file_uploader("Upload Image", type=['png', 'jpg', 'jpeg']) |
| if uploaded_file: |
| original_image = Image.open(uploaded_file) |
| st.image(original_image, caption="Original", use_container_width=True) |
| |
| if st.button("Convert to WebP"): |
| buffer = io.BytesIO() |
| original_image.save(buffer, format="WEBP", quality=80, optimize=True) |
| buffer.seek(0) |
| st.success("Converted!") |
| st.download_button("Download WebP", data=buffer, file_name="image.webp") |