| import streamlit as st |
| import requests |
| from PIL import Image, ImageDraw, ImageFont |
| import io |
| import time |
| import json |
| import base64 |
| import uuid |
| import hashlib |
| import urllib.parse |
| import random |
| import datetime |
| import re |
| from collections import Counter |
| from bs4 import BeautifulSoup |
| from fpdf import FPDF |
| import os |
| from io import BytesIO |
| import streamlit as st |
| import html |
| import string |
| |
|
|
| def lexical_replacer_tool(): |
| """ |
| The Master Function for the Lexical Space Replacer Tool. |
| Contains 100+ text manipulation features split into Normal and Dev modes. |
| """ |
|
|
| st.markdown("## 🛠️ Lexical Replacer Toolkit") |
| st.markdown("---") |
|
|
| |
| |
| if 'replacer_input' not in st.session_state: |
| st.session_state.replacer_input = "Paste your text or HTML here..." |
| if 'replacer_output' not in st.session_state: |
| st.session_state.replacer_output = "" |
|
|
| |
| |
| |
| ops = { |
| |
| "Remove Double Spaces": lambda t: re.sub(r'\s+', ' ', t), |
| "Trim Whitespace": lambda t: t.strip(), |
| "Remove Empty Lines": lambda t: "\n".join([line for line in t.splitlines() if line.strip()]), |
| "Remove Duplicate Lines": lambda t: "\n".join(list(dict.fromkeys(t.splitlines()))), |
| "Sentence Case": lambda t: ". ".join([s.capitalize() for s in t.split(". ")]), |
| "Title Case": lambda t: t.title(), |
| "UPPERCASE": lambda t: t.upper(), |
| "lowercase": lambda t: t.lower(), |
| "tOGGLE cASE": lambda t: t.swapcase(), |
| "Smart Quotes to Straight": lambda t: t.replace('“', '"').replace('”', '"').replace("‘", "'").replace("’", "'"), |
| "Remove Special Characters": lambda t: re.sub(r'[^a-zA-Z0-9\s]', '', t), |
| "Remove Emojis": lambda t: t.encode('ascii', 'ignore').decode('ascii'), |
| "Remove Numbers": lambda t: re.sub(r'\d+', '', t), |
| "Remove Non-ASCII": lambda t: re.sub(r'[^\x00-\x7F]+', '', t), |
| "Unescape HTML": lambda t: html.unescape(t), |
| "Text Reverse": lambda t: t[::-1], |
| "Word Reverse": lambda t: " ".join(t.split()[::-1]), |
| "Sort Lines A-Z": lambda t: "\n".join(sorted(t.splitlines())), |
| "Sort Lines Z-A": lambda t: "\n".join(sorted(t.splitlines(), reverse=True)), |
| "Shuffle Lines": lambda t: "\n".join(random.sample(t.splitlines(), len(t.splitlines()))), |
| |
| |
| "Add Line Breaks (<br>)": lambda t: t.replace("\n", "<br>\n"), |
| "Wrap in <p> Tags": lambda t: "\n".join([f"<p>{line}</p>" for line in t.splitlines() if line.strip()]), |
| "List Maker (Bullets)": lambda t: "<ul>\n" + "\n".join([f" <li>{line}</li>" for line in t.splitlines() if line.strip()]) + "\n</ul>", |
| "List Maker (Numbered)": lambda t: "<ol>\n" + "\n".join([f" <li>{line}</li>" for line in t.splitlines() if line.strip()]) + "\n</ol>", |
| "Markdown to HTML Bold": lambda t: re.sub(r'\*\*(.*?)\*\*', r'<b>\1</b>', t), |
| "HTML to Markdown Bold": lambda t: re.sub(r'<b>(.*?)</b>', r'**\1**', t), |
| "Strip All HTML Tags": lambda t: re.sub(r'<[^>]+>', '', t), |
| "Obfuscate Emails": lambda t: re.sub(r'([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})', r'[email protected]', t), |
| "Format Date (DD/MM/YYYY)": lambda t: t, |
| "Tab to 4 Spaces": lambda t: t.replace("\t", " "), |
| "Slugify (URL Friendly)": lambda t: re.sub(r'[^a-z0-9]+', '-', t.lower()).strip('-'), |
| "Add Target='_blank'": lambda t: t.replace('<a ', '<a target="_blank" '), |
| "Add Rel='nofollow'": lambda t: t.replace('<a ', '<a rel="nofollow" '), |
| |
| |
| "Minify JSON": lambda t: json.dumps(json.loads(t), separators=(',', ':')) if t.strip() else "", |
| "Beautify JSON": lambda t: json.dumps(json.loads(t), indent=4) if t.strip() else "", |
| "Escape HTML Entities": lambda t: html.escape(t), |
| "Escape JSON String": lambda t: json.dumps(t), |
| "Base64 Encode": lambda t: base64.b64encode(t.encode()).decode(), |
| "Base64 Decode": lambda t: base64.b64decode(t.encode()).decode(), |
| "URL Encode": lambda t: urllib.parse.quote(t), |
| "URL Decode": lambda t: urllib.parse.unquote(t), |
| "Hex to RGB": lambda t: "\n".join([f"rgb({int(h[1:3], 16)}, {int(h[3:5], 16)}, {int(h[5:7], 16)})" for h in re.findall(r'#[0-9a-fA-F]{6}', t)]), |
| |
| |
| "Blogger: Fix Image Sizes": lambda t: re.sub(r'(width|height)="\d+"', '', t), |
| "Blogger: HTTPS Force": lambda t: t.replace("http://", "https://"), |
| "Clean MS Word Junk": lambda t: re.sub(r'class="Mso.*?"', '', t), |
| "Remove Inline Styles": lambda t: re.sub(r'style=".*?"', '', t), |
| "Remove Script Tags": lambda t: re.sub(r'<script.*?>.*?</script>', '', t, flags=re.DOTALL), |
| "Remove Comments": lambda t: re.sub(r'', '', t, flags=re.DOTALL), |
| } |
|
|
| |
| |
| col1, col2 = st.columns([1, 1]) |
| |
| with col1: |
| st.subheader("Input") |
| text_input = st.text_area("Paste text here", value=st.session_state.replacer_input, height=350, key="input_widget") |
| |
| |
| if text_input != st.session_state.replacer_input: |
| st.session_state.replacer_input = text_input |
|
|
| with col2: |
| st.subheader("Control Panel") |
| |
| mode = st.radio("Select Mode:", ["🟢 Normal Mode", "🔴 Developer Mode"], horizontal=True) |
| |
| selected_ops = [] |
| |
| if mode == "🟢 Normal Mode": |
| st.info("Tools for Writing, SEO, and Formatting") |
| with st.expander("✨ Cleaning Tools", expanded=True): |
| if st.button("Remove Double Spaces"): selected_ops.append("Remove Double Spaces") |
| if st.button("Trim Whitespace"): selected_ops.append("Trim Whitespace") |
| if st.button("Remove Empty Lines"): selected_ops.append("Remove Empty Lines") |
| if st.button("Remove Duplicate Lines"): selected_ops.append("Remove Duplicate Lines") |
| if st.button("Remove Special Chars"): selected_ops.append("Remove Special Characters") |
| |
| with st.expander("🔠 Casing Tools"): |
| c1, c2, c3 = st.columns(3) |
| with c1: |
| if st.button("UPPERCASE"): selected_ops.append("UPPERCASE") |
| if st.button("Sentence Case"): selected_ops.append("Sentence Case") |
| with c2: |
| if st.button("lowercase"): selected_ops.append("lowercase") |
| if st.button("Title Case"): selected_ops.append("Title Case") |
| with c3: |
| if st.button("Toggle Case"): selected_ops.append("tOGGLE cASE") |
| |
| with st.expander("📄 Formatting"): |
| if st.button("Make HTML List (Bullet)"): selected_ops.append("List Maker (Bullets)") |
| if st.button("Make HTML List (Number)"): selected_ops.append("List Maker (Numbered)") |
| if st.button("Smart Quotes -> Straight"): selected_ops.append("Smart Quotes to Straight") |
| if st.button("Slugify Text"): selected_ops.append("Slugify (URL Friendly)") |
|
|
| else: |
| st.error("Tools for Code, Regex, and Backend") |
| |
| |
| with st.expander("🔍 Regex Find & Replace", expanded=True): |
| regex_find = st.text_input("Find Pattern (Regex)", value="") |
| regex_repl = st.text_input("Replace With", value="") |
| if st.button("Run Regex Replace"): |
| try: |
| st.session_state.replacer_input = re.sub(regex_find, regex_repl, st.session_state.replacer_input) |
| st.success("Regex Applied!") |
| st.rerun() |
| except Exception as e: |
| st.error(f"Regex Error: {e}") |
|
|
| with st.expander("💻 Encoders / Decoders"): |
| c1, c2 = st.columns(2) |
| with c1: |
| if st.button("Base64 Encode"): selected_ops.append("Base64 Encode") |
| if st.button("URL Encode"): selected_ops.append("URL Encode") |
| with c2: |
| if st.button("Base64 Decode"): selected_ops.append("Base64 Decode") |
| if st.button("URL Decode"): selected_ops.append("URL Decode") |
| |
| with st.expander("🧹 Code Cleaning"): |
| if st.button("Minify JSON"): selected_ops.append("Minify JSON") |
| if st.button("Beautify JSON"): selected_ops.append("Beautify JSON") |
| if st.button("Escape HTML"): selected_ops.append("Escape HTML Entities") |
| |
| with st.expander("🅱️ Blogger Specific"): |
| if st.button("Clean MS Word Junk"): selected_ops.append("Clean MS Word Junk") |
| if st.button("Force HTTPS"): selected_ops.append("Blogger: HTTPS Force") |
| if st.button("Remove Inline Styles"): selected_ops.append("Remove Inline Styles") |
| if st.button("Remove Scripts"): selected_ops.append("Remove Script Tags") |
|
|
| |
| st.write("---") |
| st.caption("📊 Live Analysis") |
| char_count = len(st.session_state.replacer_input) |
| word_count = len(st.session_state.replacer_input.split()) |
| st.write(f"**Chars:** {char_count} | **Words:** {word_count}") |
|
|
| |
| |
| if selected_ops: |
| current_text = st.session_state.replacer_input |
| for op_name in selected_ops: |
| try: |
| |
| current_text = ops[op_name](current_text) |
| st.toast(f"Applied: {op_name}") |
| except Exception as e: |
| st.error(f"Error in {op_name}: {e}") |
| |
| |
| st.session_state.replacer_input = current_text |
| st.rerun() |
|
|
| |
| if st.session_state.replacer_input: |
| st.download_button( |
| label="Download Result", |
| data=st.session_state.replacer_input, |
| file_name="lexical_cleaned.txt", |
| mime="text/plain" |
| ) |
|
|
|
|
| |
|
|
|
|
| def run_ultimate_pdf_converter(): |
| """ |
| The Ultimate Text-to-PDF Converter (Stable Version). |
| Features: |
| - Auto-Healing Font Loader (Fixes TTLibError) |
| - Smart Symbols & Typography |
| - Markdown Engine (Headers, Tables, Code Blocks) |
| - LMS Junk Cleaner |
| """ |
|
|
| |
| SMART_SYMBOLS = { |
| r'<->': '↔', r'->': '→', r'<-': '←', r'=>': '⇒', r'<=': '≤', r'>=': '≥', r'!=': '≠', |
| r'\.\.\.': '…', r'\(c\)': '©', r'\(r\)': '®', r'\(tm\)': '™', |
| r'\+-': '±', r'\~=': '≈', r'--': '—', |
| r'alpha': 'α', r'beta': 'β', r'theta': 'θ', r'pi': 'π', r'sigma': 'Σ', |
| r'delta': 'Δ', r'gamma': 'Γ', r'omega': 'Ω', r'mu': 'μ', r'lambda': 'λ', |
| r'deg': '°', r'infinity': '∞', r'sqrt': '√' |
| } |
|
|
| |
| class UltimatePDF(FPDF): |
| def __init__(self, orientation='P', unit='mm', format='A4'): |
| super().__init__(orientation=orientation, unit=unit, format=format) |
| self.set_auto_page_break(auto=True, margin=15) |
| self.main_font = 'Arial' |
| self.ensure_fonts() |
|
|
| def ensure_fonts(self): |
| font_filename = "DejaVuSans.ttf" |
| font_url = "https://github.com/dejavu-fonts/dejavu-fonts/raw/master/ttf/DejaVuSans.ttf" |
| |
| |
| if os.path.exists(font_filename): |
| if os.path.getsize(font_filename) < 1000: |
| os.remove(font_filename) |
| |
| |
| if not os.path.exists(font_filename): |
| try: |
| |
| headers = {'User-Agent': 'Mozilla/5.0'} |
| r = requests.get(font_url, headers=headers, timeout=10) |
| if r.status_code == 200: |
| with open(font_filename, "wb") as f: |
| f.write(r.content) |
| except Exception as e: |
| print(f"Font download failed: {e}") |
|
|
| |
| try: |
| if os.path.exists(font_filename): |
| self.add_font('DejaVu', '', font_filename, uni=True) |
| self.main_font = 'DejaVu' |
| except Exception: |
| |
| try: os.remove(font_filename) |
| except: pass |
| self.main_font = 'Arial' |
| st.toast("⚠️ Font failed to load. Using standard font (some symbols may be missing).", icon="⚠️") |
|
|
| def header(self): |
| if getattr(self, 'show_header', False): |
| self.set_font(self.main_font, '', 8) |
| self.set_text_color(128) |
| self.cell(0, 10, f'Generated by Ultimate PDF | {getattr(self, "title_meta", "Doc")}', 0, 0, 'R') |
| self.ln(10) |
|
|
| def footer(self): |
| self.set_y(-15) |
| self.set_font(self.main_font, '', 8) |
| self.set_text_color(128) |
| self.cell(0, 10, f'Page {self.page_no()}', 0, 0, 'C') |
|
|
| |
| def add_markdown_header(self, text, level): |
| sizes = {1: 20, 2: 16, 3: 14} |
| self.set_font(self.main_font, '', sizes.get(level, 12)) |
| self.set_text_color(0, 50, 100) |
| self.cell(0, 10, text, ln=True) |
| self.set_text_color(0) |
| self.set_font(self.main_font, '', 12) |
|
|
| def add_code_block(self, code_lines): |
| self.set_font("Courier", size=10) |
| self.set_fill_color(245, 245, 245) |
| for line in code_lines: |
| |
| safe_line = line.replace('\t', ' ') |
| self.cell(0, 5, safe_line, ln=True, fill=True, border=0) |
| self.set_font(self.main_font, '', 12) |
| self.ln(3) |
|
|
| def add_table(self, table_lines): |
| self.set_font(self.main_font, '', 10) |
| cell_h = 7 |
| for row in table_lines: |
| cols = [c.strip() for c in row.split('|') if c.strip()] |
| if not cols: continue |
| col_w = (self.w - 30) // len(cols) |
| for col in cols: |
| self.cell(col_w, cell_h, col, border=1) |
| self.ln() |
| self.set_font(self.main_font, '', 12) |
| self.ln(5) |
|
|
| def add_blockquote(self, text): |
| self.set_text_color(80) |
| self.set_x(self.l_margin + 8) |
| self.multi_cell(0, 6, f"“ {text}") |
| self.set_x(self.l_margin) |
| self.set_text_color(0) |
| self.ln(2) |
|
|
| def add_image_from_url(self, url): |
| try: |
| r = requests.get(url, timeout=5) |
| if r.status_code == 200: |
| img_data = BytesIO(r.content) |
| self.image(img_data, w=100) |
| self.ln(5) |
| except: |
| self.set_text_color(200, 0, 0) |
| self.cell(0, 10, f"[Image load failed: {url}]", ln=True) |
| self.set_text_color(0) |
|
|
| |
| def clean_and_parse(raw_text, use_smart_symbols=True, clean_lms=True): |
| processed_lines = [] |
| |
| |
| if clean_lms: |
| |
| patterns = [ |
| r'\[ID:?\s*\w+\]', |
| r'Question\s+ID\s*[:\-]\s*\w+', |
| r'\(\d+\s*pts?\)', |
| r'Select one:', |
| r'\[\d{1,2}:\d{2}\s*(AM|PM)?\]' |
| ] |
| for p in patterns: |
| raw_text = re.sub(p, '', raw_text, flags=re.IGNORECASE) |
| raw_text = re.sub(r'\n{3,}', '\n\n', raw_text) |
|
|
| |
| if use_smart_symbols: |
| for pattern, symbol in SMART_SYMBOLS.items(): |
| if pattern.isalpha(): |
| raw_text = re.sub(r'\b' + pattern + r'\b', symbol, raw_text, flags=re.IGNORECASE) |
| else: |
| raw_text = re.sub(pattern, symbol, raw_text) |
|
|
| lines = raw_text.split('\n') |
| |
| |
| buffer_type = None |
| buffer_content = [] |
|
|
| for line in lines: |
| line_stripped = line.strip() |
|
|
| |
| if line_stripped.startswith('```'): |
| if buffer_type == 'code': |
| processed_lines.append({'type': 'code', 'content': buffer_content}) |
| buffer_content = [] |
| buffer_type = None |
| else: |
| if buffer_type == 'table': |
| processed_lines.append({'type': 'table', 'content': buffer_content}) |
| buffer_content = [] |
| buffer_type = 'code' |
| continue |
| |
| if buffer_type == 'code': |
| buffer_content.append(line) |
| continue |
|
|
| |
| if '|' in line_stripped and len(line_stripped) > 3: |
| if buffer_type != 'table': |
| buffer_type = 'table' |
| buffer_content.append(line_stripped) |
| continue |
| elif buffer_type == 'table': |
| processed_lines.append({'type': 'table', 'content': buffer_content}) |
| buffer_content = [] |
| buffer_type = None |
|
|
| |
| if line_stripped.startswith('#'): |
| level = line_stripped.count('#') |
| text = line_stripped.replace('#', '').strip() |
| processed_lines.append({'type': 'header', 'level': min(level, 3), 'content': text}) |
| continue |
|
|
| |
| if line_stripped.startswith('> '): |
| processed_lines.append({'type': 'quote', 'content': line_stripped[2:]}) |
| continue |
|
|
| |
| if line_stripped.startswith('http') and line_stripped.lower().endswith(('.png', '.jpg', '.jpeg', '.webp')): |
| processed_lines.append({'type': 'image', 'url': line_stripped}) |
| continue |
|
|
| |
| if line_stripped.startswith(('* ', '- ')): |
| processed_lines.append({'type': 'list', 'content': line_stripped[2:]}) |
| continue |
| |
| |
| if line_stripped == '---': |
| processed_lines.append({'type': 'hr'}) |
| continue |
|
|
| if line_stripped: |
| processed_lines.append({'type': 'text', 'content': line_stripped}) |
| else: |
| processed_lines.append({'type': 'empty'}) |
|
|
| if buffer_type == 'table': |
| processed_lines.append({'type': 'table', 'content': buffer_content}) |
| |
| return processed_lines |
|
|
| |
| st.title("⚡ Ultimate PDF Engine") |
| |
| with st.expander("ℹ️ Help & Features", expanded=False): |
| st.write("- **Smart Symbols:** Writes 'alpha' as α, '->' as →") |
| st.write("- **Tables:** Use `| Name | Score |` format") |
| st.write("- **Code:** Use ` ``` ` for code blocks") |
| st.write("- **Images:** Paste URL on new line") |
|
|
| |
| with st.sidebar: |
| st.header("⚙️ PDF Config") |
| filename = st.text_input("Filename", "My_Notes.pdf") |
| orientation = st.radio("Orientation", ["Portrait", "Landscape"]) |
| st.subheader("Filters") |
| enable_lms = st.checkbox("Clean LMS Junk", True) |
| enable_smart = st.checkbox("Smart Symbols", True) |
| enable_header = st.checkbox("Show Header", True) |
| font_size = st.slider("Font Size", 8, 24, 12) |
|
|
| |
| raw_input = st.text_area("Paste text here...", height=350) |
|
|
| |
| if st.button("🚀 Generate PDF", type="primary"): |
| if not raw_input.strip(): |
| st.warning("Input is empty.") |
| return |
|
|
| with st.spinner("Processing..."): |
| |
| orient_code = 'P' if orientation == "Portrait" else 'L' |
| pdf = UltimatePDF(orientation=orient_code) |
| pdf.title_meta = filename.replace('.pdf', '') |
| pdf.show_header = enable_header |
| |
| pdf.add_page() |
| pdf.set_font(pdf.main_font, '', font_size) |
|
|
| |
| blocks = clean_and_parse(raw_input, use_smart_symbols=enable_smart, clean_lms=enable_lms) |
|
|
| |
| for block in blocks: |
| if block['type'] == 'header': |
| pdf.add_markdown_header(block['content'], block['level']) |
| elif block['type'] == 'code': |
| pdf.add_code_block(block['content']) |
| elif block['type'] == 'table': |
| pdf.add_table(block['content']) |
| elif block['type'] == 'quote': |
| pdf.add_blockquote(block['content']) |
| elif block['type'] == 'image': |
| pdf.add_image_from_url(block['url']) |
| elif block['type'] == 'list': |
| pdf.set_x(pdf.l_margin + 5) |
| pdf.write(8, f"• {block['content']}") |
| pdf.ln() |
| pdf.set_x(pdf.l_margin) |
| elif block['type'] == 'hr': |
| pdf.ln(2) |
| pdf.line(pdf.l_margin, pdf.get_y(), pdf.w - pdf.r_margin, pdf.get_y()) |
| pdf.ln(5) |
| elif block['type'] == 'text': |
| pdf.write(8, block['content']) |
| pdf.ln() |
| elif block['type'] == 'empty': |
| pdf.ln(4) |
|
|
| |
| try: |
| pdf_bytes = pdf.output(dest='S').encode('latin-1', 'replace') |
| st.success("PDF Generated Successfully!") |
| st.download_button( |
| "⬇️ Download PDF", |
| data=pdf_bytes, |
| file_name=filename if filename.endswith('.pdf') else f"{filename}.pdf", |
| mime="application/pdf" |
| ) |
| except Exception as e: |
| st.error(f"Error creating PDF file: {e}") |
|
|
|
|
|
|
| |
|
|
| |
| import streamlit as st |
| from huggingface_hub import InferenceClient |
| import os |
|
|
| |
| |
| @st.cache_data(show_spinner="Analyzing code with Qwen AI...") |
| def get_seo_data(code_snippet, file_type, api_key): |
| """ |
| Sends code to Hugging Face Inference API and returns SEO/JSON-LD strategy. |
| """ |
| if not code_snippet: |
| return None, "⚠️ Please paste some code first." |
| |
| if not api_key: |
| return None, "❌ Error: HF_TOKEN not found in secrets." |
|
|
| try: |
| client = InferenceClient(api_key=api_key) |
| |
| |
| system_instruction = f""" |
| You are an expert Technical SEO Specialist. Analyze the user's {file_type} code. |
| |
| Task: Generate Google-compliant JSON-LD structured data and SEO meta tags. |
| |
| Output Format (Strict Markdown): |
| ## SEO Metadata |
| **Title:** [Engaging Title, max 60 chars] |
| **Description:** [Summary including keywords, max 160 chars] |
| **Keywords:** [5-8 comma-separated keywords] |
| |
| ## JSON-LD Structured Data |
| ```json |
| [Insert VALID JSON-LD here. |
| - If Python: Use schema.org/SoftwareSourceCode |
| - If HTML: Use schema.org/WebPage or schema.org/TechArticle] |
| ``` |
| """ |
| |
| user_message = f"Analyze this {file_type} code:\n\n{code_snippet}" |
|
|
| response = client.chat_completion( |
| model="Qwen/Qwen2.5-Coder-32B-Instruct", |
| messages=[ |
| {"role": "system", "content": system_instruction}, |
| {"role": "user", "content": user_message} |
| ], |
| max_tokens=1500, |
| temperature=0.2 |
| ) |
| return response.choices[0].message.content, None |
|
|
| except Exception as e: |
| return None, f"Error: {str(e)}" |
|
|
| |
| def render_seo_ui(): |
| """ |
| Call this function in your main app.py where you want the SEO tool to show up. |
| """ |
| st.header("🚀 AI Code-to-SEO Generator") |
| st.markdown("Generate **JSON-LD** and **Meta Tags** for your Python/HTML files using Qwen 2.5 Coder.") |
|
|
| |
| try: |
| hf_token = st.secrets["HF_TOKEN"] |
| except: |
| hf_token = os.getenv("HF_TOKEN") |
|
|
| with st.form("seo_form"): |
| col1, col2 = st.columns([1, 3]) |
| |
| with col1: |
| file_type = st.radio("File Type", ["Python", "HTML"]) |
| |
| with col2: |
| code_input = st.text_area("Paste Code Here", height=300, placeholder="import os...") |
| |
| submitted = st.form_submit_button("✨ Generate SEO Data") |
|
|
| if submitted: |
| if not hf_token: |
| st.error("Authentication Error: Please add `HF_TOKEN` to your Streamlit secrets.") |
| else: |
| result, error = get_seo_data(code_input, file_type, hf_token) |
| |
| if error: |
| st.error(error) |
| else: |
| st.success("SEO Data Generated Successfully!") |
| st.markdown("---") |
| st.markdown(result) |
| |
| |
| st.download_button( |
| label="📥 Download Result", |
| data=result, |
| file_name="seo_strategy.md", |
| mime="text/markdown" |
| ) |
|
|
|
|
| |
|
|
| def tool_youtube_downloader(): |
| st.header("🎥 YouTube Media Extractor") |
| url = st.text_input("Paste YouTube URL", placeholder="https://youtube.com/...") |
| format_type = st.radio("Format", ["Video (MP4)", "Audio Only (MP3)"], horizontal=True) |
| |
| if url and st.button("🚀 Process Media"): |
| with st.spinner("Contacting server..."): |
| try: |
| headers = {"Accept": "application/json", "Content-Type": "application/json"} |
| payload = { |
| "url": url, |
| "vQuality": "1080", |
| "isAudioOnly": True if "Audio" in format_type else False |
| } |
| |
| response = requests.post("https://api.cobalt.tools/api/json", headers=headers, json=payload) |
| data = response.json() |
| |
| if "url" in data: |
| st.success("✅ Ready!") |
| st.link_button(f"⬇️ Download {format_type}", data["url"]) |
| if "Audio" not in format_type: |
| st.video(data["url"]) |
| else: |
| st.audio(data["url"]) |
| else: |
| st.error(f"Error: {data.get('text', 'Unknown error')}") |
| except Exception as e: |
| st.error(f"Connection failed: {str(e)}") |
|
|
| def tool_smart_converter(): |
| with st.spinner("Starting File Engine..."): |
| |
| time.sleep(0.3) |
| |
| |
| import pandas as pd |
| st.header("🔄 Smart File Converter") |
| st.info("Supports: Images (PNG/JPG/WEBP) and Data (CSV/JSON/Excel)") |
| |
| uploaded_file = st.file_uploader("Upload File", type=['png', 'jpg', 'jpeg', 'webp', 'csv', 'json', 'xlsx'],key="smart_conv_upload") |
| |
| if uploaded_file: |
| file_type = uploaded_file.name.split('.')[-1].lower() |
| |
| |
| if file_type in ['png', 'jpg', 'jpeg', 'webp']: |
| image = Image.open(uploaded_file) |
| st.image(image, caption="Preview", width=300) |
| target_format = st.selectbox("Convert to:", ["PNG", "JPEG", "WEBP", "PDF"]) |
| |
| if st.button("Convert Image"): |
| buf = io.BytesIO() |
| |
| if image.mode in ("RGBA", "P") and target_format in ["JPEG", "PDF"]: |
| image = image.convert("RGB") |
| |
| image.save(buf, format=target_format) |
| st.download_button(f"Download {target_format}", data=buf.getvalue(), file_name=f"converted.{target_format.lower()}") |
|
|
| |
| elif file_type in ['csv', 'json', 'xlsx']: |
| df = None |
| try: |
| if file_type == 'csv': df = pd.read_csv(uploaded_file) |
| elif file_type == 'json': df = pd.read_json(uploaded_file) |
| elif file_type == 'xlsx': df = pd.read_excel(uploaded_file) |
| |
| st.write("Data Preview:", df.head()) |
| target_data = st.selectbox("Convert to:", ["CSV", "JSON", "Excel"]) |
| |
| if st.button("Convert Data"): |
| buf = io.BytesIO() |
| if target_data == "CSV": |
| df.to_csv(buf, index=False) |
| ext = "csv" |
| elif target_data == "JSON": |
| df.to_json(buf, orient='records') |
| ext = "json" |
| elif target_data == "Excel": |
| df.to_excel(buf, index=False) |
| ext = "xlsx" |
| |
| st.download_button(f"Download {target_data}", data=buf.getvalue(), file_name=f"converted.{ext}") |
| except Exception as e: |
| st.error(f"Error reading file: {e}") |
|
|
| def tool_image_compressor(): |
| st.header("📉 Image Compressor") |
| |
| uploaded_file = st.file_uploader("Upload Image", type=['png', 'jpg', 'jpeg'], key="compressor") |
| |
| |
| |
| if uploaded_file: |
| image = Image.open(uploaded_file) |
| st.write(f"Original Size: {uploaded_file.size / 1024:.2f} KB") |
| quality = st.slider("Quality (Lower = Smaller file)", 10, 95, 60) |
| |
| if st.button("Compress"): |
| buf = io.BytesIO() |
| if image.mode in ("RGBA", "P"): image = image.convert("RGB") |
| image.save(buf, format="JPEG", quality=quality, optimize=True) |
| |
| size_kb = len(buf.getvalue()) / 1024 |
| st.success(f"Compressed Size: {size_kb:.2f} KB") |
| st.download_button("Download Compressed Image", data=buf.getvalue(), file_name="compressed.jpg") |
|
|
| def tool_image_resizer(): |
| st.header("📐 Image Resizer") |
| |
| uploaded_file = st.file_uploader("Upload Image", type=['png', 'jpg', 'jpeg', 'webp'], key="resizer") |
| |
| |
| |
| if uploaded_file: |
| image = Image.open(uploaded_file) |
| st.write(f"Current Dimensions: {image.size}") |
| |
| col1, col2 = st.columns(2) |
| w = col1.number_input("Width", value=image.width) |
| h = col2.number_input("Height", value=image.height) |
| |
| if st.button("Resize"): |
| new_img = image.resize((int(w), int(h))) |
| buf = io.BytesIO() |
| new_img.save(buf, format=image.format) |
| st.image(new_img, caption="Resized Preview") |
| st.download_button("Download Resized Image", data=buf.getvalue(), file_name=f"resized.{image.format.lower()}") |
|
|
| def tool_thumbnail_generator(): |
| st.header("🚀 Ultimate Thumbnail Studio") |
| |
| |
| from PIL import Image, ImageDraw, ImageFont, ImageFilter, ImageEnhance, ImageOps, ImageColor |
| import io |
|
|
| |
| |
| |
| |
| |
| with st.expander("🎨 Thumbnail Settings & Controls", expanded=True): |
| col_c1, col_c2 = st.columns(2) |
| |
| |
| with col_c1: |
| st.subheader("1. Background & Filters") |
| bg_mode = st.radio("Background Type", ["Upload Image", "Solid Color", "Gradient"], horizontal=True) |
| |
| bg_image = None |
| if bg_mode == "Upload Image": |
| bg_file = st.file_uploader("Upload BG", type=['png', 'jpg', 'jpeg', 'webp'], key="max_bg") |
| if bg_file: bg_image = Image.open(bg_file).convert("RGBA") |
| elif bg_mode == "Solid Color": |
| hex_bg = st.color_picker("Pick Color", "#1E1E1E") |
| st.session_state.thumb_bg_color = hex_bg |
| else: |
| c1_col, c2_col = st.columns(2) |
| grad_c1 = c1_col.color_picker("Start", "#12c2e9") |
| grad_c2 = c2_col.color_picker("End", "#c471ed") |
| grad_dir = st.selectbox("Direction", ["Horizontal", "Vertical"]) |
|
|
| st.markdown("---") |
| st.write("**Filters**") |
| f1, f2 = st.columns(2) |
| blur_amt = f1.slider("Blur", 0, 20, 0) |
| brightness = f2.slider("Brightness", 0.5, 1.5, 1.0) |
| |
| |
| with col_c2: |
| st.subheader("2. Text & Branding") |
| main_text = st.text_area("Main Title", "THE ULTIMATE\nGUIDE TO PYTHON", height=100) |
| |
| t1, t2 = st.columns(2) |
| font_size = t1.slider("Size", 20, 200, 80) |
| font_color = t2.color_picker("Text Color", "#FFFFFF") |
| |
| st.write("**Styling**") |
| s1, s2 = st.columns(2) |
| stroke_width = s1.slider("Outline", 0, 10, 2) |
| stroke_color = s2.color_picker("Outline Color", "#000000") |
| |
| st.markdown("---") |
| logo_file = st.file_uploader("Upload Logo (PNG)", type=['png', 'webp'], key="max_logo") |
| if logo_file: |
| l1, l2 = st.columns(2) |
| logo_size = l1.slider("Logo Size", 50, 300, 150) |
| logo_pos = l2.selectbox("Position", ["Top-Right", "Top-Left", "Bottom-Right", "Bottom-Left"]) |
| else: |
| logo_size = 150 |
| logo_pos = "Top-Right" |
|
|
| |
| st.subheader("👁️ Preview & Download") |
| |
| |
| CANVAS_W, CANVAS_H = 1280, 720 |
| canvas = Image.new("RGBA", (CANVAS_W, CANVAS_H), (0,0,0,0)) |
| |
| |
| if bg_mode == "Upload Image" and bg_image: |
| bg_ratio = bg_image.width / bg_image.height |
| target_ratio = CANVAS_W / CANVAS_H |
| if bg_ratio > target_ratio: |
| new_h = CANVAS_H |
| new_w = int(new_h * bg_ratio) |
| else: |
| new_w = CANVAS_W |
| new_h = int(new_w / bg_ratio) |
| bg_image = bg_image.resize((new_w, new_h), Image.Resampling.LANCZOS) |
| left = (new_w - CANVAS_W)/2 |
| top = (new_h - CANVAS_H)/2 |
| bg_image = bg_image.crop((left, top, left+CANVAS_W, top+CANVAS_H)) |
| canvas.paste(bg_image, (0,0)) |
| elif bg_mode == "Gradient": |
| base = Image.new('RGB', (CANVAS_W, CANVAS_H), grad_c1) |
| top_img = Image.new('RGB', (CANVAS_W, CANVAS_H), grad_c2) |
| mask = Image.new("L", (CANVAS_W, CANVAS_H)) |
| mask_data = [] |
| for y in range(CANVAS_H): |
| for x in range(CANVAS_W): |
| if grad_dir == "Vertical": mask_data.append(int(255 * (y / CANVAS_H))) |
| else: mask_data.append(int(255 * (x / CANVAS_W))) |
| mask.putdata(mask_data) |
| canvas = Image.composite(top_img, base, mask).convert("RGBA") |
| else: |
| if 'thumb_bg_color' not in st.session_state: st.session_state.thumb_bg_color = "#1E1E1E" |
| canvas = Image.new("RGBA", (CANVAS_W, CANVAS_H), st.session_state.thumb_bg_color) |
|
|
| |
| if blur_amt > 0: canvas = canvas.filter(ImageFilter.GaussianBlur(blur_amt)) |
| if brightness != 1.0: |
| enhancer = ImageEnhance.Brightness(canvas) |
| canvas = enhancer.enhance(brightness) |
|
|
| |
| txt_layer = Image.new("RGBA", canvas.size, (255,255,255,0)) |
| draw = ImageDraw.Draw(txt_layer) |
| |
| try: |
| font = ImageFont.truetype("arialbd.ttf", font_size) |
| except: |
| try: |
| font = ImageFont.truetype("arial.ttf", font_size) |
| except: |
| font = ImageFont.load_default() |
|
|
| |
| |
| try: |
| bbox = draw.multiline_textbbox((0,0), main_text, font=font, align="center") |
| text_w = bbox[2] - bbox[0] |
| text_h = bbox[3] - bbox[1] |
| except: |
| |
| text_w, text_h = draw.textsize(main_text, font=font) |
|
|
| cx, cy = CANVAS_W // 2, CANVAS_H // 2 |
| text_x = cx - (text_w // 2) |
| text_y = cy - (text_h // 2) |
|
|
| |
| draw.multiline_text((text_x + 8, text_y + 8), main_text, font=font, align="center", fill="black") |
| |
| draw.multiline_text((text_x, text_y), main_text, font=font, align="center", fill=font_color, stroke_width=stroke_width, stroke_fill=stroke_color) |
|
|
| |
| if logo_file: |
| logo = Image.open(logo_file).convert("RGBA") |
| logo.thumbnail((logo_size, logo_size), Image.Resampling.LANCZOS) |
| pad = 30 |
| if "Top" in logo_pos: ly = pad |
| elif "Bottom" in logo_pos: ly = CANVAS_H - logo.height - pad |
| if "Left" in logo_pos: lx = pad |
| elif "Right" in logo_pos: lx = CANVAS_W - logo.width - pad |
| txt_layer.paste(logo, (lx, ly), logo) |
|
|
| |
| final_comp = Image.alpha_composite(canvas, txt_layer) |
|
|
| |
| |
| col_show, col_down = st.columns([3, 1]) |
| |
| with col_show: |
| |
| st.image(final_comp, caption="Result", use_column_width=True) |
| |
| with col_down: |
| st.write("### Ready?") |
| buf = io.BytesIO() |
| final_comp.convert("RGB").save(buf, format="PNG") |
| st.download_button("💾 Download PNG", data=buf.getvalue(), file_name="thumbnail.png", mime="image/png") |
| |
| |
| if __name__ == "__main__": |
| st.set_page_config(page_title="Lexical Space Tools", layout="centered") |
| |
| |
| params = st.query_params |
| mode = params.get("mode", "home") |
|
|
| |
| |
| |
| |
| |
|
|
| def tool_meta_tag_generator(): |
| st.header("🏷️ Meta Tag Generator") |
| title = st.text_input("Site Title", "My Awesome Blog") |
| desc = st.text_area("Description", "A blog about technology and coding.") |
| keywords = st.text_input("Keywords (comma separated)", "tech, coding, python") |
| author = st.text_input("Author", "Lexical Space") |
| |
| if st.button("Generate Tags"): |
| code = f""" |
| <title>{title}</title> |
| <meta name="description" content="{desc}"> |
| <meta name="keywords" content="{keywords}"> |
| <meta name="author" content="{author}"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <meta property="og:type" content="website"> |
| <meta property="og:title" content="{title}"> |
| <meta property="og:description" content="{desc}"> |
| """ |
| st.code(code, language="html") |
|
|
| def tool_slug_generator(): |
| st.header("🐌 URL Slug Generator") |
| text = st.text_input("Enter Post Title", "How to Install Python on Windows 10!") |
| |
| if text: |
| |
| slug = text.lower().strip() |
| slug = re.sub(r'[^a-z0-9\s-]', '', slug) |
| slug = re.sub(r'[\s-]+', '-', slug) |
| st.success(f"Slug: {slug}") |
| st.code(slug, language="text") |
|
|
| def tool_robots_generator(): |
| st.header("🤖 Robots.txt Generator") |
| st.write("Control which crawlers can access your site.") |
| |
| all_agents = st.checkbox("Apply to all robots (*)", value=True) |
| disallow_admin = st.checkbox("Disallow /admin", value=True) |
| disallow_private = st.checkbox("Disallow /private", value=False) |
| sitemap_url = st.text_input("Sitemap URL (Optional)", "https://yoursite.com/sitemap.xml") |
| |
| if st.button("Generate Robots.txt"): |
| agent = "*" if all_agents else "Googlebot" |
| txt = f"User-agent: {agent}\n" |
| if disallow_admin: txt += "Disallow: /admin/\n" |
| if disallow_private: txt += "Disallow: /private/\n" |
| if sitemap_url: txt += f"\nSitemap: {sitemap_url}" |
| |
| st.text_area("Result", txt, height=150) |
|
|
| def tool_sitemap_builder(): |
| st.header("🗺️ XML Sitemap Builder") |
| urls = st.text_area("Paste URLs (one per line)", "https://site.com\nhttps://site.com/about") |
| |
| if st.button("Build XML"): |
| xml = '<?xml version="1.0" encoding="UTF-8"?>\n' |
| xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n' |
| |
| for url in urls.split('\n'): |
| if url.strip(): |
| xml += f' <url>\n <loc>{url.strip()}</loc>\n <changefreq>monthly</changefreq>\n </url>\n' |
| |
| xml += '</urlset>' |
| st.text_area("Sitemap.xml", xml, height=200) |
|
|
| def tool_keyword_density(): |
| with st.spinner("Loading Analytics..."): |
| import pandas as pd |
| from collections import Counter |
| |
| |
| st.header("📊 Keyword Density Checker") |
| text = st.text_area("Paste Article Text", height=200,key="density_text") |
| |
| if st.button("Analyze"): |
| |
| stopwords = set(['the', 'and', 'is', 'in', 'it', 'of', 'to', 'a', 'for', 'on', 'that', 'with', 'as']) |
| |
| words = re.findall(r'\w+', text.lower()) |
| filtered = [w for w in words if w not in stopwords and len(w) > 2] |
| |
| counts = Counter(filtered).most_common(10) |
| |
| df = pd.DataFrame(counts, columns=["Keyword", "Count"]) |
| df['Density %'] = (df['Count'] / len(words) * 100).round(2) |
| st.table(df) |
|
|
| def tool_plagiarism_check(): |
| st.header("🕵️ Plagiarism Scanner (Google Check)") |
| st.info("Splits text into sentences and searches Google for exact matches.") |
| text = st.text_area("Paste Text to Check", height=150,key="plag_text") |
| |
| if st.button("Check Text"): |
| sentences = re.split(r'[.!?]', text) |
| clean_sentences = [s.strip() for s in sentences if len(s.strip()) > 20] |
| |
| for i, s in enumerate(clean_sentences[:5]): |
| query = f'"{s}"' |
| url = f"https://www.google.com/search?q={query}" |
| st.markdown(f"**Sentence {i+1}:** {s[:50]}...") |
| st.link_button(f"🔍 Check Google for Match", url) |
|
|
| def tool_code_minifier(): |
| st.header("🧹 Code Minifier") |
| mode = st.radio("Type", ["HTML", "CSS"]) |
| raw_code = st.text_area("Input Code", height=200) |
| |
| if st.button("Minify"): |
| minified = "" |
| if mode == "HTML": |
| |
| lines = raw_code.split('\n') |
| minified = "".join([line.strip() for line in lines]) |
| elif mode == "CSS": |
| |
| |
| minified = re.sub(r'/\*[\s\S]*?\*/', '', raw_code) |
| |
| minified = re.sub(r'\s*([{:;,])\s*', r'\1', minified) |
| |
| minified = minified.replace('\n', '').replace('\r', '') |
| |
| st.text_area("Minified Output", minified, height=200) |
| |
|
|
| def tool_qr_generator(): |
| with st.spinner("Initializing QR Tool..."): |
| import qrcode |
| import io |
| |
| st.header("🏁 QR Code Generator") |
| data = st.text_input("Enter Link or Text", "https://lexicalspace.blogspot.com") |
| |
| if data: |
| qr = qrcode.QRCode(version=1, box_size=10, border=5) |
| qr.add_data(data) |
| qr.make(fit=True) |
| img = qr.make_image(fill='black', back_color='white') |
| |
| buf = io.BytesIO() |
| img.save(buf) |
| st.image(img.get_image(), width=300) |
| st.download_button("Download QR", data=buf.getvalue(), file_name="qrcode.png") |
|
|
| def tool_json_formatter(): |
| st.header("✨ JSON Prettifier") |
| raw = st.text_area("Paste Messy JSON", '{"id":1,"name":"Lexical","roles":["admin","dev"]}', height=150) |
| |
| col1, col2 = st.columns(2) |
| if col1.button("Format (Pretty)"): |
| try: |
| parsed = json.loads(raw) |
| st.code(json.dumps(parsed, indent=4), language="json") |
| except Exception as e: |
| st.error(f"Invalid JSON: {e}") |
| |
| if col2.button("Minify (Compact)"): |
| try: |
| parsed = json.loads(raw) |
| st.code(json.dumps(parsed, separators=(',', ':')), language="json") |
| except Exception as e: |
| st.error(f"Invalid JSON: {e}") |
|
|
| def tool_base64(): |
| st.header("🔐 Base64 Converter") |
| mode = st.radio("Action", ["Encode", "Decode"], horizontal=True) |
| text = st.text_area("Input Text") |
| |
| if st.button("Process"): |
| try: |
| if mode == "Encode": |
| res = base64.b64encode(text.encode()).decode() |
| else: |
| res = base64.b64decode(text).decode() |
| st.code(res) |
| except Exception as e: |
| st.error(f"Error: {e}") |
|
|
| def tool_url_encoder(): |
| st.header("🔗 URL Encoder/Decoder") |
| text = st.text_input("Input URL", "https://example.com/search?q=hello world") |
| |
| c1, c2 = st.columns(2) |
| with c1: |
| if st.button("Encode"): |
| st.code(urllib.parse.quote(text)) |
| with c2: |
| if st.button("Decode"): |
| st.code(urllib.parse.unquote(text)) |
|
|
| def tool_markdown_editor(): |
| st.header("📝 Markdown Editor") |
| |
| col1, col2 = st.columns(2) |
| with col1: |
| md_text = st.text_area("Write Markdown", "# Hello\n* Item 1\n* Item 2", height=400) |
| |
| with col2: |
| st.markdown("### Preview") |
| st.markdown(md_text) |
|
|
| def tool_regex_tester(): |
| st.header("🧪 Regex Tester") |
| pattern = st.text_input("Regex Pattern", r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b") |
| text = st.text_area("Test String", "Contact us at support@lexical.com or admin@site.org") |
| |
| if pattern and text: |
| try: |
| matches = re.findall(pattern, text) |
| st.write(f"Found {len(matches)} matches:") |
| st.json(matches) |
| except Exception as e: |
| st.error(f"Regex Error: {e}") |
|
|
| def tool_uuid_gen(): |
| st.header("🆔 UUID/GUID Generator") |
| count = st.number_input("How many?", 1, 100, 5) |
| |
| if st.button("Generate"): |
| uuids = [str(uuid.uuid4()) for _ in range(count)] |
| st.code("\n".join(uuids), language="text") |
|
|
| def tool_hash_gen(): |
| st.header("🔑 Hash Generator") |
| text = st.text_input("Input String", "mypassword") |
| |
| if text: |
| st.write("**MD5:**") |
| st.code(hashlib.md5(text.encode()).hexdigest()) |
| st.write("**SHA256:**") |
| st.code(hashlib.sha256(text.encode()).hexdigest()) |
| |
|
|
| |
| elif mode == "qrcode": tool_qr_generator() |
| elif mode == "json": tool_json_formatter() |
| elif mode == "base64": tool_base64() |
| elif mode == "url": tool_url_encoder() |
| elif mode == "markdown": tool_markdown_editor() |
| elif mode == "regex": tool_regex_tester() |
| elif mode == "uuid": tool_uuid_gen() |
| elif mode == "hash": tool_hash_gen() |
|
|
| |
| |
| st.write("### 🛠️ Developer Tools") |
| st.markdown(""" |
| * [🏁 QR Code Gen](?mode=qrcode) |
| * [✨ JSON Prettifier](?mode=json) |
| * [🔐 Base64 Converter](?mode=base64) |
| * [🔗 URL Encode/Decode](?mode=url) |
| * [📝 Markdown Editor](?mode=markdown) |
| * [🧪 Regex Tester](?mode=regex) |
| * [🆔 UUID Generator](?mode=uuid) |
| * [🔑 Hash Generator](?mode=hash) |
| """) |
| |
|
|
| def tool_case_converter(): |
| st.header("🔠 Case Converter") |
| text = st.text_area("Input Text", "hello world") |
| |
| c1, c2, c3, c4 = st.columns(4) |
| if c1.button("UPPERCASE"): st.code(text.upper(), language="text") |
| if c2.button("lowercase"): st.code(text.lower(), language="text") |
| if c3.button("Title Case"): st.code(text.title(), language="text") |
| if c4.button("aLtErNaTiNg"): |
| res = "".join([c.upper() if i%2==0 else c.lower() for i, c in enumerate(text)]) |
| st.code(res, language="text") |
|
|
| def tool_lorem_ipsum(): |
| st.header("📜 Lorem Ipsum Generator") |
| paras = st.slider("Paragraphs", 1, 10, 3) |
| |
| dummy_text = [ |
| "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", |
| "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", |
| "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.", |
| "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum.", |
| "Excepteur sint occaecat cupidatat non proident, sunt in culpa." |
| ] |
| |
| if st.button("Generate"): |
| result = "\n\n".join([random.choice(dummy_text) * 3 for _ in range(paras)]) |
| st.text_area("Result", result, height=200) |
|
|
| def tool_word_counter(): |
| st.header("🧮 Word & Character Counter") |
| text = st.text_area("Paste Text Here", height=200,key="counter_text") |
| |
| if text: |
| words = len(text.split()) |
| chars = len(text) |
| no_space = len(text.replace(" ", "")) |
| read_time = round(words / 200, 2) |
| |
| c1, c2, c3, c4 = st.columns(4) |
| c1.metric("Words", words) |
| c2.metric("Chars", chars) |
| c3.metric("No Spaces", no_space) |
| c4.metric("Read Time", f"{read_time} min") |
|
|
| def tool_remove_duplicates(): |
| st.header("🗑️ Remove Duplicate Lines") |
| text = st.text_area("Paste List (One per line)", "Apple\nBanana\nApple\nOrange") |
| |
| if st.button("Clean"): |
| lines = text.split('\n') |
| seen = set() |
| clean = [] |
| for line in lines: |
| if line not in seen and line.strip(): |
| clean.append(line) |
| seen.add(line) |
| st.text_area("Cleaned List", "\n".join(clean), height=200) |
|
|
| def tool_text_to_speech(): |
| with st.spinner("Loading Audio Engine..."): |
| from gtts import gTTS |
| import io |
| |
| st.header("🗣️ Text to Speech") |
| text = st.text_area("Enter Text", "Hello, welcome to Lexical Space.") |
| lang = st.selectbox("Language", ["en", "es", "fr", "de", "hi"],key="tts_text") |
| |
| if st.button("Speak"): |
| try: |
| tts = gTTS(text=text, lang=lang, slow=False) |
| buf = io.BytesIO() |
| tts.write_to_fp(buf) |
| st.audio(buf, format='audio/mp3') |
| except Exception as e: |
| st.error(f"Error: {e}") |
|
|
| def tool_timestamp(): |
| st.header("⏰ Unix Timestamp Converter") |
| now = int(time.time()) |
| st.write(f"Current Timestamp: `{now}`") |
| |
| col1, col2 = st.columns(2) |
| with col1: |
| ts_input = st.number_input("Timestamp to Date", value=now) |
| if st.button("Convert to Date"): |
| st.success(datetime.datetime.fromtimestamp(ts_input)) |
| |
| with col2: |
| d_input = st.date_input("Date to Timestamp") |
| if st.button("Convert to Timestamp"): |
| ts = int(time.mktime(d_input.timetuple())) |
| st.success(ts) |
|
|
| def tool_color_palette(): |
| st.header("🎨 Image Color Palette") |
| |
| uploaded_file = st.file_uploader("Upload Image", type=['jpg', 'png'], key="palette") |
| |
| |
| |
| if uploaded_file: |
| img = Image.open(uploaded_file).convert("RGB") |
| st.image(img, width=200) |
| |
| |
| small = img.resize((5, 1)) |
| colors = small.getdata() |
| |
| st.write("Dominant Colors:") |
| cols = st.columns(5) |
| for i, color in enumerate(colors): |
| hex_code = '#{:02x}{:02x}{:02x}'.format(*color) |
| cols[i].color_picker(f"Color {i+1}", hex_code, disabled=True) |
| cols[i].code(hex_code) |
|
|
| def tool_password_strength(): |
| st.header("💪 Password Strength") |
| pwd = st.text_input("Test Password", type="password") |
| |
| if pwd: |
| score = 0 |
| if len(pwd) >= 8: score += 1 |
| if re.search(r"[A-Z]", pwd): score += 1 |
| if re.search(r"[a-z]", pwd): score += 1 |
| if re.search(r"\d", pwd): score += 1 |
| if re.search(r"[!@#$%^&*]", pwd): score += 1 |
| |
| st.progress(score / 5) |
| if score < 3: st.warning("Weak") |
| elif score < 5: st.info("Moderate") |
| else: st.success("Strong!") |
|
|
| def tool_aspect_ratio(): |
| st.header("🖥️ Aspect Ratio Calculator") |
| w = st.number_input("Width", 1920) |
| h = st.number_input("Height", 1080) |
| |
| if w and h: |
| def gcd(a, b): |
| while b: a, b = b, a % b |
| return a |
| divisor = gcd(int(w), int(h)) |
| st.metric("Aspect Ratio", f"{int(w/divisor)}:{int(h/divisor)}") |
|
|
| def tool_stopwatch(): |
| st.header("⏱️ Stopwatch") |
| if 'start_time' not in st.session_state: st.session_state.start_time = None |
| |
| if st.button("Start/Reset"): |
| st.session_state.start_time = time.time() |
| |
| if st.session_state.start_time: |
| elapsed = time.time() - st.session_state.start_time |
| st.metric("Time Elapsed", f"{elapsed:.2f}s") |
| if st.button("Stop"): |
| st.session_state.start_time = None |
|
|
|
|
| def tool_python_checker(): |
| st.header("🐍 Python Syntax & Error Checker") |
| st.markdown("Paste your Python code or upload a `.py` file to check for syntax errors.") |
|
|
| |
| import tempfile |
| import os |
| import io |
| try: |
| from pylint.lint import Run |
| from pylint.reporters.text import TextReporter |
| except ImportError: |
| st.error("⚠️ Pylint is not installed. Please add `pylint` to your requirements.txt") |
| return |
|
|
| |
| col1, col2 = st.columns(2) |
| with col1: |
| paste_code = st.text_area("Paste Code Here", height=300) |
| with col2: |
| file_obj = st.file_uploader("Or Upload .py File", type=[".py"]) |
|
|
| |
| if st.button("Check Syntax 🚀", type="primary"): |
| code_to_check = "" |
|
|
| |
| if file_obj is not None: |
| try: |
| code_to_check = file_obj.getvalue().decode("utf-8") |
| except Exception as e: |
| st.error(f"❌ Error reading file: {str(e)}") |
| return |
| elif paste_code.strip() != "": |
| code_to_check = paste_code |
| else: |
| st.warning("⚠️ Please either paste code or upload a file.") |
| return |
|
|
| |
| |
| with tempfile.NamedTemporaryFile(delete=False, suffix=".py", mode='w', encoding='utf-8') as temp: |
| temp.write(code_to_check) |
| temp_path = temp.name |
|
|
| |
| pylint_output = io.StringIO() |
| reporter = TextReporter(pylint_output) |
| |
| with st.spinner("Analyzing syntax..."): |
| try: |
| |
| Run([temp_path, "--errors-only"], reporter=reporter, exit=False) |
| except Exception as e: |
| st.error(f"System Error: {e}") |
|
|
| |
| os.unlink(temp_path) |
| result = pylint_output.getvalue() |
|
|
| st.markdown("---") |
| if not result: |
| st.success("✅ No Syntax Errors Found! (Code looks valid)") |
| st.balloons() |
| else: |
| st.error("❌ Errors Found:") |
| |
| clean_report = result.replace(temp_path, "Your_Script.py") |
| st.code(clean_report, language="text") |
| |
|
|
| |
| if __name__ == "__main__": |
| |
| if 'mode' not in st.session_state: |
| st.session_state.mode = 'home' |
|
|
|
|
| |
| |
| def set_mode(new_mode): |
| st.session_state.mode = new_mode |
|
|
| |
| if st.session_state.mode != 'home': |
| if st.button("⬅️ Back to Grid"): |
| set_mode('home') |
| st.rerun() |
|
|
| |
| mode = st.session_state.mode |
| |
| if mode == "youtube": tool_youtube_downloader() |
| elif mode == "smart_converter": tool_smart_converter() |
| elif mode == "compressor": tool_image_compressor() |
| elif mode == "resizer": tool_image_resizer() |
| elif mode == "thumbnail": tool_thumbnail_generator() |
| elif mode == "metatags": tool_meta_tag_generator() |
| elif mode == "slug": tool_slug_generator() |
| elif mode == "robots": tool_robots_generator() |
| elif mode == "sitemap": tool_sitemap_builder() |
| elif mode == "density": tool_keyword_density() |
| elif mode == "plagiarism": tool_plagiarism_check() |
| elif mode == "minify": tool_code_minifier() |
| elif mode == "qrcode": tool_qr_generator() |
| elif mode == "json": tool_json_formatter() |
| elif mode == "base64": tool_base64() |
| elif mode == "url": tool_url_encoder() |
| elif mode == "markdown": tool_markdown_editor() |
| elif mode == "regex": tool_regex_tester() |
| elif mode == "uuid": tool_uuid_gen() |
| elif mode == "hash": tool_hash_gen() |
| elif mode == "case": tool_case_converter() |
| elif mode == "lorem": tool_lorem_ipsum() |
| elif mode == "counter": tool_word_counter() |
| elif mode == "dedupe": tool_remove_duplicates() |
| elif mode == "tts": tool_text_to_speech() |
| elif mode == "timestamp": tool_timestamp() |
| elif mode == "palette": tool_color_palette() |
| elif mode == "password": tool_password_strength() |
| elif mode == "ratio": tool_aspect_ratio() |
| elif mode == "stopwatch": tool_stopwatch() |
| elif mode == "python": tool_python_checker() |
| elif mode == "seo": render_seo_ui() |
| elif mode == "Pdf Converter": run_ultimate_pdf_converter() |
| elif mode == "Replacer Tool": lexical_replacer_tool() |
| |
| |
| else: |
| st.write("### ⚡ Select a tool to get started:") |
| |
| |
| |
| |
| c1, c2 = st.columns(2) |
| |
| with c1: |
| st.info("**📂 Media & Files**") |
| if st.button("Converter"): set_mode("Replacer Tool"); st.rerun() |
| if st.button("🎥 Pdf"): set_mode("Pdf Converter"); st.rerun() |
| if st.button("🎥 YouTube Downloader"): set_mode("youtube"); st.rerun() |
| if st.button("🎥 Seo Generator"): set_mode("seo"); st.rerun() |
| |
| if st.button("🔄 Smart File Converter"): set_mode("smart_converter"); st.rerun() |
| if st.button("📉 Image Compressor"): set_mode("compressor"); st.rerun() |
| if st.button("📐 Image Resizer"): set_mode("resizer"); st.rerun() |
| if st.button("🖼️ Thumbnail Gen"): set_mode("thumbnail"); st.rerun() |
| |
| st.info("**🛠️ Developer Tools**") |
| if st.button("🏁 QR Code Gen"): set_mode("qrcode"); st.rerun() |
| if st.button("✨ JSON Prettifier"): set_mode("json"); st.rerun() |
| if st.button("🔐 Base64 Converter"): set_mode("base64"); st.rerun() |
| if st.button("🔗 URL Encoder"): set_mode("url"); st.rerun() |
| if st.button("📝 Markdown Editor"): set_mode("markdown"); st.rerun() |
| if st.button("🧪 Regex Tester"): set_mode("regex"); st.rerun() |
| if st.button("🆔 UUID Gen"): set_mode("uuid"); st.rerun() |
| if st.button("🔑 Hash Gen"): set_mode("hash"); st.rerun() |
|
|
| with c2: |
| st.info("**🕸️ SEO & Webmaster**") |
| if st.button("🏷️ Meta Tag Gen"): set_mode("metatags"); st.rerun() |
| if st.button("🐌 Slug Generator"): set_mode("slug"); st.rerun() |
| if st.button("🤖 Robots.txt Gen"): set_mode("robots"); st.rerun() |
| if st.button("🗺️ Sitemap Builder"): set_mode("sitemap"); st.rerun() |
| if st.button("📊 Density Checker"): set_mode("density"); st.rerun() |
| if st.button("🕵️ Plagiarism Check"): set_mode("plagiarism"); st.rerun() |
| if st.button("🧹 Code Minifier"): set_mode("minify"); st.rerun() |
|
|
| st.info("**📝 Text & Utilities**") |
| if st.button("🔠 Case Converter"): set_mode("case"); st.rerun() |
| if st.button("📜 Lorem Ipsum"): set_mode("lorem"); st.rerun() |
| if st.button("🧮 Word Counter"): set_mode("counter"); st.rerun() |
| if st.button("🗑️ Dedupe Lines"): set_mode("dedupe"); st.rerun() |
| if st.button("🗣️ Text to Speech"): set_mode("tts"); st.rerun() |
| if st.button("⏰ Unix Timestamp"): set_mode("timestamp"); st.rerun() |
| if st.button("🎨 Color Palette"): set_mode("palette"); st.rerun() |
| if st.button("💪 Password Strength"): set_mode("password"); st.rerun() |
| if st.button("🖥️ Aspect Ratio"): set_mode("ratio"); st.rerun() |
| if st.button("⏱️ Stopwatch"): set_mode("stopwatch"); st.rerun() |
| if st.button("Python Checker"): set_mode("python"); st.rerun() |