Django

Code

Changeset 1529

Show
Ignore:
Timestamp:
12/04/05 06:06:16 (3 years ago)
Author:
hugo
Message:

added infrastructure code for later javascript translating (currently not active)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/bin/make-messages.py

    r1528 r1529  
    77 
    88from django.utils.translation import templateize 
     9 
     10pythonize_re = re.compile(r'\n\s*//') 
    911 
    1012localedir = None 
     
    4042        all = True 
    4143 
     44if domain not in ('django', 'djangojs'): 
     45    print "currently make-messages.py only supports domains 'django' and 'djangojs'" 
     46    sys.exit(1) 
    4247if (lang is None and not all) or domain is None: 
    4348    print "usage: make-messages.py -l <language>" 
     
    6772    for (dirpath, dirnames, filenames) in os.walk("."): 
    6873        for file in filenames: 
    69             if file.endswith('.py') or file.endswith('.html'): 
     74            if domain == 'djangojs' and file.endswith('.js'): 
     75                if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) 
     76                src = open(os.path.join(dirpath, file), "rb").read() 
     77                src = pythonize_re.sub('\n#', src) 
     78                open(os.path.join(dirpath, '%s.py' % file), "wb").write(src) 
     79                thefile = '%s.py' % file 
     80                cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy -o - "%s"' % ( 
     81                    os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile)) 
     82                (stdin, stdout, stderr) = os.popen3(cmd, 'b') 
     83                msgs = stdout.read() 
     84                errors = stderr.read() 
     85                if errors:  
     86                    print "errors happened while running xgettext on %s" % file 
     87                    print errors 
     88                    sys.exit(8) 
     89                old = '#: '+os.path.join(dirpath, thefile)[2:] 
     90                new = '#: '+os.path.join(dirpath, file)[2:] 
     91                msgs = msgs.replace(old, new) 
     92                if msgs: 
     93                    open(potfile, 'ab').write(msgs) 
     94                os.unlink(os.path.join(dirpath, thefile)) 
     95            elif domain == 'django' and (file.endswith('.py') or file.endswith('.html')): 
    7096                thefile = file 
    7197                if file.endswith('.html'): 
     
    92118                    os.unlink(os.path.join(dirpath, thefile)) 
    93119 
    94     (stdin, stdout, stderr) = os.popen3('msguniq %s' % potfile, 'b') 
    95     msgs = stdout.read() 
    96     errors = stderr.read() 
    97     if errors: 
    98         print "errors happened while running msguniq" 
    99         print errors 
    100         sys.exit(8) 
    101     open(potfile, 'w').write(msgs) 
    102     if os.path.exists(pofile): 
    103         (stdin, stdout, stderr) = os.popen3('msgmerge -q %s %s' % (pofile, potfile), 'b') 
     120    if os.path.exists(potfile): 
     121        (stdin, stdout, stderr) = os.popen3('msguniq %s' % potfile, 'b') 
    104122        msgs = stdout.read() 
    105123        errors = stderr.read() 
    106124        if errors: 
    107             print "errors happened while running msgmerge
     125            print "errors happened while running msguniq
    108126            print errors 
    109127            sys.exit(8) 
    110     open(pofile, 'wb').write(msgs) 
    111     os.unlink(potfile) 
     128        open(potfile, 'w').write(msgs) 
     129        if os.path.exists(pofile): 
     130            (stdin, stdout, stderr) = os.popen3('msgmerge -q %s %s' % (pofile, potfile), 'b') 
     131            msgs = stdout.read() 
     132            errors = stderr.read() 
     133            if errors: 
     134                print "errors happened while running msgmerge" 
     135                print errors 
     136                sys.exit(8) 
     137        open(pofile, 'wb').write(msgs) 
     138        os.unlink(potfile) 
    112139 
  • django/trunk/django/utils/text.py

    r1068 r1529  
    11import re 
     2 
     3from django.conf.settings import DEFAULT_CHARSET 
    24 
    35# Capitalizes the first letter of a string. 
     
    9193    zfile.close() 
    9294    return zbuf.getvalue() 
     95 
     96ustring_re = re.compile(u"([\u0080-\uffff])") 
     97def javascript_quote(s): 
     98 
     99    def fix(match): 
     100        return r"\u%04x" % ord(match.group(1)) 
     101 
     102    if type(s) == str: 
     103        s = s.decode(DEFAULT_ENCODING) 
     104    elif type(s) != unicode: 
     105        raise TypeError, s 
     106    s = s.replace('\\', '\\\\') 
     107    s = s.replace('\n', '\\n') 
     108    s = s.replace('\t', '\\t') 
     109    s = s.replace("'", "\\'") 
     110    return str(ustring_re.sub(fix, s)) 
     111 
  • django/trunk/django/utils/translation.py

    r1388 r1529  
    212212    from django.conf.settings import LANGUAGE_CODE 
    213213    return LANGUAGE_CODE 
     214 
     215def catalog(): 
     216    """ 
     217    This function returns the current active catalog for further processing. 
     218    This can be used if you need to modify the catalog or want to access the 
     219    whole message catalog instead of just translating one string. 
     220    """ 
     221    global _default, _active 
     222    t = _active.get(currentThread(), None) 
     223    if t is not None: 
     224        return t 
     225    if _default is None: 
     226        from django.conf import settings 
     227        _default = translation(settings.LANGUAGE_CODE) 
     228    return _default 
    214229 
    215230def gettext(message): 
  • django/trunk/django/views/i18n.py

    r1068 r1529  
     1import re 
     2import os 
     3 
     4import gettext as gettext_module 
     5 
    16from django.utils import httpwrappers 
    2 from django.utils.translation import check_for_language 
     7from django.utils.translation import check_for_language, activate, to_locale, get_language 
     8from django.utils.text import javascript_quote 
     9from django.conf import settings 
    310 
    411def set_language(request): 
     
    2128            response.set_cookie('django_language', lang_code) 
    2229    return response 
     30 
     31NullSource = """ 
     32/* gettext identity library */ 
     33 
     34function gettext(msgid) { 
     35    return msgid; 
     36} 
     37 
     38function ngettext(singular, plural, count) { 
     39    if (count == 1) { 
     40        return singular; 
     41    } else { 
     42        return plural; 
     43    } 
     44} 
     45 
     46function gettext_noop(msgid) { 
     47    return msgid; 
     48} 
     49""" 
     50 
     51LibHead = """ 
     52/* gettext library */ 
     53 
     54var catalog = new Array(); 
     55""" 
     56 
     57LibFoot = """ 
     58 
     59function gettext(msgid) { 
     60    var value = catalog[msgid]; 
     61    if (typeof(value) == 'undefined') { 
     62        return msgid; 
     63    } else { 
     64        if (typeof(value) == 'string') { 
     65            return value; 
     66        } else { 
     67            return value[0]; 
     68        } 
     69    } 
     70} 
     71 
     72function ngettext(singular, plural, count) { 
     73    value = catalog[singular]; 
     74    if (typeof(value) == 'undefined') { 
     75        if (count == 1) { 
     76            return singular; 
     77        } else { 
     78            return plural; 
     79        } 
     80    } else { 
     81        return value[pluralidx(count)]; 
     82    } 
     83} 
     84 
     85function gettext_noop(msgid) { 
     86    return msgid; 
     87} 
     88""" 
     89 
     90SimplePlural = """ 
     91function pluralidx(count) { 
     92    if (count == 1) { 
     93        return 0; 
     94    } else { 
     95        return 1; 
     96    } 
     97} 
     98""" 
     99 
     100InterPolate = r""" 
     101function interpolate(fmt, obj, named) { 
     102    if (named) { 
     103        return fmt.replace(/%\(\w+\)s/, function(match){return String(obj[match.slice(2,-2)])}); 
     104    } else { 
     105        return fmt.replace(/%s/, function(match){return String(obj.shift())}); 
     106    } 
     107} 
     108""" 
     109 
     110def javascript_catalog(request, domain='djangojs', packages=None): 
     111    """ 
     112    Returns the selected language catalog as a javascript library. 
     113 
     114    Receives the list of packages to check for translations in the 
     115    packages parameter either from an infodict or as a +-delimited 
     116    string from the request. Default is 'django.conf'. 
     117 
     118    Additionally you can override the gettext domain for this view, 
     119    but usually you don't want to do that, as JavaScript messages 
     120    go to the djangojs domain. But this might be needed if you 
     121    deliver your JavaScript source from Django templates. 
     122    """ 
     123    if request.GET: 
     124        if request.GET.has_key('language'): 
     125            if check_for_language(request.GET['language']): 
     126                activate(request.GET['language']) 
     127    if packages is None: 
     128        packages = ['django.conf'] 
     129    if type(packages) in (str, unicode): 
     130        packages = packages.split('+') 
     131    default_locale = to_locale(settings.LANGUAGE_CODE) 
     132    locale = to_locale(get_language()) 
     133    t = {} 
     134    paths = [] 
     135    for package in packages: 
     136        p = __import__(package, {}, {}, ['']) 
     137        path = os.path.join(os.path.dirname(p.__file__), 'locale') 
     138        paths.append(path) 
     139        #!!! add loading of catalogs from settings.LANGUAGE_CODE and request.LANGUAGE_CODE! 
     140        try: 
     141            catalog = gettext_module.translation(domain, path, [default_locale]) 
     142        except IOError, e: 
     143            catalog = None 
     144        if catalog is not None: 
     145            t.update(catalog._catalog) 
     146    if locale != default_locale: 
     147        for path in paths: 
     148            try: 
     149                catalog = gettext_module.translation(domain, path, [locale]) 
     150            except IOError, e: 
     151                catalog = None 
     152            if catalog is not None: 
     153                t.update(catalog._catalog) 
     154    src = [LibHead] 
     155    plural = None 
     156    for l in t[''].split('\n'): 
     157        if l.startswith('Plural-Forms:'): 
     158            plural = l.split(':',1)[1].strip() 
     159    if plural is not None: 
     160        # this should actually be a compiled function of a typical plural-form: 
     161        # 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; 
     162        plural = [el.strip() for el in plural.split(';') if el.strip().startswith('plural=')][0].split('=',1)[1] 
     163        src.append('function pluralidx(n) {\n    return %s;\n}\n' % plural) 
     164    else: 
     165        src.append(SimplePlural) 
     166    csrc = [] 
     167    pdict = {} 
     168    for k, v in t.items(): 
     169        if k == '': 
     170            continue 
     171        if type(k) in (str, unicode): 
     172            csrc.append("catalog['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(v))) 
     173        elif type(k) == tuple: 
     174            if not pdict.has_key(k[0]): 
     175                pdict[k[0]] = k[1] 
     176            else: 
     177                pdict[k[0]] = max(k[1], pdict[k[0]]) 
     178            csrc.append("catalog['%s'][%d] = '%s';\n" % (javascript_quote(k[0]), k[1], javascript_quote(v))) 
     179        else: 
     180            raise TypeError, k 
     181    csrc.sort() 
     182    for k,v in pdict.items(): 
     183        src.append("catalog['%s'] = [%s];\n" % (javascript_quote(k), ','.join(["''"]*(v+1)))) 
     184    src.extend(csrc) 
     185    src.append(LibFoot) 
     186    src.append(InterPolate) 
     187    src = ''.join(src) 
     188    return httpwrappers.HttpResponse(src, 'text/javascript') 
     189