Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow translations of applet, desklet, and extension settings via gettext/po/mo files #2283

Merged
merged 5 commits into from
Aug 23, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions files/usr/bin/cinnamon-json-makepot
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/python

import os, sys

os.execvp("/usr/lib/cinnamon-json-makepot/cinnamon-json-makepot.py", ("",) + tuple(sys.argv[1:]))

136 changes: 136 additions & 0 deletions files/usr/lib/cinnamon-json-makepot/cinnamon-json-makepot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#!/usr/bin/env python

import sys
import os
import json
try:
import polib
except:
print """

Module "polib" not available.

Please install the package "python-polib" and try again

"""
quit()


class Main:
def __init__(self):
if (len(sys.argv) < 2 or len(sys.argv) > 3) or \
(len(sys.argv) == 2 and sys.argv[1] == "-js") or \
(len(sys.argv) == 3 and sys.argv[1] != "-js"):
print """
Usage:

cinnamon-json-makepot [-js] <potfile name>

-js - Runs xgettext on any javascript files in your directory before
scanning the settings-schema.json file. This allows you to generate
a .pot file for your entire applet at once.

<potfile name> - name of the .pot file to work with. This can be pre-existing,
or the name of a new file to use. If you leave off the .pot extension, it will
be automatically appended to the file name.

For instance:

cinnamon-json-makepot myapplet

Will generate a file called myapplet.pot, or append
to a file of that name. This can then be used by translators to be
made into a po file.

For example:

msginit --locale=fr --input=myapplet.pot

Will create "fr.po" for the French language. A translator can use a utility
such as poedit to add translations to this file, or edit the file manually.

.po files can be added to a "po" folder in your applet's directory,
and will be compiled and installed into the system when the applet is installed
via Cinnamon Settings.
"""
quit()

if len(sys.argv) == 2:
self.potname = sys.argv[1]
else:
self.potname = sys.argv[2]

if not self.potname.endswith(".pot"):
self.potname = self.potname + ".pot"

self.domain = self.potname.replace(".pot", "")
self.potpath = os.path.join(os.getcwd(), self.potname)

if sys.argv[1] == "-js":
try:
import subprocess
subprocess.call(["xgettext", "--version"])
except OSError:
print "xgettext not found, you may need to install the gettext package"
quit()
print " "
print "Running xgettext on JavaScript files..."
os.system("xgettext --language=C --keyword=_ --output=%s *.js" % (self.potname))

self.current_parent_dir = ""

append = False
if os.path.exists(self.potpath):
append = True

if append:
self.po = polib.pofile(self.potpath)
else:
self.po = polib.POFile()

print "Scanning settings-schema.json..."
self.scan_dirs()

if append:
self.po.save()
else:
self.po.save(fpath=self.potpath)

print "Extraction complete"
quit()

def scan_dirs(self):
for root, subFolders, files in os.walk(os.getcwd(), topdown=False):
for file in files:
if file == "settings-schema.json":
fp = open(os.path.join(root, file))
raw = fp.read()
data = {}
data = json.loads(raw)
fp.close()
self.current_parent_dir = os.path.split(root)[1]
self.extract_strings(data)

def extract_strings(self, data, parent=""):
for key in data.keys():
if key in ("description", "tooltip", "units"):
comment = "%s->settings-schema.json->%s->%s" % (self.current_parent_dir, parent, key)
entry = polib.POEntry(comment=comment)
entry.msgid = data[key]
self.po.append(entry)
elif key in "options":
opt_data = data[key]
for option in opt_data.keys():
if opt_data[option] == "custom":
continue
comment = "%s->settings-schema.json->%s->%s" % (self.current_parent_dir, parent, key)
entry = polib.POEntry(comment=comment)
entry.msgid = option
self.po.append(entry)
try:
self.extract_strings(data[key], key)
except AttributeError:
pass

if __name__ == "__main__":
Main()
2 changes: 1 addition & 1 deletion files/usr/lib/cinnamon-settings/bin/XletSettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def get_settings_for_applet(self, path):
raise Exception("Failed to parse settings JSON data for %s %s" % (self.type, self.uuid))
instance_id = instance.split(".json")[0]
self.applet_settings[instance_id] = js
self.setting_factories[instance_id] = XletSettingsWidgets.Factory("%s/%s" % (path, instance), instance_id, self.multi_instance)
self.setting_factories[instance_id] = XletSettingsWidgets.Factory("%s/%s" % (path, instance), instance_id, self.multi_instance, self.uuid)
return True
else:
raise Exception("Could not find any active setting files for %s %s" % (self.type, self.uuid))
Expand Down
50 changes: 42 additions & 8 deletions files/usr/lib/cinnamon-settings/bin/XletSettingsWidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@


class Factory():
def __init__(self, file_name, instance_id, multi_instance):
def __init__(self, file_name, instance_id, multi_instance, uuid):
self.file = file_name
self.settings = Settings(file_name, self, instance_id, multi_instance)
self.settings = Settings(file_name, self, instance_id, multi_instance, uuid)
self.widgets = collections.OrderedDict()
self.file_obj = Gio.File.new_for_path(self.file)
self.file_monitor = self.file_obj.monitor_file(Gio.FileMonitorFlags.SEND_MOVED, None)
Expand Down Expand Up @@ -110,11 +110,22 @@ def load_from_file(self, filename):


class Settings():
def __init__(self, file_name, factory, instance_id, multi_instance):
def __init__(self, file_name, factory, instance_id, multi_instance, uuid):
self.file_name = file_name
self.factory = factory
self.instance_id = instance_id
self.multi_instance = multi_instance
self.uuid = uuid
try:
self.t = gettext.translation(self.uuid, home+"/.local/share/locale").ugettext
except IOError:
try:
self.t = gettext.translation(self.uuid, "/usr/share/locale").ugettext
except IOError:
try:
self.t = gettext.translation("cinnamon", "/usr/share/cinnamon/locale").ugettext
except IOError:
self.t = None
self.reload()

def reload (self):
Expand Down Expand Up @@ -186,6 +197,10 @@ def load_from_file(self, filename):
class BaseWidget():
def __init__(self, key, settings_obj, uuid):
self.settings_obj = settings_obj
if self.settings_obj.t:
self.t = self.settings_obj.t
else:
self.t = None
self.key = key
self.uuid = uuid
self.handler = None
Expand Down Expand Up @@ -223,20 +238,30 @@ def get_data(self):

def get_desc(self):
try:
return self.settings_obj.get_data(self.key)["description"]
if self.t:
print self.t(self.settings_obj.get_data(self.key)["description"])
return self.t(self.settings_obj.get_data(self.key)["description"])
else:
return self.settings_obj.get_data(self.key)["description"]
except:
print ("Could not find description for key '%s' in xlet '%s'" % (self.key, self.uuid))
return ""

def get_tooltip(self):
try:
return self.settings_obj.get_data(self.key)["tooltip"]
if self.t:
return self.t(self.settings_obj.get_data(self.key)["tooltip"])
else:
return self.settings_obj.get_data(self.key)["tooltip"]
except:
return ""

def get_units(self):
try:
return self.settings_obj.get_data(self.key)["units"]
if self.t:
return self.t(self.settings_obj.get_data(self.key)["units"])
else:
return self.settings_obj.get_data(self.key)["units"]
except:
print ("Could not find description for key '%s' in xlet '%s'" % (self.key, self.uuid))
return ""
Expand Down Expand Up @@ -270,9 +295,18 @@ def get_step(self):

def get_options(self):
try:
return self.settings_obj.get_data(self.key)["options"]
except:
if self.t:
ret = {}
d = self.settings_obj.get_data(self.key)["options"]
for key in d.keys():
translated_key = self.t(key)
ret[translated_key] = d[key]
return ret
else:
return self.settings_obj.get_data(self.key)["options"]
except Exception, detail:
print ("Could not find options for key '%s' in xlet '%s'" % (self.key, self.uuid))
print detail

def get_custom_val(self):
try:
Expand Down