root / snf-webproject / synnefo / webproject / manage.py @ a868c831
History | View | Annotate | Download (12.1 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 | a0abbade | Christos Stavrakakis | from django.core.management import ManagementUtility, \ |
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 | 4691814d | Ilias Tsitsimpis | from optparse import make_option |
57 | 07d104d8 | Kostas Papadimitriou | from synnefo.util.version import get_component_version |
58 | d01cd522 | Christos Stavrakakis | from synnefo.lib.dictconfig import dictConfig |
59 | d2ff89df | Kostas Papadimitriou | |
60 | d2ff89df | Kostas Papadimitriou | import sys |
61 | a45fc1ae | Christos Stavrakakis | import locale |
62 | d2ff89df | Kostas Papadimitriou | import os |
63 | 18a544f5 | Kostas Papadimitriou | import imp |
64 | 18a544f5 | Kostas Papadimitriou | |
65 | 18a544f5 | Kostas Papadimitriou | _commands = None
|
66 | 18a544f5 | Kostas Papadimitriou | |
67 | d01cd522 | Christos Stavrakakis | |
68 | 18a544f5 | Kostas Papadimitriou | def find_modules(name, path=None): |
69 | 18a544f5 | Kostas Papadimitriou | """Find all modules with name 'name'
|
70 | 18a544f5 | Kostas Papadimitriou |
|
71 | 18a544f5 | Kostas Papadimitriou | Unlike find_module in the imp package this returns a list of all
|
72 | 18a544f5 | Kostas Papadimitriou | matched modules.
|
73 | 18a544f5 | Kostas Papadimitriou | """
|
74 | 18c15348 | Kostas Papadimitriou | |
75 | 18a544f5 | Kostas Papadimitriou | results = [] |
76 | bc89ff1a | Georgios D. Tsoukalas | if path is None: |
77 | bc89ff1a | Georgios D. Tsoukalas | path = sys.path |
78 | 18a544f5 | Kostas Papadimitriou | for p in path: |
79 | 18a544f5 | Kostas Papadimitriou | importer = sys.path_importer_cache.get(p, None)
|
80 | 18a544f5 | Kostas Papadimitriou | if importer is None: |
81 | 18a544f5 | Kostas Papadimitriou | find_module = imp.find_module |
82 | 18a544f5 | Kostas Papadimitriou | else:
|
83 | 18a544f5 | Kostas Papadimitriou | find_module = importer.find_module |
84 | 18a544f5 | Kostas Papadimitriou | |
85 | 18a544f5 | Kostas Papadimitriou | try:
|
86 | 18a544f5 | Kostas Papadimitriou | result = find_module(name, [p]) |
87 | 18a544f5 | Kostas Papadimitriou | if result is not None: |
88 | 18a544f5 | Kostas Papadimitriou | results.append(result) |
89 | 18a544f5 | Kostas Papadimitriou | except ImportError: |
90 | 18c15348 | Kostas Papadimitriou | if sys.modules.get(name, None): |
91 | 18c15348 | Kostas Papadimitriou | modpath = sys.modules[name].__path__ |
92 | 4691814d | Ilias Tsitsimpis | if isinstance(modpath, basestring) \ |
93 | 4691814d | Ilias Tsitsimpis | and not ('', modpath) in results: |
94 | 4691814d | Ilias Tsitsimpis | results.append(('', sys.modules[name].__path__))
|
95 | 18c15348 | Kostas Papadimitriou | else:
|
96 | 18c15348 | Kostas Papadimitriou | for mp in modpath: |
97 | 18c15348 | Kostas Papadimitriou | if not ('', mp) in results: |
98 | 18c15348 | Kostas Papadimitriou | results.append(('', mp))
|
99 | 18a544f5 | Kostas Papadimitriou | pass
|
100 | 18c15348 | Kostas Papadimitriou | |
101 | 18a544f5 | Kostas Papadimitriou | if not results: |
102 | 18a544f5 | Kostas Papadimitriou | raise ImportError("No module named %.200s" % name) |
103 | 18c15348 | Kostas Papadimitriou | |
104 | 18a544f5 | Kostas Papadimitriou | return results
|
105 | 18a544f5 | Kostas Papadimitriou | |
106 | bc89ff1a | Georgios D. Tsoukalas | |
107 | 18a544f5 | Kostas Papadimitriou | def find_management_module(app_name): |
108 | 18a544f5 | Kostas Papadimitriou | """
|
109 | 18a544f5 | Kostas Papadimitriou | Determines the path to the management module for the given app_name,
|
110 | 18a544f5 | Kostas Papadimitriou | without actually importing the application or the management module.
|
111 | 18a544f5 | Kostas Papadimitriou |
|
112 | 18a544f5 | Kostas Papadimitriou | Raises ImportError if the management module cannot be found for any reason.
|
113 | 18a544f5 | Kostas Papadimitriou | """
|
114 | 18a544f5 | Kostas Papadimitriou | parts = app_name.split('.')
|
115 | 18a544f5 | Kostas Papadimitriou | parts.append('management')
|
116 | 18a544f5 | Kostas Papadimitriou | parts.reverse() |
117 | 18a544f5 | Kostas Papadimitriou | part = parts.pop() |
118 | 18a544f5 | Kostas Papadimitriou | paths = None
|
119 | 18a544f5 | Kostas Papadimitriou | |
120 | 18a544f5 | Kostas Papadimitriou | # When using manage.py, the project module is added to the path,
|
121 | 18a544f5 | Kostas Papadimitriou | # loaded, then removed from the path. This means that
|
122 | 18a544f5 | Kostas Papadimitriou | # testproject.testapp.models can be loaded in future, even if
|
123 | 18a544f5 | Kostas Papadimitriou | # testproject isn't in the path. When looking for the management
|
124 | 18a544f5 | Kostas Papadimitriou | # module, we need look for the case where the project name is part
|
125 | 18a544f5 | Kostas Papadimitriou | # of the app_name but the project directory itself isn't on the path.
|
126 | 18a544f5 | Kostas Papadimitriou | try:
|
127 | 18a544f5 | Kostas Papadimitriou | modules = find_modules(part, paths) |
128 | 18a544f5 | Kostas Papadimitriou | paths = [m[1] for m in modules] |
129 | bc89ff1a | Georgios D. Tsoukalas | except ImportError: |
130 | 18a544f5 | Kostas Papadimitriou | if os.path.basename(os.getcwd()) != part:
|
131 | bc89ff1a | Georgios D. Tsoukalas | raise
|
132 | 18a544f5 | Kostas Papadimitriou | |
133 | 18a544f5 | Kostas Papadimitriou | while parts:
|
134 | 18a544f5 | Kostas Papadimitriou | part = parts.pop() |
135 | 18a544f5 | Kostas Papadimitriou | modules = find_modules(part, paths) |
136 | 18a544f5 | Kostas Papadimitriou | paths = [m[1] for m in modules] |
137 | 18a544f5 | Kostas Papadimitriou | return paths[0] |
138 | 18a544f5 | Kostas Papadimitriou | |
139 | 18a544f5 | Kostas Papadimitriou | |
140 | 18a544f5 | Kostas Papadimitriou | def get_commands(): |
141 | 18a544f5 | Kostas Papadimitriou | """
|
142 | 18a544f5 | Kostas Papadimitriou | Returns a dictionary mapping command names to their callback applications.
|
143 | 18a544f5 | Kostas Papadimitriou |
|
144 | 18a544f5 | Kostas Papadimitriou | This works by looking for a management.commands package in django.core, and
|
145 | 18a544f5 | Kostas Papadimitriou | in each installed application -- if a commands package exists, all commands
|
146 | 18a544f5 | Kostas Papadimitriou | in that package are registered.
|
147 | 18a544f5 | Kostas Papadimitriou |
|
148 | 18a544f5 | Kostas Papadimitriou | Core commands are always included. If a settings module has been
|
149 | 18a544f5 | Kostas Papadimitriou | specified, user-defined commands will also be included, the
|
150 | 18a544f5 | Kostas Papadimitriou | startproject command will be disabled, and the startapp command
|
151 | 18a544f5 | Kostas Papadimitriou | will be modified to use the directory in which the settings module appears.
|
152 | 18a544f5 | Kostas Papadimitriou |
|
153 | 18a544f5 | Kostas Papadimitriou | The dictionary is in the format {command_name: app_name}. Key-value
|
154 | 18a544f5 | Kostas Papadimitriou | pairs from this dictionary can then be used in calls to
|
155 | 18a544f5 | Kostas Papadimitriou | load_command_class(app_name, command_name)
|
156 | 18a544f5 | Kostas Papadimitriou |
|
157 | 18a544f5 | Kostas Papadimitriou | If a specific version of a command must be loaded (e.g., with the
|
158 | 18a544f5 | Kostas Papadimitriou | startapp command), the instantiated module can be placed in the
|
159 | 18a544f5 | Kostas Papadimitriou | dictionary in place of the application name.
|
160 | 18a544f5 | Kostas Papadimitriou |
|
161 | 18a544f5 | Kostas Papadimitriou | The dictionary is cached on the first call and reused on subsequent
|
162 | 18a544f5 | Kostas Papadimitriou | calls.
|
163 | 18a544f5 | Kostas Papadimitriou | """
|
164 | 18a544f5 | Kostas Papadimitriou | global _commands
|
165 | 18a544f5 | Kostas Papadimitriou | if _commands is None: |
166 | 4691814d | Ilias Tsitsimpis | _commands = dict([(name, 'django.core') for name in |
167 | 4691814d | Ilias Tsitsimpis | find_commands(management.__path__[0])])
|
168 | 18a544f5 | Kostas Papadimitriou | |
169 | 18a544f5 | Kostas Papadimitriou | # Find the installed apps
|
170 | 18a544f5 | Kostas Papadimitriou | try:
|
171 | 18a544f5 | Kostas Papadimitriou | from django.conf import settings |
172 | 18a544f5 | Kostas Papadimitriou | apps = settings.INSTALLED_APPS |
173 | 18a544f5 | Kostas Papadimitriou | except (AttributeError, EnvironmentError, ImportError): |
174 | 18a544f5 | Kostas Papadimitriou | apps = [] |
175 | 18a544f5 | Kostas Papadimitriou | |
176 | 18a544f5 | Kostas Papadimitriou | # Find and load the management module for each installed app.
|
177 | 18a544f5 | Kostas Papadimitriou | for app_name in apps: |
178 | 18a544f5 | Kostas Papadimitriou | try:
|
179 | 18a544f5 | Kostas Papadimitriou | path = find_management_module(app_name) |
180 | 18a544f5 | Kostas Papadimitriou | _commands.update(dict([(name, app_name)
|
181 | 18a544f5 | Kostas Papadimitriou | for name in find_commands(path)])) |
182 | 18a544f5 | Kostas Papadimitriou | except ImportError: |
183 | bc89ff1a | Georgios D. Tsoukalas | pass # No management module - ignore this app |
184 | 18a544f5 | Kostas Papadimitriou | |
185 | a0abbade | Christos Stavrakakis | if apps:
|
186 | 18a544f5 | Kostas Papadimitriou | # Remove the "startproject" command from self.commands, because
|
187 | 18a544f5 | Kostas Papadimitriou | # that's a django-admin.py command, not a manage.py command.
|
188 | 18a544f5 | Kostas Papadimitriou | del _commands['startproject'] |
189 | 18a544f5 | Kostas Papadimitriou | |
190 | 18a544f5 | Kostas Papadimitriou | return _commands
|
191 | d2ff89df | Kostas Papadimitriou | |
192 | bc89ff1a | Georgios D. Tsoukalas | |
193 | d2ff89df | Kostas Papadimitriou | class SynnefoManagementUtility(ManagementUtility): |
194 | d2ff89df | Kostas Papadimitriou | """
|
195 | d2ff89df | Kostas Papadimitriou | Override django ManagementUtility to allow us provide a custom
|
196 | d2ff89df | Kostas Papadimitriou | --settings-dir option for synnefo application.
|
197 | d2ff89df | Kostas Papadimitriou |
|
198 | d2ff89df | Kostas Papadimitriou | Most of the following code is a copy from django.core.management module
|
199 | d2ff89df | Kostas Papadimitriou | """
|
200 | d2ff89df | Kostas Papadimitriou | |
201 | d2ff89df | Kostas Papadimitriou | def execute(self): |
202 | d2ff89df | Kostas Papadimitriou | """
|
203 | d2ff89df | Kostas Papadimitriou | Given the command-line arguments, this figures out which subcommand is
|
204 | d2ff89df | Kostas Papadimitriou | being run, creates a parser appropriate to that command, and runs it.
|
205 | d2ff89df | Kostas Papadimitriou | """
|
206 | d2ff89df | Kostas Papadimitriou | |
207 | d2ff89df | Kostas Papadimitriou | # --settings-dir option
|
208 | d2ff89df | Kostas Papadimitriou | # will remove it later to avoid django commands from raising errors
|
209 | d2ff89df | Kostas Papadimitriou | option_list = BaseCommand.option_list + ( |
210 | 4691814d | Ilias Tsitsimpis | make_option( |
211 | 4691814d | Ilias Tsitsimpis | '--settings-dir',
|
212 | d2ff89df | Kostas Papadimitriou | action='store',
|
213 | d2ff89df | Kostas Papadimitriou | dest='settings_dir',
|
214 | d2ff89df | Kostas Papadimitriou | default=None,
|
215 | d2ff89df | Kostas Papadimitriou | help='Load *.conf files from directory as settings'),)
|
216 | d2ff89df | Kostas Papadimitriou | |
217 | d2ff89df | Kostas Papadimitriou | # Preprocess options to extract --settings and --pythonpath.
|
218 | d2ff89df | Kostas Papadimitriou | # These options could affect the commands that are available, so they
|
219 | d2ff89df | Kostas Papadimitriou | # must be processed early.
|
220 | d2ff89df | Kostas Papadimitriou | parser = LaxOptionParser(usage="%prog subcommand [options] [args]",
|
221 | 07d104d8 | Kostas Papadimitriou | version=get_component_version('webproject'),
|
222 | d2ff89df | Kostas Papadimitriou | option_list=option_list) |
223 | d2ff89df | Kostas Papadimitriou | self.autocomplete()
|
224 | d2ff89df | Kostas Papadimitriou | try:
|
225 | d2ff89df | Kostas Papadimitriou | options, args = parser.parse_args(self.argv)
|
226 | d2ff89df | Kostas Papadimitriou | handle_default_options(options) |
227 | d2ff89df | Kostas Papadimitriou | except:
|
228 | bc89ff1a | Georgios D. Tsoukalas | pass # Ignore any option errors at this point. |
229 | d2ff89df | Kostas Papadimitriou | |
230 | d2ff89df | Kostas Papadimitriou | # user provides custom settings dir
|
231 | d2ff89df | Kostas Papadimitriou | # set it as environmental variable and remove it from self.argv
|
232 | d2ff89df | Kostas Papadimitriou | if options.settings_dir:
|
233 | d2ff89df | Kostas Papadimitriou | os.environ['SYNNEFO_SETTINGS_DIR'] = options.settings_dir
|
234 | d2ff89df | Kostas Papadimitriou | for arg in self.argv: |
235 | d2ff89df | Kostas Papadimitriou | if arg.startswith('--settings-dir'): |
236 | d2ff89df | Kostas Papadimitriou | self.argv.remove(arg)
|
237 | d2ff89df | Kostas Papadimitriou | |
238 | d2ff89df | Kostas Papadimitriou | try:
|
239 | d2ff89df | Kostas Papadimitriou | subcommand = self.argv[1] |
240 | d2ff89df | Kostas Papadimitriou | except IndexError: |
241 | bc89ff1a | Georgios D. Tsoukalas | subcommand = 'help' # Display help if no arguments were given. |
242 | d2ff89df | Kostas Papadimitriou | |
243 | e43ac298 | Christos Stavrakakis | # Encode stdout. This check is required because of the way python
|
244 | bc89ff1a | Georgios D. Tsoukalas | # checks if something is tty:
|
245 | bc89ff1a | Georgios D. Tsoukalas | # https://bugzilla.redhat.com/show_bug.cgi?id=841152
|
246 | 1f0030e6 | Kostas Papadimitriou | if not subcommand in ['test'] and not 'shell' in subcommand: |
247 | e43ac298 | Christos Stavrakakis | sys.stdout = EncodedStdOut(sys.stdout) |
248 | e43ac298 | Christos Stavrakakis | |
249 | d2ff89df | Kostas Papadimitriou | if subcommand == 'help': |
250 | d2ff89df | Kostas Papadimitriou | if len(args) > 2: |
251 | d2ff89df | Kostas Papadimitriou | self.fetch_command(args[2]).print_help(self.prog_name, args[2]) |
252 | d2ff89df | Kostas Papadimitriou | else:
|
253 | d2ff89df | Kostas Papadimitriou | parser.print_lax_help() |
254 | d2ff89df | Kostas Papadimitriou | sys.stdout.write(self.main_help_text() + '\n') |
255 | d2ff89df | Kostas Papadimitriou | sys.exit(1)
|
256 | d2ff89df | Kostas Papadimitriou | # Special-cases: We want 'django-admin.py --version' and
|
257 | d2ff89df | Kostas Papadimitriou | # 'django-admin.py --help' to work, for backwards compatibility.
|
258 | d2ff89df | Kostas Papadimitriou | elif self.argv[1:] == ['--version']: |
259 | d2ff89df | Kostas Papadimitriou | # LaxOptionParser already takes care of printing the version.
|
260 | d2ff89df | Kostas Papadimitriou | pass
|
261 | d2ff89df | Kostas Papadimitriou | elif self.argv[1:] in (['--help'], ['-h']): |
262 | d2ff89df | Kostas Papadimitriou | parser.print_lax_help() |
263 | d2ff89df | Kostas Papadimitriou | sys.stdout.write(self.main_help_text() + '\n') |
264 | d2ff89df | Kostas Papadimitriou | else:
|
265 | d2ff89df | Kostas Papadimitriou | self.fetch_command(subcommand).run_from_argv(self.argv) |
266 | 00b4f1be | Faidon Liambotis | |
267 | 18a544f5 | Kostas Papadimitriou | def main_help_text(self): |
268 | 18a544f5 | Kostas Papadimitriou | """
|
269 | 18a544f5 | Kostas Papadimitriou | Returns the script's main help text, as a string.
|
270 | 18a544f5 | Kostas Papadimitriou | """
|
271 | bc89ff1a | Georgios D. Tsoukalas | usage = ['', ("Type '%s help <subcommand>' for help" |
272 | bc89ff1a | Georgios D. Tsoukalas | "on a specific subcommand.") % self.prog_name, ''] |
273 | 18a544f5 | Kostas Papadimitriou | usage.append('Available subcommands:')
|
274 | 18a544f5 | Kostas Papadimitriou | commands = get_commands().keys() |
275 | 18a544f5 | Kostas Papadimitriou | commands.sort() |
276 | 18a544f5 | Kostas Papadimitriou | for cmd in commands: |
277 | 18a544f5 | Kostas Papadimitriou | usage.append(' %s' % cmd)
|
278 | 18a544f5 | Kostas Papadimitriou | return '\n'.join(usage) |
279 | 18a544f5 | Kostas Papadimitriou | |
280 | 18a544f5 | Kostas Papadimitriou | def fetch_command(self, subcommand): |
281 | 18a544f5 | Kostas Papadimitriou | """
|
282 | 18a544f5 | Kostas Papadimitriou | Tries to fetch the given subcommand, printing a message with the
|
283 | 18a544f5 | Kostas Papadimitriou | appropriate command called from the command line (usually
|
284 | 18a544f5 | Kostas Papadimitriou | "django-admin.py" or "manage.py") if it can't be found.
|
285 | 18a544f5 | Kostas Papadimitriou | """
|
286 | 18a544f5 | Kostas Papadimitriou | try:
|
287 | 18a544f5 | Kostas Papadimitriou | app_name = get_commands()[subcommand] |
288 | 18a544f5 | Kostas Papadimitriou | except KeyError: |
289 | bc89ff1a | Georgios D. Tsoukalas | sys.stderr.write(("Unknown command: %r\n"
|
290 | bc89ff1a | Georgios D. Tsoukalas | "Type '%s help' for usage.\n") %
|
291 | bc89ff1a | Georgios D. Tsoukalas | (subcommand, self.prog_name))
|
292 | 18a544f5 | Kostas Papadimitriou | sys.exit(1)
|
293 | 18a544f5 | Kostas Papadimitriou | if isinstance(app_name, BaseCommand): |
294 | 18a544f5 | Kostas Papadimitriou | # If the command is already loaded, use it directly.
|
295 | 18a544f5 | Kostas Papadimitriou | klass = app_name |
296 | 18a544f5 | Kostas Papadimitriou | else:
|
297 | 18a544f5 | Kostas Papadimitriou | klass = load_command_class(app_name, subcommand) |
298 | 18a544f5 | Kostas Papadimitriou | return klass
|
299 | 18a544f5 | Kostas Papadimitriou | |
300 | d01cd522 | Christos Stavrakakis | |
301 | d01cd522 | Christos Stavrakakis | def configure_logging(): |
302 | d01cd522 | Christos Stavrakakis | try:
|
303 | d01cd522 | Christos Stavrakakis | from synnefo.settings import SNF_MANAGE_LOGGING_SETUP |
304 | d01cd522 | Christos Stavrakakis | dictConfig(SNF_MANAGE_LOGGING_SETUP) |
305 | d01cd522 | Christos Stavrakakis | except ImportError: |
306 | d01cd522 | Christos Stavrakakis | import logging |
307 | d01cd522 | Christos Stavrakakis | logging.basicConfig() |
308 | d01cd522 | Christos Stavrakakis | log = logging.getLogger() |
309 | d01cd522 | Christos Stavrakakis | log.warning("SNF_MANAGE_LOGGING_SETUP setting missing.")
|
310 | d01cd522 | Christos Stavrakakis | |
311 | d01cd522 | Christos Stavrakakis | |
312 | a45fc1ae | Christos Stavrakakis | class EncodedStdOut(object): |
313 | 21ce46e9 | Christos Stavrakakis | def __init__(self, stdout): |
314 | c9284fad | Christos Stavrakakis | try:
|
315 | c9284fad | Christos Stavrakakis | std_encoding = stdout.encoding |
316 | c9284fad | Christos Stavrakakis | except AttributeError: |
317 | c9284fad | Christos Stavrakakis | std_encoding = None
|
318 | c9284fad | Christos Stavrakakis | self.encoding = std_encoding or locale.getpreferredencoding() |
319 | 65e4e685 | Christos Stavrakakis | self.original_stdout = stdout
|
320 | a45fc1ae | Christos Stavrakakis | |
321 | a45fc1ae | Christos Stavrakakis | def write(self, string): |
322 | a45fc1ae | Christos Stavrakakis | if isinstance(string, unicode): |
323 | a45fc1ae | Christos Stavrakakis | string = string.encode(self.encoding)
|
324 | 21ce46e9 | Christos Stavrakakis | self.original_stdout.write(string)
|
325 | a45fc1ae | Christos Stavrakakis | |
326 | c9284fad | Christos Stavrakakis | def __getattr__(self, name): |
327 | c9284fad | Christos Stavrakakis | return getattr(self.original_stdout, name) |
328 | c9284fad | Christos Stavrakakis | |
329 | a45fc1ae | Christos Stavrakakis | |
330 | b9685924 | Kostas Papadimitriou | def main(): |
331 | 4691814d | Ilias Tsitsimpis | os.environ['DJANGO_SETTINGS_MODULE'] = \
|
332 | 4691814d | Ilias Tsitsimpis | os.environ.get('DJANGO_SETTINGS_MODULE', 'synnefo.settings') |
333 | d01cd522 | Christos Stavrakakis | configure_logging() |
334 | d2ff89df | Kostas Papadimitriou | mu = SynnefoManagementUtility(sys.argv) |
335 | d2ff89df | Kostas Papadimitriou | mu.execute() |
336 | b9685924 | Kostas Papadimitriou | |
337 | b9685924 | Kostas Papadimitriou | if __name__ == "__main__": |
338 | b9685924 | Kostas Papadimitriou | main() |