| | 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() |