#!/usr/bin/env python3 """ Extract strings for translation and create Spanish .po files """ import os import re from pathlib import Path # Directories TEMPLATES_DIR = Path('templates') TRANSLATIONS_DIR = Path('translations') # Find all template files def find_template_files(): template_files = [] for root, dirs, files in os.walk(TEMPLATES_DIR): for file in files: if file.endswith('.html'): template_files.append(Path(root) / file) return template_files # Extract strings from templates def extract_strings_from_file(filepath): strings = set() with open(filepath, 'r', encoding='utf-8') as f: content = f.read() # Find all _('...') and gettext('...') calls pattern = r"[\"'](?:_|gettext)\([\"']([^\"']+)[\"']\)" matches = re.findall(r"\{\{\s*_\('([^']+)'\)\s*\}\}", content) matches += re.findall(r"\{\{\s*gettext\('([^']+)'\)\s*\}\}", content) return matches # Create .pot file def create_pot_file(strings): pot_content = """msgid "" msgstr "" "Project-Id-Version: Tablet Management System\n" "POT-Creation-Date: 2026-06-20\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: \n" "Language-Team: \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" """ for string in sorted(strings): pot_content += f'msgid "{string}"\n' pot_content += 'msgstr ""\n\n' return pot_content # Create Spanish .po file def create_es_po_file(strings): # Spanish translations translations = { # Navigation 'Tablet Management System': 'Sistema de Gestión de Tablets', 'Home': 'Inicio', 'Add Tablet': 'Añadir Tablet', 'Add User': 'Añadir Usuario', 'Loan Tablet': 'Prestar Tablet', 'History': 'Historial', 'User Loans': 'Préstamos por Usuario', 'Non-Loanable Devices': 'Dispositivos No Prestables', 'Project Management': 'Gestión de Proyectos', # Language 'Language': 'Idioma', 'English': 'Inglés', 'Español': 'Español', # Common 'Search': 'Buscar', 'Filter': 'Filtrar', 'Status': 'Estado', 'Actions': 'Acciones', 'Details': 'Detalles', 'View': 'Ver', 'All': 'Todos', 'Active': 'Activo', 'Inactive': 'Inactivo', 'Available': 'Disponible', 'Returned': 'Devuelto', 'Never': 'Nunca', 'N/A': 'N/D', 'Yes': 'Sí', 'No': 'No', 'Showing': 'Mostrando', 'to': 'a', 'of': 'de', 'Previous': 'Anterior', 'Next': 'Siguiente', 'Page': 'Página', # User Loans 'User Loans': 'Préstamos por Usuario', 'Search Users': 'Buscar Usuarios', 'Loan Status': 'Estado de Préstamo', 'All Users': 'Todos los Usuarios', 'With Active Loans': 'Con Préstamos Activos', 'No Active Loans': 'Sin Préstamos Activos', 'Search by name or identification...': 'Buscar por nombre o identificación...', 'users': 'usuarios', 'No users found': 'No se encontraron usuarios', 'No users match your search for': 'Ningún usuario coincide con tu búsqueda de', 'Clear Filters': 'Limpiar Filtros', # Table Headers 'User': 'Usuario', 'Identification': 'Identificación', 'Active Loans': 'Préstamos Activos', 'Last Loan Date': 'Fecha del Último Préstamo', 'Tablet': 'Tablet', 'Model': 'Modelo', 'Serial Number': 'Número de Serie', 'Notes': 'Notas', 'Borrower': 'Prestatario', 'Loan Date': 'Fecha de Préstamo', 'Return Date': 'Fecha de Devolución', 'Not returned': 'No devuelto', # Buttons 'Loan': 'Prestar', 'Return': 'Devolver', 'Add': 'Añadir', 'Save': 'Guardar', 'Cancel': 'Cancelar', 'Delete': 'Eliminar', 'Edit': 'Editar', 'Update': 'Actualizar', # Messages 'Tablet Management System - Internal Tool': 'Sistema de Gestión de Tablets - Herramienta Interna', 'No available tablets': 'No hay tablets disponibles', 'No active loans': 'No hay préstamos activos', 'No loan history for this user': 'Este usuario no tiene historial de préstamos', # Forms 'Brand': 'Marca', 'Model': 'Modelo', 'Serial Number': 'Número de Serie', 'Name': 'Nombre', 'Email': 'Correo Electrónico', 'Phone': 'Teléfono', 'Identification': 'Identificación', 'Date': 'Fecha', 'Notes': 'Notas', 'Required field': 'Campo obligatorio', # Status 'Active Loans': 'Préstamos Activos', 'Returned': 'Devueltos', } po_content = """msgid "" msgstr "" "Project-Id-Version: Tablet Management System\n" "POT-Creation-Date: 2026-06-20\n" "PO-Revision-Date: 2026-06-20\n" "Last-Translator: Auto-generated\n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" """ for string in sorted(strings): msgid = string msgstr = translations.get(string, '') po_content += f'msgid "{msgid}"\n' po_content += f'msgstr "{msgstr}"\n\n' return po_content # Main def main(): print("Extracting strings for translation...") # Find all template files template_files = find_template_files() print(f"Found {len(template_files)} template files") # Extract all strings all_strings = set() for filepath in template_files: strings = extract_strings_from_file(filepath) all_strings.update(strings) print(f"Found {len(all_strings)} unique strings") # Create .pot file pot_content = create_pot_file(all_strings) pot_path = TRANSLATIONS_DIR / 'messages.pot' with open(pot_path, 'w', encoding='utf-8') as f: f.write(pot_content) print(f"Created {pot_path}") # Create Spanish .po file es_po_content = create_es_po_file(all_strings) es_dir = TRANSLATIONS_DIR / 'es' / 'LC_MESSAGES' es_dir.mkdir(parents=True, exist_ok=True) es_po_path = es_dir / 'messages.po' with open(es_po_path, 'w', encoding='utf-8') as f: f.write(es_po_content) print(f"Created {es_po_path}") # Create English .po file en_dir = TRANSLATIONS_DIR / 'en' / 'LC_MESSAGES' en_dir.mkdir(parents=True, exist_ok=True) en_po_path = en_dir / 'messages.po' with open(en_po_path, 'w', encoding='utf-8') as f: f.write(create_pot_file(all_strings)) print(f"Created {en_po_path}") print("\n✅ Translation files created!") if __name__ == '__main__': main()