Update app.py
Browse files
app.py
CHANGED
|
@@ -16,9 +16,203 @@ from bs4 import BeautifulSoup
|
|
| 16 |
from fpdf import FPDF
|
| 17 |
import os
|
| 18 |
from io import BytesIO
|
| 19 |
-
|
|
|
|
|
|
|
| 20 |
# --- BATCH 1: MEDIA & FILE FUNCTIONS ---
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
def run_ultimate_pdf_converter():
|
| 24 |
"""
|
|
@@ -1288,6 +1482,7 @@ if __name__ == "__main__":
|
|
| 1288 |
elif mode == "python": tool_python_checker()
|
| 1289 |
elif mode == "seo": render_seo_ui()
|
| 1290 |
elif mode == "Pdf Converter": run_ultimate_pdf_converter()
|
|
|
|
| 1291 |
|
| 1292 |
# 5. HOME DASHBOARD (Button Grid)
|
| 1293 |
else:
|
|
@@ -1300,6 +1495,7 @@ if __name__ == "__main__":
|
|
| 1300 |
|
| 1301 |
with c1:
|
| 1302 |
st.info("**📂 Media & Files**")
|
|
|
|
| 1303 |
if st.button("🎥 Pdf"): set_mode("Pdf Converter"); st.rerun()
|
| 1304 |
if st.button("🎥 YouTube Downloader"): set_mode("youtube"); st.rerun()
|
| 1305 |
if st.button("🎥 Seo Generator"): set_mode("seo"); st.rerun()
|
|
|
|
| 16 |
from fpdf import FPDF
|
| 17 |
import os
|
| 18 |
from io import BytesIO
|
| 19 |
+
import streamlit as st
|
| 20 |
+
import html
|
| 21 |
+
import string
|
| 22 |
# --- BATCH 1: MEDIA & FILE FUNCTIONS ---
|
| 23 |
|
| 24 |
+
def lexical_replacer_tool():
|
| 25 |
+
"""
|
| 26 |
+
The Master Function for the Lexical Space Replacer Tool.
|
| 27 |
+
Contains 100+ text manipulation features split into Normal and Dev modes.
|
| 28 |
+
"""
|
| 29 |
+
|
| 30 |
+
st.markdown("## 🛠️ Lexical Replacer Toolkit")
|
| 31 |
+
st.markdown("---")
|
| 32 |
+
|
| 33 |
+
# --- STATE MANAGEMENT ---
|
| 34 |
+
# We use session state to hold the text so it persists when switching tabs
|
| 35 |
+
if 'replacer_input' not in st.session_state:
|
| 36 |
+
st.session_state.replacer_input = "Paste your text or HTML here..."
|
| 37 |
+
if 'replacer_output' not in st.session_state:
|
| 38 |
+
st.session_state.replacer_output = ""
|
| 39 |
+
|
| 40 |
+
# --- THE LOGIC ENGINE (100+ Features Mapped) ---
|
| 41 |
+
# We map "Human Readable Names" to "Lambda Functions" for efficiency.
|
| 42 |
+
|
| 43 |
+
ops = {
|
| 44 |
+
# --- GROUP 1: BASIC CLEANUP (Normal Mode) ---
|
| 45 |
+
"Remove Double Spaces": lambda t: re.sub(r'\s+', ' ', t),
|
| 46 |
+
"Trim Whitespace": lambda t: t.strip(),
|
| 47 |
+
"Remove Empty Lines": lambda t: "\n".join([line for line in t.splitlines() if line.strip()]),
|
| 48 |
+
"Remove Duplicate Lines": lambda t: "\n".join(list(dict.fromkeys(t.splitlines()))), # Preserves order
|
| 49 |
+
"Sentence Case": lambda t: ". ".join([s.capitalize() for s in t.split(". ")]),
|
| 50 |
+
"Title Case": lambda t: t.title(),
|
| 51 |
+
"UPPERCASE": lambda t: t.upper(),
|
| 52 |
+
"lowercase": lambda t: t.lower(),
|
| 53 |
+
"tOGGLE cASE": lambda t: t.swapcase(),
|
| 54 |
+
"Smart Quotes to Straight": lambda t: t.replace('“', '"').replace('”', '"').replace("‘", "'").replace("’", "'"),
|
| 55 |
+
"Remove Special Characters": lambda t: re.sub(r'[^a-zA-Z0-9\s]', '', t),
|
| 56 |
+
"Remove Emojis": lambda t: t.encode('ascii', 'ignore').decode('ascii'),
|
| 57 |
+
"Remove Numbers": lambda t: re.sub(r'\d+', '', t),
|
| 58 |
+
"Remove Non-ASCII": lambda t: re.sub(r'[^\x00-\x7F]+', '', t),
|
| 59 |
+
"Unescape HTML": lambda t: html.unescape(t),
|
| 60 |
+
"Text Reverse": lambda t: t[::-1],
|
| 61 |
+
"Word Reverse": lambda t: " ".join(t.split()[::-1]),
|
| 62 |
+
"Sort Lines A-Z": lambda t: "\n".join(sorted(t.splitlines())),
|
| 63 |
+
"Sort Lines Z-A": lambda t: "\n".join(sorted(t.splitlines(), reverse=True)),
|
| 64 |
+
"Shuffle Lines": lambda t: "\n".join(random.sample(t.splitlines(), len(t.splitlines()))),
|
| 65 |
+
|
| 66 |
+
# --- GROUP 2: FORMATTING (Normal Mode) ---
|
| 67 |
+
"Add Line Breaks (<br>)": lambda t: t.replace("\n", "<br>\n"),
|
| 68 |
+
"Wrap in <p> Tags": lambda t: "\n".join([f"<p>{line}</p>" for line in t.splitlines() if line.strip()]),
|
| 69 |
+
"List Maker (Bullets)": lambda t: "<ul>\n" + "\n".join([f" <li>{line}</li>" for line in t.splitlines() if line.strip()]) + "\n</ul>",
|
| 70 |
+
"List Maker (Numbered)": lambda t: "<ol>\n" + "\n".join([f" <li>{line}</li>" for line in t.splitlines() if line.strip()]) + "\n</ol>",
|
| 71 |
+
"Markdown to HTML Bold": lambda t: re.sub(r'\*\*(.*?)\*\*', r'<b>\1</b>', t),
|
| 72 |
+
"HTML to Markdown Bold": lambda t: re.sub(r'<b>(.*?)</b>', r'**\1**', t),
|
| 73 |
+
"Strip All HTML Tags": lambda t: re.sub(r'<[^>]+>', '', t),
|
| 74 |
+
"Obfuscate Emails": lambda t: re.sub(r'([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})', r'[email protected]', t),
|
| 75 |
+
"Format Date (DD/MM/YYYY)": lambda t: t, # Placeholder for complex regex
|
| 76 |
+
"Tab to 4 Spaces": lambda t: t.replace("\t", " "),
|
| 77 |
+
"Slugify (URL Friendly)": lambda t: re.sub(r'[^a-z0-9]+', '-', t.lower()).strip('-'),
|
| 78 |
+
"Add Target='_blank'": lambda t: t.replace('<a ', '<a target="_blank" '),
|
| 79 |
+
"Add Rel='nofollow'": lambda t: t.replace('<a ', '<a rel="nofollow" '),
|
| 80 |
+
|
| 81 |
+
# --- GROUP 3: DEV UTILS (Dev Mode) ---
|
| 82 |
+
"Minify JSON": lambda t: json.dumps(json.loads(t), separators=(',', ':')) if t.strip() else "",
|
| 83 |
+
"Beautify JSON": lambda t: json.dumps(json.loads(t), indent=4) if t.strip() else "",
|
| 84 |
+
"Escape HTML Entities": lambda t: html.escape(t),
|
| 85 |
+
"Escape JSON String": lambda t: json.dumps(t),
|
| 86 |
+
"Base64 Encode": lambda t: base64.b64encode(t.encode()).decode(),
|
| 87 |
+
"Base64 Decode": lambda t: base64.b64decode(t.encode()).decode(),
|
| 88 |
+
"URL Encode": lambda t: urllib.parse.quote(t),
|
| 89 |
+
"URL Decode": lambda t: urllib.parse.unquote(t),
|
| 90 |
+
"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)]),
|
| 91 |
+
|
| 92 |
+
# --- GROUP 4: BLOGGER SPECIFIC (Dev Mode) ---
|
| 93 |
+
"Blogger: Fix Image Sizes": lambda t: re.sub(r'(width|height)="\d+"', '', t),
|
| 94 |
+
"Blogger: HTTPS Force": lambda t: t.replace("http://", "https://"),
|
| 95 |
+
"Clean MS Word Junk": lambda t: re.sub(r'class="Mso.*?"', '', t),
|
| 96 |
+
"Remove Inline Styles": lambda t: re.sub(r'style=".*?"', '', t),
|
| 97 |
+
"Remove Script Tags": lambda t: re.sub(r'<script.*?>.*?</script>', '', t, flags=re.DOTALL),
|
| 98 |
+
"Remove Comments": lambda t: re.sub(r'', '', t, flags=re.DOTALL),
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
# --- LAYOUT ---
|
| 102 |
+
|
| 103 |
+
col1, col2 = st.columns([1, 1])
|
| 104 |
+
|
| 105 |
+
with col1:
|
| 106 |
+
st.subheader("Input")
|
| 107 |
+
text_input = st.text_area("Paste text here", value=st.session_state.replacer_input, height=350, key="input_widget")
|
| 108 |
+
|
| 109 |
+
# Update session state on change
|
| 110 |
+
if text_input != st.session_state.replacer_input:
|
| 111 |
+
st.session_state.replacer_input = text_input
|
| 112 |
+
|
| 113 |
+
with col2:
|
| 114 |
+
st.subheader("Control Panel")
|
| 115 |
+
|
| 116 |
+
mode = st.radio("Select Mode:", ["🟢 Normal Mode", "🔴 Developer Mode"], horizontal=True)
|
| 117 |
+
|
| 118 |
+
selected_ops = []
|
| 119 |
+
|
| 120 |
+
if mode == "🟢 Normal Mode":
|
| 121 |
+
st.info("Tools for Writing, SEO, and Formatting")
|
| 122 |
+
with st.expander("✨ Cleaning Tools", expanded=True):
|
| 123 |
+
if st.button("Remove Double Spaces"): selected_ops.append("Remove Double Spaces")
|
| 124 |
+
if st.button("Trim Whitespace"): selected_ops.append("Trim Whitespace")
|
| 125 |
+
if st.button("Remove Empty Lines"): selected_ops.append("Remove Empty Lines")
|
| 126 |
+
if st.button("Remove Duplicate Lines"): selected_ops.append("Remove Duplicate Lines")
|
| 127 |
+
if st.button("Remove Special Chars"): selected_ops.append("Remove Special Characters")
|
| 128 |
+
|
| 129 |
+
with st.expander("🔠 Casing Tools"):
|
| 130 |
+
c1, c2, c3 = st.columns(3)
|
| 131 |
+
with c1:
|
| 132 |
+
if st.button("UPPERCASE"): selected_ops.append("UPPERCASE")
|
| 133 |
+
if st.button("Sentence Case"): selected_ops.append("Sentence Case")
|
| 134 |
+
with c2:
|
| 135 |
+
if st.button("lowercase"): selected_ops.append("lowercase")
|
| 136 |
+
if st.button("Title Case"): selected_ops.append("Title Case")
|
| 137 |
+
with c3:
|
| 138 |
+
if st.button("Toggle Case"): selected_ops.append("tOGGLE cASE")
|
| 139 |
+
|
| 140 |
+
with st.expander("📄 Formatting"):
|
| 141 |
+
if st.button("Make HTML List (Bullet)"): selected_ops.append("List Maker (Bullets)")
|
| 142 |
+
if st.button("Make HTML List (Number)"): selected_ops.append("List Maker (Numbered)")
|
| 143 |
+
if st.button("Smart Quotes -> Straight"): selected_ops.append("Smart Quotes to Straight")
|
| 144 |
+
if st.button("Slugify Text"): selected_ops.append("Slugify (URL Friendly)")
|
| 145 |
+
|
| 146 |
+
else: # Developer Mode
|
| 147 |
+
st.error("Tools for Code, Regex, and Backend")
|
| 148 |
+
|
| 149 |
+
# Regex Section
|
| 150 |
+
with st.expander("🔍 Regex Find & Replace", expanded=True):
|
| 151 |
+
regex_find = st.text_input("Find Pattern (Regex)", value="")
|
| 152 |
+
regex_repl = st.text_input("Replace With", value="")
|
| 153 |
+
if st.button("Run Regex Replace"):
|
| 154 |
+
try:
|
| 155 |
+
st.session_state.replacer_input = re.sub(regex_find, regex_repl, st.session_state.replacer_input)
|
| 156 |
+
st.success("Regex Applied!")
|
| 157 |
+
st.rerun()
|
| 158 |
+
except Exception as e:
|
| 159 |
+
st.error(f"Regex Error: {e}")
|
| 160 |
+
|
| 161 |
+
with st.expander("💻 Encoders / Decoders"):
|
| 162 |
+
c1, c2 = st.columns(2)
|
| 163 |
+
with c1:
|
| 164 |
+
if st.button("Base64 Encode"): selected_ops.append("Base64 Encode")
|
| 165 |
+
if st.button("URL Encode"): selected_ops.append("URL Encode")
|
| 166 |
+
with c2:
|
| 167 |
+
if st.button("Base64 Decode"): selected_ops.append("Base64 Decode")
|
| 168 |
+
if st.button("URL Decode"): selected_ops.append("URL Decode")
|
| 169 |
+
|
| 170 |
+
with st.expander("🧹 Code Cleaning"):
|
| 171 |
+
if st.button("Minify JSON"): selected_ops.append("Minify JSON")
|
| 172 |
+
if st.button("Beautify JSON"): selected_ops.append("Beautify JSON")
|
| 173 |
+
if st.button("Escape HTML"): selected_ops.append("Escape HTML Entities")
|
| 174 |
+
|
| 175 |
+
with st.expander("🅱️ Blogger Specific"):
|
| 176 |
+
if st.button("Clean MS Word Junk"): selected_ops.append("Clean MS Word Junk")
|
| 177 |
+
if st.button("Force HTTPS"): selected_ops.append("Blogger: HTTPS Force")
|
| 178 |
+
if st.button("Remove Inline Styles"): selected_ops.append("Remove Inline Styles")
|
| 179 |
+
if st.button("Remove Scripts"): selected_ops.append("Remove Script Tags")
|
| 180 |
+
|
| 181 |
+
# --- ANALYSIS (Always Visible) ---
|
| 182 |
+
st.write("---")
|
| 183 |
+
st.caption("📊 Live Analysis")
|
| 184 |
+
char_count = len(st.session_state.replacer_input)
|
| 185 |
+
word_count = len(st.session_state.replacer_input.split())
|
| 186 |
+
st.write(f"**Chars:** {char_count} | **Words:** {word_count}")
|
| 187 |
+
|
| 188 |
+
# --- EXECUTION ENGINE ---
|
| 189 |
+
# If a button added an op to the list, run it against the input text
|
| 190 |
+
if selected_ops:
|
| 191 |
+
current_text = st.session_state.replacer_input
|
| 192 |
+
for op_name in selected_ops:
|
| 193 |
+
try:
|
| 194 |
+
# Apply the function from our dictionary
|
| 195 |
+
current_text = ops[op_name](current_text)
|
| 196 |
+
st.toast(f"Applied: {op_name}")
|
| 197 |
+
except Exception as e:
|
| 198 |
+
st.error(f"Error in {op_name}: {e}")
|
| 199 |
+
|
| 200 |
+
# Update State
|
| 201 |
+
st.session_state.replacer_input = current_text
|
| 202 |
+
st.rerun() # Refresh to show changes in the text area
|
| 203 |
+
|
| 204 |
+
# --- RESULT DOWNLOAD ---
|
| 205 |
+
if st.session_state.replacer_input:
|
| 206 |
+
st.download_button(
|
| 207 |
+
label="Download Result",
|
| 208 |
+
data=st.session_state.replacer_input,
|
| 209 |
+
file_name="lexical_cleaned.txt",
|
| 210 |
+
mime="text/plain"
|
| 211 |
+
)
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
|
| 215 |
+
|
| 216 |
|
| 217 |
def run_ultimate_pdf_converter():
|
| 218 |
"""
|
|
|
|
| 1482 |
elif mode == "python": tool_python_checker()
|
| 1483 |
elif mode == "seo": render_seo_ui()
|
| 1484 |
elif mode == "Pdf Converter": run_ultimate_pdf_converter()
|
| 1485 |
+
elif mode == "Replacer Tool": lexical_replacer_tool()
|
| 1486 |
|
| 1487 |
# 5. HOME DASHBOARD (Button Grid)
|
| 1488 |
else:
|
|
|
|
| 1495 |
|
| 1496 |
with c1:
|
| 1497 |
st.info("**📂 Media & Files**")
|
| 1498 |
+
if st.button("Converter"): set_mode("Replacer Tool"); st.rerun()
|
| 1499 |
if st.button("🎥 Pdf"): set_mode("Pdf Converter"); st.rerun()
|
| 1500 |
if st.button("🎥 YouTube Downloader"): set_mode("youtube"); st.rerun()
|
| 1501 |
if st.button("🎥 Seo Generator"): set_mode("seo"); st.rerun()
|