import json import logging from datetime import datetime, timezone from logging.handlers import RotatingFileHandler from pathlib import Path import gradio as gr from text_tools import ( analyze_sentiment, analyze_text, check_reading_level, detect_language, extract_keywords, readability_advice, spell_check, summarize_text, ) LOG_DIR = Path("logs") LOG_FILE = LOG_DIR / "mcp.log" def _utc_now_iso() -> str: return datetime.now(timezone.utc).isoformat() class JsonLineFormatter(logging.Formatter): def format(self, record): message = record.getMessage() try: payload = json.loads(message) payload["level"] = record.levelname payload["logger"] = record.name return json.dumps(payload, ensure_ascii=False) except json.JSONDecodeError: return json.dumps({ "timestamp": _utc_now_iso(), "level": record.levelname, "logger": record.name, "message": message, }, ensure_ascii=False) def _configure_logging() -> None: LOG_DIR.mkdir(parents=True, exist_ok=True) root_logger = logging.getLogger() root_logger.setLevel(logging.INFO) text_formatter = logging.Formatter("%(asctime)s %(levelname)s %(name)s %(message)s") stream_handler = logging.StreamHandler() stream_handler.setFormatter(text_formatter) root_logger.addHandler(stream_handler) file_handler = RotatingFileHandler(LOG_FILE, maxBytes=1_000_000, backupCount=3) file_handler.setFormatter(JsonLineFormatter()) root_logger.addHandler(file_handler) with gr.Blocks(title="Text Processor") as demo: gr.Markdown("# Text Processing Tools") gr.Markdown( "Analyze text statistics, extract keywords, check reading difficulty, " "detect sentiment, identify language, summarize text, check spelling, " "and suggest readability improvements." ) with gr.Tab("Analyze Text"): text_input1 = gr.Textbox(label="Enter text", lines=8, placeholder="Paste your text here...") analysis_output = gr.Textbox(label="Analysis Results", lines=8) gr.Button("Analyze", size="lg").click(analyze_text, text_input1, analysis_output) with gr.Tab("Extract Keywords"): text_input2 = gr.Textbox(label="Enter text", lines=8) count_input = gr.Slider(1, 20, value=5, step=1, label="Number of keywords") keywords_output = gr.Textbox(label="Keywords", lines=8) gr.Button("Extract", size="lg").click(extract_keywords, [text_input2, count_input], keywords_output) with gr.Tab("Reading Level"): text_input3 = gr.Textbox(label="Enter text", lines=8) level_output = gr.Textbox(label="Reading Level Analysis", lines=5) gr.Button("Check Level", size="lg").click(check_reading_level, text_input3, level_output) with gr.Tab("Sentiment"): text_input4 = gr.Textbox(label="Enter text", lines=8) sentiment_output = gr.Textbox(label="Sentiment Analysis", lines=6) gr.Button("Analyze Sentiment", size="lg").click(analyze_sentiment, text_input4, sentiment_output) with gr.Tab("Language"): text_input5 = gr.Textbox(label="Enter text", lines=8) language_output = gr.Textbox(label="Language Detection", lines=8) gr.Button("Detect Language", size="lg").click(detect_language, text_input5, language_output) with gr.Tab("Summary"): text_input6 = gr.Textbox(label="Enter text", lines=8) summary_output = gr.Textbox(label="Summary", lines=8) gr.Button("Summarize", size="lg").click(summarize_text, text_input6, summary_output) with gr.Tab("Spell Check"): text_input7 = gr.Textbox(label="Enter text", lines=8) spell_output = gr.Textbox(label="Spelling Analysis", lines=10) gr.Button("Check Spelling", size="lg").click(spell_check, text_input7, spell_output) with gr.Tab("Readability Tips"): text_input8 = gr.Textbox(label="Enter text", lines=8) tips_output = gr.Textbox(label="Readability Advice", lines=10) gr.Button("Get Advice", size="lg").click(readability_advice, text_input8, tips_output) if __name__ == "__main__": _configure_logging() demo.launch(mcp_server=True)