mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	added infrastructure code for later javascript translating (currently not active)
git-svn-id: http://code.djangoproject.com/svn/django/trunk@1529 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -7,6 +7,8 @@ import getopt | ||||
|  | ||||
| from django.utils.translation import templateize | ||||
|  | ||||
| pythonize_re = re.compile(r'\n\s*//') | ||||
|  | ||||
| localedir = None | ||||
|  | ||||
| if os.path.isdir(os.path.join('conf', 'locale')): | ||||
| @@ -39,6 +41,9 @@ for o, v in opts: | ||||
|     elif o == '-a': | ||||
|         all = True | ||||
|  | ||||
| if domain not in ('django', 'djangojs'): | ||||
|     print "currently make-messages.py only supports domains 'django' and 'djangojs'" | ||||
|     sys.exit(1) | ||||
| if (lang is None and not all) or domain is None: | ||||
|     print "usage: make-messages.py -l <language>" | ||||
|     print "   or: make-messages.py -a" | ||||
| @@ -66,7 +71,28 @@ for lang in languages: | ||||
|  | ||||
|     for (dirpath, dirnames, filenames) in os.walk("."): | ||||
|         for file in filenames: | ||||
|             if file.endswith('.py') or file.endswith('.html'): | ||||
|             if domain == 'djangojs' and file.endswith('.js'): | ||||
|                 if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) | ||||
|                 src = open(os.path.join(dirpath, file), "rb").read() | ||||
|                 src = pythonize_re.sub('\n#', src) | ||||
|                 open(os.path.join(dirpath, '%s.py' % file), "wb").write(src) | ||||
|                 thefile = '%s.py' % file | ||||
|                 cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy -o - "%s"' % ( | ||||
|                     os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile)) | ||||
|                 (stdin, stdout, stderr) = os.popen3(cmd, 'b') | ||||
|                 msgs = stdout.read() | ||||
|                 errors = stderr.read() | ||||
|                 if errors:  | ||||
|                     print "errors happened while running xgettext on %s" % file | ||||
|                     print errors | ||||
|                     sys.exit(8) | ||||
|                 old = '#: '+os.path.join(dirpath, thefile)[2:] | ||||
|                 new = '#: '+os.path.join(dirpath, file)[2:] | ||||
|                 msgs = msgs.replace(old, new) | ||||
|                 if msgs: | ||||
|                     open(potfile, 'ab').write(msgs) | ||||
|                 os.unlink(os.path.join(dirpath, thefile)) | ||||
|             elif domain == 'django' and (file.endswith('.py') or file.endswith('.html')): | ||||
|                 thefile = file | ||||
|                 if file.endswith('.html'): | ||||
|                     src = open(os.path.join(dirpath, file), "rb").read() | ||||
| @@ -91,22 +117,23 @@ for lang in languages: | ||||
|                 if thefile != file: | ||||
|                     os.unlink(os.path.join(dirpath, thefile)) | ||||
|  | ||||
|     (stdin, stdout, stderr) = os.popen3('msguniq %s' % potfile, 'b') | ||||
|     msgs = stdout.read() | ||||
|     errors = stderr.read() | ||||
|     if errors: | ||||
|         print "errors happened while running msguniq" | ||||
|         print errors | ||||
|         sys.exit(8) | ||||
|     open(potfile, 'w').write(msgs) | ||||
|     if os.path.exists(pofile): | ||||
|         (stdin, stdout, stderr) = os.popen3('msgmerge -q %s %s' % (pofile, potfile), 'b') | ||||
|     if os.path.exists(potfile): | ||||
|         (stdin, stdout, stderr) = os.popen3('msguniq %s' % potfile, 'b') | ||||
|         msgs = stdout.read() | ||||
|         errors = stderr.read() | ||||
|         if errors: | ||||
|             print "errors happened while running msgmerge" | ||||
|             print "errors happened while running msguniq" | ||||
|             print errors | ||||
|             sys.exit(8) | ||||
|     open(pofile, 'wb').write(msgs) | ||||
|     os.unlink(potfile) | ||||
|         open(potfile, 'w').write(msgs) | ||||
|         if os.path.exists(pofile): | ||||
|             (stdin, stdout, stderr) = os.popen3('msgmerge -q %s %s' % (pofile, potfile), 'b') | ||||
|             msgs = stdout.read() | ||||
|             errors = stderr.read() | ||||
|             if errors: | ||||
|                 print "errors happened while running msgmerge" | ||||
|                 print errors | ||||
|                 sys.exit(8) | ||||
|         open(pofile, 'wb').write(msgs) | ||||
|         os.unlink(potfile) | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| import re | ||||
|  | ||||
| from django.conf.settings import DEFAULT_CHARSET | ||||
|  | ||||
| # Capitalizes the first letter of a string. | ||||
| capfirst = lambda x: x and x[0].upper() + x[1:] | ||||
|  | ||||
| @@ -90,3 +92,20 @@ def compress_string(s): | ||||
|     zfile.write(s) | ||||
|     zfile.close() | ||||
|     return zbuf.getvalue() | ||||
|  | ||||
| ustring_re = re.compile(u"([\u0080-\uffff])") | ||||
| def javascript_quote(s): | ||||
|  | ||||
|     def fix(match): | ||||
|         return r"\u%04x" % ord(match.group(1)) | ||||
|  | ||||
|     if type(s) == str: | ||||
|         s = s.decode(DEFAULT_ENCODING) | ||||
|     elif type(s) != unicode: | ||||
|         raise TypeError, s | ||||
|     s = s.replace('\\', '\\\\') | ||||
|     s = s.replace('\n', '\\n') | ||||
|     s = s.replace('\t', '\\t') | ||||
|     s = s.replace("'", "\\'") | ||||
|     return str(ustring_re.sub(fix, s)) | ||||
|  | ||||
|   | ||||
| @@ -212,6 +212,21 @@ def get_language(): | ||||
|     from django.conf.settings import LANGUAGE_CODE | ||||
|     return LANGUAGE_CODE | ||||
|  | ||||
| def catalog(): | ||||
|     """ | ||||
|     This function returns the current active catalog for further processing. | ||||
|     This can be used if you need to modify the catalog or want to access the | ||||
|     whole message catalog instead of just translating one string. | ||||
|     """ | ||||
|     global _default, _active | ||||
|     t = _active.get(currentThread(), None) | ||||
|     if t is not None: | ||||
|         return t | ||||
|     if _default is None: | ||||
|         from django.conf import settings | ||||
|         _default = translation(settings.LANGUAGE_CODE) | ||||
|     return _default | ||||
|  | ||||
| def gettext(message): | ||||
|     """ | ||||
|     This function will be patched into the builtins module to provide the _ | ||||
|   | ||||
| @@ -1,5 +1,12 @@ | ||||
| import re | ||||
| import os | ||||
|  | ||||
| import gettext as gettext_module | ||||
|  | ||||
| from django.utils import httpwrappers | ||||
| from django.utils.translation import check_for_language | ||||
| from django.utils.translation import check_for_language, activate, to_locale, get_language | ||||
| from django.utils.text import javascript_quote | ||||
| from django.conf import settings | ||||
|  | ||||
| def set_language(request): | ||||
|     """ | ||||
| @@ -20,3 +27,163 @@ def set_language(request): | ||||
|         else: | ||||
|             response.set_cookie('django_language', lang_code) | ||||
|     return response | ||||
|  | ||||
| NullSource = """ | ||||
| /* gettext identity library */ | ||||
|  | ||||
| function gettext(msgid) { | ||||
|     return msgid; | ||||
| } | ||||
|  | ||||
| function ngettext(singular, plural, count) { | ||||
|     if (count == 1) { | ||||
|         return singular; | ||||
|     } else { | ||||
|         return plural; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function gettext_noop(msgid) { | ||||
|     return msgid; | ||||
| } | ||||
| """ | ||||
|  | ||||
| LibHead = """ | ||||
| /* gettext library */ | ||||
|  | ||||
| var catalog = new Array(); | ||||
| """ | ||||
|  | ||||
| LibFoot = """ | ||||
|  | ||||
| function gettext(msgid) { | ||||
|     var value = catalog[msgid]; | ||||
|     if (typeof(value) == 'undefined') { | ||||
|         return msgid; | ||||
|     } else { | ||||
|         if (typeof(value) == 'string') { | ||||
|             return value; | ||||
|         } else { | ||||
|             return value[0]; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| function ngettext(singular, plural, count) { | ||||
|     value = catalog[singular]; | ||||
|     if (typeof(value) == 'undefined') { | ||||
|         if (count == 1) { | ||||
|             return singular; | ||||
|         } else { | ||||
|             return plural; | ||||
|         } | ||||
|     } else { | ||||
|         return value[pluralidx(count)]; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function gettext_noop(msgid) { | ||||
|     return msgid; | ||||
| } | ||||
| """ | ||||
|  | ||||
| SimplePlural = """ | ||||
| function pluralidx(count) { | ||||
|     if (count == 1) { | ||||
|         return 0; | ||||
|     } else { | ||||
|         return 1; | ||||
|     } | ||||
| } | ||||
| """ | ||||
|  | ||||
| InterPolate = r""" | ||||
| function interpolate(fmt, obj, named) { | ||||
|     if (named) { | ||||
|         return fmt.replace(/%\(\w+\)s/, function(match){return String(obj[match.slice(2,-2)])}); | ||||
|     } else { | ||||
|         return fmt.replace(/%s/, function(match){return String(obj.shift())}); | ||||
|     } | ||||
| } | ||||
| """ | ||||
|  | ||||
| def javascript_catalog(request, domain='djangojs', packages=None): | ||||
|     """ | ||||
|     Returns the selected language catalog as a javascript library. | ||||
|  | ||||
|     Receives the list of packages to check for translations in the | ||||
|     packages parameter either from an infodict or as a +-delimited | ||||
|     string from the request. Default is 'django.conf'. | ||||
|  | ||||
|     Additionally you can override the gettext domain for this view, | ||||
|     but usually you don't want to do that, as JavaScript messages | ||||
|     go to the djangojs domain. But this might be needed if you | ||||
|     deliver your JavaScript source from Django templates. | ||||
|     """ | ||||
|     if request.GET: | ||||
|         if request.GET.has_key('language'): | ||||
|             if check_for_language(request.GET['language']): | ||||
|                 activate(request.GET['language']) | ||||
|     if packages is None: | ||||
|         packages = ['django.conf'] | ||||
|     if type(packages) in (str, unicode): | ||||
|         packages = packages.split('+') | ||||
|     default_locale = to_locale(settings.LANGUAGE_CODE) | ||||
|     locale = to_locale(get_language()) | ||||
|     t = {} | ||||
|     paths = [] | ||||
|     for package in packages: | ||||
|         p = __import__(package, {}, {}, ['']) | ||||
|         path = os.path.join(os.path.dirname(p.__file__), 'locale') | ||||
|         paths.append(path) | ||||
|         #!!! add loading of catalogs from settings.LANGUAGE_CODE and request.LANGUAGE_CODE! | ||||
|         try: | ||||
|             catalog = gettext_module.translation(domain, path, [default_locale]) | ||||
|         except IOError, e: | ||||
|             catalog = None | ||||
|         if catalog is not None: | ||||
|             t.update(catalog._catalog) | ||||
|     if locale != default_locale: | ||||
|         for path in paths: | ||||
|             try: | ||||
|                 catalog = gettext_module.translation(domain, path, [locale]) | ||||
|             except IOError, e: | ||||
|                 catalog = None | ||||
|             if catalog is not None: | ||||
|                 t.update(catalog._catalog) | ||||
|     src = [LibHead] | ||||
|     plural = None | ||||
|     for l in t[''].split('\n'): | ||||
|         if l.startswith('Plural-Forms:'): | ||||
|             plural = l.split(':',1)[1].strip() | ||||
|     if plural is not None: | ||||
|         # this should actually be a compiled function of a typical plural-form: | ||||
|         # Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2; | ||||
|         plural = [el.strip() for el in plural.split(';') if el.strip().startswith('plural=')][0].split('=',1)[1] | ||||
|         src.append('function pluralidx(n) {\n    return %s;\n}\n' % plural) | ||||
|     else: | ||||
|         src.append(SimplePlural) | ||||
|     csrc = [] | ||||
|     pdict = {} | ||||
|     for k, v in t.items(): | ||||
|         if k == '': | ||||
|             continue | ||||
|         if type(k) in (str, unicode): | ||||
|             csrc.append("catalog['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(v))) | ||||
|         elif type(k) == tuple: | ||||
|             if not pdict.has_key(k[0]): | ||||
|                 pdict[k[0]] = k[1] | ||||
|             else: | ||||
|                 pdict[k[0]] = max(k[1], pdict[k[0]]) | ||||
|             csrc.append("catalog['%s'][%d] = '%s';\n" % (javascript_quote(k[0]), k[1], javascript_quote(v))) | ||||
|         else: | ||||
|             raise TypeError, k | ||||
|     csrc.sort() | ||||
|     for k,v in pdict.items(): | ||||
|         src.append("catalog['%s'] = [%s];\n" % (javascript_quote(k), ','.join(["''"]*(v+1)))) | ||||
|     src.extend(csrc) | ||||
|     src.append(LibFoot) | ||||
|     src.append(InterPolate) | ||||
|     src = ''.join(src) | ||||
|     return httpwrappers.HttpResponse(src, 'text/javascript') | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user