diff --git a/serp.py b/serp.py index 1459146..5f1f006 100644 --- a/serp.py +++ b/serp.py @@ -44,6 +44,7 @@ logger = logging.getLogger(__name__) TRANSLATIONS = { "en": { "search": "Search", "crawl": "Crawl", "live": "Live Feed", "about": "About", + "random": "Random", "phantom": "Phantom", "loading": "Loading...", "start_crawl": "Start Crawl", "pause": "Pause", "resume": "Resume", "delete": "Delete", "url": "URL", "mode": "Mode", "depth": "Depth", "keywords": "Keywords", "screenshots": "Screenshots", "fast_mode": "Fast Mode", "fresh_start": "Fresh Start", @@ -54,10 +55,11 @@ TRANSLATIONS = { "everything": "Everything (text + media)", "all_media": "All media (images + videos + audio)", "images_only": "Images only", "videos_only": "Videos only", "text_only": "Text only", "recent_jobs": "Recent Jobs", "search_placeholder": "Search media...", - "media": "Media", "pages_label": "Pages", + "media": "Media", "pages_label": "Pages", "download": "Download", }, "zh": { "search": "搜索", "crawl": "爬取", "live": "实时动态", "about": "关于", + "random": "随机", "phantom": "幻影", "loading": "加载中...", "start_crawl": "开始爬取", "pause": "暂停", "resume": "继续", "delete": "删除", "url": "网址", "mode": "模式", "depth": "深度", "keywords": "关键词", "screenshots": "截图", "fast_mode": "快速模式", "fresh_start": "全新开始", @@ -68,10 +70,11 @@ TRANSLATIONS = { "everything": "全部(文本+媒体)", "all_media": "所有媒体(图片+视频+音频)", "images_only": "仅图片", "videos_only": "仅视频", "text_only": "仅文本", "recent_jobs": "最近任务", "search_placeholder": "搜索媒体...", - "media": "媒体", "pages_label": "页面", + "media": "媒体", "pages_label": "页面", "download": "下载", }, "es": { "search": "Buscar", "crawl": "Rastrear", "live": "En Vivo", "about": "Acerca de", + "random": "Aleatorio", "phantom": "Fantasma", "loading": "Cargando...", "start_crawl": "Iniciar Rastreo", "pause": "Pausar", "resume": "Reanudar", "delete": "Eliminar", "url": "URL", "mode": "Modo", "depth": "Profundidad", "keywords": "Palabras clave", "screenshots": "Capturas", "fast_mode": "Modo Rápido", "fresh_start": "Inicio Limpio", @@ -82,10 +85,11 @@ TRANSLATIONS = { "everything": "Todo (texto + medios)", "all_media": "Todos los medios", "images_only": "Solo imágenes", "videos_only": "Solo videos", "text_only": "Solo texto", "recent_jobs": "Tareas Recientes", "search_placeholder": "Buscar medios...", - "media": "Medios", "pages_label": "Páginas", + "media": "Medios", "pages_label": "Páginas", "download": "Descargar", }, "hi": { "search": "खोजें", "crawl": "क्रॉल", "live": "लाइव फ़ीड", "about": "के बारे में", + "random": "यादृच्छिक", "phantom": "प्रेत", "loading": "लोड हो रहा है...", "start_crawl": "क्रॉल शुरू करें", "pause": "रोकें", "resume": "जारी रखें", "delete": "हटाएं", "url": "यूआरएल", "mode": "मोड", "depth": "गहराई", "keywords": "कीवर्ड", "screenshots": "स्क्रीनशॉट", "fast_mode": "फास्ट मोड", "fresh_start": "नई शुरुआत", @@ -96,10 +100,11 @@ TRANSLATIONS = { "everything": "सब कुछ", "all_media": "सभी मीडिया", "images_only": "केवल चित्र", "videos_only": "केवल वीडियो", "text_only": "केवल टेक्स्ट", "recent_jobs": "हाल के कार्य", "search_placeholder": "मीडिया खोजें...", - "media": "मीडिया", "pages_label": "पेज", + "media": "मीडिया", "pages_label": "पेज", "download": "डाउनलोड", }, "ar": { "search": "بحث", "crawl": "زحف", "live": "مباشر", "about": "حول", + "random": "عشوائي", "phantom": "شبح", "loading": "جاري التحميل...", "start_crawl": "بدء الزحف", "pause": "إيقاف", "resume": "استئناف", "delete": "حذف", "url": "الرابط", "mode": "الوضع", "depth": "العمق", "keywords": "كلمات مفتاحية", "screenshots": "لقطات", "fast_mode": "وضع سريع", "fresh_start": "بداية جديدة", @@ -110,10 +115,11 @@ TRANSLATIONS = { "everything": "الكل", "all_media": "جميع الوسائط", "images_only": "صور فقط", "videos_only": "فيديو فقط", "text_only": "نص فقط", "recent_jobs": "المهام الأخيرة", "search_placeholder": "بحث في الوسائط...", - "media": "وسائط", "pages_label": "صفحات", + "media": "وسائط", "pages_label": "صفحات", "download": "تحميل", }, "pt": { "search": "Pesquisar", "crawl": "Rastrear", "live": "Ao Vivo", "about": "Sobre", + "random": "Aleatório", "phantom": "Fantasma", "loading": "Carregando...", "start_crawl": "Iniciar Rastreio", "pause": "Pausar", "resume": "Retomar", "delete": "Excluir", "url": "URL", "mode": "Modo", "depth": "Profundidade", "keywords": "Palavras-chave", "screenshots": "Capturas", "fast_mode": "Modo Rápido", "fresh_start": "Novo Início", @@ -124,10 +130,11 @@ TRANSLATIONS = { "everything": "Tudo (texto + mídia)", "all_media": "Toda mídia", "images_only": "Apenas imagens", "videos_only": "Apenas vídeos", "text_only": "Apenas texto", "recent_jobs": "Tarefas Recentes", "search_placeholder": "Pesquisar mídia...", - "media": "Mídia", "pages_label": "Páginas", + "media": "Mídia", "pages_label": "Páginas", "download": "Baixar", }, "ru": { "search": "Поиск", "crawl": "Сканировать", "live": "Прямой эфир", "about": "О нас", + "random": "Случайное", "phantom": "Призрак", "loading": "Загрузка...", "start_crawl": "Начать сканирование", "pause": "Пауза", "resume": "Продолжить", "delete": "Удалить", "url": "URL", "mode": "Режим", "depth": "Глубина", "keywords": "Ключевые слова", "screenshots": "Скриншоты", "fast_mode": "Быстрый режим", "fresh_start": "Начать заново", @@ -138,10 +145,11 @@ TRANSLATIONS = { "everything": "Всё (текст + медиа)", "all_media": "Все медиа", "images_only": "Только изображения", "videos_only": "Только видео", "text_only": "Только текст", "recent_jobs": "Недавние задачи", "search_placeholder": "Поиск медиа...", - "media": "Медиа", "pages_label": "Страницы", + "media": "Медиа", "pages_label": "Страницы", "download": "Скачать", }, "ja": { "search": "検索", "crawl": "クロール", "live": "ライブ", "about": "について", + "random": "ランダム", "phantom": "ファントム", "loading": "読み込み中...", "start_crawl": "クロール開始", "pause": "一時停止", "resume": "再開", "delete": "削除", "url": "URL", "mode": "モード", "depth": "深さ", "keywords": "キーワード", "screenshots": "スクリーンショット", "fast_mode": "高速モード", "fresh_start": "新規開始", @@ -152,10 +160,11 @@ TRANSLATIONS = { "everything": "すべて(テキスト+メディア)", "all_media": "すべてのメディア", "images_only": "画像のみ", "videos_only": "動画のみ", "text_only": "テキストのみ", "recent_jobs": "最近のジョブ", "search_placeholder": "メディアを検索...", - "media": "メディア", "pages_label": "ページ", + "media": "メディア", "pages_label": "ページ", "download": "ダウンロード", }, "fr": { "search": "Rechercher", "crawl": "Explorer", "live": "En Direct", "about": "À propos", + "random": "Aléatoire", "phantom": "Fantôme", "loading": "Chargement...", "start_crawl": "Démarrer", "pause": "Pause", "resume": "Reprendre", "delete": "Supprimer", "url": "URL", "mode": "Mode", "depth": "Profondeur", "keywords": "Mots-clés", "screenshots": "Captures", "fast_mode": "Mode Rapide", "fresh_start": "Nouveau Départ", @@ -166,10 +175,11 @@ TRANSLATIONS = { "everything": "Tout (texte + médias)", "all_media": "Tous les médias", "images_only": "Images uniquement", "videos_only": "Vidéos uniquement", "text_only": "Texte uniquement", "recent_jobs": "Tâches Récentes", "search_placeholder": "Rechercher des médias...", - "media": "Médias", "pages_label": "Pages", + "media": "Médias", "pages_label": "Pages", "download": "Télécharger", }, "de": { "search": "Suchen", "crawl": "Crawlen", "live": "Live-Feed", "about": "Über", + "random": "Zufällig", "phantom": "Phantom", "loading": "Laden...", "start_crawl": "Crawl starten", "pause": "Pause", "resume": "Fortsetzen", "delete": "Löschen", "url": "URL", "mode": "Modus", "depth": "Tiefe", "keywords": "Stichwörter", "screenshots": "Screenshots", "fast_mode": "Schnellmodus", "fresh_start": "Neustart", @@ -180,10 +190,11 @@ TRANSLATIONS = { "everything": "Alles (Text + Medien)", "all_media": "Alle Medien", "images_only": "Nur Bilder", "videos_only": "Nur Videos", "text_only": "Nur Text", "recent_jobs": "Letzte Aufgaben", "search_placeholder": "Medien suchen...", - "media": "Medien", "pages_label": "Seiten", + "media": "Medien", "pages_label": "Seiten", "download": "Herunterladen", }, "ko": { "search": "검색", "crawl": "크롤", "live": "라이브", "about": "정보", + "random": "랜덤", "phantom": "팬텀", "loading": "로딩 중...", "start_crawl": "크롤 시작", "pause": "일시정지", "resume": "재개", "delete": "삭제", "url": "URL", "mode": "모드", "depth": "깊이", "keywords": "키워드", "screenshots": "스크린샷", "fast_mode": "빠른 모드", "fresh_start": "새로 시작", @@ -194,10 +205,11 @@ TRANSLATIONS = { "everything": "모두", "all_media": "모든 미디어", "images_only": "이미지만", "videos_only": "동영상만", "text_only": "텍스트만", "recent_jobs": "최근 작업", "search_placeholder": "미디어 검색...", - "media": "미디어", "pages_label": "페이지", + "media": "미디어", "pages_label": "페이지", "download": "다운로드", }, "it": { "search": "Cerca", "crawl": "Scansiona", "live": "In Diretta", "about": "Info", + "random": "Casuale", "phantom": "Fantasma", "loading": "Caricamento...", "start_crawl": "Avvia Scansione", "pause": "Pausa", "resume": "Riprendi", "delete": "Elimina", "url": "URL", "mode": "Modalità", "depth": "Profondità", "keywords": "Parole chiave", "screenshots": "Screenshot", "fast_mode": "Modalità Veloce", "fresh_start": "Nuovo Inizio", @@ -208,10 +220,11 @@ TRANSLATIONS = { "everything": "Tutto", "all_media": "Tutti i media", "images_only": "Solo immagini", "videos_only": "Solo video", "text_only": "Solo testo", "recent_jobs": "Attività Recenti", "search_placeholder": "Cerca media...", - "media": "Media", "pages_label": "Pagine", + "media": "Media", "pages_label": "Pagine", "download": "Scarica", }, "nl": { "search": "Zoeken", "crawl": "Crawlen", "live": "Live", "about": "Over", + "random": "Willekeurig", "phantom": "Fantoom", "loading": "Laden...", "start_crawl": "Start Crawl", "pause": "Pauzeer", "resume": "Hervat", "delete": "Verwijder", "url": "URL", "mode": "Modus", "depth": "Diepte", "keywords": "Trefwoorden", "screenshots": "Schermafbeeldingen", "fast_mode": "Snelle Modus", "fresh_start": "Nieuwe Start", @@ -222,10 +235,11 @@ TRANSLATIONS = { "everything": "Alles", "all_media": "Alle media", "images_only": "Alleen afbeeldingen", "videos_only": "Alleen video's", "text_only": "Alleen tekst", "recent_jobs": "Recente Taken", "search_placeholder": "Zoek media...", - "media": "Media", "pages_label": "Pagina's", + "media": "Media", "pages_label": "Pagina's", "download": "Downloaden", }, "pl": { "search": "Szukaj", "crawl": "Indeksuj", "live": "Na żywo", "about": "O nas", + "random": "Losowo", "phantom": "Fantom", "loading": "Ładowanie...", "start_crawl": "Rozpocznij", "pause": "Pauza", "resume": "Wznów", "delete": "Usuń", "url": "URL", "mode": "Tryb", "depth": "Głębokość", "keywords": "Słowa kluczowe", "screenshots": "Zrzuty ekranu", "fast_mode": "Tryb szybki", "fresh_start": "Nowy start", @@ -236,10 +250,11 @@ TRANSLATIONS = { "everything": "Wszystko", "all_media": "Wszystkie media", "images_only": "Tylko obrazy", "videos_only": "Tylko filmy", "text_only": "Tylko tekst", "recent_jobs": "Ostatnie Zadania", "search_placeholder": "Szukaj mediów...", - "media": "Media", "pages_label": "Strony", + "media": "Media", "pages_label": "Strony", "download": "Pobierz", }, "tr": { "search": "Ara", "crawl": "Tara", "live": "Canlı", "about": "Hakkında", + "random": "Rastgele", "phantom": "Hayalet", "loading": "Yükleniyor...", "start_crawl": "Taramayı Başlat", "pause": "Duraklat", "resume": "Devam", "delete": "Sil", "url": "URL", "mode": "Mod", "depth": "Derinlik", "keywords": "Anahtar kelimeler", "screenshots": "Ekran görüntüleri", "fast_mode": "Hızlı Mod", "fresh_start": "Yeni Başlangıç", @@ -250,10 +265,11 @@ TRANSLATIONS = { "everything": "Her şey", "all_media": "Tüm medya", "images_only": "Sadece resimler", "videos_only": "Sadece videolar", "text_only": "Sadece metin", "recent_jobs": "Son Görevler", "search_placeholder": "Medya ara...", - "media": "Medya", "pages_label": "Sayfalar", + "media": "Medya", "pages_label": "Sayfalar", "download": "İndir", }, "vi": { "search": "Tìm kiếm", "crawl": "Thu thập", "live": "Trực tiếp", "about": "Giới thiệu", + "random": "Ngẫu nhiên", "phantom": "Bóng ma", "loading": "Đang tải...", "start_crawl": "Bắt đầu", "pause": "Tạm dừng", "resume": "Tiếp tục", "delete": "Xóa", "url": "URL", "mode": "Chế độ", "depth": "Độ sâu", "keywords": "Từ khóa", "screenshots": "Ảnh chụp", "fast_mode": "Chế độ nhanh", "fresh_start": "Bắt đầu mới", @@ -264,10 +280,11 @@ TRANSLATIONS = { "everything": "Tất cả", "all_media": "Tất cả media", "images_only": "Chỉ hình ảnh", "videos_only": "Chỉ video", "text_only": "Chỉ văn bản", "recent_jobs": "Tác vụ gần đây", "search_placeholder": "Tìm media...", - "media": "Media", "pages_label": "Trang", + "media": "Media", "pages_label": "Trang", "download": "Tải xuống", }, "th": { "search": "ค้นหา", "crawl": "รวบรวม", "live": "สด", "about": "เกี่ยวกับ", + "random": "สุ่ม", "phantom": "แฟนทอม", "loading": "กำลังโหลด...", "start_crawl": "เริ่มรวบรวม", "pause": "หยุดชั่วคราว", "resume": "ดำเนินต่อ", "delete": "ลบ", "url": "URL", "mode": "โหมด", "depth": "ความลึก", "keywords": "คำสำคัญ", "screenshots": "ภาพหน้าจอ", "fast_mode": "โหมดเร็ว", "fresh_start": "เริ่มใหม่", @@ -278,10 +295,11 @@ TRANSLATIONS = { "everything": "ทั้งหมด", "all_media": "สื่อทั้งหมด", "images_only": "เฉพาะรูปภาพ", "videos_only": "เฉพาะวิดีโอ", "text_only": "เฉพาะข้อความ", "recent_jobs": "งานล่าสุด", "search_placeholder": "ค้นหาสื่อ...", - "media": "สื่อ", "pages_label": "หน้า", + "media": "สื่อ", "pages_label": "หน้า", "download": "ดาวน์โหลด", }, "id": { "search": "Cari", "crawl": "Jelajahi", "live": "Langsung", "about": "Tentang", + "random": "Acak", "phantom": "Hantu", "loading": "Memuat...", "start_crawl": "Mulai Jelajah", "pause": "Jeda", "resume": "Lanjutkan", "delete": "Hapus", "url": "URL", "mode": "Mode", "depth": "Kedalaman", "keywords": "Kata kunci", "screenshots": "Tangkapan layar", "fast_mode": "Mode Cepat", "fresh_start": "Mulai Baru", @@ -292,10 +310,11 @@ TRANSLATIONS = { "everything": "Semua", "all_media": "Semua media", "images_only": "Hanya gambar", "videos_only": "Hanya video", "text_only": "Hanya teks", "recent_jobs": "Tugas Terbaru", "search_placeholder": "Cari media...", - "media": "Media", "pages_label": "Halaman", + "media": "Media", "pages_label": "Halaman", "download": "Unduh", }, "uk": { "search": "Пошук", "crawl": "Сканувати", "live": "Наживо", "about": "Про нас", + "random": "Випадково", "phantom": "Привид", "loading": "Завантаження...", "start_crawl": "Почати сканування", "pause": "Пауза", "resume": "Продовжити", "delete": "Видалити", "url": "URL", "mode": "Режим", "depth": "Глибина", "keywords": "Ключові слова", "screenshots": "Знімки екрану", "fast_mode": "Швидкий режим", "fresh_start": "Новий старт", @@ -306,10 +325,11 @@ TRANSLATIONS = { "everything": "Все", "all_media": "Усі медіа", "images_only": "Лише зображення", "videos_only": "Лише відео", "text_only": "Лише текст", "recent_jobs": "Останні завдання", "search_placeholder": "Пошук медіа...", - "media": "Медіа", "pages_label": "Сторінки", + "media": "Медіа", "pages_label": "Сторінки", "download": "Завантажити", }, "sv": { "search": "Sök", "crawl": "Genomsök", "live": "Live", "about": "Om", + "random": "Slumpmässig", "phantom": "Fantom", "loading": "Laddar...", "start_crawl": "Starta genomsökning", "pause": "Pausa", "resume": "Återuppta", "delete": "Ta bort", "url": "URL", "mode": "Läge", "depth": "Djup", "keywords": "Nyckelord", "screenshots": "Skärmbilder", "fast_mode": "Snabbläge", "fresh_start": "Ny start", @@ -320,7 +340,7 @@ TRANSLATIONS = { "everything": "Allt", "all_media": "Alla media", "images_only": "Endast bilder", "videos_only": "Endast videor", "text_only": "Endast text", "recent_jobs": "Senaste Jobb", "search_placeholder": "Sök media...", - "media": "Media", "pages_label": "Sidor", + "media": "Media", "pages_label": "Sidor", "download": "Ladda ner", }, } @@ -351,11 +371,24 @@ def t(key: str, lang: str = "en") -> str: """Get translation for key in language.""" return TRANSLATIONS.get(lang, TRANSLATIONS["en"]).get(key, TRANSLATIONS["en"].get(key, key)) +# Single source of truth for navigation - uses {{key}} placeholders +NAV_HTML = '''
''' + def inject_i18n(html: str, lang: str) -> str: """Replace {key} placeholders and inject JS translations + language selector.""" trans = TRANSLATIONS.get(lang, TRANSLATIONS["en"]) # Add lang attribute and inject JS translations html = html.replace('', f'') + # Replace nav placeholder with actual nav + html = html.replace('', NAV_HTML) # Build language selector options lang_options = ''.join(f'' for code, name in LANG_NAMES.items()) @@ -368,13 +401,8 @@ function setLang(code) { } ''' html = html.replace('