Added more missing localization, added LocalizationChecker tool, moved CriticalCSSGenerator to tools folder

This commit is contained in:
2026-01-01 19:03:57 +01:00
parent 3e433c3cbe
commit 6f4ffbcaa6
8 changed files with 209 additions and 16 deletions

4
.gitignore vendored
View File

@@ -18,5 +18,5 @@ src/Server/logs
src/Shared/bin
src/Shared/obj
src/Server/wwwroot/logs/*
src/Server/CriticalCSS/node_modules
src/Server/CriticalCSS/package*.json
src/Server/Tools/CriticalCSS/node_modules
src/Server/Tools/CriticalCSS/package*.json

View File

@@ -55,7 +55,7 @@
<value>Such-Cache</value>
</data>
<data name="Search cache utilization" xml:space="preserve">
<value>Such-Cache Speicherauslastung</value>
<value>Such-Cache-Speicherauslastung</value>
</data>
<data name="Clear" xml:space="preserve">
<value>Leeren</value>
@@ -121,7 +121,7 @@
<value>Searchdomain Name</value>
</data>
<data name="Enable cache reconciliation" xml:space="preserve">
<value>Cache Abgleich verwenden</value>
<value>Cache-Abgleich verwenden</value>
</data>
<data name="Create entity" xml:space="preserve">
<value>Entity erstellen</value>
@@ -175,10 +175,10 @@
<value>Searchdomain konnte nicht erstellt werden</value>
</data>
<data name="Searchdomain cache was cleared successfully" xml:space="preserve">
<value>Searchdomain Cache wurde erfolgreich geleert</value>
<value>Searchdomain-Cache wurde erfolgreich geleert</value>
</data>
<data name="Failed to clear searchdomain cache" xml:space="preserve">
<value>Searchdomain Cache konnte nicht geleert werden</value>
<value>Searchdomain-Cache konnte nicht geleert werden</value>
</data>
<data name="Entity was deleted successfully" xml:space="preserve">
<value>Entity wurde erfolgreich gelöscht</value>
@@ -229,7 +229,7 @@
<value>Searchdomain Einstellungen konnten nicht abgerufen werden</value>
</data>
<data name="Unable to fetch searchdomain cache utilization" xml:space="preserve">
<value>Searchdomain Cache-Auslastung konnte nicht abgerufen werden</value>
<value>Searchdomain-Cache-Auslastung konnte nicht abgerufen werden</value>
</data>
<data name="Details" xml:space="preserve">
<value>Details</value>
@@ -243,4 +243,61 @@
<data name="Close alert" xml:space="preserve">
<value>Benachrichtigung schließen</value>
</data>
<data name="Recent queries" xml:space="preserve">
<value>Letzte Queries</value>
</data>
<data name="Home" xml:space="preserve">
<value>Dashboard</value>
</data>
<data name="Searchdomains" xml:space="preserve">
<value>Searchdomains</value>
</data>
<data name="Swagger" xml:space="preserve">
<value>Swagger</value>
</data>
<data name="Elmah" xml:space="preserve">
<value>Elmah</value>
</data>
<data name="Hi!" xml:space="preserve">
<value>Hallo!</value>
</data>
<data name="Hi, {0}!" xml:space="preserve">
<value>Hallo {0}!</value>
</data>
<data name="Embedding Cache" xml:space="preserve">
<value>Embedding-Cache</value>
</data>
<data name="Size" xml:space="preserve">
<value>Größe</value>
</data>
<data name="Strings" xml:space="preserve">
<value>Zeichenketten</value>
</data>
<data name="stringsCountInfo" xml:space="preserve">
<value>Die Anzahl der Zeichenketten, für die Embeddings vorliegen. D.h. wenn zwei Modelle verwendet werden, ist die Zahl der Embeddings zweimal so hoch.</value>
</data>
<data name="Embeddings" xml:space="preserve">
<value>Embeddings</value>
</data>
<data name="Health Checks" xml:space="preserve">
<value>Health Checks</value>
</data>
<data name="Server" xml:space="preserve">
<value>Server</value>
</data>
<data name="AI Providers" xml:space="preserve">
<value>AI Providers</value>
</data>
<data name="Count" xml:space="preserve">
<value>Anzahl</value>
</data>
<data name="Total Entities" xml:space="preserve">
<value>Entities insgesamt</value>
</data>
<data name="Total query cache utilization" xml:space="preserve">
<value>Query-Cache-Verwendung insgesamt</value>
</data>
<data name="Unable to fetch searchdomain database utilization" xml:space="preserve">
<value>Searchdomain Datenbank-Auslastung konnte nicht abgerufen werden</value>
</data>
</root>

View File

@@ -243,4 +243,61 @@
<data name="Close alert" xml:space="preserve">
<value>Close alert</value>
</data>
<data name="Recent queries" xml:space="preserve">
<value>Recent queries</value>
</data>
<data name="Home" xml:space="preserve">
<value>Dashboard</value>
</data>
<data name="Searchdomains" xml:space="preserve">
<value>Searchdomains</value>
</data>
<data name="Swagger" xml:space="preserve">
<value>Swagger</value>
</data>
<data name="Elmah" xml:space="preserve">
<value>Elmah</value>
</data>
<data name="Hi!" xml:space="preserve">
<value>Hi!</value>
</data>
<data name="Hi, {0}!" xml:space="preserve">
<value>Hi {0}!</value>
</data>
<data name="Embedding Cache" xml:space="preserve">
<value>Embedding Cache</value>
</data>
<data name="Size" xml:space="preserve">
<value>Size</value>
</data>
<data name="Strings" xml:space="preserve">
<value>Strings</value>
</data>
<data name="stringsCountInfo" xml:space="preserve">
<value>The number of strings for which there are embeddings. I.e. If you use two models, the amount of embeddings will be twice this number.</value>
</data>
<data name="Embeddings" xml:space="preserve">
<value>Embeddings</value>
</data>
<data name="Health Checks" xml:space="preserve">
<value>Health Checks</value>
</data>
<data name="Server" xml:space="preserve">
<value>Server</value>
</data>
<data name="AI Providers" xml:space="preserve">
<value>AI Providers</value>
</data>
<data name="Count" xml:space="preserve">
<value>Count</value>
</data>
<data name="Total Entities" xml:space="preserve">
<value>Total Entities</value>
</data>
<data name="Total query cache utilization" xml:space="preserve">
<value>Total query cache utilization</value>
</data>
<data name="Unable to fetch searchdomain database utilization" xml:space="preserve">
<value>Unable to fetch searchdomain database utilization</value>
</data>
</root>

View File

@@ -8,3 +8,4 @@ npm install puppeteer
```bash
node CriticalCSSGenerator.js
```
3. Move the `.css` files from the current directory to the `CriticalCSS/` folder (overwrite existing files)

View File

@@ -0,0 +1,78 @@
import re
import sys
def extract_translations_from_View(view_path):
"""Extract all translation strings from file A"""
translations = {}
try:
with open(view_path, 'r', encoding='utf-8') as file_a:
for line_num, line in enumerate(file_a, 1):
# Match T["..."] patterns
matches = re.findall(r'T\["([^"]*)"\]', line)
for match in matches:
translations[match] = line_num
except FileNotFoundError:
print(f"Error: File {view_path} not found")
sys.exit(1)
except Exception as e:
print(f"Error reading file {view_path}: {e}")
sys.exit(1)
return translations
def extract_localizations_from_resource_file(file_b_path):
"""Extract all translation strings from file B"""
translations = set()
try:
with open(file_b_path, 'r', encoding='utf-8') as file_b:
for line in file_b:
# Match the pattern in file B
match = re.search(r'<data name="([^"]*)"', line)
if match:
translations.add(match.group(1))
except FileNotFoundError:
print(f"Error: File {file_b_path} not found")
sys.exit(1)
except Exception as e:
print(f"Error reading file {file_b_path}: {e}")
sys.exit(1)
return translations
def find_missing_translations(view, resource):
"""Find translations in file A that don't exist in file B"""
# Extract translations from both files
file_a_translations = extract_translations_from_View(view)
file_b_translations = extract_localizations_from_resource_file(resource)
# Find missing translations
missing_translations = []
for translation_text, line_number in file_a_translations.items():
if translation_text not in file_b_translations:
missing_translations.append((translation_text, line_number))
return missing_translations
def main():
views = ["Shared/_Layout.cshtml", "Home/Index.cshtml", "Home/Searchdomains.cshtml"]
resources = ["SharedResources.en.resx", "SharedResources.de.resx"]
print("Checking for missing translations...")
print("=" * 50)
for view in views:
for resource in resources:
missing = find_missing_translations("../../Views/" + view, "../../Resources/" + resource)
if missing:
print(f"Found {len(missing)} missing translations in {view}:")
print("-" * 50)
for translation_text, line_number in missing:
print(f"Line {line_number}: T[\"{translation_text}\"]")
else:
print(f"All localizations in {view} have a matching resource in {resource}!")
if __name__ == "__main__":
main()

View File

@@ -41,7 +41,7 @@
@T["Strings"]
<i class="bi bi-info-circle-fill text-info"
data-bs-toggle="tooltip"
title="The number of strings for which there are embeddings. I.e. If you use two models, the amount of embeddings will be twice this number."></i>
title="@T["stringsCountInfo"]"></i>
</span>
<strong id="embeddingcacheElementCount"></strong>
</div>

View File

@@ -92,7 +92,7 @@
<div class="card section-card mb-4">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center mb-2">
<h3>Recent queries</h3>
<h3>@T["Recent queries"]</h3>
<input
type="text"
class="form-control form-control-sm w-25"
@@ -103,8 +103,8 @@
<table id="queriesTable" class="table table-striped" style="max-height: 60vh; overflow-y: auto; display: block;">
<thead>
<tr>
<th class="visually-hidden">Name</th>
<th class="visually-hidden">Action</th>
<th class="visually-hidden">@T["Name"]</th>
<th class="visually-hidden">@T["Action"]</th>
</tr>
</thead>
<tbody>
@@ -129,8 +129,8 @@
<table id="entitiesTable" class="table table-striped" style="max-height: 60vh; overflow-y: auto; display: block;">
<thead>
<tr>
<th class="visually-hidden">Name</th>
<th class="visually-hidden">Action</th>
<th class="visually-hidden">@T["Name"]</th>
<th class="visually-hidden">@T["Action"]</th>
</tr>
</thead>
<tbody>
@@ -298,10 +298,10 @@
<div class="modal-footer">
<button type="button" class="btn btn-warning" onclick="renameSearchdomain(getSelectedDomainKey(), document.getElementById('renameSearchdomainNewName').value)" data-bs-dismiss="modal">
Rename
@T["Rename"]
</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Close
@T["Close"]
</button>
</div>
</div>