~grupoesoc/cubicerp-addons/7.0

« back to all changes in this revision

Viewing changes to report_geraldo/lib/geraldo/site/newsite/django_1_0/django/core/management/__init__.py

  • Committer: Cubic ERP
  • Date: 2014-01-07 15:38:09 UTC
  • Revision ID: info@cubicerp.com-20140107153809-4jmif3zoi8rcveve
[ADD] cubicReport

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import os
 
2
import sys
 
3
from optparse import OptionParser
 
4
from imp import find_module
 
5
 
 
6
import django
 
7
from django.core.management.base import BaseCommand, CommandError, handle_default_options
 
8
 
 
9
# For backwards compatibility: get_version() used to be in this module.
 
10
get_version = django.get_version
 
11
 
 
12
# A cache of loaded commands, so that call_command
 
13
# doesn't have to reload every time it's called.
 
14
_commands = None
 
15
 
 
16
def find_commands(management_dir):
 
17
    """
 
18
    Given a path to a management directory, returns a list of all the command
 
19
    names that are available.
 
20
 
 
21
    Returns an empty list if no commands are defined.
 
22
    """
 
23
    command_dir = os.path.join(management_dir, 'commands')
 
24
    try:
 
25
        return [f[:-3] for f in os.listdir(command_dir)
 
26
                if not f.startswith('_') and f.endswith('.py')]
 
27
    except OSError:
 
28
        return []
 
29
 
 
30
def find_management_module(app_name):
 
31
    """
 
32
    Determines the path to the management module for the given app_name,
 
33
    without actually importing the application or the management module.
 
34
 
 
35
    Raises ImportError if the management module cannot be found for any reason.
 
36
    """
 
37
    parts = app_name.split('.')
 
38
    parts.append('management')
 
39
    parts.reverse()
 
40
    path = None
 
41
    while parts:
 
42
        part = parts.pop()
 
43
        f, path, descr = find_module(part, path and [path] or None)
 
44
    return path
 
45
 
 
46
def load_command_class(app_name, name):
 
47
    """
 
48
    Given a command name and an application name, returns the Command
 
49
    class instance. All errors raised by the import process
 
50
    (ImportError, AttributeError) are allowed to propagate.
 
51
    """
 
52
    return getattr(__import__('%s.management.commands.%s' % (app_name, name),
 
53
                   {}, {}, ['Command']), 'Command')()
 
54
 
 
55
def get_commands(load_user_commands=True, project_directory=None):
 
56
    """
 
57
    Returns a dictionary mapping command names to their callback applications.
 
58
 
 
59
    This works by looking for a management.commands package in django.core, and
 
60
    in each installed application -- if a commands package exists, all commands
 
61
    in that package are registered.
 
62
 
 
63
    Core commands are always included. If a settings module has been
 
64
    specified, user-defined commands will also be included, the
 
65
    startproject command will be disabled, and the startapp command
 
66
    will be modified to use the directory in which that module appears.
 
67
 
 
68
    The dictionary is in the format {command_name: app_name}. Key-value
 
69
    pairs from this dictionary can then be used in calls to
 
70
    load_command_class(app_name, command_name)
 
71
 
 
72
    If a specific version of a command must be loaded (e.g., with the
 
73
    startapp command), the instantiated module can be placed in the
 
74
    dictionary in place of the application name.
 
75
 
 
76
    The dictionary is cached on the first call and reused on subsequent
 
77
    calls.
 
78
    """
 
79
    global _commands
 
80
    if _commands is None:
 
81
        _commands = dict([(name, 'django.core') for name in find_commands(__path__[0])])
 
82
 
 
83
        if load_user_commands:
 
84
            # Get commands from all installed apps.
 
85
            from django.conf import settings
 
86
            for app_name in settings.INSTALLED_APPS:
 
87
                try:
 
88
                    path = find_management_module(app_name)
 
89
                    _commands.update(dict([(name, app_name) for name in find_commands(path)]))
 
90
                except ImportError:
 
91
                    pass # No management module -- ignore this app.
 
92
 
 
93
        if project_directory:
 
94
            # Remove the "startproject" command from self.commands, because
 
95
            # that's a django-admin.py command, not a manage.py command.
 
96
            del _commands['startproject']
 
97
 
 
98
            # Override the startapp command so that it always uses the
 
99
            # project_directory, not the current working directory
 
100
            # (which is default).
 
101
            from django.core.management.commands.startapp import ProjectCommand
 
102
            _commands['startapp'] = ProjectCommand(project_directory)
 
103
 
 
104
    return _commands
 
105
 
 
106
def call_command(name, *args, **options):
 
107
    """
 
108
    Calls the given command, with the given options and args/kwargs.
 
109
 
 
110
    This is the primary API you should use for calling specific commands.
 
111
 
 
112
    Some examples:
 
113
        call_command('syncdb')
 
114
        call_command('shell', plain=True)
 
115
        call_command('sqlall', 'myapp')
 
116
    """
 
117
    try:
 
118
        app_name = get_commands()[name]
 
119
        if isinstance(app_name, BaseCommand):
 
120
            # If the command is already loaded, use it directly.
 
121
            klass = app_name
 
122
        else:
 
123
            klass = load_command_class(app_name, name)
 
124
    except KeyError:
 
125
        raise CommandError, "Unknown command: %r" % name
 
126
    return klass.execute(*args, **options)
 
127
 
 
128
class LaxOptionParser(OptionParser):
 
129
    """
 
130
    An option parser that doesn't raise any errors on unknown options.
 
131
 
 
132
    This is needed because the --settings and --pythonpath options affect
 
133
    the commands (and thus the options) that are available to the user.
 
134
    """
 
135
    def error(self, msg):
 
136
        pass
 
137
    
 
138
    def _process_args(self, largs, rargs, values):
 
139
        """
 
140
        Overrides OptionParser._process_args to exclusively handle default
 
141
        options and ignore args and other options. 
 
142
        
 
143
        This overrides the behavior of the super class, which stop parsing 
 
144
        at the first unrecognized option.
 
145
        """
 
146
        while rargs:
 
147
            arg = rargs[0]
 
148
            try:
 
149
                if arg[0:2] == "--" and len(arg) > 2:
 
150
                    # process a single long option (possibly with value(s))
 
151
                    # the superclass code pops the arg off rargs
 
152
                    self._process_long_opt(rargs, values)
 
153
                elif arg[:1] == "-" and len(arg) > 1:
 
154
                    # process a cluster of short options (possibly with
 
155
                    # value(s) for the last one only)
 
156
                    # the superclass code pops the arg off rargs
 
157
                    self._process_short_opts(rargs, values)
 
158
                else:
 
159
                    # it's either a non-default option or an arg
 
160
                    # either way, add it to the args list so we can keep
 
161
                    # dealing with options
 
162
                    del rargs[0]
 
163
                    raise error
 
164
            except:
 
165
                largs.append(arg)
 
166
 
 
167
class ManagementUtility(object):
 
168
    """
 
169
    Encapsulates the logic of the django-admin.py and manage.py utilities.
 
170
 
 
171
    A ManagementUtility has a number of commands, which can be manipulated
 
172
    by editing the self.commands dictionary.
 
173
    """
 
174
    def __init__(self, argv=None):
 
175
        self.argv = argv or sys.argv[:]
 
176
        self.prog_name = os.path.basename(self.argv[0])
 
177
        self.project_directory = None
 
178
        self.user_commands = False
 
179
 
 
180
    def main_help_text(self):
 
181
        """
 
182
        Returns the script's main help text, as a string.
 
183
        """
 
184
        usage = ['%s <subcommand> [options] [args]' % self.prog_name]
 
185
        usage.append('Django command line tool, version %s' % django.get_version())
 
186
        usage.append("Type '%s help <subcommand>' for help on a specific subcommand." % self.prog_name)
 
187
        usage.append('Available subcommands:')
 
188
        commands = get_commands(self.user_commands, self.project_directory).keys()
 
189
        commands.sort()
 
190
        for cmd in commands:
 
191
            usage.append('  %s' % cmd)
 
192
        return '\n'.join(usage)
 
193
 
 
194
    def fetch_command(self, subcommand):
 
195
        """
 
196
        Tries to fetch the given subcommand, printing a message with the
 
197
        appropriate command called from the command line (usually
 
198
        "django-admin.py" or "manage.py") if it can't be found.
 
199
        """
 
200
        try:
 
201
            app_name = get_commands(self.user_commands, self.project_directory)[subcommand]
 
202
            if isinstance(app_name, BaseCommand):
 
203
                # If the command is already loaded, use it directly.
 
204
                klass = app_name
 
205
            else:
 
206
                klass = load_command_class(app_name, subcommand)
 
207
        except KeyError:
 
208
            sys.stderr.write("Unknown command: %r\nType '%s help' for usage.\n" % \
 
209
                (subcommand, self.prog_name))
 
210
            sys.exit(1)
 
211
        return klass
 
212
 
 
213
    def execute(self):
 
214
        """
 
215
        Given the command-line arguments, this figures out which subcommand is
 
216
        being run, creates a parser appropriate to that command, and runs it.
 
217
        """
 
218
        # Preprocess options to extract --settings and --pythonpath.
 
219
        # These options could affect the commands that are available, so they
 
220
        # must be processed early.
 
221
        parser = LaxOptionParser(version=get_version(), option_list=BaseCommand.option_list)
 
222
        try:
 
223
            options, args = parser.parse_args(self.argv)
 
224
            handle_default_options(options)
 
225
        except:
 
226
            pass # Ignore any option errors at this point.
 
227
 
 
228
        try:
 
229
            subcommand = self.argv[1]
 
230
        except IndexError:
 
231
            sys.stderr.write("Type '%s help' for usage.\n" % self.prog_name)
 
232
            sys.exit(1)
 
233
 
 
234
        if subcommand == 'help':
 
235
            if len(args) > 2:
 
236
                self.fetch_command(args[2]).print_help(self.prog_name, args[2])
 
237
            else:
 
238
                sys.stderr.write(self.main_help_text() + '\n')
 
239
                sys.exit(1)
 
240
        # Special-cases: We want 'django-admin.py --version' and
 
241
        # 'django-admin.py --help' to work, for backwards compatibility.
 
242
        elif self.argv[1:] == ['--version']:
 
243
            # LaxOptionParser already takes care of printing the version.
 
244
            pass
 
245
        elif self.argv[1:] == ['--help']:
 
246
            sys.stderr.write(self.main_help_text() + '\n')
 
247
        else:
 
248
            self.fetch_command(subcommand).run_from_argv(self.argv)
 
249
 
 
250
class ProjectManagementUtility(ManagementUtility):
 
251
    """
 
252
    A ManagementUtility that is specific to a particular Django project.
 
253
    As such, its commands are slightly different than those of its parent
 
254
    class.
 
255
 
 
256
    In practice, this class represents manage.py, whereas ManagementUtility
 
257
    represents django-admin.py.
 
258
    """
 
259
    def __init__(self, argv, project_directory):
 
260
        super(ProjectManagementUtility, self).__init__(argv)
 
261
        self.project_directory = project_directory
 
262
        self.user_commands = True
 
263
 
 
264
def setup_environ(settings_mod):
 
265
    """
 
266
    Configures the runtime environment. This can also be used by external
 
267
    scripts wanting to set up a similar environment to manage.py.
 
268
    Returns the project directory (assuming the passed settings module is
 
269
    directly in the project directory).
 
270
    """
 
271
    # Add this project to sys.path so that it's importable in the conventional
 
272
    # way. For example, if this file (manage.py) lives in a directory
 
273
    # "myproject", this code would add "/path/to/myproject" to sys.path.
 
274
    project_directory, settings_filename = os.path.split(settings_mod.__file__)
 
275
    if project_directory == os.curdir or not project_directory:
 
276
        project_directory = os.getcwd()
 
277
    project_name = os.path.basename(project_directory)
 
278
    settings_name = os.path.splitext(settings_filename)[0]
 
279
    sys.path.append(os.path.join(project_directory, os.pardir))
 
280
    project_module = __import__(project_name, {}, {}, [''])
 
281
    sys.path.pop()
 
282
 
 
283
    # Set DJANGO_SETTINGS_MODULE appropriately.
 
284
    os.environ['DJANGO_SETTINGS_MODULE'] = '%s.%s' % (project_name, settings_name)
 
285
    return project_directory
 
286
 
 
287
def execute_from_command_line(argv=None):
 
288
    """
 
289
    A simple method that runs a ManagementUtility.
 
290
    """
 
291
    utility = ManagementUtility(argv)
 
292
    utility.execute()
 
293
 
 
294
def execute_manager(settings_mod, argv=None):
 
295
    """
 
296
    Like execute_from_command_line(), but for use by manage.py, a
 
297
    project-specific django-admin.py utility.
 
298
    """
 
299
    project_directory = setup_environ(settings_mod)
 
300
    utility = ProjectManagementUtility(argv, project_directory)
 
301
    utility.execute()