web/lib/django_extensions/management/commands/runscript.py
changeset 3 526ebd3988b0
equal deleted inserted replaced
1:ebaad720f88b 3:526ebd3988b0
       
     1 from django.core.management.base import BaseCommand
       
     2 from django.core.management.color import no_style
       
     3 from optparse import make_option
       
     4 import sys
       
     5 import os
       
     6 
       
     7 try:
       
     8     set
       
     9 except NameError:
       
    10     from sets import Set as set   # Python 2.3 fallback
       
    11 
       
    12 class Command(BaseCommand):
       
    13     option_list = BaseCommand.option_list + (
       
    14         make_option('--fixtures', action='store_true', dest='infixtures', default=False,
       
    15             help='Only look in app.fixtures subdir'),
       
    16         make_option('--noscripts', action='store_true', dest='noscripts', default=False,
       
    17             help='Look in app.scripts subdir'),
       
    18         make_option('-s', '--silent', action='store_true', dest='silent', default=False,
       
    19             help='Run silently, do not show errors and tracebacks'),
       
    20         make_option('--no-traceback', action='store_true', dest='no_traceback', default=False,
       
    21             help='Do not show tracebacks'),
       
    22     )
       
    23     help = 'Runs a script in django context.'
       
    24     args = "script [script ...]"
       
    25 
       
    26     def handle(self, *scripts, **options):
       
    27         from django.db.models import get_apps
       
    28         
       
    29         NOTICE = self.style.SQL_TABLE
       
    30         NOTICE2 = self.style.SQL_FIELD
       
    31         ERROR = self.style.ERROR_OUTPUT
       
    32         ERROR2 = self.style.NOTICE
       
    33 
       
    34         subdirs = []
       
    35 
       
    36         if not options.get('noscripts'):
       
    37             subdirs.append('scripts')
       
    38         if options.get('infixtures'):
       
    39             subdirs.append('fixtures')
       
    40         verbosity = int(options.get('verbosity', 1))
       
    41         show_traceback = options.get('traceback', True)
       
    42         if show_traceback is None:
       
    43             # XXX: traceback is set to None from Django ?
       
    44             show_traceback = True
       
    45         no_traceback = options.get('no_traceback', False)
       
    46         if no_traceback:
       
    47             show_traceback = False
       
    48         silent = options.get('silent', False)
       
    49         if silent:
       
    50             verbosity = 0
       
    51 
       
    52         if len(subdirs) < 1:
       
    53             print NOTICE("No subdirs to run left.")
       
    54             return
       
    55 
       
    56         if len(scripts) < 1:
       
    57             print ERROR("Script name required.")
       
    58             return
       
    59 
       
    60         def run_script(mod):
       
    61             # TODO: add arguments to run
       
    62             try:
       
    63                 mod.run()
       
    64             except Exception, e:
       
    65                 if silent:
       
    66                     return
       
    67                 if verbosity > 0:
       
    68                     print ERROR("Exception while running run() in '%s'" % mod.__name__)
       
    69                 if show_traceback:
       
    70                     raise
       
    71         
       
    72         def my_import(mod):
       
    73             if verbosity > 1:
       
    74                 print NOTICE("Check for %s" % mod)
       
    75             try:
       
    76                 t = __import__(mod, [], [], [" "])
       
    77                 #if verbosity > 1:
       
    78                 #    print NOTICE("Found script %s ..." % mod)
       
    79                 if hasattr(t, "run"):
       
    80                     if verbosity > 1:
       
    81                         print NOTICE2("Found script '%s' ..." % mod)
       
    82                     #if verbosity > 1:
       
    83                     #    print NOTICE("found run() in %s. executing..." % mod)
       
    84                     return t
       
    85                 else:
       
    86                     if verbosity > 1:
       
    87                         print ERROR2("Find script '%s' but no run() function found." % mod)
       
    88             except ImportError:
       
    89                 return False
       
    90         
       
    91         def find_modules_for_script(script):
       
    92             """ find script module which contains 'run' attribute """
       
    93             modules = []
       
    94             # first look in apps
       
    95             for app in get_apps():
       
    96                 app_name = app.__name__.split(".")[:-1] # + ['fixtures']
       
    97                 for subdir in subdirs:
       
    98                     mod = my_import(".".join(app_name + [subdir, script]))
       
    99                     if mod:
       
   100                         modules.append(mod)
       
   101 
       
   102             # try app.DIR.script import
       
   103             sa = script.split(".")
       
   104             for subdir in subdirs:
       
   105                 nn = ".".join(sa[:-1] + [subdir, sa[-1]])
       
   106                 mod = my_import(nn)
       
   107                 if mod:
       
   108                     modules.append(mod)
       
   109 
       
   110             # try direct import
       
   111             if script.find(".") != -1:
       
   112                 mod = my_import(script)
       
   113                 if mod:
       
   114                     modules.append(mod)
       
   115             
       
   116             return modules
       
   117         
       
   118         for script in scripts:
       
   119             modules = find_modules_for_script(script)
       
   120             if not modules:
       
   121                 if verbosity>0 and not silent:
       
   122                     print ERROR("No module for script '%s' found" % script)
       
   123             for mod in modules:
       
   124                 if verbosity>1:
       
   125                     print NOTICE2("Running script '%s' ..." % mod.__name__)
       
   126                 run_script(mod)
       
   127 
       
   128 # Backwards compatibility for Django r9110
       
   129 if not [opt for opt in Command.option_list if opt.dest=='verbosity']:
       
   130     Command.option_list += (
       
   131         make_option('--verbosity', '-v', action="store", dest="verbosity",
       
   132                     default='1', type='choice', choices=['0', '1', '2'],
       
   133                     help="Verbosity level; 0=minimal output, 1=normal output, 2=all output"),
       
   134     )