Is there an established approach to embed gettext locale/xy/LC_MESSAGES/*
in a PYZ bundle? Specifically to have Gtks automatic widget translation pick them up from within the ZIP archive.
For other embedded resources pkgutil.get_deta
or inspect
/get_source
work well enough. But system and Python gettext APIs depend on bindtextdomain
being supplied a plain old localedir
; no resources or strings etc.
So I couldn't contrive a workable or even remotely practical workaround:
Virtual
gvfs
/gio
paths
Now usingarchive://file%3A%2F%2Fmypkg.pyz%2Fmessages%2F
IRIs would be an alternative to read other files directly from a zip. But glibs g_dgettext is still just a thin wrapper around the system lib. And therefore any such URLs can't be used aslocaledir
.Partially extracting the zip
That's how PyInstaller works I think. But it's of course somewhat ridiculous to bundle something as .pyz application, only to have it preextracted on each invocation.Userland gettext
.mo
/.po
extraction
Now reading out the message catalogues manually or just using trivial dicts instead would be an option. But only for in-application strings. That's again no way to have Gtk/GtkBuilder pick them up implicitly.
Thus I had to manually traverse the whole widget tree, Labels, text, inner widgets, markup_text, etc. Possible, but meh.FUSE mounting
This would be superflaky. But of course, the zip contents could be accessedgvfs-mount
etc. Just seems like a certain memory hog. And I doubt it's gonna stay reliable with e.g. two app instances running, or a previous uncleanly terminated. (I don't know, due to a system library, like gettext, stumbling over a fragile zip fuse point..)Gtk signal/event for translation(?)
I've found squat about this, so I'm somewhat certain there's no alternative mechanism for widget translations in Gtk/PyGtk/GI. Gtk/Builder expects and is tied to gettext.
Is there a more dependable approach perhaps?
This my example Glade/GtkBuilder/Gtk application. I've defined a function
xml_gettext
which transparently translates glade xml files and passes togtk.Builder
instance as a string.I've archived my locale directories into
locale.zip
which is included in thepyz
bundle.This is contents of
locale.zip
To make the locale.zip as a filesystem I use ZipFS from fs.
Fortunately Python
gettext
is not GNU gettext.gettext
is pure Python it doesn't use GNU gettext but mimics it.gettext
has two core functionsfind
andtranslation
. I've redefined these two in a seperate module namedmygettext
to make them use files from theZipFS
.gettext
usesos.path
,os.path.exists
andopen
to find files and open them which I replace with the equivalent ones formfs
module.This is contents of my application.
Because
pyz
files have text, usually a shebang, prepended to it, I skip this line after opening thepyz
file in binary mode. Other modules in the application that want to use thegettext.gettext
function, should importzfs_gettext
instead frommygettext
and make it an alias to_
.Here goes
mygettext.py
.The following two shouldn't be called because
glade
doesn't use Pythongettext
.