shukdev3's picture
Update app.py
137cedc verified
Raw
History Blame Contribute Delete
9.61 kB
import gradio as gr
import unicodeconverter as uc
from weasyprint import HTML
import os
import tempfile
import shutil
import re
from groq import Groq
from docx import Document
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
# Default font (fallback)
DEFAULT_FONT_PATH = os.path.abspath("SolaimanLipi_22-02-2012.ttf")
HAS_DEFAULT_FONT = os.path.exists(DEFAULT_FONT_PATH)
def detect_and_preserve_english(text, groq_api_key):
"""
Use Groq AI to identify English segments in mixed Bijoy-English text
Returns a list of tuples: (text_segment, is_english)
"""
try:
client = Groq(api_key=groq_api_key)
prompt = f"""You are a text analyzer. Analyze this text and identify which parts are English and which are Bijoy-encoded Bengali.
Text: {text}
Return a JSON array where each element is an object with:
- "text": the text segment
- "is_english": true if English, false if Bijoy Bengali
Rules:
1. English segments include: letters (a-z, A-Z), common punctuation, numbers in English context
2. Bijoy segments include: Bengali-encoded characters with special symbols
3. Preserve exact spacing and punctuation
4. Split at language boundaries
Example output format:
[
{{"text": "bijoy text here", "is_english": false}},
{{"text": " This is English.", "is_english": true}},
{{"text": " more bijoy", "is_english": false}}
]
Return ONLY the JSON array, nothing else."""
response = client.chat.completions.create(
messages=[{"role": "user", "content": prompt}],
model="llama-3.3-70b-versatile",
temperature=0.1,
max_tokens=2000
)
result_text = response.choices[0].message.content.strip()
# Extract JSON from response
json_match = re.search(r'\[.*\]', result_text, re.DOTALL)
if json_match:
import json
segments = json.loads(json_match.group())
return segments
else:
return [{"text": text, "is_english": False}]
except Exception as e:
print(f"Groq API Error: {e}")
return [{"text": text, "is_english": False}]
def create_txt_file(unicode_text):
"""Create a TXT file with the converted Unicode text"""
temp_txt = tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode='w', encoding='utf-8')
temp_txt.write(unicode_text)
temp_txt.close()
return temp_txt.name
def create_docx_file(unicode_text):
"""Create a DOCX file with the converted Unicode text"""
doc = Document()
# Add paragraph with Bengali text
paragraph = doc.add_paragraph(unicode_text)
# Format the paragraph
paragraph_format = paragraph.paragraph_format
paragraph_format.line_spacing = 1.5
paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT
# Format the text run
for run in paragraph.runs:
run.font.size = Pt(12)
run.font.name = 'Noto Sans Bengali'
run.font.color.rgb = RGBColor(0, 0, 0)
# Save to temp file
temp_docx = tempfile.NamedTemporaryFile(delete=False, suffix=".docx")
temp_docx.close()
doc.save(temp_docx.name)
return temp_docx.name
def bijoy_to_all_formats(bijoy_text, uploaded_font, groq_api_key):
try:
if not groq_api_key or groq_api_key.strip() == "":
return "Error: Please enter your Groq API key.", None, None, None
# Detect and separate English and Bijoy segments
segments = detect_and_preserve_english(bijoy_text, groq_api_key)
# Convert only Bijoy segments to Unicode
converted_segments = []
for segment in segments:
if segment["is_english"]:
converted_segments.append(segment["text"])
else:
try:
unicode_segment = uc.convert_bijoy_to_unicode(segment["text"])
converted_segments.append(unicode_segment)
except:
converted_segments.append(segment["text"])
unicode_text = "".join(converted_segments)
# Generate TXT file
txt_path = create_txt_file(unicode_text)
# Generate DOCX file
docx_path = create_docx_file(unicode_text)
# Determine font path for PDF
if uploaded_font is not None:
temp_font_dir = tempfile.mkdtemp()
font_path = os.path.join(temp_font_dir, os.path.basename(uploaded_font.name))
shutil.copy(uploaded_font.name, font_path)
else:
if not HAS_DEFAULT_FONT:
raise FileNotFoundError(
"No font uploaded and default SolaimanLipi font not found."
)
font_path = DEFAULT_FONT_PATH
# HTML content for PDF
html_content = f"""
<!DOCTYPE html>
<html lang="bn">
<head>
<meta charset="UTF-8">
<style>
@page {{
size: A4;
margin: 1in;
}}
@font-face {{
font-family: 'UserBengaliFont';
src: url('file://{font_path}');
}}
body {{
font-family: 'UserBengaliFont', 'Noto Sans Bengali', Arial, sans-serif;
font-size: 12pt;
line-height: 18pt;
color: #000;
}}
p {{
margin-bottom: 12pt;
text-align: left;
}}
</style>
</head>
<body>
<p>{unicode_text}</p>
</body>
</html>
"""
# Create PDF
temp_pdf = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf")
temp_pdf.close()
HTML(string=html_content).write_pdf(
temp_pdf.name,
presentational_hints=True
)
return unicode_text, temp_pdf.name, docx_path, txt_path
except Exception as e:
return f"Error: {str(e)}", None, None, None
# -------------------------------------------------
# BIJOY TEXT EXAMPLES
# -------------------------------------------------
bijoy_examples = [
"""‡nj‡g‡Ui wb‡P mvbM­vm| mKvj‡eLv‡b cÖwZw`b gvbyl ‡Kvyvi g‡Zv RvqMv _v‡K bv| ‡divi c‡_ Zviv Avcbvi mgq, kÖg Ges AwfÁZv‡K GKmv‡_ wb‡q Rxeb cÖwZ‡e`b K‡i|""",
"""evsjv‡`‡ki cÖK…wZ gvby‡li g‡b wewfbœ Av‡eM m„wó K‡i| b`x, cvnv‡o Ges meyR gvwUi mv‡_ gvby‡li AvZœxq m¤úK© AvMvb _v‡K| G mgqB Zviv cÖK…wZi m~ÿ wQšÍv K‡i|""",
"""wkÿv gvb‡e Rxeb‡K cÖKvwkZ K‡i Ges gvbwmK w`K _v‡K m„wó K‡i| wkÿv Qvov gvbyl AwbðqZvi g‡a¨ _v‡K Ges mvgvwRK weKv‡k cÖwZKzjZvi m¤§yLxb nq|""",
"""AvaywbK cÖhyw³ gvby‡li `xN©Rxeb‡K m¤ú~Y©iƒ‡c cwieZ©b K‡i‡Q| cÖhyw³i e¨envi Avgv‡`i KvR‡K mnR K‡i Ges mgq euvPvq, Z‡e myweav m¤ú‡K© mZK© _vKvI cÖ‡qvRb|""",
"""mvgvwRK g~j¨‡eva gvby‡li AvPiY Ges AvPib‡K wbqš¿Y K‡i| mZ¨Zv, b¨vq Ges m¤§vb gvb‡ei g‡a¨ GK‡gvmZ cÖKvk K‡i Ges mvgvwRK m¤úªxwZi Dci AwZ¸i"Z¡c~Y©|"""
]
# -------------------------------------------------
# GRADIO UI
# -------------------------------------------------
with gr.Blocks(title="Bijoy to Unicode Bengali Converter", theme=gr.themes.Ocean()) as app:
gr.Markdown("## 📝 Bijoy → Unicode Bengali Converter (PDF + DOCX + TXT)")
gr.Markdown(
"**Features:**\n"
"- Convert Bijoy Bangla to Unicode using AI\n"
"- Automatically detects and preserves English text\n"
"- Generate PDF, DOCX, and TXT files\n"
"- Upload your preferred Bengali font (.ttf)\n\n"
"**Note:** You need a free Groq API key. Get one at [https://console.groq.com](https://console.groq.com)"
)
groq_key_input = gr.Textbox(
label="Groq API Key",
placeholder="Enter your Groq API key here (e.g., gsk_...)",
type="password"
)
bijoy_input = gr.Textbox(
label="Bijoy Text (Mixed Bengali & English)",
placeholder="Paste Bijoy-encoded Bangla text with English here...",
lines=10
)
font_input = gr.File(
label="Optional Bengali Font (.ttf)",
file_types=[".ttf"]
)
convert_btn = gr.Button("Convert & Generate All Files", variant="primary")
unicode_output = gr.Textbox(
label="Converted Unicode Text",
lines=10,
show_copy_button=True
)
with gr.Row():
pdf_output = gr.File(label="📄 Download PDF")
docx_output = gr.File(label="📝 Download DOCX")
txt_output = gr.File(label="📃 Download TXT")
gr.Examples(
examples=bijoy_examples,
inputs=bijoy_input,
label="📌 Example Bijoy Texts"
)
convert_btn.click(
fn=bijoy_to_all_formats,
inputs=[bijoy_input, font_input, groq_key_input],
outputs=[unicode_output, pdf_output, docx_output, txt_output]
)
gr.Markdown(
"---\n"
"### How to get Groq API Key:\n"
"1. Visit [console.groq.com](https://console.groq.com)\n"
"2. Sign up for free\n"
"3. Create an API key\n"
"4. Paste it above\n\n"
"### Output Files:\n"
"- **PDF**: Print-ready with custom font support\n"
"- **DOCX**: Editable Word document\n"
"- **TXT**: Plain text Unicode file\n\n"
"The app uses the free **llama-3.3-70b-versatile** model to detect English text."
)
app.launch()