[CalendarServer-changes] [3650] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Mon Feb 9 08:57:03 PST 2009
Revision: 3650
http://trac.macosforge.org/projects/calendarserver/changeset/3650
Author: sagen at apple.com
Date: 2009-02-09 08:57:03 -0800 (Mon, 09 Feb 2009)
Log Message:
-----------
At startup, scan for Apple .lproj translations and convert them to gnutext form
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/tap/caldav.py
CalendarServer/trunk/conf/caldavd-test.plist
CalendarServer/trunk/twistedcaldav/config.py
CalendarServer/trunk/twistedcaldav/localization.py
CalendarServer/trunk/twistedcaldav/test/test_localization.py
Added Paths:
-----------
CalendarServer/trunk/locales/en_EN.ISO8859-1/
CalendarServer/trunk/locales/en_EN.ISO8859-1/LC_MESSAGES/
Removed Paths:
-------------
CalendarServer/trunk/locales/en/
CalendarServer/trunk/locales/en_EN.ISO8859-1/LC_MESSAGES/
Modified: CalendarServer/trunk/calendarserver/tap/caldav.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/caldav.py 2009-02-08 18:21:54 UTC (rev 3649)
+++ CalendarServer/trunk/calendarserver/tap/caldav.py 2009-02-09 16:57:03 UTC (rev 3650)
@@ -76,6 +76,7 @@
from twistedcaldav import memcachepool
from twistedcaldav.notify import installNotificationClient
from twistedcaldav.util import getNCPU
+from twistedcaldav.localization import processLocalizationFiles
try:
from twistedcaldav.authkerb import NegotiateCredentialFactory
@@ -717,6 +718,9 @@
def makeService_Combined(self, options):
s = MultiService()
+ # Process localization string files
+ processLocalizationFiles(config.Localization)
+
# The logger service must come before the monitor service, otherwise
# we won't know which logging port to pass to the slaves' command lines
Modified: CalendarServer/trunk/conf/caldavd-test.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd-test.plist 2009-02-08 18:21:54 UTC (rev 3649)
+++ CalendarServer/trunk/conf/caldavd-test.plist 2009-02-09 16:57:03 UTC (rev 3650)
@@ -670,7 +670,7 @@
<key>LocalesDirectory</key>
<string>locales</string>
<key>Language</key>
- <string>en</string>
+ <string>English</string>
</dict>
</dict>
Modified: CalendarServer/trunk/twistedcaldav/config.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/config.py 2009-02-08 18:21:54 UTC (rev 3649)
+++ CalendarServer/trunk/twistedcaldav/config.py 2009-02-09 16:57:03 UTC (rev 3650)
@@ -344,8 +344,9 @@
# Localization
#
"Localization" : {
- "LocalesDirectory" : "/usr/share/caldavd/locales",
- "Language" : "en",
+ "TranslationsDirectory" : "/usr/share/caldavd/share/translations",
+ "LocalesDirectory" : "/usr/share/caldavd/share/locales",
+ "Language" : "English",
},
Modified: CalendarServer/trunk/twistedcaldav/localization.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/localization.py 2009-02-08 18:21:54 UTC (rev 3649)
+++ CalendarServer/trunk/twistedcaldav/localization.py 2009-02-09 16:57:03 UTC (rev 3650)
@@ -1,5 +1,5 @@
##
-# Copyright (c) 2005-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,6 +14,19 @@
# limitations under the License.
##
+from __future__ import with_statement
+import gettext
+import inspect
+import datetime
+import os
+import struct
+import array
+from locale import normalize
+from twistedcaldav.config import config
+from twistedcaldav.log import Logger
+
+log = Logger()
+
"""
Localization module
@@ -85,12 +98,6 @@
"""
-import gettext
-import inspect
-import datetime
-from twistedcaldav.config import config
-
-
class translationTo(object):
translations = {}
@@ -333,3 +340,159 @@
_("NOV"),
_("DEC"),
]
+
+
+
+##
+# String file conversion routines
+##
+
+def processLocalizationFiles(settings):
+
+ lprojRoot = settings.TranslationsDirectory
+ gnuRoot = settings.LocalesDirectory
+
+ # Do we have an Apple translations directory?
+ if lprojRoot and gnuRoot and os.path.exists(lprojRoot):
+
+ log.info("Looking for Apple .lproj directories in %s" % (lprojRoot,))
+
+ # Make sure the gnutext translations directory exists
+ if not os.path.exists(gnuRoot):
+ os.mkdir(gnuRoot)
+
+ # Scan for Apple translations (directories ending in .lproj)
+ for item in os.listdir(lprojRoot):
+ if item.endswith(".lproj"):
+ stringsFile = os.path.join(lprojRoot, item,
+ 'calendarserver.strings')
+ localeName = normalize(item[:-6])
+ moFile = os.path.join(gnuRoot, localeName, 'LC_MESSAGES',
+ 'calendarserver.mo')
+ if os.path.exists(stringsFile):
+ if (not os.path.exists(moFile) or
+ os.stat(stringsFile).st_mtime >
+ os.stat(moFile).st_mtime):
+ log.info("Converting %s to %s" % (stringsFile, moFile))
+ try:
+ convertStringsFile(stringsFile, moFile)
+ except Exception, e:
+ log.error("Failed to convert %s to %s: %s" %
+ (stringsFile, moFile, e))
+ else:
+ log.info("%s is up to date" % (moFile,))
+
+class ParseError(Exception):
+ pass
+
+def parseString(text, index=0):
+
+ value = ""
+
+ while index < len(text):
+ ch = text[index]
+
+ if ch == '"':
+ if text[index-1] != "\\":
+ # At unescaped quote
+ if value:
+ # ...marking end of string; return it
+ return (value, index+1)
+ else:
+ # ...marking beginning of string; skip it
+ index += 1
+ continue
+
+ value += text[index]
+ index += 1
+
+ # no closing quote "
+ raise ParseError("No closing quote")
+
+def parseLine(line):
+
+ key, index = parseString(line)
+ remaining = line[index:].strip()
+ if remaining[0] != "=":
+ raise ParseError("Expected equals sign")
+ remaining = remaining[1:].strip()
+ value, index = parseString(remaining)
+ return (key, value)
+
+
+def convertStringsFile(src, dest):
+ strings = { }
+
+ dir = os.path.dirname(dest)
+
+ if not os.path.exists(dir):
+ try:
+ os.makedirs(dir)
+ except OSError:
+ # can't create directory to hold .po file
+ return
+
+ with open(src) as input:
+ lines = input.readlines()
+
+ for num, line in enumerate(lines):
+ line = line.strip()
+ if not line.startswith('"'):
+ continue
+
+ try:
+ key, value = parseLine(line)
+ except ParseError, err:
+ log.error("Error on line %d of %s: %s" % (num+1, src, str(err)))
+ raise
+
+ strings[key] = value
+
+ # The format of GNUtext MO files is described here:
+ # http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html
+
+ originals = strings.keys()
+ originals.sort()
+
+ descriptors = []
+ keys = ''
+ values = ''
+
+ for original in originals:
+ translation = strings[original]
+
+ descriptors.append((len(keys), len(original), len(values),
+ len(translation)))
+ keys += original + '\0' # <NUL> terminated
+ values += translation + '\0'
+
+ # The header is 28 bytes, each descriptor is 8 bytes, with two descriptors
+ # per string (one pointing at original, one pointing at translation)
+ keysOffset = 28 + len(originals) * 2 * 8
+ valuesOffset = keysOffset + len(keys)
+
+ keyDescriptors = []
+ valueDescriptors = []
+ for origOffset, origLen, transOffset, transLen in descriptors:
+ keyDescriptors.append(origLen)
+ keyDescriptors.append(keysOffset + origOffset)
+ valueDescriptors.append(transLen)
+ valueDescriptors.append(valuesOffset + transOffset)
+
+ result = struct.pack(
+ "Iiiiiii",
+ 0x950412DEL, # magic number
+ 0, # file format revision
+ len(originals), # number of strings
+ 28, # offset of table with original strings
+ 28+len(originals)*8, # offset of table with translation strings
+ 0, # size of hashing table
+ 0 # offset of hashing table
+ )
+ result += array.array("i", keyDescriptors).tostring()
+ result += array.array("i", valueDescriptors).tostring()
+ result += keys
+ result += values
+
+ with open(dest, "wb") as outFile:
+ outFile.write(result)
Modified: CalendarServer/trunk/twistedcaldav/test/test_localization.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_localization.py 2009-02-08 18:21:54 UTC (rev 3649)
+++ CalendarServer/trunk/twistedcaldav/test/test_localization.py 2009-02-09 16:57:03 UTC (rev 3650)
@@ -62,7 +62,7 @@
def test_TimeFormattingAMPM(self):
- with translationTo('en', localeDir=localeDir) as t:
+ with translationTo('English', localeDir=localeDir) as t:
self.assertEquals(t.dtTime(time(0,0)), "12:00 AM")
self.assertEquals(t.dtTime(time(12,0)), "12:00 PM")
@@ -82,7 +82,7 @@
def test_CalendarFormatting(self):
- with translationTo('en', localeDir=localeDir) as t:
+ with translationTo('English', localeDir=localeDir) as t:
comp = data[0][1]
self.assertEquals(t.date(comp), "Saturday, October 25, 2008")
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090209/675a847d/attachment.html>
More information about the calendarserver-changes
mailing list