maposmatic-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Maposmatic-dev] [PATCH ocitysmap 1/2] New infrastructure to translate a


From: David MENTRE
Subject: [Maposmatic-dev] [PATCH ocitysmap 1/2] New infrastructure to translate amenities
Date: Tue, 22 Dec 2009 14:34:42 +0100

Add a new infrastructure to translate amenities added to map index.

* ocitysmap.conf: One should now give the path to ocitysmap/locale/
  directory.

* ocitysmap/i18n.py, ocitysmap/street_index.py: Code for new
  infrastructure.

* I18N: Documentation file that explains how to add a new translation.
---
 I18N                      |   17 +++++++++
 ocitysmap.conf            |    1 +
 ocitysmap/i18n.py         |   84 +++++++++++++++++++++++++++++----------------
 ocitysmap/street_index.py |   36 +++++++++++--------
 4 files changed, 93 insertions(+), 45 deletions(-)
 create mode 100644 I18N

diff --git a/I18N b/I18N
new file mode 100644
index 0000000..4d7d945
--- /dev/null
+++ b/I18N
@@ -0,0 +1,17 @@
+Translation support in ocitysmap
+
+ * To build .pot file
+
+   ocitysmap$ pygettext -d ocitysmap -p locale ocitysmap/street_index.py
+
+ * Make the .po file for your language. Look at Map_Features in your
+   language to find correct transaltions:
+     http://wiki.openstreetmap.org/wiki/Map_Features
+
+   ocitysmap$ cp locale/ocitysmap.pot locale/fr/LC_MESSAGES/ocitysmap.po
+
+   ocitysmap$ poedit locale/fr/LC_MESSAGES/ocitysmap.po
+
+ * Compile the .mo for your language
+
+   ocitysmap$ msgfmt locale/fr/LC_MESSAGES/ocitysmap.po
diff --git a/ocitysmap.conf b/ocitysmap.conf
index 9c341b1..0d6bb04 100644
--- a/ocitysmap.conf
+++ b/ocitysmap.conf
@@ -30,3 +30,4 @@ map=/path/to/mapnik-osm/osm.xml
 
 [ocitysmap]
 copyright_logo=/path/to/ocitysmap/Openstreetmap_logo.png
+locale_path=/path/to/ocitysmap/locale
diff --git a/ocitysmap/i18n.py b/ocitysmap/i18n.py
index 45b4cb8..75eed3a 100644
--- a/ocitysmap/i18n.py
+++ b/ocitysmap/i18n.py
@@ -22,6 +22,14 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import re
+import gettext
+
+def _install_language(language, locale_path):
+    t = gettext.translation(domain='ocitysmap', 
+                            localedir=locale_path,
+                            languages=[language],
+                            fallback=True)
+    t.install(unicode=True)
 
 class i18n:
     """Functions needed to be implemented for a new language.
@@ -36,10 +44,16 @@ class i18n:
         pass
 
 class i18n_template_code_CODE(i18n):
+    def __init__(self, language, language_path):
+        """Install the _() function for the chosen locale other
+           object initialisation"""
+        self.language = language
+        _install_language(language, locale_path)
+        
     def language_code(self):
         """returns the language code of the specific language
            supported, e.g. fr_FR.UTF-8"""
-        return "code_Code.UTF-8"
+        return self.language
 
     def user_readable_street(self, name):
         """ transforms a street name into a suitable form for
@@ -80,8 +94,9 @@ class i18n_fr_generic(i18n):
     O_ACCENT = re.compile(ur"[óòôöõ]", re.IGNORECASE | re.UNICODE)
     U_ACCENT = re.compile(ur"[úùûüũ]", re.IGNORECASE | re.UNICODE)
 
-    def __init__(self, language):
+    def __init__(self, language, locale_path):
         self.language = language
+        _install_language(language, locale_path)
 
     def _upper_unaccent_string(self, s):
         s = self.E_ACCENT.sub("e", s)
@@ -105,8 +120,9 @@ class i18n_fr_generic(i18n):
 
 
 class i18n_generic(i18n):
-    def __init__(self, language):
+    def __init__(self, language, locale_path):
         self.language = language
+        _install_language(language, locale_path)
 
     def language_code(self):
         return self.language
@@ -117,31 +133,39 @@ class i18n_generic(i18n):
     def first_letter_equal(self, a, b):
         return a == b
 
-# The global map used by module users
-language_map = { # 'code_CODE.UTF-8': i18n_template_code_CODE(), # example for
-                                                                 # new language
-                 'C': i18n_generic('C'),
-                 'fr_BE.UTF-8': i18n_fr_generic('fr_BE.UTF-8'),
-                 'fr_FR.UTF-8': i18n_fr_generic('fr_FR.UTF-8'),
-                 'fr_CA.UTF-8': i18n_fr_generic('fr_CA.UTF-8'),
-                 'fr_CH.UTF-8': i18n_fr_generic('fr_CH.UTF-8'),
-                 'fr_LU.UTF-8': i18n_fr_generic('fr_LU.UTF-8'),
-                 'en_AG': i18n_generic('en_AG'),
-                 'en_AU.UTF-8': i18n_generic('en_AU.UTF-8'),
-                 'en_BW.UTF-8': i18n_generic('en_BW.UTF-8'),
-                 'en_CA.UTF-8': i18n_generic('en_CA.UTF-8'),
-                 'en_DK.UTF-8': i18n_generic('en_DK.UTF-8'),
-                 'en_GB.UTF-8': i18n_generic('en_GB.UTF-8'),
-                 'en_HK.UTF-8': i18n_generic('en_HK.UTF-8'),
-                 'en_IE.UTF-8': i18n_generic('en_IE.UTF-8'),
-                 'en_IN': i18n_generic('en_IN'),
-                 'en_NG': i18n_generic('en_NG'),
-                 'en_NZ.UTF-8': i18n_generic('en_NZ.UTF-8'),
-                 'en_PH.UTF-8': i18n_generic('en_PH.UTF-8'),
-                 'en_SG.UTF-8': i18n_generic('en_SG.UTF-8'),
-                 'en_US.UTF-8': i18n_generic('en_US.UTF-8'),
-                 'en_ZA.UTF-8': i18n_generic('en_ZA.UTF-8'),
-                 'en_ZW.UTF-8': i18n_generic('en_ZW.UTF-8'),
-                 'de_BE.UTF-8': i18n_generic('de_BE.UTF-8'),
-                 'nl_BE.UTF-8': i18n_generic('nl_BE.UTF-8')}
+language_class_map = { # 'code_CODE.UTF-8': i18n_template_code_CODE(), # 
example for
+                                                             # new language
+    'C': 'i18n_generic',
+    'fr_BE.UTF-8': 'i18n_fr_generic',
+    'fr_FR.UTF-8': 'i18n_fr_generic',
+    'fr_CA.UTF-8': 'i18n_fr_generic',
+    'fr_CH.UTF-8': 'i18n_fr_generic',
+    'fr_LU.UTF-8': 'i18n_fr_generic',
+    'en_AG': 'i18n_generic',
+    'en_AU.UTF-8': 'i18n_generic',
+    'en_BW.UTF-8': 'i18n_generic',
+    'en_CA.UTF-8': 'i18n_generic',
+    'en_DK.UTF-8': 'i18n_generic',
+    'en_GB.UTF-8': 'i18n_generic',
+    'en_HK.UTF-8': 'i18n_generic',
+    'en_IE.UTF-8': 'i18n_generic',
+    'en_IN': 'i18n_generic',
+    'en_NG': 'i18n_generic',
+    'en_NZ.UTF-8': 'i18n_generic',
+    'en_PH.UTF-8': 'i18n_generic',
+    'en_SG.UTF-8': 'i18n_generic',
+    'en_US.UTF-8': 'i18n_generic',
+    'en_ZA.UTF-8': 'i18n_generic',
+    'en_ZW.UTF-8': 'i18n_generic',
+    'de_BE.UTF-8': 'i18n_generic',
+    'nl_BE.UTF-8': 'i18n_generic'}
+
+def install_translation(language, locale_path):
+    def _construct_by_name(cname,*p,**k):
+        """Instantiate an object from its class name with two parameters
+           p and k. Python black-magic given by d2"""
+        return globals()[cname](*p,**k)
+
+    return _construct_by_name(language_class_map[language], language,
+                              locale_path)
 
diff --git a/ocitysmap/street_index.py b/ocitysmap/street_index.py
index db31b91..66260c0 100644
--- a/ocitysmap/street_index.py
+++ b/ocitysmap/street_index.py
@@ -228,17 +228,6 @@ class IndexPageGenerator:
                 x += colwidth
 
 class OCitySMap:
-    SELECTED_AMENITIES = [
-        ("Places of worship", "place_of_worship", "Places of worship"),
-        ("Education", "kindergarten", "Kindergarten"),
-        ("Education", "school", "School"),
-        ("Education", "college", "College"),
-        ("Education", "university", "University"),
-        ("Education", "library", "Library"),
-        ("Public buildings", "townhall", "Town hall"),
-        ("Public buildings", "post_office", "Post office"),
-        ("Public buildings", "police", "Police")]
-
     def __init__(self, config_file=None, city_name=None, boundingbox=None,
                  osmid=None, language=None):
         """Creates a new OCitySMap renderer instance for the given city.
@@ -262,9 +251,6 @@ class OCitySMap:
 
         (self.city_name, self.boundingbox, self.osmid) = (city_name, 
boundingbox, osmid)
 
-        self.i18n = i18n.language_map[language]
-        LOG.info('Language ' + self.i18n.language_code())
-
         if self.city_name:
             LOG.info('OCitySMap renderer for %s.' % self.city_name)
         elif self.boundingbox:
@@ -281,6 +267,23 @@ class OCitySMap:
                             os.getenv('HOME') + '/.ocitysmap.conf']
         if not self.parser.read(config_files):
             raise IOError, 'Failed to load the config file'
+
+        locale_path = self.parser.get('ocitysmap', 'locale_path')
+        self.i18n = i18n.install_translation(language, locale_path)
+        LOG.info('Language: ' + self.i18n.language_code())
+        print _(u"Places of worship")
+
+        self.SELECTED_AMENITIES = [
+            (_(u"Places of worship"), "place_of_worship", _(u"Places of 
worship")),
+            (_(u"Education"), "kindergarten", _(u"Kindergarten")),
+            (_(u"Education"), "school", _(u"School")),
+            (_(u"Education"), "college", _(u"College")),
+            (_(u"Education"), "university", _(u"University")),
+            (_(u"Education"), "library", _(u"Library")),
+            (_(u"Public buildings"), "townhall", _(u"Town hall")),
+            (_(u"Public buildings"), "post_office", _(u"Post office")),
+            (_(u"Public buildings"), "police", _(u"Police"))]
+
         datasource = dict(self.parser.items('datasource'))
 
         db = pgdb.connect('Notre Base', datasource['user'],
@@ -315,6 +318,7 @@ class OCitySMap:
 
         LOG.info('City bounding box is %s.' % str(self.boundingbox))
 
+
     def find_bounding_box_by_name(self, db, name):
         """Find the bounding box of a city from its name.
 
@@ -720,7 +724,9 @@ class OCitySMap:
                               as foo
                               group by amenity, name
                               order by amenity, name;""" % \
-                              (cat, pgdb.escape_string(city.encode('utf-8')), 
amenity))
+                              (pgdb.escape_string(cat.encode('utf-8')), 
+                               pgdb.escape_string(city.encode('utf-8')),
+                               amenity))
             sub_al = cursor.fetchall()
             for a in sub_al:
                 if a[1] == None:
-- 
1.6.3.3





reply via email to

[Prev in Thread] Current Thread [Next in Thread]