Commit 3cfa3cbd authored by Malcolm Tredinnick's avatar Malcolm Tredinnick
Browse files

Fixed #5522 -- Moved make-messages, compile-messages and daily-cleanup into django-admin.py.

They are now called  "makemessages", "compilemessages" and "cleanup". This is
backwards incompatible for make-messages.py and compile-messages.py, although
the old executables still exist for now and print an error pointing the caller
to the right command to call.

This reduces the number of binaries and man pages Django needs to install.

Patch from Janis Leidel.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@7844 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent bff07597
Loading
Loading
Loading
Loading
+8 −61
Original line number Diff line number Diff line
#!/usr/bin/env python

import optparse
import os
if __name__ == "__main__":
    import sys

try:
    set
except NameError:
    from sets import Set as set     # For Python 2.3


def compile_messages(locale=None):
    basedirs = (os.path.join('conf', 'locale'), 'locale')
    if os.environ.get('DJANGO_SETTINGS_MODULE'):
        from django.conf import settings
        basedirs += settings.LOCALE_PATHS

    # Gather existing directories.
    basedirs = set(map(os.path.abspath, filter(os.path.isdir, basedirs)))

    if not basedirs:
        print "This script should be run from the Django SVN tree or your project or app tree, or with the settings module specified."
    name = sys.argv[0]
    args = ' '.join(sys.argv[1:])
    print >> sys.stderr, "%s has been moved into django-admin.py" % name
    print >> sys.stderr, 'Please run "django-admin.py compilemessages %s" instead.'% args
    print >> sys.stderr
    sys.exit(1)
    for basedir in basedirs:
        if locale:
            basedir = os.path.join(basedir, locale, 'LC_MESSAGES')
        compile_messages_in_dir(basedir)

def compile_messages_in_dir(basedir):
    for dirpath, dirnames, filenames in os.walk(basedir):
        for f in filenames:
            if f.endswith('.po'):
                sys.stderr.write('processing file %s in %s\n' % (f, dirpath))
                pf = os.path.splitext(os.path.join(dirpath, f))[0]
                # Store the names of the .mo and .po files in an environment
                # variable, rather than doing a string replacement into the
                # command, so that we can take advantage of shell quoting, to
                # quote any malicious characters/escaping.
                # See http://cyberelk.net/tim/articles/cmdline/ar01s02.html
                os.environ['djangocompilemo'] = pf + '.mo'
                os.environ['djangocompilepo'] = pf + '.po'
                if sys.platform == 'win32': # Different shell-variable syntax
                    cmd = 'msgfmt --check-format -o "%djangocompilemo%" "%djangocompilepo%"'
                else:
                    cmd = 'msgfmt --check-format -o "$djangocompilemo" "$djangocompilepo"'
                os.system(cmd)

def main():
    parser = optparse.OptionParser()
    parser.add_option('-l', '--locale', dest='locale',
            help="The locale to process. Default is to process all.")
    parser.add_option('--settings',
        help='Python path to settings module, e.g. "myproject.settings". If provided, all LOCALE_PATHS will be processed. If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be checked as well.')
    options, args = parser.parse_args()
    if len(args):
        parser.error("This program takes no arguments")
    if options.settings:
        os.environ['DJANGO_SETTINGS_MODULE'] = options.settings
    compile_messages(options.locale)

if __name__ == "__main__":
    main()
+2 −9
Original line number Diff line number Diff line
@@ -7,14 +7,7 @@ Can be run as a cronjob to clean out old data from the database (only expired
sessions at the moment).
"""

import datetime
from django.db import transaction
from django.contrib.sessions.models import Session

def clean_up():
    """Clean up expired sessions."""
    Session.objects.filter(expire_date__lt=datetime.datetime.now()).delete()
    transaction.commit_unless_managed()
from django.core import management

if __name__ == "__main__":
    clean_up()
    management.call_command('cleanup')
+8 −156
Original line number Diff line number Diff line
#!/usr/bin/env python

# Need to ensure that the i18n framework is enabled
from django.conf import settings
settings.configure(USE_I18N = True)

from django.utils.translation import templatize
import re
import os
if __name__ == "__main__":
    import sys
import getopt
from itertools import dropwhile

pythonize_re = re.compile(r'\n\s*//')

def make_messages():
    localedir = None

    if os.path.isdir(os.path.join('conf', 'locale')):
        localedir = os.path.abspath(os.path.join('conf', 'locale'))
    elif os.path.isdir('locale'):
        localedir = os.path.abspath('locale')
    else:
        print "This script should be run from the django svn tree or your project or app tree."
        print "If you did indeed run it from the svn checkout or your project or application,"
        print "maybe you are just missing the conf/locale (in the django tree) or locale (for project"
        print "and application) directory?"
        print "make-messages.py doesn't create it automatically, you have to create it by hand if"
        print "you want to enable i18n for your project or application."
        sys.exit(1)

    (opts, args) = getopt.getopt(sys.argv[1:], 'l:d:va')

    lang = None
    domain = 'django'
    verbose = False
    all = False

    for o, v in opts:
        if o == '-l':
            lang = v
        elif o == '-d':
            domain = v
        elif o == '-v':
            verbose = True
        elif o == '-a':
            all = True

    if domain not in ('django', 'djangojs'):
        print "currently make-messages.py only supports domains 'django' and 'djangojs'"
    name = sys.argv[0]
    args = ' '.join(sys.argv[1:])
    print >> sys.stderr, "%s has been moved into django-admin.py" % name
    print >> sys.stderr, 'Please run "django-admin.py makemessages %s" instead.'% args
    print >> sys.stderr
    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"
        sys.exit(1)

    languages = []

    if lang is not None:
        languages.append(lang)
    elif all:
        languages = [el for el in os.listdir(localedir) if not el.startswith('.')]

    for lang in languages:

        print "processing language", lang
        basedir = os.path.join(localedir, lang, 'LC_MESSAGES')
        if not os.path.isdir(basedir):
            os.makedirs(basedir)
        pofile = os.path.join(basedir, '%s.po' % domain)
        potfile = os.path.join(basedir, '%s.pot' % domain)

        if os.path.exists(potfile):
            os.unlink(potfile)

        all_files = []
        for (dirpath, dirnames, filenames) in os.walk("."):
            all_files.extend([(dirpath, f) for f in filenames])
        all_files.sort()
        for dirpath, file in all_files:
            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 -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (domain, os.path.join(dirpath, thefile))
                (stdin, stdout, stderr) = os.popen3(cmd, 't')
                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 os.path.exists(potfile):
                    # Strip the header
                    msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
                else:
                    msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
                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()
                    thefile = '%s.py' % file
                    open(os.path.join(dirpath, thefile), "wb").write(templatize(src))
                if verbose:
                    sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
                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"' % (
                    domain, os.path.join(dirpath, thefile))
                (stdin, stdout, stderr) = os.popen3(cmd, 't')
                msgs = stdout.read()
                errors = stderr.read()
                if errors:
                    print "errors happened while running xgettext on %s" % file
                    print errors
                    sys.exit(8)
                if thefile != file:
                    old = '#: '+os.path.join(dirpath, thefile)[2:]
                    new = '#: '+os.path.join(dirpath, file)[2:]
                    msgs = msgs.replace(old, new)
                if os.path.exists(potfile):
                    # Strip the header
                    msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
                else:
                    msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
                if msgs:
                    open(potfile, 'ab').write(msgs)
                if thefile != file:
                    os.unlink(os.path.join(dirpath, thefile))

        if os.path.exists(potfile):
            (stdin, stdout, stderr) = os.popen3('msguniq --to-code=utf-8 "%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')
                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)

if __name__ == "__main__":
    make_messages()
+5 −0
Original line number Diff line number Diff line
@@ -6,6 +6,11 @@ import django
from django.core.exceptions import ImproperlyConfigured
from django.core.management.color import color_style

try:
    set
except NameError:
    from sets import Set as set     # For Python 2.3

class CommandError(Exception):
    pass

+11 −0
Original line number Diff line number Diff line
import datetime
from django.core.management.base import NoArgsCommand

class Command(NoArgsCommand):
    help = "Can be run as a cronjob or directly to clean out old data from the database (only expired sessions at the moment)."

    def handle_noargs(self, **options):
        from django.db import transaction
        from django.contrib.sessions.models import Session
        Session.objects.filter(expire_date__lt=datetime.datetime.now()).delete()
        transaction.commit_unless_managed()
Loading