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/giopaths
Now usingarchive://file%3A%2F%2Fmypkg.pyz%2Fmessages%2FIRIs 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/.poextraction
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-mountetc. 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_gettextwhich transparently translates glade xml files and passes togtk.Builderinstance as a string.I've archived my locale directories into
locale.zipwhich is included in thepyzbundle.This is contents of
locale.zipTo make the locale.zip as a filesystem I use ZipFS from fs.
Fortunately Python
gettextis not GNU gettext.gettextis pure Python it doesn't use GNU gettext but mimics it.gettexthas two core functionsfindandtranslation. I've redefined these two in a seperate module namedmygettextto make them use files from theZipFS.gettextusesos.path,os.path.existsandopento find files and open them which I replace with the equivalent ones formfsmodule.This is contents of my application.
Because
pyzfiles have text, usually a shebang, prepended to it, I skip this line after opening thepyzfile in binary mode. Other modules in the application that want to use thegettext.gettextfunction, should importzfs_gettextinstead frommygettextand make it an alias to_.Here goes
mygettext.py.The following two shouldn't be called because
gladedoesn't use Pythongettext.