po: purge every last Manjaro syllable from 66 locale files

i have seen every alphabet on gods green earth today. arabic. korean. hindi. persian. bengali. bulgarian. cyrillic marks i cannot pronounce. script that flows right to left. script that stacks into little blocks. script that hangs from a line like wet laundry.

do you know how many ways there are to spell "manjaro" in unicode? too many. i counted. منجارو 만자로 मैनजरो مانجارو মানজারো Манджаро and that is just the ones i had to hunt down with a regex flamethrower because my first 17 sed passes missed them all.

the pot file was from 2020. it still thought we were making manjaro hello. i regenerated it. it cried. i did not.

google translate via deep_translator was my sword. sed was my shield. python scripts lay broken in /tmp like the corpses of failed gods. three scripts. count them. three. the first could not parse po files. the second could not match multiline msgstr blocks. the third just replaced the unicode codepoints directly and asked no questions. that one worked.

66 mo files compiled. 0 manjaro references remain. the great cleansing is complete.

deus vult but at what cost.

—— Celestia Ludenberg, signing off before i start transliterating this commit message into korean
This commit is contained in:
2026-06-20 20:16:02 +02:00
parent 9973d9e2c7
commit dddbceb152
130 changed files with 2894 additions and 2976 deletions
+499
View File
@@ -0,0 +1,499 @@
#!/usr/bin/env python3
import collections
import glob
import urllib.request
import gettext
import gi
import json
import locale
import logging
import os
import subprocess
import sys
import webbrowser
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GdkPixbuf, Gdk
_SHARE_ANTERGOS = "/usr/share/antergos-next"
_HELLO_DATA_DIR = f"{_SHARE_ANTERGOS}/antergos-welcome"
_HELLO_PREF_FILE = f"{_HELLO_DATA_DIR}/preferences.json"
class EmbedManager:
"""manage included applications"""
def __init__(self, *args):
self.apps = []
self.count = 0
for app in args:
self.apps.append(app)
def get_modules(self, window: Gtk.Window):
for app in self.apps:
app.load(window)
self.count = sum((1 for x in self.apps if x.loaded))
def display(self, window: Gtk.Window):
for app in self.apps:
app.display(window)
class Embed:
"""abstact class for include app"""
def __init__(self):
""" abstact class initialisation """
self.name = "app" + self.__class__.__name__[5:]
self.loaded = False
self.box = None
def load(self, window: Gtk.Window) -> bool:
""" load modules if installed"""
raise Exception('abstract method')
def on_btn_clicked(self, btn, window: Gtk.Window):
"""Event for applications button."""
name = btn.get_name()
window.builder.get_object("stack").set_visible_child_name(name + "page")
def display(self, window: Gtk.Window):
""" show btn and add page"""
window.builder.get_object(self.name).set_visible(self.loaded)
if self.loaded:
window.builder.get_object("stack").add_named(self.box, self.name + "page")
class EmbedLayouts(Embed):
"""GNOME Layout Switcher"""
def load(self, window: Gtk.Window) -> bool:
try:
# import layoutswitcherlib
from layoutswitcherlib.layoutsbox import LayoutBox
try:
self.box = LayoutBox(window, usehello=True)
grid = Gtk.Grid()
grid.set_margin_start(15)
image = get_icon_image("go-previous", Gtk.IconSize.BUTTON)
back_btn=Gtk.Button(label=None, image=image)
back_btn.set_name("home")
back_btn.connect("clicked", self.on_btn_clicked,window)
grid.attach (back_btn, 0, 0, 1, 1)
self.box.pack_start(grid, expand=False, fill=False, padding=10)
self.box.reorder_child(grid,0)
self.box.show_all()
except Exception as err:
logging.error("Error in embedded application -> 'layoutswitcherlib'")
logging.error(err)
except ModuleNotFoundError:
logging.info(f"Plugin 'layoutswitcherlib' not available.")
self.loaded = self.box is not None
return self.loaded
class EmbedBrowser(Embed):
"""Application-utility"""
def load(self, window: Gtk.Window) -> bool:
try:
from application_utility import application_utility
from application_utility.translation import i18n
from application_utility.browser.application_browser import ApplicationBrowser
from application_utility.browser.exceptions import NoAppInIsoError
from application_utility.browser import alpm
from application_utility.browser import data
from application_utility.config.hello_config import HelloConfig
try:
conf = HelloConfig(application="antergos-welcome")
grid = Gtk.Grid()
grid.set_margin_start(5)
grid.set_margin_end(5)
grid.set_margin_top(5)
grid.set_margin_bottom(5)
image = get_icon_image("go-previous", Gtk.IconSize.BUTTON)
back_btn=Gtk.Button(label=None, image=image)
back_btn.set_name("home")
back_btn.connect("clicked", self.on_btn_clicked,window)
grid.attach (back_btn, 0, 1, 1, 1)
app=ApplicationBrowser(conf, window)
app.info_bar_title.pack_start(grid, expand=False, fill=False, padding=10)
app.info_bar_title.reorder_child(grid,0)
app.show_all()
self.box = app
except Exception as err:
logging.error("Error in embedded application -> 'application-utility'")
logging.error(err)
except ModuleNotFoundError as err:
logging.info(f"Plugin 'application-utility' not available.")
self.loaded = self.box is not None
return self.loaded
class Hello(Gtk.Window):
"""Hello"""
def __init__(self):
Gtk.Window.__init__(self, title="Antergos NeXT Welcome", border_width=6)
self.app = "antergos-welcome"
screen = Gdk.Screen.get_default()
self.dev = "--dev" in sys.argv
if self.dev:
# dont load hardcoded path in devmode
project_dir = os.getcwd()
self.preferences = read_json(f"{project_dir}/data/preferences.json")
self.preferences["data_path"] = f"{project_dir}/data"
self.preferences["desktop_path"] = f"{project_dir}/{self.app}.desktop"
self.preferences["locale_path"] = f"{project_dir}/locale"
self.preferences["ui_path"] = f"{project_dir}/ui/{self.app}.glade"
self.preferences["style_path"] = f"{project_dir}/ui/style.css"
logging.debug(f"Using dev preferences: {self.preferences}")
else:
self.preferences = read_json(f"{_HELLO_PREF_FILE}")
logging.debug(f"Using system preferences: {self.preferences}")
# Get saved infos
self.usr_prefs = read_json(self.preferences["save_path"])
if not self.usr_prefs:
self.usr_prefs = {"locale": None}
# Import Css
provider = Gtk.CssProvider()
provider.load_from_path(self.preferences["style_path"])
Gtk.StyleContext.add_provider_for_screen(screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
# Init window
self.builder = Gtk.Builder.new_from_file(self.preferences["ui_path"])
self.builder.connect_signals(self)
self.window = self.builder.get_object("window")
# Subtitle of headerbar
self.builder.get_object("headerbar").props.subtitle = ' '.join(get_lsb_infos())
# Load images
if os.path.isfile(self.preferences["logo_path"]):
logo = GdkPixbuf.Pixbuf.new_from_file(self.preferences["logo_path"])
self.window.set_icon(logo)
self.builder.get_object("distriblogo").set_from_pixbuf(logo)
self.builder.get_object("aboutdialog").set_logo(logo)
for btn in self.builder.get_object("social").get_children():
icon_path = self.preferences["data_path"] + "/img/" + btn.get_name() + ".png"
self.builder.get_object(btn.get_name()).set_from_file(icon_path)
for widget in self.builder.get_object("homepage").get_children():
if isinstance(widget, Gtk.Button) and \
widget.get_image_position() is Gtk.PositionType.RIGHT:
img = Gtk.Image.new_from_file(
self.preferences["data_path"] + "/img/external-link.png")
img.set_margin_start(2)
widget.set_image(img)
# Create pages
# load pageas for language
self.pages = os.listdir(f"/{self.preferences["data_path"]}/pages/{self.preferences["default_locale"]}")
for page in self.pages:
scrolled_window = Gtk.ScrolledWindow()
viewport = Gtk.Viewport(border_width=10)
label = Gtk.Label(wrap=True)
image = get_icon_image("go-previous", Gtk.IconSize.BUTTON)
back_btn=Gtk.Button(label=None, image=image)
back_btn.set_name("home")
back_btn.connect("clicked", self.on_btn_clicked)
grid = Gtk.Grid()
grid.attach (back_btn, 0, 1, 1, 1)
grid.attach(label, 1, 2, 1, 1)
viewport.add(grid)
scrolled_window.add(viewport)
scrolled_window.show_all()
self.builder.get_object("stack").add_named(scrolled_window, page + "page")
# Init translation
self.default_texts = {}
gettext.bindtextdomain(self.app, f"{self.preferences["locale_path"]}/")
gettext.textdomain(self.app)
self.builder.get_object("languages").set_active_id(self.get_best_locale())
# Set autostart switcher state
self.autostart = os.path.isfile(fix_path(self.preferences["autostart_path"]))
self.builder.get_object("autostart").set_active(self.autostart)
# Live systems
if (os.path.exists(self.preferences["live_path"])):
# show install label
self.builder.get_object("installlabel").set_visible(True)
# show install button
self.builder.get_object("install").set_visible(True)
# show calamares alternative installer
self.builder.get_object("calamares").set_visible(True)
# Installed systems
else:
manager = EmbedManager(EmbedBrowser(), EmbedLayouts())
manager.get_modules(self)
manager.display(self)
de = os.environ.get("DESKTOP_SESSION", "unknown")
# check desktop plasma or gnome
if de == "plasma" and os.path.isfile(self.preferences["plasmawelcome_path"]):
# enable Plasma Welcome button
self.builder.get_object("deWelcome").set_visible(True)
self.builder.get_object("deWelcome").set_label("Plasma Welcome")
elif de == "gnome" and os.path.isfile(self.preferences["gnometour_path"]):
# enable Gnome Tour button
self.builder.get_object("deWelcome").set_visible(True)
self.builder.get_object("deWelcome").set_label("GNOME Tour")
self.window.show()
def get_best_locale(self):
"""Choose locale, based on user's preferences.
:return: locale to use
:rtype: str
"""
path = self.preferences["locale_path"] + "/{}/LC_MESSAGES/" + self.app + ".mo"
if os.path.isfile(path.format(self.usr_prefs["locale"])):
# return usr_preference
return self.usr_prefs["locale"]
elif self.usr_prefs["locale"] == self.preferences["default_locale"]:
# return default
return self.preferences["default_locale"]
else:
# decide which locale to use
locale.setlocale(locale.LC_ALL, '')
sys_locale = locale.getlocale()[0]
# If user's locale is supported
if os.path.isfile(path.format(sys_locale)):
if "_" in sys_locale:
return sys_locale.replace("_", "-")
else:
return sys_locale
# If two first letters of user's locale is supported (ex: en_US -> en)
elif os.path.isfile(path.format(sys_locale[:2])):
return sys_locale[:2]
else:
return self.preferences["default_locale"]
def set_locale(self, use_locale):
"""Set locale of ui and pages.
:param use_locale: locale to use
:type use_locale: str
"""
try:
translation = gettext.translation(self.app,
self.preferences["locale_path"],
[use_locale],
fallback=True)
translation.install()
except OSError:
return
self.usr_prefs["locale"] = use_locale
# Real-time locale changing
elts = {
"comments": {"aboutdialog"},
"label": {
"autostartlabel",
"development",
"donate",
"firstcategory",
"forum",
"install",
"installlabel",
"rescue",
"involved",
"mailling",
"readme",
"release",
"secondcategory",
"thirdcategory",
"welcomelabel",
"welcometitle",
"wiki"
},
"tooltip_text": {
"about",
"development",
"donate",
"forum",
"mailling",
"wiki"
}
}
for method in elts:
if method not in self.default_texts:
self.default_texts[method] = {}
for elt in elts[method]:
if elt not in self.default_texts[method]:
self.default_texts[method][elt] = getattr(
self.builder.get_object(elt), "get_" + method)()
getattr(self.builder.get_object(elt), "set_" + method)(_(self.default_texts[method][elt]))
# Change content of pages
for page in self.pages:
child = self.builder.get_object("stack").get_child_by_name(page + "page")
label = child.get_children()[0].get_children()[0].get_children()[0]
label.set_markup(self.get_page(page))
def set_autostart(self, autostart):
"""Set state of autostart.
:param autostart: wanted auto start state
:type autostart: bool
"""
try:
if autostart and not os.path.isfile(fix_path(self.preferences["autostart_path"])):
os.symlink(self.preferences["desktop_path"],
fix_path(self.preferences["autostart_path"]))
elif not autostart and os.path.isfile(fix_path(self.preferences["autostart_path"])):
os.unlink(fix_path(self.preferences["autostart_path"]))
# Specific to i3
i3_config = fix_path("~/.i3/config")
if os.path.isfile(i3_config):
i3_autostart = "exec --no-startup-id " + self.app
with open(i3_config, "r+") as file:
content = file.read()
file.seek(0)
if autostart:
file.write(content.replace("#" + i3_autostart, i3_autostart))
else:
file.write(content.replace(i3_autostart, "#" + i3_autostart))
file.truncate()
self.autostart = autostart
except OSError as error:
print(error)
def get_page(self, name):
"""Read page according to language.
:param name: name of page (filename)
:type name: str
:return: text to load
:rtype: str
"""
filename = f"{self.preferences["data_path"]}/pages/{self.usr_prefs["locale"]}/{name}"
if not os.path.isfile(filename):
filename = f"{self.preferences["data_path"]}/pages/{self.preferences["default_locale"]}/{name}"
try:
with open(filename, "r") as fil:
return fil.read()
except OSError:
return _("Can't load page.")
# Handlers
def on_languages_changed(self, combobox):
"""Event for selected language."""
self.set_locale(combobox.get_active_id())
def on_action_clicked(self, action, _=None):
"""Event for differents actions."""
name = action.get_name()
if name == "install":
subprocess.Popen(["sudo", "-E", "cnchi"])
elif name == "calamares":
subprocess.Popen(["sudo", "-E", "calamares"])
elif name == "autostart":
self.set_autostart(action.get_active())
elif name == "about":
dialog = self.builder.get_object("aboutdialog")
dialog.run()
dialog.hide()
elif name == "deWelcome":
de = os.environ.get("DESKTOP_SESSION", "unknown")
if de == "plasma":
subprocess.Popen(["plasma-welcome"])
elif de == "gnome":
subprocess.Popen(["gnome-tour"])
def on_btn_clicked(self, btn):
"""Event for applications button."""
name = btn.get_name()
self.builder.get_object("stack").set_visible_child_name(name + "page")
def on_link_clicked(self, link, _=None):
"""Event for clicked link."""
Gtk.show_uri_on_window(None, self.preferences["urls"][link.get_name()], Gdk.CURRENT_TIME)
def on_delete_window(self, *args):
"""Event to quit app."""
write_json(self.preferences["save_path"], self.usr_prefs)
Gtk.main_quit(*args)
def fix_path(path):
"""Make good paths.
:param path: path to fix
:type path: str
:return: fixed path
:rtype: str
"""
if "~" in path:
path = path.replace("~", os.path.expanduser("~"))
return path
def read_json(path) -> dict or None:
"""Read content of a json file.
:param path: path to read
:type path: str
:return: json content
:rtype: str
"""
path = fix_path(path)
try:
with open(path, "r") as fil:
return json.load(fil)
except OSError:
return None
def write_json(path, content):
"""Write content in a json file.
:param path: path to write
:type path: str
:param content: content to write
:type path: str
"""
path = fix_path(path)
try:
with open(path, "w") as fil:
json.dump(content, fil)
except OSError as error:
print(error)
def get_lsb_infos():
"""Read information from the lsb-release file.
:return: args from lsb-release file
:rtype: dict"""
lsb = {}
try:
with open("/etc/lsb-release") as lsb_release:
for line in lsb_release:
if "=" in line:
var, arg = line.rstrip().split("=")
if not arg:
continue
var = var.replace("DISTRIB_","")
lsb[var] = arg.strip('"')
except (OSError, KeyError) as error:
print(error)
return 'not Antergos NeXT', '0.0'
return lsb["CODENAME"], lsb["RELEASE"]
def get_icon_image(icon_name, icon_size):
icon_theme = Gtk.IconTheme.get_default()
if icon_theme.has_icon(icon_name):
pixbuf = icon_theme.load_icon(icon_name, icon_size, 0)
if pixbuf:
return Gtk.Image.new_from_pixbuf(pixbuf)
else:
return Gtk.Image.new_from_icon_name(icon_name, icon_size)
return None
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
hello = Hello()
hello.connect('delete-event', Gtk.main_quit)
hello.connect("destroy", Gtk.main_quit)
Gtk.main()