]> git.evergreen-ils.org Git - working/Evergreen.git/blob - build/i18n/scripts/db-seed-i18n.py
baa78914ce5091b12254a96ff58fec3c5179c2d4
[working/Evergreen.git] / build / i18n / scripts / db-seed-i18n.py
1 #/usr/bin/env python
2 #
3 # Copyright 2007 Dan Scott <dscott@laurentian.ca>
4 #
5 # This class enables translation of Evergreen's seed database strings.
6 #
7 # Requires polib from http://polib.googlecode.com
8 #
9 # ####
10 #
11 # This program is free software; you can redistribute it and/or
12 # modify it under the terms of the GNU General Public License
13 # as published by the Free Software Foundation; either version 2
14 # of the License, or (at your option) any later version.
15 #
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 # GNU General Public License for more details.
20
21 import polib
22 import re
23 import time
24
25 class EvergreenSQL:
26     """
27     This class provides methods for extracting translatable strings from
28     Evergreen's database seed values, generating a translatable POT file,
29     reading translated PO files, and generating SQL for inserting the
30     translated values into the Evergreen database.
31     """
32
33     def getstrings(self, source):
34         """
35         Each INSERT statement contains a schema and tablename which we need to
36         insert into the config.i18n table. We'll push this into our
37         POEntry.occurences attribute.
38         
39         Each INSERT statement also contains 0 or more oils_i18n_gettext()
40         markers for the en-US string that we'll use for our msgid attribute.
41
42         A sample INSERT string that we'll scan is as follows:
43
44             INSERT INTO foo.bar (key, value) VALUES 
45                 (99, oils_i18n_gettext('string'));
46         """
47         date = time.strftime("%Y-%m-%d %H:%M:%S")
48         self.pot = polib.POFile()
49
50         # We should be smarter about the Project-Id-Version attribute
51         self.pot.metadata['Project-Id-Version'] = 'Evergreen 1.4'
52         self.pot.metadata['Report-Msgid-Bugs-To'] = 'open-ils-dev@list.georgialibraries.org'
53         # Cheat and hard-code the time zone offset
54         self.pot.metadata['POT-Creation-Date'] = "%s %s" % (date, '-0400')
55         self.pot.metadata['PO-Revision-Date'] = 'YEAR-MO-DA HO:MI+ZONE'
56         self.pot.metadata['Last-Translator'] = 'FULL NAME <EMAIL@ADDRESS>'
57         self.pot.metadata['Language-Team'] = 'LANGUAGE <LL@li.org>'
58         self.pot.metadata['MIME-Version'] = '1.0'
59         self.pot.metadata['Content-Type'] = 'text/plain; charset=utf-8'
60         self.pot.metadata['Content-Transfer-Encoding'] = '8-bit'
61
62         # table holds the fully-qualified table name (schema.table)
63         # The source SQL may use multi-row VALUES clauses for a single
64         # insert statement, so we need to remember the fq-table for
65         # multiple lines
66         table = ''
67         n = 1
68         findtable = re.compile(r'\s*INSERT\s+INTO\s+(\S+).*?$')
69         findi18n = re.compile(r'.*?oils_i18n_gettext\(\'(.+?)\'\)')
70
71         # Iterate through the source SQL grabbing table names and l10n strings
72         sourcefile = open(source)
73         for line in sourcefile:
74             ftable = findtable.search(line)
75             if ftable is not None:
76                 table = ftable.group(1)
77             fi18n = findi18n.search(line)
78             if fi18n is not None:
79                 for i18n in fi18n.groups():
80                     # Unescape escaped SQL single-quotes for translators' sanity
81                     i18n = re.compile(r'\'\'').sub("'", i18n)
82                     if i18n is not None:
83                         poe = polib.POEntry()
84                         poe.occurences = [(table, n)]
85                         poe.msgid = i18n
86                         self.pot.append(poe)
87             n = n + 1
88
89     def savepot(self, destination):
90         """
91         Saves the POT file to a specified file.
92         """
93         self.pot.save(destination)
94         
95     def loadpo(self, source):
96         """
97         Loads a translated PO file so we can generate the corresponding SQL.
98         """
99         self.pot = polib.pofile(source)
100
101     def createsql(self, locale):
102         """
103         Creates a set of INSERT statements that place translated strings
104         into the config.i18n_core table.
105         """
106
107         insert = "INSERT INTO config.i18n_core (fq_field, identity_value, translation, string) VALUES ('%s', '%s', '%s', '%s');"
108         self.sql = [] 
109         for entry in self.pot:
110             for table in entry.occurences:
111                 # Escape SQL single-quotes to avoid b0rkage
112                 msgid = re.compile(r'\'').sub("''", entry.msgid)
113                 msgstr = re.compile(r'\'').sub("''", entry.msgstr)
114                 if msgstr == '':
115                     # Don't generate a stmt for an untranslated string
116                     break
117                 self.sql.append(insert % (table[0], msgid, locale, msgstr))
118
119     def __str__(self):
120         """
121         Returns the PO representation of the strings.
122         """
123         return self.pot.__str__()
124  
125 if __name__ == '__main__':
126     pot = EvergreenSQL()
127     pot.getstrings('../../Open-ILS/src/sql/Pg/950.data.seed-values.sql')
128     pot.savepot('po/db.seed.pot')
129
130 #    test = EvergreenSQL()
131 #    test.loadpo('po/db.seed.pot')
132 #    test.createsql('fr-CA')
133 #    for insert in test.sql: 
134 #       print insert