16 KiB
16 KiB
CSV Auto-Export/Import - Easiest Way
1. CSV Auto-Generieren (aus .ts)
Problem
Du willst CSV mit:
- Spalte 1: Alle Deutsch-Wörter (aus mail-adler_de.ts)
- Spalte 2: Leer für neue Sprache
- Mit Kommas korrekt formatiert
Statt manuell alle Wörter zu kopieren
Lösung: Export-Script
#!/usr/bin/env python3
# scripts/export_to_csv.py
import xml.etree.ElementTree as ET
import csv
import argparse
from pathlib import Path
def ts_to_csv(ts_file: str, csv_output: str, language_name: str = "Neue Sprache"):
"""
Exportiere alle Deutsch-Strings aus .ts zu CSV
Output:
Deutsch,Neue Sprache
Eingang,
Gesendet,
...
"""
tree = ET.parse(ts_file)
root = tree.getroot()
ns = {'ts': 'http://trolltech.com/TS'}
# Sammle alle Deutsch-Strings
german_strings = []
for message in root.findall('.//message', ns):
source_elem = message.find('source', ns)
if source_elem is not None and source_elem.text:
german_strings.append(source_elem.text.strip())
# Dedupliziere (falls gleiche Wörter mehrmals vorkommen)
german_strings = list(dict.fromkeys(german_strings))
german_strings.sort()
# Schreibe CSV
with open(csv_output, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
# Header
writer.writerow(['Deutsch', language_name])
# Alle Strings
for word in german_strings:
writer.writerow([word, '']) # Zweite Spalte leer
print(f"✅ Export fertig!")
print(f" Datei: {csv_output}")
print(f" Strings: {len(german_strings)}")
print(f"")
print(f"Nächster Schritt:")
print(f"1. Öffne {csv_output} in Excel")
print(f"2. Fülle die '{language_name}'-Spalte mit Übersetzungen")
print(f"3. Speichern")
print(f"4. Führe import_csv.py aus")
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Export .ts zu CSV')
parser.add_argument('--source', required=True, help='mail-adler_de.ts')
parser.add_argument('--output', required=True, help='output.csv')
parser.add_argument('--language', default='English', help='Sprachen-Name')
args = parser.parse_args()
ts_to_csv(args.source, args.output, args.language)
Verwendung:
# Exportiere für Niederländisch
python3 scripts/export_to_csv.py \
--source translations/mail-adler_de.ts \
--output translations/glossary_nl.csv \
--language Niederländisch
# Output: glossary_nl.csv erstellt
# CSV hat:
# - Spalte 1: "Deutsch" (alle Strings)
# - Spalte 2: "Niederländisch" (leer)
glossary_nl.csv sieht so aus:
Deutsch,Niederländisch
Abbrechen,
Anmeldedaten,
Antworten,
Ansicht,
Archive,
Archiv,
Bearbeiten,
Beenden,
...
2. In Excel bearbeiten
Schritt 1: CSV öffnen
1. Windows: Rechts-Klick auf glossary_nl.csv
→ "Öffnen mit" → Excel
2. Oder: Excel → Datei → Öffnen → glossary_nl.csv
Schritt 2: Niederländisch-Spalte ausfüllen
Excel-Tabelle:
┌─────────────────┬──────────────────┐
│ Deutsch │ Niederländisch │
├─────────────────┼──────────────────┤
│ Abbrechen │ Annuleren │
│ Anmeldedaten │ Inloggegevens │
│ Antworten │ Antwoorden │
│ Ansicht │ Weergave │
│ ... │ ... │
└─────────────────┴──────────────────┘
Schritt 3: Speichern (als CSV!)
Excel:
1. Datei → Speichern unter
2. Format: "CSV UTF-8 (Kommagetrennt)"
(WICHTIG: UTF-8, nicht Standart-CSV)
3. Speichern
3. Import zurück zu .ts
Import-Script
#!/usr/bin/env python3
# scripts/import_csv_to_ts.py
import csv
import xml.etree.ElementTree as ET
import argparse
def csv_to_ts(csv_file: str, ts_source: str, ts_output: str, language_column: str = 1):
"""
Importiere CSV-Übersetzungen zurück zu .ts
CSV-Format:
Deutsch,English (oder Französisch, Niederländisch, etc.)
Eingang,Inbox
...
"""
# 1. Lese CSV
translations = {}
with open(csv_file, 'r', encoding='utf-8') as f:
reader = csv.reader(f)
header = next(reader) # Überspringe Header
for row in reader:
if len(row) >= 2:
deutsch = row[0].strip()
übersetzt = row[1].strip()
if deutsch and übersetzt: # Nur wenn beide gefüllt
translations[deutsch] = übersetzt
print(f"✅ CSV geladen: {len(translations)} Übersetzungen gefunden")
# 2. Parse .ts Datei
tree = ET.parse(ts_source)
root = tree.getroot()
ns = {'ts': 'http://trolltech.com/TS'}
ET.register_namespace('', 'http://trolltech.com/TS')
# 3. Update Übersetzungen
updated = 0
missing = 0
for message in root.findall('.//message', ns):
source_elem = message.find('source', ns)
trans_elem = message.find('translation', ns)
if source_elem is None or trans_elem is None:
continue
deutsch_text = source_elem.text
if deutsch_text in translations:
trans_elem.text = translations[deutsch_text]
trans_elem.set('type', 'finished')
updated += 1
print(f" ✓ {deutsch_text:30} → {translations[deutsch_text]}")
else:
missing += 1
# 4. Speichern
tree.write(ts_output, encoding='UTF-8', xml_declaration=True)
print(f"\n✅ FERTIG!")
print(f" Aktualisiert: {updated}")
print(f" Fehlend (nicht in CSV): {missing}")
print(f" Ausgabedatei: {ts_output}")
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Import CSV zu .ts')
parser.add_argument('--csv', required=True, help='glossary_nl.csv')
parser.add_argument('--source', required=True, help='mail-adler_de.ts')
parser.add_argument('--output', required=True, help='mail-adler_nl.ts')
args = parser.parse_args()
csv_to_ts(args.csv, args.source, args.output)
Verwendung:
# Importiere CSV zurück zu .ts
python3 scripts/import_csv_to_ts.py \
--csv translations/glossary_nl.csv \
--source translations/mail-adler_de.ts \
--output translations/mail-adler_nl.ts
# Output:
# ✅ CSV geladen: 247 Übersetzungen gefunden
# ✓ Abbrechen → Annuleren
# ✓ Anmeldedaten → Inloggegevens
# ...
# ✅ FERTIG!
# Aktualisiert: 247
# Fehlend: 0
# Ausgabedatei: translations/mail-adler_nl.ts
4. Kompletter Workflow für neue Sprache
# 1️⃣ EXPORT: Alle Deutsch-Strings → CSV
python3 scripts/export_to_csv.py \
--source translations/mail-adler_de.ts \
--output translations/glossary_nl.csv \
--language Niederländisch
# Output: glossary_nl.csv erstellt (250 leere Zeilen)
# 2️⃣ BEARBEITEN: In Excel ausfüllen
# → Öffne glossary_nl.csv in Excel
# → Fülle Niederländisch-Spalte
# → Speichern (als CSV UTF-8!)
# 3️⃣ IMPORT: CSV → .ts
python3 scripts/import_csv_to_ts.py \
--csv translations/glossary_nl.csv \
--source translations/mail-adler_de.ts \
--output translations/mail-adler_nl.ts
# 4️⃣ KOMPILIEREN
lrelease translations/mail-adler_nl.ts
# 5️⃣ GIT & RELEASE
git add translations/glossary_nl.csv translations/mail-adler_nl.ts
git commit -m "Add Dutch translation"
./scripts/release_with_translation.sh nl_NL
5. Mit LM Studio (Copy-Paste aus Excel)
Schneller Workflow:
1. Export: glossary_nl.csv erstellen
python3 scripts/export_to_csv.py ...
2. Excel: glossary_nl.csv öffnen
Links: Deutsch, Rechts: Niederländisch (leer)
3. LM Studio offen (http://localhost:1234)
4. Copy-Paste Loop:
- Excel: "Abbrechen" kopieren
- LM Studio: "Übersetze ins Niederländische: Abbrechen"
- LM Studio antwortet: "Annuleren"
- Excel: "Annuleren" einfügen
- Nächst Wort...
5. Nach alle Wörter:
Import: glossary_nl.csv → mail-adler_nl.ts
python3 scripts/import_csv_to_ts.py ...
6. Fertig!
6. Mehrere Sprachen gleichzeitig (in einer Datei)
Super praktisch: Ein CSV für alle Sprachen
#!/usr/bin/env python3
# scripts/export_to_csv_multilang.py
import xml.etree.ElementTree as ET
import csv
import argparse
def ts_to_csv_multilang(ts_file: str, csv_output: str, languages: list):
"""
Exportiere zu CSV mit mehreren Sprach-Spalten
languages = ["English", "Français", "Español", "Niederländisch"]
Output:
Deutsch,English,Français,Español,Niederländisch
Eingang,Inbox,Boîte de réception,Bandeja de entrada,Postvak IN
...
"""
tree = ET.parse(ts_file)
root = tree.getroot()
ns = {'ts': 'http://trolltech.com/TS'}
# Sammle Deutsch-Strings
german_strings = []
for message in root.findall('.//message', ns):
source_elem = message.find('source', ns)
if source_elem is not None and source_elem.text:
german_strings.append(source_elem.text.strip())
german_strings = list(dict.fromkeys(german_strings))
german_strings.sort()
# Schreibe CSV mit mehreren Sprachen
with open(csv_output, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
# Header
writer.writerow(['Deutsch'] + languages)
# Alle Strings (nur erste Spalte gefüllt)
for word in german_strings:
row = [word] + ([''] * len(languages))
writer.writerow(row)
print(f"✅ Multi-Language CSV erstellt!")
print(f" Datei: {csv_output}")
print(f" Strings: {len(german_strings)}")
print(f" Sprachen: {', '.join(languages)}")
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--source', required=True, help='mail-adler_de.ts')
parser.add_argument('--output', required=True, help='output.csv')
parser.add_argument('--languages', required=True,
help='Comma-separated: "English,Français,Español,Niederländisch"')
args = parser.parse_args()
langs = [l.strip() for l in args.languages.split(',')]
ts_to_csv_multilang(args.source, args.output, langs)
Verwendung:
python3 scripts/export_to_csv_multilang.py \
--source translations/mail-adler_de.ts \
--output translations/glossary_all.csv \
--languages "English,Français,Español,Niederländisch,Portugiesisch,Italienisch"
# Output: glossary_all.csv mit 6 leeren Sprach-Spalten
Ergebnis (in Excel):
Deutsch,English,Français,Español,Niederländisch,Portugiesisch,Italienisch
Abbrechen,Cancel,Annuler,Cancelar,Annuleren,Cancelar,Annulla
Anmeldedaten,Credentials,Identifiants,Credenciales,Inloggegevens,Credenciais,Credenziali
...
Jetzt kannst du alle Sprachen in EINER Datei übersetzen!
7. Import für jede einzelne Spalte
# Nach du alle Spalten in Excel gefüllt hast:
# Englisch extrahieren & importieren
python3 scripts/import_csv_column_to_ts.py \
--csv translations/glossary_all.csv \
--column English \
--source translations/mail-adler_de.ts \
--output translations/mail-adler_en.ts
# Französisch
python3 scripts/import_csv_column_to_ts.py \
--csv translations/glossary_all.csv \
--column Français \
--source translations/mail-adler_de.ts \
--output translations/mail-adler_fr.ts
# Niederländisch
python3 scripts/import_csv_column_to_ts.py \
--csv translations/glossary_all.csv \
--column Niederländisch \
--source translations/mail-adler_de.ts \
--output translations/mail-adler_nl.ts
# ... für alle Sprachen
Script dafür:
#!/usr/bin/env python3
# scripts/import_csv_column_to_ts.py
import csv
import xml.etree.ElementTree as ET
import argparse
def csv_column_to_ts(csv_file: str, column_name: str, ts_source: str, ts_output: str):
"""
Importiere eine bestimmte Spalte aus CSV zu .ts
"""
# Lese CSV & finde Spalte
translations = {}
with open(csv_file, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f) # Nutzt Header als Keys
for row in reader:
deutsch = row['Deutsch'].strip()
übersetzt = row.get(column_name, '').strip()
if deutsch and übersetzt:
translations[deutsch] = übersetzt
print(f"✅ Spalte '{column_name}' geladen: {len(translations)} Übersetzungen")
# Update .ts
tree = ET.parse(ts_source)
root = tree.getroot()
ns = {'ts': 'http://trolltech.com/TS'}
ET.register_namespace('', 'http://trolltech.com/TS')
updated = 0
for message in root.findall('.//message', ns):
source_elem = message.find('source', ns)
trans_elem = message.find('translation', ns)
if source_elem is not None and trans_elem is not None:
deutsch_text = source_elem.text
if deutsch_text in translations:
trans_elem.text = translations[deutsch_text]
trans_elem.set('type', 'finished')
updated += 1
tree.write(ts_output, encoding='UTF-8', xml_declaration=True)
print(f"✅ {updated} Strings aktualisiert → {ts_output}")
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--csv', required=True)
parser.add_argument('--column', required=True, help='Spalten-Name')
parser.add_argument('--source', required=True)
parser.add_argument('--output', required=True)
args = parser.parse_args()
csv_column_to_ts(args.csv, args.column, args.source, args.output)
8. Batch-Script für alle Sprachen
#!/bin/bash
# scripts/batch_import_all_languages.sh
CSV="translations/glossary_all.csv"
SOURCE="translations/mail-adler_de.ts"
LANGUAGES=("English" "Français" "Español" "Niederländisch" "Portugiesisch" "Italienisch")
LANG_CODES=("en" "fr" "es" "nl" "pt" "it")
for i in "${!LANGUAGES[@]}"; do
LANG="${LANGUAGES[$i]}"
CODE="${LANG_CODES[$i]}"
echo "🌍 Importiere $LANG..."
python3 scripts/import_csv_column_to_ts.py \
--csv "$CSV" \
--column "$LANG" \
--source "$SOURCE" \
--output "translations/mail-adler_${CODE}.ts"
lrelease "translations/mail-adler_${CODE}.ts"
done
echo "✅ Alle Sprachen importiert & kompiliert!"
Verwendung:
chmod +x scripts/batch_import_all_languages.sh
./scripts/batch_import_all_languages.sh
# Output:
# 🌍 Importiere English...
# ✅ 247 Strings aktualisiert → translations/mail-adler_en.ts
# 🌍 Importiere Français...
# ✅ 247 Strings aktualisiert → translations/mail-adler_fr.ts
# ...
# ✅ Alle Sprachen importiert & kompiliert!
9. Zusammenfassung: Der EASIEST Workflow
Super Einfach (für dich perfekt):
Schritt 1: EXPORT (Auto)
python3 scripts/export_to_csv_multilang.py \
--source translations/mail-adler_de.ts \
--output translations/glossary_all.csv \
--languages "English,Français,Español,Niederländisch,Portugiesisch,Italienisch"
Schritt 2: BEARBEITEN (Excel)
Öffne glossary_all.csv in Excel
Fülle alle Spalten mit Übersetzungen
(oder nutze LM Studio: Copy-Paste jedes Wort)
Speichern (Format: CSV UTF-8!)
Schritt 3: IMPORT (Auto)
./scripts/batch_import_all_languages.sh
Schritt 4: RELEASE (Auto)
git add translations/
git commit -m "Add all translations"
git push
# GitHub Action macht den Rest
Fertig! Keine .ts-Bearbeitung, keine komplexe Formate, nur Excel!