root / snf-webproject / synnefo / webproject / manage.py @ 4691814d
History | View | Annotate | Download (12.9 kB)
1 | eeda4702 | Kostas Papadimitriou | # Copyright 2011 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | eeda4702 | Kostas Papadimitriou | #
|
3 | eeda4702 | Kostas Papadimitriou | # Redistribution and use in source and binary forms, with or
|
4 | eeda4702 | Kostas Papadimitriou | # without modification, are permitted provided that the following
|
5 | eeda4702 | Kostas Papadimitriou | # conditions are met:
|
6 | eeda4702 | Kostas Papadimitriou | #
|
7 | eeda4702 | Kostas Papadimitriou | # 1. Redistributions of source code must retain the above
|
8 | eeda4702 | Kostas Papadimitriou | # copyright notice, this list of conditions and the following
|
9 | eeda4702 | Kostas Papadimitriou | # disclaimer.
|
10 | eeda4702 | Kostas Papadimitriou | #
|
11 | eeda4702 | Kostas Papadimitriou | # 2. Redistributions in binary form must reproduce the above
|
12 | eeda4702 | Kostas Papadimitriou | # copyright notice, this list of conditions and the following
|
13 | eeda4702 | Kostas Papadimitriou | # disclaimer in the documentation and/or other materials
|
14 | eeda4702 | Kostas Papadimitriou | # provided with the distribution.
|
15 | eeda4702 | Kostas Papadimitriou | #
|
16 | eeda4702 | Kostas Papadimitriou | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | eeda4702 | Kostas Papadimitriou | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | eeda4702 | Kostas Papadimitriou | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | eeda4702 | Kostas Papadimitriou | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | eeda4702 | Kostas Papadimitriou | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | eeda4702 | Kostas Papadimitriou | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | eeda4702 | Kostas Papadimitriou | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | eeda4702 | Kostas Papadimitriou | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | eeda4702 | Kostas Papadimitriou | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | eeda4702 | Kostas Papadimitriou | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | eeda4702 | Kostas Papadimitriou | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | eeda4702 | Kostas Papadimitriou | # POSSIBILITY OF SUCH DAMAGE.
|
28 | eeda4702 | Kostas Papadimitriou | #
|
29 | eeda4702 | Kostas Papadimitriou | # The views and conclusions contained in the software and
|
30 | eeda4702 | Kostas Papadimitriou | # documentation are those of the authors and should not be
|
31 | eeda4702 | Kostas Papadimitriou | # interpreted as representing official policies, either expressed
|
32 | eeda4702 | Kostas Papadimitriou | # or implied, of GRNET S.A.
|
33 | eeda4702 | Kostas Papadimitriou | |
34 | 18a544f5 | Kostas Papadimitriou | """
|
35 | 18a544f5 | Kostas Papadimitriou | Extented django management module
|
36 | 18a544f5 | Kostas Papadimitriou |
|
37 | 18a544f5 | Kostas Papadimitriou | Most of the code is shared from django.core.management module
|
38 | 18a544f5 | Kostas Papadimitriou | to allow us extend the default django ManagementUtility object
|
39 | 18a544f5 | Kostas Papadimitriou | used to provide command line interface of the django project
|
40 | 18a544f5 | Kostas Papadimitriou | included in snf-webproject package.
|
41 | 18a544f5 | Kostas Papadimitriou |
|
42 | 18a544f5 | Kostas Papadimitriou | The extended class provides the following:
|
43 | 18a544f5 | Kostas Papadimitriou |
|
44 | 18a544f5 | Kostas Papadimitriou | - additional argument for the configuration of the SYNNEFO_SETTINGS_DIR
|
45 | 18a544f5 | Kostas Papadimitriou | environmental variable (--settings-dir).
|
46 | 18a544f5 | Kostas Papadimitriou | - a fix for management utility to handle custom commands defined in
|
47 | 18a544f5 | Kostas Papadimitriou | applications living in namespaced packages (django ticket #14087)
|
48 | 18a544f5 | Kostas Papadimitriou | - override of --version command to display the snf-webproject version
|
49 | 18a544f5 | Kostas Papadimitriou | """
|
50 | 8c34763c | Giorgos Verigakis | |
51 | d2ff89df | Kostas Papadimitriou | from django.core.management import ManagementUtility, setup_environ, \ |
52 | 4691814d | Ilias Tsitsimpis | BaseCommand, LaxOptionParser, handle_default_options, find_commands, \ |
53 | 4691814d | Ilias Tsitsimpis | load_command_class
|
54 | d2ff89df | Kostas Papadimitriou | |
55 | 18a544f5 | Kostas Papadimitriou | from django.core import management |
56 | 18a544f5 | Kostas Papadimitriou | from django.utils.importlib import import_module |
57 | 4691814d | Ilias Tsitsimpis | from optparse import make_option |
58 | 07d104d8 | Kostas Papadimitriou | from synnefo.util.version import get_component_version |
59 | d01cd522 | Christos Stavrakakis | from synnefo.lib.dictconfig import dictConfig |
60 | d2ff89df | Kostas Papadimitriou | |
61 | d2ff89df | Kostas Papadimitriou | import sys |
62 | a45fc1ae | Christos Stavrakakis | import locale |
63 | d2ff89df | Kostas Papadimitriou | import os |
64 | 18a544f5 | Kostas Papadimitriou | import imp |
65 | 18a544f5 | Kostas Papadimitriou | |
66 | 18a544f5 | Kostas Papadimitriou | _commands = None
|
67 | 18a544f5 | Kostas Papadimitriou | |
68 | d01cd522 | Christos Stavrakakis | |
69 | 18a544f5 | Kostas Papadimitriou | def find_modules(name, path=None): |
70 | 18a544f5 | Kostas Papadimitriou | """Find all modules with name 'name'
|
71 | 18a544f5 | Kostas Papadimitriou |
|
72 | 18a544f5 | Kostas Papadimitriou | Unlike find_module in the imp package this returns a list of all
|
73 | 18a544f5 | Kostas Papadimitriou | matched modules.
|
74 | 18a544f5 | Kostas Papadimitriou | """
|
75 | 18c15348 | Kostas Papadimitriou | |
76 | 18a544f5 | Kostas Papadimitriou | results = [] |
77 | bc89ff1a | Georgios D. Tsoukalas | if path is None: |
78 | bc89ff1a | Georgios D. Tsoukalas | path = sys.path |
79 | 18a544f5 | Kostas Papadimitriou | for p in path: |
80 | 18a544f5 | Kostas Papadimitriou | importer = sys.path_importer_cache.get(p, None)
|
81 | 18a544f5 | Kostas Papadimitriou | if importer is None: |
82 | 18a544f5 | Kostas Papadimitriou | find_module = imp.find_module |
83 | 18a544f5 | Kostas Papadimitriou | else:
|
84 | 18a544f5 | Kostas Papadimitriou | find_module = importer.find_module |
85 | 18a544f5 | Kostas Papadimitriou | |
86 | 18a544f5 | Kostas Papadimitriou | try:
|
87 | 18a544f5 | Kostas Papadimitriou | result = find_module(name, [p]) |
88 | 18a544f5 | Kostas Papadimitriou | if result is not None: |
89 | 18a544f5 | Kostas Papadimitriou | results.append(result) |
90 | 18a544f5 | Kostas Papadimitriou | except ImportError: |
91 | 18c15348 | Kostas Papadimitriou | if sys.modules.get(name, None): |
92 | 18c15348 | Kostas Papadimitriou | modpath = sys.modules[name].__path__ |
93 | 4691814d | Ilias Tsitsimpis | if isinstance(modpath, basestring) \ |
94 | 4691814d | Ilias Tsitsimpis | and not ('', modpath) in results: |
95 | 4691814d | Ilias Tsitsimpis | results.append(('', sys.modules[name].__path__))
|
96 | 18c15348 | Kostas Papadimitriou | else:
|
97 | 18c15348 | Kostas Papadimitriou | for mp in modpath: |
98 | 18c15348 | Kostas Papadimitriou | if not ('', mp) in results: |
99 | 18c15348 | Kostas Papadimitriou | results.append(('', mp))
|
100 | 18a544f5 | Kostas Papadimitriou | pass
|
101 | 18c15348 | Kostas Papadimitriou | |
102 | 18a544f5 | Kostas Papadimitriou | if not results: |
103 | 18a544f5 | Kostas Papadimitriou | raise ImportError("No module named %.200s" % name) |
104 | 18c15348 | Kostas Papadimitriou | |
105 | 18a544f5 | Kostas Papadimitriou | return results
|
106 | 18a544f5 | Kostas Papadimitriou | |
107 | bc89ff1a | Georgios D. Tsoukalas | |
108 | 18a544f5 | Kostas Papadimitriou | def find_management_module(app_name): |
109 | 18a544f5 | Kostas Papadimitriou | """
|
110 | 18a544f5 | Kostas Papadimitriou | Determines the path to the management module for the given app_name,
|
111 | 18a544f5 | Kostas Papadimitriou | without actually importing the application or the management module.
|
112 | 18a544f5 | Kostas Papadimitriou |
|
113 | 18a544f5 | Kostas Papadimitriou | Raises ImportError if the management module cannot be found for any reason.
|
114 | 18a544f5 | Kostas Papadimitriou | """
|
115 | 18a544f5 | Kostas Papadimitriou | parts = app_name.split('.')
|
116 | 18a544f5 | Kostas Papadimitriou | parts.append('management')
|
117 | 18a544f5 | Kostas Papadimitriou | parts.reverse() |
118 | 18a544f5 | Kostas Papadimitriou | part = parts.pop() |
119 | 18a544f5 | Kostas Papadimitriou | paths = None
|
120 | 18a544f5 | Kostas Papadimitriou | |
121 | 18a544f5 | Kostas Papadimitriou | # When using manage.py, the project module is added to the path,
|
122 | 18a544f5 | Kostas Papadimitriou | # loaded, then removed from the path. This means that
|
123 | 18a544f5 | Kostas Papadimitriou | # testproject.testapp.models can be loaded in future, even if
|
124 | 18a544f5 | Kostas Papadimitriou | # testproject isn't in the path. When looking for the management
|
125 | 18a544f5 | Kostas Papadimitriou | # module, we need look for the case where the project name is part
|
126 | 18a544f5 | Kostas Papadimitriou | # of the app_name but the project directory itself isn't on the path.
|
127 | 18a544f5 | Kostas Papadimitriou | try:
|
128 | 18a544f5 | Kostas Papadimitriou | modules = find_modules(part, paths) |
129 | 18a544f5 | Kostas Papadimitriou | paths = [m[1] for m in modules] |
130 | bc89ff1a | Georgios D. Tsoukalas | except ImportError: |
131 | 18a544f5 | Kostas Papadimitriou | if os.path.basename(os.getcwd()) != part:
|
132 | bc89ff1a | Georgios D. Tsoukalas | raise
|
133 | 18a544f5 | Kostas Papadimitriou | |
134 | 18a544f5 | Kostas Papadimitriou | while parts:
|
135 | 18a544f5 | Kostas Papadimitriou | part = parts.pop() |
136 | 18a544f5 | Kostas Papadimitriou | modules = find_modules(part, paths) |
137 | 18a544f5 | Kostas Papadimitriou | paths = [m[1] for m in modules] |
138 | 18a544f5 | Kostas Papadimitriou | return paths[0] |
139 | 18a544f5 | Kostas Papadimitriou | |
140 | 18a544f5 | Kostas Papadimitriou | |
141 | 18a544f5 | Kostas Papadimitriou | def get_commands(): |
142 | 18a544f5 | Kostas Papadimitriou | """
|
143 | 18a544f5 | Kostas Papadimitriou | Returns a dictionary mapping command names to their callback applications.
|
144 | 18a544f5 | Kostas Papadimitriou |
|
145 | 18a544f5 | Kostas Papadimitriou | This works by looking for a management.commands package in django.core, and
|
146 | 18a544f5 | Kostas Papadimitriou | in each installed application -- if a commands package exists, all commands
|
147 | 18a544f5 | Kostas Papadimitriou | in that package are registered.
|
148 | 18a544f5 | Kostas Papadimitriou |
|
149 | 18a544f5 | Kostas Papadimitriou | Core commands are always included. If a settings module has been
|
150 | 18a544f5 | Kostas Papadimitriou | specified, user-defined commands will also be included, the
|
151 | 18a544f5 | Kostas Papadimitriou | startproject command will be disabled, and the startapp command
|
152 | 18a544f5 | Kostas Papadimitriou | will be modified to use the directory in which the settings module appears.
|
153 | 18a544f5 | Kostas Papadimitriou |
|
154 | 18a544f5 | Kostas Papadimitriou | The dictionary is in the format {command_name: app_name}. Key-value
|
155 | 18a544f5 | Kostas Papadimitriou | pairs from this dictionary can then be used in calls to
|
156 | 18a544f5 | Kostas Papadimitriou | load_command_class(app_name, command_name)
|
157 | 18a544f5 | Kostas Papadimitriou |
|
158 | 18a544f5 | Kostas Papadimitriou | If a specific version of a command must be loaded (e.g., with the
|
159 | 18a544f5 | Kostas Papadimitriou | startapp command), the instantiated module can be placed in the
|
160 | 18a544f5 | Kostas Papadimitriou | dictionary in place of the application name.
|
161 | 18a544f5 | Kostas Papadimitriou |
|
162 | 18a544f5 | Kostas Papadimitriou | The dictionary is cached on the first call and reused on subsequent
|
163 | 18a544f5 | Kostas Papadimitriou | calls.
|
164 | 18a544f5 | Kostas Papadimitriou | """
|
165 | 18a544f5 | Kostas Papadimitriou | global _commands
|
166 | 18a544f5 | Kostas Papadimitriou | if _commands is None: |
167 | 4691814d | Ilias Tsitsimpis | _commands = dict([(name, 'django.core') for name in |
168 | 4691814d | Ilias Tsitsimpis | find_commands(management.__path__[0])])
|
169 | 18a544f5 | Kostas Papadimitriou | |
170 | 18a544f5 | Kostas Papadimitriou | # Find the installed apps
|
171 | 18a544f5 | Kostas Papadimitriou | try:
|
172 | 18a544f5 | Kostas Papadimitriou | from django.conf import settings |
173 | 18a544f5 | Kostas Papadimitriou | apps = settings.INSTALLED_APPS |
174 | 18a544f5 | Kostas Papadimitriou | except (AttributeError, EnvironmentError, ImportError): |
175 | 18a544f5 | Kostas Papadimitriou | apps = [] |
176 | 18a544f5 | Kostas Papadimitriou | |
177 | 18a544f5 | Kostas Papadimitriou | # Find the project directory
|
178 | 18a544f5 | Kostas Papadimitriou | try:
|
179 | 18a544f5 | Kostas Papadimitriou | from django.conf import settings |
180 | 18a544f5 | Kostas Papadimitriou | module = import_module(settings.SETTINGS_MODULE) |
181 | 18a544f5 | Kostas Papadimitriou | project_directory = setup_environ(module, settings.SETTINGS_MODULE) |
182 | 18a544f5 | Kostas Papadimitriou | except (AttributeError, EnvironmentError, ImportError, KeyError): |
183 | 18a544f5 | Kostas Papadimitriou | project_directory = None
|
184 | 18a544f5 | Kostas Papadimitriou | |
185 | 18a544f5 | Kostas Papadimitriou | # Find and load the management module for each installed app.
|
186 | 18a544f5 | Kostas Papadimitriou | for app_name in apps: |
187 | 18a544f5 | Kostas Papadimitriou | try:
|
188 | 18a544f5 | Kostas Papadimitriou | path = find_management_module(app_name) |
189 | 18a544f5 | Kostas Papadimitriou | _commands.update(dict([(name, app_name)
|
190 | 18a544f5 | Kostas Papadimitriou | for name in find_commands(path)])) |
191 | 18a544f5 | Kostas Papadimitriou | except ImportError: |
192 | bc89ff1a | Georgios D. Tsoukalas | pass # No management module - ignore this app |
193 | 18a544f5 | Kostas Papadimitriou | |
194 | 18a544f5 | Kostas Papadimitriou | if project_directory:
|
195 | 18a544f5 | Kostas Papadimitriou | # Remove the "startproject" command from self.commands, because
|
196 | 18a544f5 | Kostas Papadimitriou | # that's a django-admin.py command, not a manage.py command.
|
197 | 18a544f5 | Kostas Papadimitriou | del _commands['startproject'] |
198 | 18a544f5 | Kostas Papadimitriou | |
199 | 18a544f5 | Kostas Papadimitriou | # Override the startapp command so that it always uses the
|
200 | 18a544f5 | Kostas Papadimitriou | # project_directory, not the current working directory
|
201 | 18a544f5 | Kostas Papadimitriou | # (which is default).
|
202 | 18a544f5 | Kostas Papadimitriou | from django.core.management.commands.startapp import ProjectCommand |
203 | 18a544f5 | Kostas Papadimitriou | _commands['startapp'] = ProjectCommand(project_directory)
|
204 | 18a544f5 | Kostas Papadimitriou | |
205 | 18a544f5 | Kostas Papadimitriou | return _commands
|
206 | d2ff89df | Kostas Papadimitriou | |
207 | bc89ff1a | Georgios D. Tsoukalas | |
208 | d2ff89df | Kostas Papadimitriou | class SynnefoManagementUtility(ManagementUtility): |
209 | d2ff89df | Kostas Papadimitriou | """
|
210 | d2ff89df | Kostas Papadimitriou | Override django ManagementUtility to allow us provide a custom
|
211 | d2ff89df | Kostas Papadimitriou | --settings-dir option for synnefo application.
|
212 | d2ff89df | Kostas Papadimitriou |
|
213 | d2ff89df | Kostas Papadimitriou | Most of the following code is a copy from django.core.management module
|
214 | d2ff89df | Kostas Papadimitriou | """
|
215 | d2ff89df | Kostas Papadimitriou | |
216 | d2ff89df | Kostas Papadimitriou | def execute(self): |
217 | d2ff89df | Kostas Papadimitriou | """
|
218 | d2ff89df | Kostas Papadimitriou | Given the command-line arguments, this figures out which subcommand is
|
219 | d2ff89df | Kostas Papadimitriou | being run, creates a parser appropriate to that command, and runs it.
|
220 | d2ff89df | Kostas Papadimitriou | """
|
221 | d2ff89df | Kostas Papadimitriou | |
222 | d2ff89df | Kostas Papadimitriou | # --settings-dir option
|
223 | d2ff89df | Kostas Papadimitriou | # will remove it later to avoid django commands from raising errors
|
224 | d2ff89df | Kostas Papadimitriou | option_list = BaseCommand.option_list + ( |
225 | 4691814d | Ilias Tsitsimpis | make_option( |
226 | 4691814d | Ilias Tsitsimpis | '--settings-dir',
|
227 | d2ff89df | Kostas Papadimitriou | action='store',
|
228 | d2ff89df | Kostas Papadimitriou | dest='settings_dir',
|
229 | d2ff89df | Kostas Papadimitriou | default=None,
|
230 | d2ff89df | Kostas Papadimitriou | help='Load *.conf files from directory as settings'),)
|
231 | d2ff89df | Kostas Papadimitriou | |
232 | d2ff89df | Kostas Papadimitriou | # Preprocess options to extract --settings and --pythonpath.
|
233 | d2ff89df | Kostas Papadimitriou | # These options could affect the commands that are available, so they
|
234 | d2ff89df | Kostas Papadimitriou | # must be processed early.
|
235 | d2ff89df | Kostas Papadimitriou | parser = LaxOptionParser(usage="%prog subcommand [options] [args]",
|
236 | 07d104d8 | Kostas Papadimitriou | version=get_component_version('webproject'),
|
237 | d2ff89df | Kostas Papadimitriou | option_list=option_list) |
238 | d2ff89df | Kostas Papadimitriou | self.autocomplete()
|
239 | d2ff89df | Kostas Papadimitriou | try:
|
240 | d2ff89df | Kostas Papadimitriou | options, args = parser.parse_args(self.argv)
|
241 | d2ff89df | Kostas Papadimitriou | handle_default_options(options) |
242 | d2ff89df | Kostas Papadimitriou | except:
|
243 | bc89ff1a | Georgios D. Tsoukalas | pass # Ignore any option errors at this point. |
244 | d2ff89df | Kostas Papadimitriou | |
245 | d2ff89df | Kostas Papadimitriou | # user provides custom settings dir
|
246 | d2ff89df | Kostas Papadimitriou | # set it as environmental variable and remove it from self.argv
|
247 | d2ff89df | Kostas Papadimitriou | if options.settings_dir:
|
248 | d2ff89df | Kostas Papadimitriou | os.environ['SYNNEFO_SETTINGS_DIR'] = options.settings_dir
|
249 | d2ff89df | Kostas Papadimitriou | for arg in self.argv: |
250 | d2ff89df | Kostas Papadimitriou | if arg.startswith('--settings-dir'): |
251 | d2ff89df | Kostas Papadimitriou | self.argv.remove(arg)
|
252 | d2ff89df | Kostas Papadimitriou | |
253 | d2ff89df | Kostas Papadimitriou | try:
|
254 | d2ff89df | Kostas Papadimitriou | subcommand = self.argv[1] |
255 | d2ff89df | Kostas Papadimitriou | except IndexError: |
256 | bc89ff1a | Georgios D. Tsoukalas | subcommand = 'help' # Display help if no arguments were given. |
257 | d2ff89df | Kostas Papadimitriou | |
258 | e43ac298 | Christos Stavrakakis | # Encode stdout. This check is required because of the way python
|
259 | bc89ff1a | Georgios D. Tsoukalas | # checks if something is tty:
|
260 | bc89ff1a | Georgios D. Tsoukalas | # https://bugzilla.redhat.com/show_bug.cgi?id=841152
|
261 | 1f0030e6 | Kostas Papadimitriou | if not subcommand in ['test'] and not 'shell' in subcommand: |
262 | e43ac298 | Christos Stavrakakis | sys.stdout = EncodedStdOut(sys.stdout) |
263 | e43ac298 | Christos Stavrakakis | |
264 | d2ff89df | Kostas Papadimitriou | if subcommand == 'help': |
265 | d2ff89df | Kostas Papadimitriou | if len(args) > 2: |
266 | d2ff89df | Kostas Papadimitriou | self.fetch_command(args[2]).print_help(self.prog_name, args[2]) |
267 | d2ff89df | Kostas Papadimitriou | else:
|
268 | d2ff89df | Kostas Papadimitriou | parser.print_lax_help() |
269 | d2ff89df | Kostas Papadimitriou | sys.stdout.write(self.main_help_text() + '\n') |
270 | d2ff89df | Kostas Papadimitriou | sys.exit(1)
|
271 | d2ff89df | Kostas Papadimitriou | # Special-cases: We want 'django-admin.py --version' and
|
272 | d2ff89df | Kostas Papadimitriou | # 'django-admin.py --help' to work, for backwards compatibility.
|
273 | d2ff89df | Kostas Papadimitriou | elif self.argv[1:] == ['--version']: |
274 | d2ff89df | Kostas Papadimitriou | # LaxOptionParser already takes care of printing the version.
|
275 | d2ff89df | Kostas Papadimitriou | pass
|
276 | d2ff89df | Kostas Papadimitriou | elif self.argv[1:] in (['--help'], ['-h']): |
277 | d2ff89df | Kostas Papadimitriou | parser.print_lax_help() |
278 | d2ff89df | Kostas Papadimitriou | sys.stdout.write(self.main_help_text() + '\n') |
279 | d2ff89df | Kostas Papadimitriou | else:
|
280 | d2ff89df | Kostas Papadimitriou | self.fetch_command(subcommand).run_from_argv(self.argv) |
281 | 00b4f1be | Faidon Liambotis | |
282 | 18a544f5 | Kostas Papadimitriou | def main_help_text(self): |
283 | 18a544f5 | Kostas Papadimitriou | """
|
284 | 18a544f5 | Kostas Papadimitriou | Returns the script's main help text, as a string.
|
285 | 18a544f5 | Kostas Papadimitriou | """
|
286 | bc89ff1a | Georgios D. Tsoukalas | usage = ['', ("Type '%s help <subcommand>' for help" |
287 | bc89ff1a | Georgios D. Tsoukalas | "on a specific subcommand.") % self.prog_name, ''] |
288 | 18a544f5 | Kostas Papadimitriou | usage.append('Available subcommands:')
|
289 | 18a544f5 | Kostas Papadimitriou | commands = get_commands().keys() |
290 | 18a544f5 | Kostas Papadimitriou | commands.sort() |
291 | 18a544f5 | Kostas Papadimitriou | for cmd in commands: |
292 | 18a544f5 | Kostas Papadimitriou | usage.append(' %s' % cmd)
|
293 | 18a544f5 | Kostas Papadimitriou | return '\n'.join(usage) |
294 | 18a544f5 | Kostas Papadimitriou | |
295 | 18a544f5 | Kostas Papadimitriou | def fetch_command(self, subcommand): |
296 | 18a544f5 | Kostas Papadimitriou | """
|
297 | 18a544f5 | Kostas Papadimitriou | Tries to fetch the given subcommand, printing a message with the
|
298 | 18a544f5 | Kostas Papadimitriou | appropriate command called from the command line (usually
|
299 | 18a544f5 | Kostas Papadimitriou | "django-admin.py" or "manage.py") if it can't be found.
|
300 | 18a544f5 | Kostas Papadimitriou | """
|
301 | 18a544f5 | Kostas Papadimitriou | try:
|
302 | 18a544f5 | Kostas Papadimitriou | app_name = get_commands()[subcommand] |
303 | 18a544f5 | Kostas Papadimitriou | except KeyError: |
304 | bc89ff1a | Georgios D. Tsoukalas | sys.stderr.write(("Unknown command: %r\n"
|
305 | bc89ff1a | Georgios D. Tsoukalas | "Type '%s help' for usage.\n") %
|
306 | bc89ff1a | Georgios D. Tsoukalas | (subcommand, self.prog_name))
|
307 | 18a544f5 | Kostas Papadimitriou | sys.exit(1)
|
308 | 18a544f5 | Kostas Papadimitriou | if isinstance(app_name, BaseCommand): |
309 | 18a544f5 | Kostas Papadimitriou | # If the command is already loaded, use it directly.
|
310 | 18a544f5 | Kostas Papadimitriou | klass = app_name |
311 | 18a544f5 | Kostas Papadimitriou | else:
|
312 | 18a544f5 | Kostas Papadimitriou | klass = load_command_class(app_name, subcommand) |
313 | 18a544f5 | Kostas Papadimitriou | return klass
|
314 | 18a544f5 | Kostas Papadimitriou | |
315 | d01cd522 | Christos Stavrakakis | |
316 | d01cd522 | Christos Stavrakakis | def configure_logging(): |
317 | d01cd522 | Christos Stavrakakis | try:
|
318 | d01cd522 | Christos Stavrakakis | from synnefo.settings import SNF_MANAGE_LOGGING_SETUP |
319 | d01cd522 | Christos Stavrakakis | dictConfig(SNF_MANAGE_LOGGING_SETUP) |
320 | d01cd522 | Christos Stavrakakis | except ImportError: |
321 | d01cd522 | Christos Stavrakakis | import logging |
322 | d01cd522 | Christos Stavrakakis | logging.basicConfig() |
323 | d01cd522 | Christos Stavrakakis | log = logging.getLogger() |
324 | d01cd522 | Christos Stavrakakis | log.warning("SNF_MANAGE_LOGGING_SETUP setting missing.")
|
325 | d01cd522 | Christos Stavrakakis | |
326 | d01cd522 | Christos Stavrakakis | |
327 | a45fc1ae | Christos Stavrakakis | class EncodedStdOut(object): |
328 | 21ce46e9 | Christos Stavrakakis | def __init__(self, stdout): |
329 | c9284fad | Christos Stavrakakis | try:
|
330 | c9284fad | Christos Stavrakakis | std_encoding = stdout.encoding |
331 | c9284fad | Christos Stavrakakis | except AttributeError: |
332 | c9284fad | Christos Stavrakakis | std_encoding = None
|
333 | c9284fad | Christos Stavrakakis | self.encoding = std_encoding or locale.getpreferredencoding() |
334 | 65e4e685 | Christos Stavrakakis | self.original_stdout = stdout
|
335 | a45fc1ae | Christos Stavrakakis | |
336 | a45fc1ae | Christos Stavrakakis | def write(self, string): |
337 | a45fc1ae | Christos Stavrakakis | if isinstance(string, unicode): |
338 | a45fc1ae | Christos Stavrakakis | string = string.encode(self.encoding)
|
339 | 21ce46e9 | Christos Stavrakakis | self.original_stdout.write(string)
|
340 | a45fc1ae | Christos Stavrakakis | |
341 | c9284fad | Christos Stavrakakis | def __getattr__(self, name): |
342 | c9284fad | Christos Stavrakakis | return getattr(self.original_stdout, name) |
343 | c9284fad | Christos Stavrakakis | |
344 | a45fc1ae | Christos Stavrakakis | |
345 | b9685924 | Kostas Papadimitriou | def main(): |
346 | d2ff89df | Kostas Papadimitriou | # no need to run setup_environ
|
347 | d2ff89df | Kostas Papadimitriou | # we already know our project
|
348 | 4691814d | Ilias Tsitsimpis | os.environ['DJANGO_SETTINGS_MODULE'] = \
|
349 | 4691814d | Ilias Tsitsimpis | os.environ.get('DJANGO_SETTINGS_MODULE', 'synnefo.settings') |
350 | d01cd522 | Christos Stavrakakis | configure_logging() |
351 | d2ff89df | Kostas Papadimitriou | mu = SynnefoManagementUtility(sys.argv) |
352 | d2ff89df | Kostas Papadimitriou | mu.execute() |
353 | b9685924 | Kostas Papadimitriou | |
354 | b9685924 | Kostas Papadimitriou | if __name__ == "__main__": |
355 | b9685924 | Kostas Papadimitriou | main() |