Code

Ticket #5522: django-admin.4.diff

File django-admin.4.diff, 36.8 KB (added by jezdez, 6 years ago)

makemessages and compileessages should now work in the svn root either by running django-admin.py * or bin/*.py without asking for DJANGO_SETTINGS_MODULE

Line 
1Index: django/core/management/commands/makemessages.py
2===================================================================
3--- django/core/management/commands/makemessages.py     (Revision 0)
4+++ django/core/management/commands/makemessages.py     (Revision 0)
5@@ -0,0 +1,35 @@
6+import re
7+import os
8+import sys
9+from optparse import make_option
10+from django.core.management.base import CommandError, BaseCommand, make_messages
11+
12+pythonize_re = re.compile(r'\n\s*//')
13+
14+class Command(BaseCommand):
15+    option_list = BaseCommand.option_list + (
16+        make_option('--locale', '-l', default=None, dest='locale',
17+            help='Creates or updates the message files only for the given locale (e.g. pt_BR).'),
18+        make_option('--domain', '-d', default='django', dest='domain',
19+            help='The domain of the message files (default: "django").'),
20+        make_option('--verbosity', '-v', action='store', dest='verbosity',
21+            default='1', type='choice', choices=['0', '1', '2'],
22+            help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
23+        make_option('--all', '-a', action='store_true', dest='all',
24+            default=False, help='Reexamines all source code and templates for new translation strings and updates all message files for all available languages.'),
25+    )
26+    help = "Runs over the entire source tree of the current directory and pulls out all strings marked for translation. It creates (or updates) a message file in the conf/locale (in the django tree) or locale (for project and application) directory."
27+
28+    requires_model_validation = False
29+    can_import_settings = False
30+
31+    def handle(self, *args, **options):
32+        if len(args) != 0:
33+            raise CommandError("Command doesn't accept any arguments")
34+
35+        locale = options.get('locale')
36+        domain = options.get('domain')
37+        verbosity = int(options.get('verbosity'))
38+        process_all = options.get('all')
39+
40+        make_messages(locale, domain, verbosity, process_all)
41Index: django/core/management/commands/compilemessages.py
42===================================================================
43--- django/core/management/commands/compilemessages.py  (Revision 0)
44+++ django/core/management/commands/compilemessages.py  (Revision 0)
45@@ -0,0 +1,24 @@
46+import os
47+import sys
48+from optparse import make_option
49+from django.core.management.base import BaseCommand, compile_messages
50+from django.core.management.color import no_style
51+
52+try:
53+    set
54+except NameError:
55+    from sets import Set as set     # For Python 2.3
56+
57+class Command(BaseCommand):
58+    option_list = BaseCommand.option_list + (
59+        make_option('--locale', '-l', dest='locale',
60+            help='The locale to process. Default is to process all.'),
61+    )
62+    help = 'Compiles .po files to .mo files for use with builtin gettext support.'
63+
64+    requires_model_validation = False
65+    can_import_settings = False
66+
67+    def handle(self, **options):
68+        locale = options.get('locale')
69+        compile_messages(locale)
70Index: django/core/management/commands/cleanup.py
71===================================================================
72--- django/core/management/commands/cleanup.py  (Revision 0)
73+++ django/core/management/commands/cleanup.py  (Revision 0)
74@@ -0,0 +1,11 @@
75+import datetime
76+from django.core.management.base import NoArgsCommand
77+
78+class Command(NoArgsCommand):
79+    help = "Can be run as a cronjob or directly to clean out old data from the database (only expired sessions at the moment)."
80+
81+    def handle_noargs(self, **options):
82+        from django.db import transaction
83+        from django.contrib.sessions.models import Session
84+        Session.objects.filter(expire_date__lt=datetime.datetime.now()).delete()
85+        transaction.commit_unless_managed()
86Index: django/core/management/base.py
87===================================================================
88--- django/core/management/base.py      (Revision 7275)
89+++ django/core/management/base.py      (Arbeitskopie)
90@@ -1,11 +1,17 @@
91 import os
92 import sys
93+from itertools import dropwhile
94 from optparse import make_option, OptionParser
95 
96 import django
97 from django.core.exceptions import ImproperlyConfigured
98 from django.core.management.color import color_style
99 
100+try:
101+    set
102+except NameError:
103+    from sets import Set as set     # For Python 2.3
104+
105 class CommandError(Exception):
106     pass
107 
108@@ -170,6 +176,166 @@
109     def handle_noargs(self, **options):
110         raise NotImplementedError()
111 
112+def make_messages(locale=None, domain='django', verbosity='1', all=False):
113+    """
114+    Uses the locale directory from the Django SVN tree or an application/
115+    project to process all
116+    """
117+    # Need to ensure that the i18n framework is enabled
118+    from django.conf import settings
119+    settings.configure(USE_I18N = True)
120+   
121+    from django.utils.translation import templatize
122+
123+    if os.path.isdir(os.path.join('conf', 'locale')):
124+        localedir = os.path.abspath(os.path.join('conf', 'locale'))
125+    elif os.path.isdir('locale'):
126+        localedir = os.path.abspath('locale')
127+    else:
128+        raise CommandError("This script should be run from the Django SVN tree or your project or app tree. If you did indeed run it from the SVN checkout or your project or application, maybe you are just missing the conf/locale (in the django tree) or locale (for project and application) directory? It is not created automatically, you have to create it by hand if you want to enable i18n for your project or application.")
129+   
130+    if domain not in ('django', 'djangojs'):
131+        raise CommandError("currently makemessages only supports domains 'django' and 'djangojs'")
132+
133+    if (locale is None and not all) or domain is None:
134+        # backwards compatible error message
135+        if not sys.argv[0].endswith("make-messages.py"):
136+            message = "Type '%s help %s' for usage.\n" % (os.path.basename(sys.argv[0]), sys.argv[1])
137+        else:
138+            message = "usage: make-messages.py -l <language>\n   or: make-messages.py -a\n"
139+        sys.stderr.write(message)
140+        sys.exit(1)
141+
142+    languages = []
143+    if locale is not None:
144+        languages.append(locale)
145+    elif all:
146+        languages = [el for el in os.listdir(localedir) if not el.startswith('.')]
147+
148+    for locale in languages:
149+        if verbosity > 0:
150+            print "processing language", locale
151+        basedir = os.path.join(localedir, locale, 'LC_MESSAGES')
152+        if not os.path.isdir(basedir):
153+            os.makedirs(basedir)
154+
155+        pofile = os.path.join(basedir, '%s.po' % domain)
156+        potfile = os.path.join(basedir, '%s.pot' % domain)
157+
158+        if os.path.exists(potfile):
159+            os.unlink(potfile)
160+
161+        all_files = []
162+        for (dirpath, dirnames, filenames) in os.walk("."):
163+            all_files.extend([(dirpath, f) for f in filenames])
164+        all_files.sort()
165+        for dirpath, file in all_files:
166+            if domain == 'djangojs' and file.endswith('.js'):
167+                if verbosity > 1:
168+                    sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
169+                src = open(os.path.join(dirpath, file), "rb").read()
170+                src = pythonize_re.sub('\n#', src)
171+                open(os.path.join(dirpath, '%s.py' % file), "wb").write(src)
172+                thefile = '%s.py' % file
173+                cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
174+                    os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile))
175+                (stdin, stdout, stderr) = os.popen3(cmd, 't')
176+                msgs = stdout.read()
177+                errors = stderr.read()
178+                if errors:
179+                    print "errors happened while running xgettext on %s" % file
180+                    print errors
181+                    sys.exit(8)
182+                old = '#: '+os.path.join(dirpath, thefile)[2:]
183+                new = '#: '+os.path.join(dirpath, file)[2:]
184+                msgs = msgs.replace(old, new)
185+                if msgs:
186+                    open(potfile, 'ab').write(msgs)
187+                os.unlink(os.path.join(dirpath, thefile))
188+            elif domain == 'django' and (file.endswith('.py') or file.endswith('.html')):
189+                thefile = file
190+                if file.endswith('.html'):
191+                    src = open(os.path.join(dirpath, file), "rb").read()
192+                    thefile = '%s.py' % file
193+                    open(os.path.join(dirpath, thefile), "wb").write(templatize(src))
194+                if verbosity > 1:
195+                    sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
196+                cmd = 'xgettext -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=ugettext_noop --keyword=ugettext_lazy --keyword=ungettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
197+                    domain, os.path.join(dirpath, thefile))
198+                (stdin, stdout, stderr) = os.popen3(cmd, 't')
199+                msgs = stdout.read()
200+                errors = stderr.read()
201+                if errors:
202+                    print "errors happened while running xgettext on %s" % file
203+                    print errors
204+                    sys.exit(8)
205+                if thefile != file:
206+                    old = '#: '+os.path.join(dirpath, thefile)[2:]
207+                    new = '#: '+os.path.join(dirpath, file)[2:]
208+                    msgs = msgs.replace(old, new)
209+                if os.path.exists(potfile):
210+                    # Strip the header
211+                    msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
212+                else:
213+                    msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
214+                if msgs:
215+                    open(potfile, 'ab').write(msgs)
216+                if thefile != file:
217+                    os.unlink(os.path.join(dirpath, thefile))
218+
219+        if os.path.exists(potfile):
220+            (stdin, stdout, stderr) = os.popen3('msguniq --to-code=utf-8 "%s"' % potfile, 'b')
221+            msgs = stdout.read()
222+            errors = stderr.read()
223+            if errors:
224+                print "errors happened while running msguniq"
225+                print errors
226+                sys.exit(8)
227+            open(potfile, 'w').write(msgs)
228+            if os.path.exists(pofile):
229+                (stdin, stdout, stderr) = os.popen3('msgmerge -q "%s" "%s"' % (pofile, potfile), 'b')
230+                msgs = stdout.read()
231+                errors = stderr.read()
232+                if errors:
233+                    print "errors happened while running msgmerge"
234+                    print errors
235+                    sys.exit(8)
236+            open(pofile, 'wb').write(msgs)
237+            os.unlink(potfile)
238+
239+def compile_messages(locale=None):
240+    basedirs = (os.path.join('conf', 'locale'), 'locale')
241+    if os.environ.get('DJANGO_SETTINGS_MODULE'):
242+        from django.conf import settings
243+        basedirs += settings.LOCALE_PATHS
244+
245+    # Gather existing directories.
246+    basedirs = set(map(os.path.abspath, filter(os.path.isdir, basedirs)))
247+   
248+    if not basedirs:
249+        raise CommandError("This script should be run from the Django SVN tree or your project or app tree, or with the settings module specified.")
250+
251+    for basedir in basedirs:
252+        if locale:
253+            basedir = os.path.join(basedir, locale, 'LC_MESSAGES')
254+        for dirpath, dirnames, filenames in os.walk(basedir):
255+            for f in filenames:
256+                if f.endswith('.po'):
257+                    sys.stderr.write('processing file %s in %s\n' % (f, dirpath))
258+                    pf = os.path.splitext(os.path.join(dirpath, f))[0]
259+                    # Store the names of the .mo and .po files in an environment
260+                    # variable, rather than doing a string replacement into the
261+                    # command, so that we can take advantage of shell quoting, to
262+                    # quote any malicious characters/escaping.
263+                    # See http://cyberelk.net/tim/articles/cmdline/ar01s02.html
264+                    os.environ['djangocompilemo'] = pf + '.mo'
265+                    os.environ['djangocompilepo'] = pf + '.po'
266+                    if sys.platform == 'win32': # Different shell-variable syntax
267+                        cmd = 'msgfmt --check-format -o "%djangocompilemo%" "%djangocompilepo%"'
268+                    else:
269+                        cmd = 'msgfmt --check-format -o "$djangocompilemo" "$djangocompilepo"'
270+                    os.system(cmd)
271+
272 def copy_helper(style, app_or_project, name, directory, other_name=''):
273     """
274     Copies either a Django application layout template or a Django project
275Index: django/bin/daily_cleanup.py
276===================================================================
277--- django/bin/daily_cleanup.py (Revision 7275)
278+++ django/bin/daily_cleanup.py (Arbeitskopie)
279@@ -7,14 +7,7 @@
280 sessions at the moment).
281 """
282 
283-import datetime
284-from django.db import transaction
285-from django.contrib.sessions.models import Session
286+from django.core import management
287 
288-def clean_up():
289-    """Clean up expired sessions."""
290-    Session.objects.filter(expire_date__lt=datetime.datetime.now()).delete()
291-    transaction.commit_unless_managed()
292-
293 if __name__ == "__main__":
294-    clean_up()
295+    management.call_command('cleanup')
296Index: django/bin/compile-messages.py
297===================================================================
298--- django/bin/compile-messages.py      (Revision 7275)
299+++ django/bin/compile-messages.py      (Arbeitskopie)
300@@ -1,52 +1,9 @@
301 #!/usr/bin/env python
302 
303-import optparse
304 import os
305-import sys
306+import optparse
307+from django.core.management.base import compile_messages
308 
309-try:
310-    set
311-except NameError:
312-    from sets import Set as set     # For Python 2.3
313-
314-
315-def compile_messages(locale=None):
316-    basedirs = (os.path.join('conf', 'locale'), 'locale')
317-    if os.environ.get('DJANGO_SETTINGS_MODULE'):
318-        from django.conf import settings
319-        basedirs += settings.LOCALE_PATHS
320-
321-    # Gather existing directories.
322-    basedirs = set(map(os.path.abspath, filter(os.path.isdir, basedirs)))
323-
324-    if not basedirs:
325-        print "This script should be run from the Django SVN tree or your project or app tree, or with the settings module specified."
326-        sys.exit(1)
327-
328-    for basedir in basedirs:
329-        if locale:
330-            basedir = os.path.join(basedir, locale, 'LC_MESSAGES')
331-        compile_messages_in_dir(basedir)
332-
333-def compile_messages_in_dir(basedir):
334-    for dirpath, dirnames, filenames in os.walk(basedir):
335-        for f in filenames:
336-            if f.endswith('.po'):
337-                sys.stderr.write('processing file %s in %s\n' % (f, dirpath))
338-                pf = os.path.splitext(os.path.join(dirpath, f))[0]
339-                # Store the names of the .mo and .po files in an environment
340-                # variable, rather than doing a string replacement into the
341-                # command, so that we can take advantage of shell quoting, to
342-                # quote any malicious characters/escaping.
343-                # See http://cyberelk.net/tim/articles/cmdline/ar01s02.html
344-                os.environ['djangocompilemo'] = pf + '.mo'
345-                os.environ['djangocompilepo'] = pf + '.po'
346-                if sys.platform == 'win32': # Different shell-variable syntax
347-                    cmd = 'msgfmt --check-format -o "%djangocompilemo%" "%djangocompilepo%"'
348-                else:
349-                    cmd = 'msgfmt --check-format -o "$djangocompilemo" "$djangocompilepo"'
350-                os.system(cmd)
351-
352 def main():
353     parser = optparse.OptionParser()
354     parser.add_option('-l', '--locale', dest='locale',
355Index: django/bin/make-messages.py
356===================================================================
357--- django/bin/make-messages.py (Revision 7275)
358+++ django/bin/make-messages.py (Arbeitskopie)
359@@ -1,155 +1,33 @@
360 #!/usr/bin/env python
361 
362-# Need to ensure that the i18n framework is enabled
363-from django.conf import settings
364-settings.configure(USE_I18N = True)
365-
366-from django.utils.translation import templatize
367-import re
368 import os
369-import sys
370-import getopt
371-from itertools import dropwhile
372+import optparse
373+from django.core.management.base import make_messages
374 
375-pythonize_re = re.compile(r'\n\s*//')
376+def main():
377+    parser = optparse.OptionParser()
378+    parser.add_option('-l', '--locale', dest='locale',
379+        help='Creates or updates the message files only for the \
380+            given locale (e.g. pt_BR).')
381+    parser.add_option('-d', '--domain', dest='domain', default='django',
382+        help='The domain of the message files (default: "django").')
383+    parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
384+        default=False, help='Verbosity output')
385+    parser.add_option('-a', '--all', action='store_true', dest='all',
386+        default=False, help='Reexamines all source code and templates for \
387+            new translation strings and updates all message files for all \
388+            available languages.')
389 
390-def make_messages():
391-    localedir = None
392-
393-    if os.path.isdir(os.path.join('conf', 'locale')):
394-        localedir = os.path.abspath(os.path.join('conf', 'locale'))
395-    elif os.path.isdir('locale'):
396-        localedir = os.path.abspath('locale')
397+    options, args = parser.parse_args()
398+    if len(args):
399+        parser.error("This program takes no arguments")
400+    if options.verbose:
401+        verbosity = 2
402     else:
403-        print "This script should be run from the django svn tree or your project or app tree."
404-        print "If you did indeed run it from the svn checkout or your project or application,"
405-        print "maybe you are just missing the conf/locale (in the django tree) or locale (for project"
406-        print "and application) directory?"
407-        print "make-messages.py doesn't create it automatically, you have to create it by hand if"
408-        print "you want to enable i18n for your project or application."
409-        sys.exit(1)
410+        verbosity = 1
411+   
412+    make_messages(locale=options.locale, domain=options.domain,
413+        verbosity=verbosity, all=options.all)
414 
415-    (opts, args) = getopt.getopt(sys.argv[1:], 'l:d:va')
416-
417-    lang = None
418-    domain = 'django'
419-    verbose = False
420-    all = False
421-
422-    for o, v in opts:
423-        if o == '-l':
424-            lang = v
425-        elif o == '-d':
426-            domain = v
427-        elif o == '-v':
428-            verbose = True
429-        elif o == '-a':
430-            all = True
431-
432-    if domain not in ('django', 'djangojs'):
433-        print "currently make-messages.py only supports domains 'django' and 'djangojs'"
434-        sys.exit(1)
435-    if (lang is None and not all) or domain is None:
436-        print "usage: make-messages.py -l <language>"
437-        print "   or: make-messages.py -a"
438-        sys.exit(1)
439-
440-    languages = []
441-
442-    if lang is not None:
443-        languages.append(lang)
444-    elif all:
445-        languages = [el for el in os.listdir(localedir) if not el.startswith('.')]
446-
447-    for lang in languages:
448-
449-        print "processing language", lang
450-        basedir = os.path.join(localedir, lang, 'LC_MESSAGES')
451-        if not os.path.isdir(basedir):
452-            os.makedirs(basedir)
453-
454-        pofile = os.path.join(basedir, '%s.po' % domain)
455-        potfile = os.path.join(basedir, '%s.pot' % domain)
456-
457-        if os.path.exists(potfile):
458-            os.unlink(potfile)
459-
460-        all_files = []
461-        for (dirpath, dirnames, filenames) in os.walk("."):
462-            all_files.extend([(dirpath, f) for f in filenames])
463-        all_files.sort()
464-        for dirpath, file in all_files:
465-            if domain == 'djangojs' and file.endswith('.js'):
466-                if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
467-                src = open(os.path.join(dirpath, file), "rb").read()
468-                src = pythonize_re.sub('\n#', src)
469-                open(os.path.join(dirpath, '%s.py' % file), "wb").write(src)
470-                thefile = '%s.py' % file
471-                cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
472-                    os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile))
473-                (stdin, stdout, stderr) = os.popen3(cmd, 't')
474-                msgs = stdout.read()
475-                errors = stderr.read()
476-                if errors:
477-                    print "errors happened while running xgettext on %s" % file
478-                    print errors
479-                    sys.exit(8)
480-                old = '#: '+os.path.join(dirpath, thefile)[2:]
481-                new = '#: '+os.path.join(dirpath, file)[2:]
482-                msgs = msgs.replace(old, new)
483-                if msgs:
484-                    open(potfile, 'ab').write(msgs)
485-                os.unlink(os.path.join(dirpath, thefile))
486-            elif domain == 'django' and (file.endswith('.py') or file.endswith('.html')):
487-                thefile = file
488-                if file.endswith('.html'):
489-                    src = open(os.path.join(dirpath, file), "rb").read()
490-                    thefile = '%s.py' % file
491-                    open(os.path.join(dirpath, thefile), "wb").write(templatize(src))
492-                if verbose:
493-                    sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
494-                cmd = 'xgettext -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=ugettext_noop --keyword=ugettext_lazy --keyword=ungettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
495-                    domain, os.path.join(dirpath, thefile))
496-                (stdin, stdout, stderr) = os.popen3(cmd, 't')
497-                msgs = stdout.read()
498-                errors = stderr.read()
499-                if errors:
500-                    print "errors happened while running xgettext on %s" % file
501-                    print errors
502-                    sys.exit(8)
503-                if thefile != file:
504-                    old = '#: '+os.path.join(dirpath, thefile)[2:]
505-                    new = '#: '+os.path.join(dirpath, file)[2:]
506-                    msgs = msgs.replace(old, new)
507-                if os.path.exists(potfile):
508-                    # Strip the header
509-                    msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
510-                else:
511-                    msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
512-                if msgs:
513-                    open(potfile, 'ab').write(msgs)
514-                if thefile != file:
515-                    os.unlink(os.path.join(dirpath, thefile))
516-
517-        if os.path.exists(potfile):
518-            (stdin, stdout, stderr) = os.popen3('msguniq --to-code=utf-8 "%s"' % potfile, 'b')
519-            msgs = stdout.read()
520-            errors = stderr.read()
521-            if errors:
522-                print "errors happened while running msguniq"
523-                print errors
524-                sys.exit(8)
525-            open(potfile, 'w').write(msgs)
526-            if os.path.exists(pofile):
527-                (stdin, stdout, stderr) = os.popen3('msgmerge -q "%s" "%s"' % (pofile, potfile), 'b')
528-                msgs = stdout.read()
529-                errors = stderr.read()
530-                if errors:
531-                    print "errors happened while running msgmerge"
532-                    print errors
533-                    sys.exit(8)
534-            open(pofile, 'wb').write(msgs)
535-            os.unlink(potfile)
536-
537 if __name__ == "__main__":
538-    make_messages()
539+    main()
540Index: extras/django_bash_completion
541===================================================================
542--- extras/django_bash_completion       (Revision 7274)
543+++ extras/django_bash_completion       (Arbeitskopie)
544@@ -42,13 +42,15 @@
545     prev="${COMP_WORDS[COMP_CWORD-1]}"
546 
547     # Standalone options
548-    opts="--help --settings --pythonpath --noinput --noreload --format --indent --verbosity --adminmedia --version"
549+    opts="--help --settings --pythonpath --noinput --noreload --locale --all --domain --format --indent --verbosity --adminmedia --version"
550+
551     # Actions
552-    actions="adminindex createcachetable dbshell diffsettings \
553-             dumpdata flush inspectdb loaddata reset runfcgi runserver \
554-             shell sql sqlall sqlclear sqlcustom sqlflush sqlindexes \
555-             sqlreset sqlsequencereset startapp startproject \
556-             syncdb test validate"
557+    actions="adminindex createcachetable cleanup compilemessages dbshell \
558+             diffsettings dumpdata flush inspectdb loaddata makemessages \
559+             reset runfcgi runserver shell sql sqlall sqlclear sqlcustom \
560+             sqlflush sqlindexes sqlreset sqlsequencereset startapp \
561+             startproject syncdb test validate"
562+
563     # Action's options
564     action_shell_opts="--plain"
565     action_runfcgi_opts="host port socket method maxspare minspare maxchildren daemonize pidfile workdir"
566@@ -112,8 +114,9 @@
567                 return 0
568                 ;;
569 
570-            createcachetable|dbshell|diffsettings| \
571-            inspectdb|runserver|startapp|startproject|syncdb| \
572+            createcachetable|cleanup|compilemessages|dbshell| \
573+            diffsettings|inspectdb|makemessages| \
574+            runserver|startapp|startproject|syncdb| \
575             validate)
576                 COMPREPLY=()
577                 return 0
578Index: docs/man/django-admin.1
579===================================================================
580--- docs/man/django-admin.1     (Revision 7274)
581+++ docs/man/django-admin.1     (Arbeitskopie)
582@@ -1,4 +1,4 @@
583-.TH "django-admin.py" "1" "June 2007" "Django Project" ""
584+.TH "django-admin.py" "1" "March 2008" "Django Project" ""
585 .SH "NAME"
586 django\-admin.py \- Utility script for the Django web framework
587 .SH "SYNOPSIS"
588@@ -21,6 +21,12 @@
589 .BI "adminindex [" "appname ..." "]"
590 Prints the admin\-index template snippet for the given app name(s).
591 .TP
592+.BI cleanup
593+Cleans out old data from the database (only expired sessions at the moment).
594+.TP
595+.BI "compilemessages [" "\-\-locale=LOCALE" "]"
596+Compiles .po files to .mo files for use with builtin gettext support.
597+.TP
598 .BI "createcachetable [" "tablename" "]"
599 Creates the table needed to use the SQL cache backend
600 .TP
601@@ -43,6 +49,11 @@
602 .B sqlall
603 for the given app(s) in the current database.
604 .TP
605+.BI "makemessages [" "\-\-locale=LOCALE" "] [" "\-\-domain=DOMAIN" "] [" "\-\-all" "]"
606+Runs over the entire source tree of the current directory and pulls out all
607+strings marked for translation. It creates (or updates) a message file in the
608+conf/locale (in the django tree) or locale (for project and application) directory.
609+.TP
610 .BI "reset [" "appname ..." "]"
611 Executes
612 .B sqlreset
613@@ -136,7 +147,15 @@
614 .TP
615 .I \-\-adminmedia=ADMIN_MEDIA_PATH
616 Specifies the directory from which to serve admin media when using the development server.
617-
618+.TP
619+.I \-l, \-\-locale=LOCALE
620+The locale to process when using makemessages or compilemessages.
621+.TP
622+.I \-d, \-\-domain=DOMAIN
623+The domain of the message files (default: "django") when using makemessages.
624+.TP
625+.I \-a, \-\-all
626+Process all available locales when using makemessages.
627 .SH "ENVIRONMENT"
628 .TP
629 .I DJANGO_SETTINGS_MODULE
630Index: docs/settings.txt
631===================================================================
632--- docs/settings.txt   (Revision 7274)
633+++ docs/settings.txt   (Arbeitskopie)
634@@ -625,10 +625,10 @@
635         ('en', gettext('English')),
636     )
637 
638-With this arrangement, ``make-messages.py`` will still find and mark these
639-strings for translation, but the translation won't happen at runtime -- so
640-you'll have to remember to wrap the languages in the *real* ``gettext()`` in
641-any code that uses ``LANGUAGES`` at runtime.
642+With this arrangement, ``django-admin.py makemessages`` will still find and
643+mark these strings for translation, but the translation won't happen at
644+runtime -- so you'll have to remember to wrap the languages in the *real*
645+``gettext()`` in any code that uses ``LANGUAGES`` at runtime.
646 
647 LOCALE_PATHS
648 ------------
649Index: docs/i18n.txt
650===================================================================
651--- docs/i18n.txt       (Revision 7274)
652+++ docs/i18n.txt       (Arbeitskopie)
653@@ -122,8 +122,8 @@
654 
655 (The caveat with using variables or computed values, as in the previous two
656 examples, is that Django's translation-string-detecting utility,
657-``make-messages.py``, won't be able to find these strings. More on
658-``make-messages`` later.)
659+``django-admin.py makemessages``, won't be able to find these strings. More on
660+``makemessages`` later.)
661 
662 The strings you pass to ``_()`` or ``ugettext()`` can take placeholders,
663 specified with Python's standard named-string interpolation syntax. Example::
664@@ -392,12 +392,12 @@
665 available translation strings and how they should be represented in the given
666 language. Message files have a ``.po`` file extension.
667 
668-Django comes with a tool, ``bin/make-messages.py``, that automates the creation
669-and upkeep of these files.
670+Django comes with a tool, ``django-admin.py makemessages``, that automates the
671+creation and upkeep of these files.
672 
673 To create or update a message file, run this command::
674 
675-    bin/make-messages.py -l de
676+    django-admin.py makemessages -l de
677 
678 ...where ``de`` is the language code for the message file you want to create.
679 The language code, in this case, is in locale format. For example, it's
680@@ -422,11 +422,11 @@
681 
682 .. admonition:: No gettext?
683 
684-    If you don't have the ``gettext`` utilities installed, ``make-messages.py``
685-    will create empty files. If that's the case, either install the ``gettext``
686-    utilities or just copy the English message file
687-    (``conf/locale/en/LC_MESSAGES/django.po``) and use it as a starting point;
688-    it's just an empty translation file.
689+    If you don't have the ``gettext`` utilities installed,
690+    ``django-admin.py makemessages`` will create empty files. If that's the
691+    case, either install the ``gettext`` utilities or just copy the English
692+    message file (``conf/locale/en/LC_MESSAGES/django.po``) and use it as a
693+    starting point; it's just an empty translation file.
694 
695 The format of ``.po`` files is straightforward. Each ``.po`` file contains a
696 small bit of metadata, such as the translation maintainer's contact
697@@ -439,8 +439,8 @@
698 
699     _("Welcome to my site.")
700 
701-...then ``make-messages.py`` will have created a ``.po`` file containing the
702-following snippet -- a message::
703+...then ``django-admin.py makemessages`` will have created a ``.po`` file
704+containing the following snippet -- a message::
705 
706     #: path/to/python/module.py:23
707     msgid "Welcome to my site."
708@@ -475,7 +475,7 @@
709 To reexamine all source code and templates for new translation strings and
710 update all message files for **all** languages, run this::
711 
712-    make-messages.py -a
713+    django-admin.py makemessages -a
714 
715 Compiling message files
716 -----------------------
717@@ -486,7 +486,7 @@
718 
719 This tool runs over all available ``.po`` files and creates ``.mo`` files,
720 which are binary files optimized for use by ``gettext``. In the same directory
721-from which you ran ``make-messages.py``, run ``compile-messages.py`` like
722+from which you ran ``django-admin.py makemessages``, run ``compile-messages.py`` like
723 this::
724 
725    bin/compile-messages.py
726@@ -597,9 +597,9 @@
727               ('en', ugettext('English')),
728           )
729 
730-      With this arrangement, ``make-messages.py`` will still find and mark
731-      these strings for translation, but the translation won't happen at
732-      runtime -- so you'll have to remember to wrap the languages in the *real*
733+      With this arrangement, ``django-admin.py makemessages`` will still find
734+      and mark these strings for translation, but the translation won't happen
735+      at runtime -- so you'll have to remember to wrap the languages in the *real*
736       ``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.
737 
738     * The ``LocaleMiddleware`` can only select languages for which there is a
739@@ -676,12 +676,12 @@
740       searched in that order for ``<language>/LC_MESSAGES/django.(po|mo)``
741     * ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
742 
743-To create message files, you use the same ``make-messages.py`` tool as with the
744-Django message files. You only need to be in the right place -- in the directory
745-where either the ``conf/locale`` (in case of the source tree) or the ``locale/``
746-(in case of app messages or project messages) directory are located. And you
747-use the same ``compile-messages.py`` to produce the binary ``django.mo`` files
748-that are used by ``gettext``.
749+To create message files, you use the same ``django-admin.py makemessages``
750+tool as with the Django message files. You only need to be in the right place
751+-- in the directory where either the ``conf/locale`` (in case of the source
752+tree) or the ``locale/`` (in case of app messages or project messages)
753+directory are located. And you use the same ``compile-messages.py`` to produce
754+the binary ``django.mo`` files that are used by ``gettext``.
755 
756 You can also run ``compile-message.py --settings=path.to.settings`` to make
757 the compiler process all the directories in your ``LOCALE_PATHS`` setting.
758@@ -694,15 +694,15 @@
759 files. If your applications need to be delivered to other users and will
760 be used in other projects, you might want to use app-specific translations.
761 But using app-specific translations and project translations could produce
762-weird problems with ``make-messages``: ``make-messages`` will traverse all
763+weird problems with ``makemessages``: ``makemessages`` will traverse all
764 directories below the current path and so might put message IDs into the
765 project message file that are already in application message files.
766 
767 The easiest way out is to store applications that are not part of the project
768 (and so carry their own translations) outside the project tree. That way,
769-``make-messages`` on the project level will only translate strings that are
770-connected to your explicit project and not strings that are distributed
771-independently.
772+``django-admin.py makemessages`` on the project level will only translate
773+strings that are connected to your explicit project and not strings that are
774+distributed independently.
775 
776 The ``set_language`` redirect view
777 ==================================
778@@ -834,10 +834,10 @@
779 ----------------------------------------
780 
781 You create and update the translation catalogs the same way as the other
782-Django translation catalogs -- with the make-messages.py tool. The only
783-difference is you need to provide a ``-d djangojs`` parameter, like this::
784+Django translation catalogs -- with the django-admin.py makemessages tool. The
785+only difference is you need to provide a ``-d djangojs`` parameter, like this::
786 
787-    make-messages.py -d djangojs -l de
788+    django-admin.py makemessages -d djangojs -l de
789 
790 This would create or update the translation catalog for JavaScript for German.
791 After updating translation catalogs, just run ``compile-messages.py`` the same
792Index: docs/django-admin.txt
793===================================================================
794--- docs/django-admin.txt       (Revision 7274)
795+++ docs/django-admin.txt       (Arbeitskopie)
796@@ -85,6 +85,28 @@
797 
798 .. _Tutorial 2: ../tutorial02/
799 
800+cleanup
801+-------
802+
803+Can be run as a cronjob or directly to clean out old data from the database
804+(only expired sessions at the moment).
805+
806+compilemessages
807+---------------
808+
809+Compiles .po files created with ``makemessages`` to .mo files for use with
810+the builtin gettext support. See the `i18n documentation`_ for details.
811+
812+--locale
813+~~~~~~~~
814+
815+Use the ``--locale`` or ``-l`` option to specify the locale to process.
816+If not provided all locales are processed.
817+
818+Example usage::
819+
820+    django-admin.py compilemessages --locale=br_PT
821+
822 createcachetable <tablename>
823 ----------------------------
824 
825@@ -321,6 +343,60 @@
826 
827     django-admin.py loaddata --verbosity=2
828 
829+makemessages
830+------------
831+
832+Runs over the entire source tree of the current directory and pulls out all
833+strings marked for translation. It creates (or updates) a message file in the
834+conf/locale (in the django tree) or locale (for project and application)
835+directory. After making changes to the messages files you need to compile them
836+with ``compilemessages`` for use with the builtin gettext support. See the
837+`i18n documentation`_ for details.
838+
839+.. _i18n documentation: ../i18n/#how-to-create-language-files
840+
841+--all
842+~~~~~
843+
844+Use the ``--all`` or ``-a`` option to update the message files for all
845+available languages.
846+
847+Example usage::
848+
849+    django-admin.py makemessages --all
850+
851+--locale
852+~~~~~~~~
853+
854+Use the ``--locale`` or ``-l`` option to specify the locale to process.
855+
856+Example usage::
857+
858+    django-admin.py makemessages --locale=br_PT
859+
860+--domain
861+~~~~~~~~
862+
863+Use the ``--domain`` or ``-d`` option to change the domain of the messages files.
864+Currently supported:
865+
866+       * ``django`` for all ``*.py`` and ``*.html`` files (default)
867+       * ``djangojs`` for ``*.js`` files
868+
869+--verbosity
870+~~~~~~~~~~~
871+
872+Use ``--verbosity`` or ``-v`` to specify the amount of notification and debug
873+information that ``django-admin.py`` should print to the console.
874+
875+       * ``0`` means no input.
876+       * ``1`` means normal input (default).
877+       * ``2`` means verbose input.
878+
879+Example usage::
880+
881+    django-admin.py makemessages --verbosity=2
882+
883 reset <appname appname ...>
884 ---------------------------
885