mirror of
https://github.com/django/django.git
synced 2025-07-04 17:59:13 +00:00
magic-removal: Fixed #1491 -- Added nice terminal colors to django-admin SQL output. Thanks, plmeister@gmail.com
git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2585 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
639fe6a87a
commit
493f8b9e5b
@ -5,6 +5,7 @@ import django
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
import os, re, sys, textwrap
|
||||
from optparse import OptionParser
|
||||
from django.utils import termcolors
|
||||
|
||||
# For Python 2.3
|
||||
if not hasattr(__builtins__, 'set'):
|
||||
@ -26,6 +27,28 @@ PROJECT_TEMPLATE_DIR = os.path.join(django.__path__[0], 'conf', '%s_template')
|
||||
|
||||
INVALID_PROJECT_NAMES = ('django', 'test')
|
||||
|
||||
# Set up the terminal color scheme.
|
||||
class dummy: pass
|
||||
style = dummy()
|
||||
style.ERROR = termcolors.make_style(fg='red', opts=('bold',))
|
||||
style.ERROR_OUTPUT = termcolors.make_style(fg='red', opts=('bold',))
|
||||
style.SQL_FIELD = termcolors.make_style(fg='green', opts=('bold',))
|
||||
style.SQL_COLTYPE = termcolors.make_style(fg='green')
|
||||
style.SQL_KEYWORD = termcolors.make_style(fg='yellow')
|
||||
style.SQL_TABLE = termcolors.make_style(opts=('bold',))
|
||||
del dummy
|
||||
|
||||
def disable_termcolors():
|
||||
class dummy:
|
||||
def __getattr__(self, attr):
|
||||
return lambda x: x
|
||||
global style
|
||||
style = dummy()
|
||||
|
||||
# Disable terminal coloring if somebody's piping the output.
|
||||
if (not sys.stdout.isatty()) or (sys.platform == 'win32'):
|
||||
disable_termcolors()
|
||||
|
||||
def _is_valid_dir_name(s):
|
||||
return bool(re.search(r'^\w+$', s))
|
||||
|
||||
@ -66,9 +89,9 @@ def get_sql_create(app):
|
||||
if not data_types:
|
||||
# This must be the "dummy" database backend, which means the user
|
||||
# hasn't set DATABASE_ENGINE.
|
||||
sys.stderr.write("Error: Django doesn't know which syntax to use for your SQL statements,\n" +
|
||||
sys.stderr.write(style.ERROR("Error: Django doesn't know which syntax to use for your SQL statements,\n" +
|
||||
"because you haven't specified the DATABASE_ENGINE setting.\n" +
|
||||
"Edit your settings file and change DATABASE_ENGINE to something like 'postgresql' or 'mysql'.\n")
|
||||
"Edit your settings file and change DATABASE_ENGINE to something like 'postgresql' or 'mysql'.\n"))
|
||||
sys.exit(1)
|
||||
|
||||
# Get installed models, so we generate REFERENCES right
|
||||
@ -128,29 +151,33 @@ def _get_sql_model_create(klass, models_already_seen=set()):
|
||||
col_type = data_types[data_type]
|
||||
if col_type is not None:
|
||||
# Make the definition (e.g. 'foo VARCHAR(30)') for this field.
|
||||
field_output = [backend.quote_name(f.column), col_type % rel_field.__dict__]
|
||||
field_output.append('%sNULL' % (not f.null and 'NOT ' or ''))
|
||||
field_output = [style.SQL_FIELD(backend.quote_name(f.column)),
|
||||
style.SQL_COLTYPE(col_type % rel_field.__dict__)]
|
||||
field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or '')))
|
||||
if f.unique:
|
||||
field_output.append('UNIQUE')
|
||||
field_output.append(style.SQL_KEYWORD('UNIQUE'))
|
||||
if f.primary_key:
|
||||
field_output.append('PRIMARY KEY')
|
||||
field_output.append(style.SQL_KEYWORD('PRIMARY KEY'))
|
||||
if f.rel:
|
||||
if f.rel.to in models_already_seen:
|
||||
field_output.append('REFERENCES %s (%s)' % \
|
||||
(backend.quote_name(f.rel.to._meta.db_table),
|
||||
backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)))
|
||||
field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \
|
||||
style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)) + ' (' + \
|
||||
style.SQL_FIELD(backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')'
|
||||
)
|
||||
else:
|
||||
# We haven't yet created the table to which this field
|
||||
# is related, so save it for later.
|
||||
pr = pending_references.setdefault(f.rel.to, []).append((klass, f))
|
||||
table_output.append(' '.join(field_output))
|
||||
if opts.order_with_respect_to:
|
||||
table_output.append('%s %s NULL' % (backend.quote_name('_order'), data_types['IntegerField']))
|
||||
table_output.append(style.SQL_FIELD(backend.quote_name('_order')) + ' ' + \
|
||||
style.SQL_COLTYPE(data_types['IntegerField']) + ' ' + \
|
||||
style.SQL_KEYWORD('NULL'))
|
||||
for field_constraints in opts.unique_together:
|
||||
table_output.append('UNIQUE (%s)' % \
|
||||
", ".join([backend.quote_name(opts.get_field(f).column) for f in field_constraints]))
|
||||
table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \
|
||||
", ".join([backend.quote_name(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints]))
|
||||
|
||||
full_statement = ['CREATE TABLE %s (' % backend.quote_name(opts.db_table)]
|
||||
full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(backend.quote_name(opts.db_table)) + ' (']
|
||||
for i, line in enumerate(table_output): # Combine and add commas.
|
||||
full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or ''))
|
||||
full_statement.append(');')
|
||||
@ -175,9 +202,9 @@ def _get_sql_for_pending_references(klass, pending_references):
|
||||
r_col = f.column
|
||||
table = opts.db_table
|
||||
col = opts.get_field(f.rel.field_name).column
|
||||
final_output.append('ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s);' % \
|
||||
final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s);' % \
|
||||
(backend.quote_name(r_table),
|
||||
backend.quote_name("%s_referencing_%s_%s" % (r_col, table, col)),
|
||||
backend.quote_name('%s_referencing_%s_%s' % (r_col, table, col)),
|
||||
backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col)))
|
||||
del pending_references[klass]
|
||||
return final_output
|
||||
@ -189,21 +216,28 @@ def _get_many_to_many_sql_for_model(klass):
|
||||
opts = klass._meta
|
||||
final_output = []
|
||||
for f in opts.many_to_many:
|
||||
table_output = ['CREATE TABLE %s (' % backend.quote_name(f.m2m_db_table())]
|
||||
table_output.append(' %s %s NOT NULL PRIMARY KEY,' % (backend.quote_name('id'), data_types['AutoField']))
|
||||
table_output.append(' %s %s NOT NULL REFERENCES %s (%s),' % \
|
||||
(backend.quote_name(f.m2m_column_name()),
|
||||
data_types[get_rel_data_type(opts.pk)] % opts.pk.__dict__,
|
||||
backend.quote_name(opts.db_table),
|
||||
backend.quote_name(opts.pk.column)))
|
||||
table_output.append(' %s %s NOT NULL REFERENCES %s (%s),' % \
|
||||
(backend.quote_name(f.m2m_reverse_name()),
|
||||
data_types[get_rel_data_type(f.rel.to._meta.pk)] % f.rel.to._meta.pk.__dict__,
|
||||
backend.quote_name(f.rel.to._meta.db_table),
|
||||
backend.quote_name(f.rel.to._meta.pk.column)))
|
||||
table_output.append(' UNIQUE (%s, %s)' % \
|
||||
(backend.quote_name(f.m2m_column_name()),
|
||||
backend.quote_name(f.m2m_reverse_name())))
|
||||
table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \
|
||||
style.SQL_TABLE(backend.quote_name(f.m2m_db_table())) + ' (']
|
||||
table_output.append(' %s %s %s,' % \
|
||||
(style.SQL_FIELD(backend.quote_name('id')),
|
||||
style.SQL_COLTYPE(data_types['AutoField']),
|
||||
style.SQL_KEYWORD('NOT NULL PRIMARY KEY')))
|
||||
table_output.append(' %s %s %s %s (%s),' % \
|
||||
(style.SQL_FIELD(backend.quote_name(f.m2m_column_name())),
|
||||
style.SQL_COLTYPE(data_types[get_rel_data_type(opts.pk)] % opts.pk.__dict__),
|
||||
style.SQL_KEYWORD('NOT NULL REFERENCES'),
|
||||
style.SQL_TABLE(backend.quote_name(opts.db_table)),
|
||||
style.SQL_FIELD(backend.quote_name(opts.pk.column))))
|
||||
table_output.append(' %s %s %s %s (%s),' % \
|
||||
(style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())),
|
||||
style.SQL_COLTYPE(data_types[get_rel_data_type(f.rel.to._meta.pk)] % f.rel.to._meta.pk.__dict__),
|
||||
style.SQL_KEYWORD('NOT NULL REFERENCES'),
|
||||
style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)),
|
||||
style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column))))
|
||||
table_output.append(' %s (%s, %s)' % \
|
||||
(style.SQL_KEYWORD('UNIQUE'),
|
||||
style.SQL_FIELD(backend.quote_name(f.m2m_column_name())),
|
||||
style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name()))))
|
||||
table_output.append(');')
|
||||
final_output.append('\n'.join(table_output))
|
||||
return final_output
|
||||
@ -244,17 +278,20 @@ def get_sql_delete(app):
|
||||
|
||||
for klass in app_models:
|
||||
if cursor and klass._meta.db_table in table_names:
|
||||
# Drop the able now
|
||||
output.append("DROP TABLE %s;" % backend.quote_name(klass._meta.db_table))
|
||||
# Drop the table now
|
||||
output.append('%s %s;' % (style.SQL_KEYWORD('DROP TABLE'),
|
||||
style.SQL_TABLE(backend.quote_name(klass._meta.db_table))))
|
||||
if backend.supports_constraints and references_to_delete.has_key(klass):
|
||||
for rel_class, f in references_to_delete[klass]:
|
||||
table = rel_class._meta.db_table
|
||||
col = f.column
|
||||
r_table = klass._meta.db_table
|
||||
r_col = klass._meta.get_field(f.rel.field_name).column
|
||||
output.append('ALTER TABLE %s DROP CONSTRAINT %s;' % \
|
||||
(backend.quote_name(table),
|
||||
backend.quote_name("%s_referencing_%s_%s" % (col, r_table, r_col))))
|
||||
output.append('%s %s %s %s;' % \
|
||||
(style.SQL_KEYWORD('ALTER TABLE'),
|
||||
style.SQL_TABLE(backend.quote_name(table)),
|
||||
style.SQL_KEYWORD('DROP CONSTRAINT'),
|
||||
style.SQL_FIELD(backend.quote_name("%s_referencing_%s_%s" % (col, r_table, r_col)))))
|
||||
del references_to_delete[klass]
|
||||
|
||||
# Output DROP TABLE statements for many-to-many tables.
|
||||
@ -262,10 +299,13 @@ def get_sql_delete(app):
|
||||
opts = klass._meta
|
||||
for f in opts.many_to_many:
|
||||
if cursor and f.m2m_db_table() in table_names:
|
||||
output.append("DROP TABLE %s;" % backend.quote_name(f.m2m_db_table()))
|
||||
output.append("%s %s;" % (style.SQL_KEYWORD('DROP TABLE'),
|
||||
style.SQL_TABLE(backend.quote_name(f.m2m_db_table()))))
|
||||
|
||||
app_label = app_models[0]._meta.app_label
|
||||
|
||||
# TODO: Remove the following section.
|
||||
|
||||
# Delete from django_package, auth_permission, django_content_type.
|
||||
if cursor and "django_content_type" in table_names:
|
||||
|
||||
@ -346,12 +386,22 @@ def get_sql_sequence_reset(app):
|
||||
for klass in models.get_models(app):
|
||||
for f in klass._meta.fields:
|
||||
if isinstance(f, models.AutoField):
|
||||
output.append("SELECT setval('%s_%s_seq', (SELECT max(%s) FROM %s));" % \
|
||||
(klass._meta.db_table, f.column, backend.quote_name(f.column),
|
||||
backend.quote_name(klass._meta.db_table)))
|
||||
output.append("%s setval('%s', (%s max(%s) %s %s));" % \
|
||||
(style.SQL_KEYWORD('SELECT'),
|
||||
style.SQL_FIELD('%s_%s_seq' % (klass._meta.db_table, f.column)),
|
||||
style.SQL_KEYWORD('SELECT'),
|
||||
style.SQL_FIELD(backend.quote_name(f.column)),
|
||||
style.SQL_KEYWORD('FROM'),
|
||||
style.SQL_TABLE(backend.quote_name(klass._meta.db_table))))
|
||||
break # Only one AutoField is allowed per model, so don't bother continuing.
|
||||
for f in klass._meta.many_to_many:
|
||||
output.append("SELECT setval('%s_id_seq', (SELECT max(%s) FROM %s));" % \
|
||||
(f.m2m_db_table(), backend.quote_name('id'), f.m2m_db_table()))
|
||||
output.append("%s setval('%s', (%s max(%s) %s %s));" % \
|
||||
(style.SQL_KEYWORD('SELECT'),
|
||||
style.SQL_FIELD('%s_id_seq' % f.m2m_db_table()),
|
||||
style.SQL_KEYWORD('SELECT'),
|
||||
style.SQL_FIELD(backend.quote_name('id')),
|
||||
style.SQL_KEYWORD('FROM'),
|
||||
style.SQL_TABLE(f.m2m_db_table())))
|
||||
return output
|
||||
get_sql_sequence_reset.help_doc = "Prints the SQL statements for resetting PostgreSQL sequences for the given app name(s)."
|
||||
get_sql_sequence_reset.args = APP_ARGS
|
||||
@ -364,10 +414,14 @@ def get_sql_indexes(app):
|
||||
for klass in models.get_models(app):
|
||||
for f in klass._meta.fields:
|
||||
if f.db_index:
|
||||
unique = f.unique and "UNIQUE " or ""
|
||||
output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \
|
||||
(unique, klass._meta.db_table, f.column,
|
||||
backend.quote_name(klass._meta.db_table), backend.quote_name(f.column)))
|
||||
unique = f.unique and 'UNIQUE ' or ''
|
||||
output.append(
|
||||
style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \
|
||||
style.SQL_TABLE('%s_%s' % (klass._meta.db_table, f.column)) + ' ' + \
|
||||
style.SQL_KEYWORD('ON') + ' ' + \
|
||||
style.SQL_TABLE(backend.quote_name(klass._meta.db_table)) + ' ' + \
|
||||
"(%s);" % style.SQL_FIELD(backend.quote_name(f.column))
|
||||
)
|
||||
return output
|
||||
get_sql_indexes.help_doc = "Prints the CREATE INDEX SQL statements for the given model module name(s)."
|
||||
get_sql_indexes.args = APP_ARGS
|
||||
@ -385,7 +439,9 @@ def syncdb():
|
||||
from django.conf import settings
|
||||
from django.dispatch import dispatcher
|
||||
|
||||
# Check that there are no validation errors before continuing
|
||||
disable_termcolors()
|
||||
|
||||
# First, try validating the models.
|
||||
_check_for_validation_errors()
|
||||
|
||||
# Import the 'management' module within each installed app, to register
|
||||
@ -489,6 +545,8 @@ def install(app):
|
||||
|
||||
app_name = app.__name__.split('.')[-2]
|
||||
|
||||
disable_termcolors()
|
||||
|
||||
# First, try validating the models.
|
||||
_check_for_validation_errors(app)
|
||||
|
||||
@ -499,12 +557,12 @@ def install(app):
|
||||
for sql in sql_list:
|
||||
cursor.execute(sql)
|
||||
except Exception, e:
|
||||
sys.stderr.write("""Error: %s couldn't be installed. Possible reasons:
|
||||
sys.stderr.write(style.ERROR("""Error: %s couldn't be installed. Possible reasons:
|
||||
* The database isn't running or isn't configured correctly.
|
||||
* At least one of the database tables already exists.
|
||||
* The SQL was invalid.
|
||||
Hint: Look at the output of 'django-admin.py sqlall %s'. That's the SQL this command wasn't able to run.
|
||||
The full error: %s\n""" % (app_name, app_name, e))
|
||||
The full error: """ % (app_name, app_name)) + style.ERROR_OUTPUT(e) + '\n')
|
||||
transaction.rollback_unless_managed()
|
||||
sys.exit(1)
|
||||
transaction.commit_unless_managed()
|
||||
@ -517,6 +575,8 @@ def reset(app):
|
||||
from cStringIO import StringIO
|
||||
app_name = app.__name__.split('.')[-2]
|
||||
|
||||
disable_termcolors()
|
||||
|
||||
# First, try validating the models.
|
||||
_check_for_validation_errors(app)
|
||||
sql_list = get_sql_reset(app)
|
||||
@ -533,12 +593,12 @@ Type 'yes' to continue, or 'no' to cancel: """)
|
||||
for sql in sql_list:
|
||||
cursor.execute(sql)
|
||||
except Exception, e:
|
||||
sys.stderr.write("""Error: %s couldn't be installed. Possible reasons:
|
||||
sys.stderr.write(style.ERROR("""Error: %s couldn't be installed. Possible reasons:
|
||||
* The database isn't running or isn't configured correctly.
|
||||
* At least one of the database tables already exists.
|
||||
* The SQL was invalid.
|
||||
Hint: Look at the output of 'django-admin.py sqlreset %s'. That's the SQL this command wasn't able to run.
|
||||
The full error: %s\n""" % (app_name, app_name, e))
|
||||
The full error: """ % (app_name, app_name)) + style.ERROR_OUTPUT(e) + '\n')
|
||||
transaction.rollback_unless_managed()
|
||||
sys.exit(1)
|
||||
transaction.commit_unless_managed()
|
||||
@ -550,13 +610,13 @@ reset.args = APP_ARGS
|
||||
def _start_helper(app_or_project, name, directory, other_name=''):
|
||||
other = {'project': 'app', 'app': 'project'}[app_or_project]
|
||||
if not _is_valid_dir_name(name):
|
||||
sys.stderr.write("Error: %r is not a valid %s name. Please use only numbers, letters and underscores.\n" % (name, app_or_project))
|
||||
sys.stderr.write(style.ERROR("Error: %r is not a valid %s name. Please use only numbers, letters and underscores.\n" % (name, app_or_project)))
|
||||
sys.exit(1)
|
||||
top_dir = os.path.join(directory, name)
|
||||
try:
|
||||
os.mkdir(top_dir)
|
||||
except OSError, e:
|
||||
sys.stderr.write("Error: %s\n" % e)
|
||||
sys.stderr.write(style.ERROR("Error: %s\n" % e))
|
||||
sys.exit(1)
|
||||
template_dir = PROJECT_TEMPLATE_DIR % app_or_project
|
||||
for d, subdirs, files in os.walk(template_dir):
|
||||
@ -579,7 +639,7 @@ def startproject(project_name, directory):
|
||||
"Creates a Django project for the given project_name in the given directory."
|
||||
from random import choice
|
||||
if project_name in INVALID_PROJECT_NAMES:
|
||||
sys.stderr.write("Error: %r isn't a valid project name. Please try another.\n" % project_name)
|
||||
sys.stderr.write(style.ERROR("Error: %r isn't a valid project name. Please try another.\n" % project_name))
|
||||
sys.exit(1)
|
||||
_start_helper('project', project_name, directory)
|
||||
# Create a random SECRET_KEY hash, and put it in the main settings.
|
||||
@ -714,7 +774,7 @@ class ModelErrorCollection:
|
||||
|
||||
def add(self, opts, error):
|
||||
self.errors.append((opts, error))
|
||||
self.outfile.write("%s.%s: %s\n" % (opts.app_label, opts.module_name, error))
|
||||
self.outfile.write(style.ERROR("%s.%s: %s\n" % (opts.app_label, opts.module_name, error)))
|
||||
|
||||
def get_validation_errors(outfile, app=None):
|
||||
"""
|
||||
@ -885,7 +945,7 @@ def _check_for_validation_errors(app=None):
|
||||
s = StringIO()
|
||||
num_errors = get_validation_errors(s, app)
|
||||
if num_errors:
|
||||
sys.stderr.write("Error: %s couldn't be installed, because there were errors in your model:\n" % app)
|
||||
sys.stderr.write(style.ERROR("Error: %s couldn't be installed, because there were errors in your model:\n" % app))
|
||||
s.seek(0)
|
||||
sys.stderr.write(s.read())
|
||||
sys.exit(1)
|
||||
@ -897,7 +957,7 @@ def runserver(addr, port):
|
||||
if not addr:
|
||||
addr = '127.0.0.1'
|
||||
if not port.isdigit():
|
||||
sys.stderr.write("Error: %r is not a valid port number.\n" % port)
|
||||
sys.stderr.write(style.ERROR("Error: %r is not a valid port number.\n" % port))
|
||||
sys.exit(1)
|
||||
def inner_run():
|
||||
from django.conf import settings
|
||||
@ -919,7 +979,7 @@ def runserver(addr, port):
|
||||
error_text = ERRORS[e.args[0].args[0]]
|
||||
except (AttributeError, KeyError):
|
||||
error_text = str(e)
|
||||
sys.stderr.write("Error: %s\n" % error_text)
|
||||
sys.stderr.write(style.ERROR("Error: %s" % error_text) + '\n')
|
||||
sys.exit(1)
|
||||
except KeyboardInterrupt:
|
||||
sys.exit(0)
|
||||
@ -1005,7 +1065,8 @@ NO_SQL_TRANSACTION = (
|
||||
'createcachetable',
|
||||
'install',
|
||||
'reset',
|
||||
'sqlindexes'
|
||||
'sqlindexes',
|
||||
'syncdb'
|
||||
)
|
||||
|
||||
class DjangoOptionParser(OptionParser):
|
||||
@ -1029,7 +1090,7 @@ def get_usage(action_mapping):
|
||||
return '\n'.join(usage[:-1]) # Cut off last list element, an empty space.
|
||||
|
||||
def print_error(msg, cmd):
|
||||
sys.stderr.write('Error: %s\nRun "%s --help" for help.\n' % (msg, cmd))
|
||||
sys.stderr.write(style.ERROR('Error: %s' % msg) + '\nRun "%s --help" for help.\n' % cmd)
|
||||
sys.exit(1)
|
||||
|
||||
def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING):
|
||||
@ -1078,7 +1139,7 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING):
|
||||
for line in action_mapping[action](param):
|
||||
print line
|
||||
except NotImplementedError:
|
||||
sys.stderr.write("Error: %r isn't supported for the currently selected database backend.\n" % action)
|
||||
sys.stderr.write(style.ERROR("Error: %r isn't supported for the currently selected database backend.\n" % action))
|
||||
sys.exit(1)
|
||||
elif action == 'createcachetable':
|
||||
try:
|
||||
@ -1106,18 +1167,18 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING):
|
||||
try:
|
||||
mod_list = [models.get_app(app_label) for app_label in args[1:]]
|
||||
except ImportError, e:
|
||||
sys.stderr.write("Error: %s. Are you sure your INSTALLED_APPS setting is correct?\n" % e)
|
||||
sys.stderr.write(style.ERROR("Error: %s. Are you sure your INSTALLED_APPS setting is correct?\n" % e))
|
||||
sys.exit(1)
|
||||
if not mod_list:
|
||||
parser.print_usage_and_exit()
|
||||
if action not in NO_SQL_TRANSACTION:
|
||||
print "BEGIN;"
|
||||
print style.SQL_KEYWORD("BEGIN;")
|
||||
for mod in mod_list:
|
||||
output = action_mapping[action](mod)
|
||||
if output:
|
||||
print '\n'.join(output)
|
||||
if action not in NO_SQL_TRANSACTION:
|
||||
print "COMMIT;"
|
||||
print style.SQL_KEYWORD("COMMIT;")
|
||||
|
||||
def execute_manager(settings_mod):
|
||||
# Add this project to sys.path so that it's importable in the conventional
|
||||
|
70
django/utils/termcolors.py
Normal file
70
django/utils/termcolors.py
Normal file
@ -0,0 +1,70 @@
|
||||
"""
|
||||
termcolors.py
|
||||
"""
|
||||
|
||||
import types
|
||||
|
||||
color_names = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white')
|
||||
foreground = dict([(color_names[x], '3%s' % x) for x in range(8)])
|
||||
background = dict([(color_names[x], '4%s' % x) for x in range(8)])
|
||||
del color_names
|
||||
|
||||
RESET = '0'
|
||||
opt_dict = {'bold': '1', 'underscore': '4', 'blink': '5', 'reverse': '7', 'conceal': '8'}
|
||||
|
||||
def colorize(text='', opts=(), **kwargs):
|
||||
"""
|
||||
Returns your text, enclosed in ANSI graphics codes.
|
||||
|
||||
Depends on the keyword arguments 'fg' and 'bg', and the contents of
|
||||
the opts tuple/list.
|
||||
|
||||
Returns the RESET code if no parameters are given.
|
||||
|
||||
Valid colors:
|
||||
'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'
|
||||
|
||||
Valid options:
|
||||
'bold'
|
||||
'underscore'
|
||||
'blink'
|
||||
'reverse'
|
||||
'conceal'
|
||||
'noreset' - string will not be auto-terminated with the RESET code
|
||||
|
||||
Examples:
|
||||
colorize('hello', fg='red', bg='blue', opts=('blink',))
|
||||
colorize()
|
||||
colorize('goodbye', opts=('underscore',))
|
||||
print colorize('first line', fg='red', opts=('noreset',))
|
||||
print 'this should be red too'
|
||||
print colorize('and so should this')
|
||||
print 'this should not be red'
|
||||
"""
|
||||
text = str(text)
|
||||
code_list = []
|
||||
if text == '' and len(opts) == 1 and opts[0] == 'reset':
|
||||
return '\x1b[%sm' % RESET
|
||||
for k, v in kwargs.iteritems():
|
||||
if k == 'fg':
|
||||
code_list.append(foreground[v])
|
||||
elif k == 'bg':
|
||||
code_list.append(background[v])
|
||||
for o in opts:
|
||||
if o in opt_dict:
|
||||
code_list.append(opt_dict[o])
|
||||
if 'noreset' not in opts:
|
||||
text = text + '\x1b[%sm' % RESET
|
||||
return ('\x1b[%sm' % ';'.join(code_list)) + text
|
||||
|
||||
def make_style(opts=(), **kwargs):
|
||||
"""
|
||||
Returns a function with default parameters for colorize()
|
||||
|
||||
Example:
|
||||
bold_red = make_style(opts=('bold',), fg='red')
|
||||
print bold_red('hello')
|
||||
KEYWORD = make_style(fg='yellow')
|
||||
COMMENT = make_style(fg='blue', opts=('bold',))
|
||||
"""
|
||||
return lambda text: colorize(text, opts, **kwargs)
|
Loading…
x
Reference in New Issue
Block a user