Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI | |
| from fastapi.responses import FileResponse, JSONResponse | |
| from pydantic import BaseModel | |
| import uuid | |
| import os | |
| import glob | |
| import re | |
| import pypandoc | |
| app = FastAPI() | |
| # Control de descargas por archivo | |
| descargas = {} | |
| class MarkdownInput(BaseModel): | |
| content: str | |
| # Reemplaza '---' por saltos de línea | |
| def limpiar_lineas_hr(markdown_text: str) -> str: | |
| return re.sub(r'^\s*---\s*$', '\n', markdown_text, flags=re.MULTILINE) | |
| # Convierte \[...\] y \(...\) a $$...$$ y $...$ | |
| def normalizar_ecuaciones(md: str) -> str: | |
| md = re.sub(r'\\\[\s*(.*?)\s*\\\]', r'$$\1$$', md, flags=re.DOTALL) | |
| md = re.sub(r'\\\(\s*(.*?)\s*\\\)', r'$\1$', md, flags=re.DOTALL) | |
| return md | |
| def save_markdown_to_file(content: str, path: str): | |
| with open(path, "w", encoding="utf-8") as f: | |
| f.write(content) | |
| def convert_markdown_to_docx(input_md: str, output_docx: str): | |
| pypandoc.convert_file( | |
| source_file=input_md, | |
| to="docx", | |
| format="md", | |
| outputfile=output_docx, | |
| extra_args=["--standalone"] | |
| ) | |
| def limpieza(): | |
| for ext in ["*.docx", "*.md"]: | |
| for file in glob.glob(ext): | |
| try: | |
| os.remove(file) | |
| except Exception as e: | |
| print(f"No se pudo eliminar {file}: {e}") | |
| def convert(data: MarkdownInput): | |
| try: | |
| limpieza() | |
| uid = str(uuid.uuid4()) | |
| input_md = f"{uid}.md" | |
| output_docx = f"{uid}.docx" | |
| contenido_limpio = limpiar_lineas_hr(data.content) | |
| contenido_limpio = normalizar_ecuaciones(contenido_limpio) | |
| save_markdown_to_file(contenido_limpio, input_md) | |
| convert_markdown_to_docx(input_md, output_docx) | |
| os.remove(input_md) | |
| descargas[uid] = 0 | |
| return { | |
| "message": "Archivo generado exitosamente, para descargar acceder a la URL", | |
| "url": f"https://jairodanielmt-markdown-docx.hf.space/download/{uid}" | |
| } | |
| except Exception as e: | |
| return JSONResponse(content={"error": str(e)}, status_code=500) | |
| def download(file_id: str): | |
| output_docx = f"{file_id}.docx" | |
| if not os.path.exists(output_docx): | |
| return JSONResponse( | |
| content={"error": "El archivo no existe o ya fue eliminado."}, | |
| status_code=404 | |
| ) | |
| if file_id not in descargas: | |
| return JSONResponse( | |
| content={"error": "ID de archivo no válido."}, | |
| status_code=400 | |
| ) | |
| if descargas[file_id] >= 2: | |
| os.remove(output_docx) | |
| del descargas[file_id] | |
| return JSONResponse( | |
| content={"error": "El archivo ya no está disponible. Genere uno nuevo."}, | |
| status_code=410 | |
| ) | |
| descargas[file_id] += 1 | |
| return FileResponse( | |
| path=output_docx, | |
| filename="material_educativo.docx", | |
| media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document", | |
| ) | |