Code

Ticket #1491: colourful.2.diff

File colourful.2.diff, 30.4 KB (added by plmeister@…, 8 years ago)

noticed a small broken part

Line 
1Index: termcolors.py
2===================================================================
3--- termcolors.py       (revision 0)
4+++ termcolors.py       (revision 0)
5@@ -0,0 +1,88 @@
6+#!/usr/bin/python
7+
8+"""
9+termcolors.py
10+
11+set termcolors.DISABLE = True to disable the whole shebang
12+"""
13+import types
14+
15+colour_names = ('black', 'red', 'green', 'yellow', 'blue', 'magenta',
16+        'cyan', 'white')
17+foreground = {}; background = {}
18+[ foreground.update({colour_names[x]: '3%s' % x}) for x in range(8) ]
19+[ background.update({colour_names[x]: '4%s' % x}) for x in range(8) ]
20+
21+RESET, BOLD, UNDERSCORE, BLINK, REVERSE, CONCEAL = '014578'
22+opt_dict = {'bold': BOLD, 'underscore': UNDERSCORE, 'blink': BLINK,
23+        'reverse': REVERSE, 'conceal': CONCEAL,}
24+
25+DISABLE = False
26+
27+def gfx(text='', opts=(), **kwargs):
28+    """Returns your text, enclosed in ANSI graphics codes
29+   
30+Depends on the keyword arguments 'fgcol' and 'bgcol', and the contents of the
31+opts tuple/list
32+
33+With no parameters is a special case - it returns the RESET code
34+
35+Valid colours:
36+    'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'
37+   
38+Valid options:
39+    'bold'
40+    'underscore'
41+    'blink'
42+    'reverse'
43+    'conceal'
44+    'noreset' - string will not be auto-terminated with the RESET code
45+
46+Examples:
47+    gfx('hello', fgcol='red', bgcol='blue', opts=('blink',))
48+    gfx()
49+    gfx('goodbye', opts=('underscore',))
50+    print gfx('first line', fgcol='red', opts=('noreset',))
51+    print 'this should be red too'
52+    print gfx('and so should this')
53+    print 'this should not be red'
54+"""
55+    text = str(text)
56+    if DISABLE:
57+        return text
58+    code_list = []
59+    if text == '' and len(opts) == 1 and opts[0] == 'reset':
60+        return '\x1b[%sm' % RESET
61+    for k,v in kwargs.iteritems():
62+        if k == 'fgcol':
63+            code_list.append(foreground[v])
64+        elif k == 'bgcol':
65+            code_list.append(background[v])
66+    for o in opts:
67+        if o in opt_dict:
68+            code_list.append(opt_dict[o])
69+    if not ('noreset' in opts):
70+        text = text + '\x1b[%sm' % RESET
71+    return ('\x1b[%sm' % ';'.join(code_list)) + text
72+
73+def make_style(opts=(), **kwargs):
74+    """Returns a function with default parameters for gfx()
75+
76+    Example:
77+        bold_red = make_style(opts=('bold',), fgcol='red')
78+        print bold_red('hello')
79+
80+        KEYWORD = make_style(fgcol='yellow')
81+        COMMENT = make_style(fgcol='blue', opts=('bold',))
82+    etc
83+    """
84+    return lambda text: gfx(text, opts, **kwargs)
85+
86+    result = ''
87+    for a in args:
88+        if a.__class__ in types.StringTypes:
89+            result += a
90+        elif a.__class__ in [types.TupleType, types.ListType]:
91+            result += a[0](a[1])
92+    return result
93+
94Index: management.py
95===================================================================
96--- management.py       (revision 2509)
97+++ management.py       (working copy)
98@@ -4,7 +4,38 @@
99 import django
100 import os, re, sys, textwrap
101 from optparse import OptionParser
102+import termcolors
103 
104+class dummy:
105+    pass
106+
107+style = dummy()
108+
109+style.ERROR = termcolors.make_style(fgcol='white', bgcol='red', opts=('bold',))
110+style.ERROR_OUTPUT = termcolors.make_style(fgcol='red', opts=('bold',))
111+style.OK = termcolors.make_style(fgcol='green', opts=('bold',))
112+style.SQL_STRING = termcolors.make_style(fgcol='cyan')
113+style.SQL_FIELD = termcolors.make_style(fgcol='green')
114+style.SQL_KEYWORD = termcolors.make_style(fgcol='yellow')
115+style.SQL_NUMBER = style.SQL_STRING
116+style.SQL_TABLE = termcolors.make_style(fgcol='green', opts=('bold',))
117+style.SQL_TRANS = termcolors.make_style(opts=('bold',))
118+
119+def J(*args):
120+    return ''.join(map(str, args))
121+
122+def disable_sql_styles():
123+    l = lambda x: x
124+    style.SQL_STRING = l
125+    style.SQL_FIELD = l
126+    style.SQL_KEYWORD = l
127+    style.SQL_TABLE = l
128+
129+if (not sys.stdout.isatty()) or (sys.platform == 'win32'):
130+    # if somebody's piping our output through to psql or something,
131+    # they might be a touch miffed if it's all full of escape chars
132+    termcolors.DISABLE = True
133+
134 # For Python 2.3
135 if not hasattr(__builtins__, 'set'):
136     from sets import Set as set
137@@ -27,9 +58,13 @@
138 
139 def _get_packages_insert(app_label):
140     from django.core.db import db
141-    return "INSERT INTO %s (%s, %s) VALUES ('%s', '%s');" % \
142-        (db.quote_name('packages'), db.quote_name('label'), db.quote_name('name'),
143-        app_label, app_label)
144+    return J(style.SQL_KEYWORD("INSERT INTO")," %s (%s, %s) ",
145+                   style.SQL_KEYWORD("VALUES")," (%s, %s);") % \
146+        (style.SQL_TABLE(db.quote_name('packages')),
147+         style.SQL_FIELD(db.quote_name('label')),
148+         style.SQL_FIELD(db.quote_name('name')),
149+         style.SQL_STRING("'"+app_label+"'"),
150+         style.SQL_STRING("'"+app_label+"'"))
151 
152 def _get_permission_codename(action, opts):
153     return '%s_%s' % (action, opts.object_name.lower())
154@@ -44,15 +79,27 @@
155 
156 def _get_permission_insert(name, codename, opts):
157     from django.core.db import db
158-    return "INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s');" % \
159-        (db.quote_name('auth_permissions'), db.quote_name('name'), db.quote_name('package'),
160-        db.quote_name('codename'), name.replace("'", "''"), opts.app_label, codename)
161+    return J(style.SQL_KEYWORD("INSERT INTO")," %s (%s, %s, %s) ",
162+                   style.SQL_KEYWORD("VALUES")," (%s, %s, %s);") % \
163+        (style.SQL_TABLE(db.quote_name('auth_permissions')),
164+         style.SQL_FIELD(db.quote_name('name')),
165+         style.SQL_FIELD(db.quote_name('package')),
166+         style.SQL_FIELD(db.quote_name('codename')),
167+         style.SQL_STRING("'"+name.replace("'", "''")+"'"),
168+         style.SQL_STRING("'"+opts.app_label+"'"),
169+         style.SQL_STRING("'"+codename+"'"))
170 
171 def _get_contenttype_insert(opts):
172     from django.core.db import db
173-    return "INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s');" % \
174-        (db.quote_name('content_types'), db.quote_name('name'), db.quote_name('package'),
175-        db.quote_name('python_module_name'), opts.verbose_name, opts.app_label, opts.module_name)
176+    return J(style.SQL_KEYWORD("INSERT INTO"), " %s (%s, %s, %s) ",
177+                   style.SQL_KEYWORD("VALUES"), " (%s, %s, %s);") % \
178+        (style.SQL_TABLE(db.quote_name('content_types')),
179+         style.SQL_FIELD(db.quote_name('name')),
180+         style.SQL_FIELD(db.quote_name('package')),
181+         style.SQL_FIELD(db.quote_name('python_module_name')),
182+         style.SQL_STRING("'"+opts.verbose_name.__str__()+"'"),
183+         style.SQL_STRING("'"+opts.app_label.__str__()+"'"),
184+         style.SQL_STRING("'"+opts.module_name.__str__()+"'"))
185 
186 def _is_valid_dir_name(s):
187     return bool(re.search(r'^\w+$', s))
188@@ -87,24 +134,29 @@
189                 data_type = f.get_internal_type()
190             col_type = db.DATA_TYPES[data_type]
191             if col_type is not None:
192-                field_output = [db.db.quote_name(f.column), col_type % rel_field.__dict__]
193-                field_output.append('%sNULL' % (not f.null and 'NOT ' or ''))
194+                field_output = [style.SQL_FIELD(db.db.quote_name(f.column)),
195+                                col_type % rel_field.__dict__]
196+                field_output.append(style.SQL_KEYWORD('%sNULL') % \
197+                        (not f.null and 'NOT ' or ''))
198                 if f.unique:
199-                    field_output.append('UNIQUE')
200+                    field_output.append(style.SQL_KEYWORD('UNIQUE'))
201                 if f.primary_key:
202-                    field_output.append('PRIMARY KEY')
203+                    field_output.append(style.SQL_KEYWORD('PRIMARY KEY'))
204                 if f.rel:
205-                    field_output.append('REFERENCES %s (%s)' % \
206-                        (db.db.quote_name(f.rel.to.db_table),
207-                        db.db.quote_name(f.rel.to.get_field(f.rel.field_name).column)))
208+                    field_output.append(J(style.SQL_KEYWORD('REFERENCES'),
209+                                        ' %s (%s)') % \
210+                        (style.SQL_TABLE(db.db.quote_name(f.rel.to.db_table)),
211+                        style.SQL_FIELD(db.db.quote_name(f.rel.to.get_field(f.rel.field_name).column))))
212                 table_output.append(' '.join(field_output))
213         if opts.order_with_respect_to:
214-            table_output.append('%s %s NULL' % (db.db.quote_name('_order'), db.DATA_TYPES['IntegerField']))
215+            table_output.append(J('%s %s ',style.SQL_KEYWORD('NULL')) % \
216+                    (style.SQL_FIELD(db.db.quote_name('_order')),
217+                        db.DATA_TYPES['IntegerField']))
218         for field_constraints in opts.unique_together:
219-            table_output.append('UNIQUE (%s)' % \
220-                ", ".join([db.db.quote_name(opts.get_field(f).column) for f in field_constraints]))
221+            table_output.append(style.SQL_KEYWORD('UNIQUE')+' (%s)' % \
222+                ", ".join([style.SQL_FIELD(db.db.quote_name(opts.get_field(f).column)) for f in field_constraints]))
223 
224-        full_statement = ['CREATE TABLE %s (' % db.db.quote_name(opts.db_table)]
225+        full_statement = [style.SQL_KEYWORD('CREATE TABLE')+' %s (' % style.SQL_TABLE(db.db.quote_name(opts.db_table))]
226         for i, line in enumerate(table_output): # Combine and add commas.
227             full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or ''))
228         full_statement.append(');')
229@@ -113,21 +165,29 @@
230     for klass in mod._MODELS:
231         opts = klass._meta
232         for f in opts.many_to_many:
233-            table_output = ['CREATE TABLE %s (' % db.db.quote_name(f.get_m2m_db_table(opts))]
234-            table_output.append('    %s %s NOT NULL PRIMARY KEY,' % (db.db.quote_name('id'), db.DATA_TYPES['AutoField']))
235-            table_output.append('    %s %s NOT NULL REFERENCES %s (%s),' % \
236-                (db.db.quote_name(opts.object_name.lower() + '_id'),
237+            table_output = [J(style.SQL_KEYWORD('CREATE TABLE'),' %s (') % \
238+                    style.SQL_TABLE(db.db.quote_name(f.get_m2m_db_table(opts))
239+                            )]
240+            table_output.append(J('    %s %s ',
241+                style.SQL_KEYWORD('NOT NULL PRIMARY KEY'),',') % \
242+                        (style.SQL_FIELD(db.db.quote_name('id')),
243+                            db.DATA_TYPES['AutoField']))
244+            table_output.append(J('    %s %s ',
245+                style.SQL_KEYWORD('NOT NULL REFERENCES'),' %s (%s),') % \
246+                (style.SQL_FIELD(db.db.quote_name(opts.object_name.lower() + '_id')),
247                 db.DATA_TYPES[get_rel_data_type(opts.pk)] % opts.pk.__dict__,
248-                db.db.quote_name(opts.db_table),
249-                db.db.quote_name(opts.pk.column)))
250-            table_output.append('    %s %s NOT NULL REFERENCES %s (%s),' % \
251-                (db.db.quote_name(f.rel.to.object_name.lower() + '_id'),
252+                style.SQL_TABLE(db.db.quote_name(opts.db_table)),
253+                style.SQL_FIELD(db.db.quote_name(opts.pk.column))))
254+            table_output.append(J('    %s %s ',
255+                style.SQL_KEYWORD('NOT NULL REFERENCES'),' %s (%s),') % \
256+                (style.SQL_FIELD(db.db.quote_name(f.rel.to.object_name.lower() + '_id')),
257                 db.DATA_TYPES[get_rel_data_type(f.rel.to.pk)] % f.rel.to.pk.__dict__,
258-                db.db.quote_name(f.rel.to.db_table),
259-                db.db.quote_name(f.rel.to.pk.column)))
260-            table_output.append('    UNIQUE (%s, %s)' % \
261-                (db.db.quote_name(opts.object_name.lower() + '_id'),
262-                db.db.quote_name(f.rel.to.object_name.lower() + '_id')))
263+                style.SQL_TABLE(db.db.quote_name(f.rel.to.db_table)),
264+                style.SQL_FIELD(db.db.quote_name(f.rel.to.pk.column))))
265+            table_output.append(J('    ',style.SQL_KEYWORD('UNIQUE'),
266+                ' (%s, %s)') % \
267+                (style.SQL_FIELD(db.db.quote_name(opts.object_name.lower() + '_id')),
268+                style.SQL_FIELD(db.db.quote_name(f.rel.to.object_name.lower() + '_id'))))
269             table_output.append(');')
270             final_output.append('\n'.join(table_output))
271     return final_output
272@@ -167,7 +227,8 @@
273             # The table doesn't exist, so it doesn't need to be dropped.
274             db.db.rollback()
275         else:
276-            output.append("DROP TABLE %s;" % db.db.quote_name(klass._meta.db_table))
277+            output.append(J(style.SQL_KEYWORD("DROP TABLE")," %s;") % \
278+                    style.SQL_TABLE(db.db.quote_name(klass._meta.db_table)))
279 
280     # Output DROP TABLE statements for many-to-many tables.
281     for klass in mod._MODELS:
282@@ -175,21 +236,32 @@
283         for f in opts.many_to_many:
284             try:
285                 if cursor is not None:
286-                    cursor.execute("SELECT 1 FROM %s LIMIT 1" % db.db.quote_name(f.get_m2m_db_table(opts)))
287+                    cursor.execute("SELECT 1 FROM %s LIMIT 1" % \
288+                            db.db.quote_name(f.get_m2m_db_table(opts)))
289             except:
290                 db.db.rollback()
291             else:
292-                output.append("DROP TABLE %s;" % db.db.quote_name(f.get_m2m_db_table(opts)))
293+                output.append(J(style.SQL_KEYWORD("DROP TABLE")," %s;") % \
294+                        style.SQL_TABLE(db.db.quote_name(f.get_m2m_db_table(opts))))
295 
296     app_label = mod._MODELS[0]._meta.app_label
297 
298     # Delete from packages, auth_permissions, content_types.
299-    output.append("DELETE FROM %s WHERE %s = '%s';" % \
300-        (db.db.quote_name('packages'), db.db.quote_name('label'), app_label))
301-    output.append("DELETE FROM %s WHERE %s = '%s';" % \
302-        (db.db.quote_name('auth_permissions'), db.db.quote_name('package'), app_label))
303-    output.append("DELETE FROM %s WHERE %s = '%s';" % \
304-        (db.db.quote_name('content_types'), db.db.quote_name('package'), app_label))
305+    output.append(J(style.SQL_KEYWORD("DELETE FROM")," %s ",
306+        style.SQL_KEYWORD("WHERE")," %s = %s;") % \
307+        (style.SQL_TABLE(db.db.quote_name('packages')),
308+            style.SQL_FIELD(db.db.quote_name('label')),
309+            style.SQL_STRING("'"+app_label+"'")))
310+    output.append(J(style.SQL_KEYWORD("DELETE FROM")," %s ",
311+        style.SQL_KEYWORD("WHERE")," %s = %s;") % \
312+        (style.SQL_TABLE(db.db.quote_name('auth_permissions')),
313+            style.SQL_FIELD(db.db.quote_name('package')),
314+            style.SQL_STRING("'"+app_label+"'")))
315+    output.append(J(style.SQL_KEYWORD("DELETE FROM")," %s ",
316+        style.SQL_KEYWORD("WHERE")," %s = %s;") % \
317+        (style.SQL_TABLE(db.db.quote_name('content_types')),
318+            style.SQL_FIELD(db.db.quote_name('package')),
319+            style.SQL_STRING("'"+app_label+"'")))
320 
321     # Delete from the admin log.
322     if cursor is not None:
323@@ -198,8 +270,11 @@
324             db.db.quote_name('package')), [app_label])
325         if admin_log_exists:
326             for row in cursor.fetchall():
327-                output.append("DELETE FROM %s WHERE %s = %s;" % \
328-                    (db.db.quote_name('django_admin_log'), db.db.quote_name('content_type_id'), row[0]))
329+                output.append(J(style.SQL_KEYWORD("DELETE FROM")," %s ",
330+                    style.SQL_KEYWORD("WHERE")," %s = %s;") % \
331+                    (style.SQL_TABLE(db.db.quote_name('django_admin_log')),
332+                        style.SQL_FIELD(db.db.quote_name('content_type_id')),
333+                        style.SQL_NUMBER(row[0])))
334 
335     # Close database connection explicitly, in case this output is being piped
336     # directly into a database client, to avoid locking issues.
337@@ -252,12 +327,22 @@
338     for klass in mod._MODELS:
339         for f in klass._meta.fields:
340             if isinstance(f, meta.AutoField):
341-                output.append("SELECT setval('%s_%s_seq', (SELECT max(%s) FROM %s));" % \
342-                    (klass._meta.db_table, f.column, db.db.quote_name(f.column),
343-                    db.db.quote_name(klass._meta.db_table)))
344+                output.append(J(style.SQL_KEYWORD("SELECT"),
345+                    " setval('%s_%s_seq', (",
346+                    style.SQL_KEYWORD("SELECT")," max(%s) ",
347+                    style.SQL_KEYWORD("FROM")," %s));") % \
348+                    (klass._meta.db_table,
349+                        f.column,
350+                        style.SQL_FIELD(db.db.quote_name(f.column)),
351+                    style.SQL_TABLE(db.db.quote_name(klass._meta.db_table))))
352         for f in klass._meta.many_to_many:
353-            output.append("SELECT setval('%s_id_seq', (SELECT max(%s) FROM %s));" % \
354-                (f.get_m2m_db_table(klass._meta), db.db.quote_name('id'), f.get_m2m_db_table(klass._meta)))
355+            output.append(J(style.SQL_KEYWORD("SELECT"),
356+                " setval('%s_id_seq', (",
357+                style.SQL_KEYWORD("SELECT")," max(%s) ",
358+                style.SQL_KEYWORD("FROM")," %s));") % \
359+                (f.get_m2m_db_table(klass._meta),
360+                    style.SQL_FIELD(db.db.quote_name('id')),
361+                    style.SQL_TABLE(f.get_m2m_db_table(klass._meta))))
362     return output
363 get_sql_sequence_reset.help_doc = "Prints the SQL statements for resetting PostgreSQL sequences for the given model module name(s)."
364 get_sql_sequence_reset.args = APP_ARGS
365@@ -270,9 +355,10 @@
366         for f in klass._meta.fields:
367             if f.db_index:
368                 unique = f.unique and "UNIQUE " or ""
369-                output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \
370+                output.append(J(style.SQL_KEYWORD("CREATE %sINDEX")," %s_%s ",style.SQL_KEYWORD("ON")," %s (%s);") % \
371                     (unique, klass._meta.db_table, f.column,
372-                    db.quote_name(klass._meta.db_table), db.quote_name(f.column)))
373+                    style.SQL_TABLE(db.quote_name(klass._meta.db_table)),
374+                    style.SQL_FIELD(db.quote_name(f.column))))
375     return output
376 get_sql_indexes.help_doc = "Prints the CREATE INDEX SQL statements for the given model module name(s)."
377 get_sql_indexes.args = APP_ARGS
378@@ -337,9 +423,14 @@
379             perms_seen[row[0]]
380         except KeyError:
381 #             sys.stderr.write("A permission called '%s.%s' was found in the database but not in the model.\n" % (app_label, row[0]))
382-            print "DELETE FROM %s WHERE %s='%s' AND %s = '%s';" % \
383-                (db.db.quote_name('auth_permissions'), db.db.quote_name('package'),
384-                app_label, db.db.quote_name('codename'), row[0])
385+            print J(style.SQL_KEYWORD("DELETE FROM"), " %s ",
386+                    style.SQL_KEYWORD("WHERE"), " %s='%s' ",
387+                    style.SQL_KEYWORD("AND"), " %s = '%s';") % \
388+                (style.SQL_TABLE(db.db.quote_name('auth_permissions')),
389+                        style.SQL_FIELD(db.db.quote_name('package')),
390+                        style.SQL_STRING(app_label),
391+                        style.SQL_FIELD(db.db.quote_name('codename')),
392+                        style.SQL_STRING(row[0]))
393 
394     # Check that there aren't any *extra* content types in the DB that the
395     # model doesn't know about.
396@@ -351,9 +442,14 @@
397             contenttypes_seen[row[0]]
398         except KeyError:
399 #             sys.stderr.write("A content type called '%s.%s' was found in the database but not in the model.\n" % (app_label, row[0]))
400-            print "DELETE FROM %s WHERE %s='%s' AND %s = '%s';" % \
401-                (db.db.quote_name('content_types'), db.db.quote_name('package'),
402-                app_label, db.db.quote_name('python_module_name'), row[0])
403+            print J(style.SQL_KEYWORD("DELETE FROM")," %s ",
404+                    style.SQL_KEYWORD("WHERE")," %s='%s' ",
405+                    style.SQL_KEYWORD("AND")," %s = '%s';") % \
406+                (style.SQL_TABLE(db.db.quote_name('content_types')),
407+                        style.SQL_FIELD(db.db.quote_name('package')),
408+                        style.SQL_STRING(app_label),
409+                        style.SQL_FIELD(db.db.quote_name('python_module_name')),
410+                        style.SQL_STRING(row[0]))
411 database_check.help_doc = "Checks that everything is installed in the database for the given model module name(s) and prints SQL statements if needed."
412 database_check.args = APP_ARGS
413 
414@@ -381,6 +477,7 @@
415 
416 def init():
417     "Initializes the database with auth and core."
418+    disable_sql_styles()
419     try:
420         from django.core import db, meta
421         auth = meta.get_app('auth')
422@@ -392,7 +489,10 @@
423             (db.db.quote_name(core.Site._meta.db_table), db.db.quote_name('domain'),
424             db.db.quote_name('name')))
425     except Exception, e:
426-        sys.stderr.write("Error: The database couldn't be initialized.\n%s\n" % e)
427+        sys.stderr.write(
428+                J(style.ERROR("Error: The database couldn't be initialized."),
429+                    "\n",style.ERROR_OUTPUT(e),"\n")
430+                    )
431         try:
432             db.db.rollback()
433         except UnboundLocalError:
434@@ -408,13 +508,14 @@
435     from cStringIO import StringIO
436     mod_name = mod.__name__[mod.__name__.rindex('.')+1:]
437 
438+    disable_sql_styles()
439     # First, try validating the models.
440     s = StringIO()
441     num_errors = get_validation_errors(s)
442     if num_errors:
443-        sys.stderr.write("Error: %s couldn't be installed, because there were errors in your model:\n" % mod_name)
444+        sys.stderr.write(J(style.ERROR("Error: %s couldn't be installed, because there were errors in your model:"),"\n") % mod_name)
445         s.seek(0)
446-        sys.stderr.write(s.read())
447+        sys.stderr.write(style.ERROR_OUTPUT(s.read()))
448         sys.exit(1)
449     sql_list = get_sql_all(mod)
450 
451@@ -423,12 +524,14 @@
452         for sql in sql_list:
453             cursor.execute(sql)
454     except Exception, e:
455-        sys.stderr.write("""Error: %s couldn't be installed. Possible reasons:
456+        sys.stderr.write(
457+        J(style.ERROR("Error: %s couldn't be installed. Possible reasons:"),
458+        style.ERROR_OUTPUT("""
459   * The database isn't running or isn't configured correctly.
460   * At least one of the database tables already exists.
461   * The SQL was invalid.
462 Hint: Look at the output of 'django-admin.py sqlall %s'. That's the SQL this command wasn't able to run.
463-The full error: %s\n""" % \
464+The full error: %s"""),"\n") % \
465             (mod_name, mod_name, e))
466         db.db.rollback()
467         sys.exit(1)
468@@ -440,6 +543,9 @@
469     "Installs any permissions for the given model, if needed."
470     from django.models.auth import permissions
471     from django.models.core import packages
472+
473+    disable_sql_styles()
474+   
475     num_added = 0
476     package = packages.get_object(pk=mod._MODELS[0]._meta.app_label)
477     for klass in mod._MODELS:
478@@ -450,23 +556,23 @@
479             except permissions.PermissionDoesNotExist:
480                 p = permissions.Permission(name=name, package=package, codename=codename)
481                 p.save()
482-                print "Added permission '%r'." % p
483+                print style.OK("Added permission '%r'." % p)
484                 num_added += 1
485     if not num_added:
486-        print "No permissions were added, because all necessary permissions were already installed."
487+        print style.OK("No permissions were added, because all necessary permissions were already installed.")
488 installperms.help_doc = "Installs any permissions for the given model module name(s), if needed."
489 installperms.args = APP_ARGS
490 
491 def _start_helper(app_or_project, name, directory, other_name=''):
492     other = {'project': 'app', 'app': 'project'}[app_or_project]
493     if not _is_valid_dir_name(name):
494-        sys.stderr.write("Error: %r is not a valid %s name. Please use only numbers, letters and underscores.\n" % (name, app_or_project))
495+        sys.stderr.write(J(style.ERROR("Error: %r is not a valid %s name. Please use only numbers, letters and underscores."),"\n") % (name, app_or_project))
496         sys.exit(1)
497     top_dir = os.path.join(directory, name)
498     try:
499         os.mkdir(top_dir)
500     except OSError, e:
501-        sys.stderr.write("Error: %s\n" % e)
502+        sys.stderr.write(J(style.ERROR("Error: %s"),"\n") % e)
503         sys.exit(1)
504     template_dir = PROJECT_TEMPLATE_DIR % app_or_project
505     for d, subdirs, files in os.walk(template_dir):
506@@ -489,7 +595,7 @@
507     "Creates a Django project for the given project_name in the given directory."
508     from random import choice
509     if project_name in INVALID_PROJECT_NAMES:
510-        sys.stderr.write("Error: %r isn't a valid project name. Please try another.\n" % project_name)
511+        sys.stderr.write(J(style.ERROR("Error: %r isn't a valid project name. Please try another."),"\n") % project_name)
512         sys.exit(1)
513     _start_helper('project', project_name, directory)
514     # Create a random SECRET_KEY hash, and put it in the main settings.
515@@ -523,14 +629,14 @@
516             if not username:
517                 username = raw_input('Username (only letters, digits and underscores): ')
518             if not username.isalnum():
519-                sys.stderr.write("Error: That username is invalid.\n")
520+                sys.stderr.write(J(style.ERROR("Error: That username is invalid."),"\n"))
521                 username = None
522             try:
523                 users.get_object(username__exact=username)
524             except users.UserDoesNotExist:
525                 break
526             else:
527-                sys.stderr.write("Error: That username is already taken.\n")
528+                sys.stderr.write(J(style.ERROR("Error: That username is already taken."),"\n"))
529                 username = None
530         while 1:
531             if not email:
532@@ -538,7 +644,7 @@
533             try:
534                 validators.isValidEmail(email, None)
535             except validators.ValidationError:
536-                sys.stderr.write("Error: That e-mail address is invalid.\n")
537+                sys.stderr.write(J(style.ERROR("Error: That e-mail address is invalid."),"\n"))
538                 email = None
539             else:
540                 break
541@@ -547,23 +653,23 @@
542                 password = getpass.getpass()
543                 password2 = getpass.getpass('Password (again): ')
544                 if password != password2:
545-                    sys.stderr.write("Error: Your passwords didn't match.\n")
546+                    sys.stderr.write(J(style.ERROR("Error: Your passwords didn't match."),"\n"))
547                     password = None
548                     continue
549             if password.strip() == '':
550-                sys.stderr.write("Error: Blank passwords aren't allowed.\n")
551+                sys.stderr.write(J(style.ERROR("Error: Blank passwords aren't allowed."),"\n"))
552                 password = None
553                 continue
554             break
555     except KeyboardInterrupt:
556-        sys.stderr.write("\nOperation cancelled.\n")
557+        sys.stderr.write(J('\n',style.ERROR("Operation cancelled."),'\n'))
558         sys.exit(1)
559     u = users.create_user(username, email, password)
560     u.is_staff = True
561     u.is_active = True
562     u.is_superuser = True
563     u.save()
564-    print "User created successfully."
565+    print style.OK("User created successfully.")
566 createsuperuser.args = '[username] [email] [password] (Either all or none)'
567 
568 def inspectdb(db_name):
569@@ -798,14 +904,15 @@
570     if not addr:
571         addr = '127.0.0.1'
572     if not port.isdigit():
573-        sys.stderr.write("Error: %r is not a valid port number.\n" % port)
574+        sys.stderr.write(style.ERROR("Error: %r is not a valid port number.\n" % port))
575         sys.exit(1)
576     def inner_run():
577         from django.conf.settings import SETTINGS_MODULE
578         print "Validating models..."
579         validate()
580-        print "\nDjango version %s, using settings %r" % (get_version(), SETTINGS_MODULE)
581-        print "Development server is running at http://%s:%s/" % (addr, port)
582+        print
583+        print style.OK("Django version %s, using settings %r") % (get_version(), SETTINGS_MODULE)
584+        print style.OK("Development server is running at http://%s:%s/" % (addr, port))
585         print "Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows)."
586         try:
587             run(addr, int(port), AdminMediaHandler(WSGIHandler()))
588@@ -820,7 +927,7 @@
589                 error_text = ERRORS[e.args[0].args[0]]
590             except (AttributeError, KeyError):
591                 error_text = str(e)
592-            sys.stderr.write("Error: %s\n" % error_text)
593+            sys.stderr.write(style.ERROR("Error: %s\n" % error_text))
594             sys.exit(1)
595         except KeyboardInterrupt:
596             sys.exit(0)
597@@ -925,7 +1032,7 @@
598     return '\n'.join(usage[:-1]) # Cut off last list element, an empty space.
599 
600 def print_error(msg, cmd):
601-    sys.stderr.write('Error: %s\nRun "%s --help" for help.\n' % (msg, cmd))
602+    sys.stderr.write(J(style.ERROR('Error: %s'),'\n',style.ERROR_OUTPUT('Run "%s --help" for help.'),'\n') % (msg, cmd))
603     sys.exit(1)
604 
605 def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING):
606@@ -968,7 +1075,7 @@
607             if len(args) == 1: # We got no arguments, just the action.
608                 action_mapping[action]()
609             else:
610-                sys.stderr.write("Error: %r requires arguments of 'username email password' or no argument at all.\n")
611+                sys.stderr.write(J(style.ERROR("Error: %r requires arguments of 'username email password' or no argument at all."),"\n"))
612                 sys.exit(1)
613         else:
614             action_mapping[action](username, email, password)
615@@ -985,7 +1092,7 @@
616             for line in action_mapping[action](param):
617                 print line
618         except NotImplementedError:
619-            sys.stderr.write("Error: %r isn't supported for the currently selected database backend.\n" % action)
620+            sys.stderr.write(J(style.ERROR("Error: %r isn't supported for the currently selected database backend."),"\n") % action)
621             sys.exit(1)
622     elif action == 'createcachetable':
623         try:
624@@ -1016,18 +1123,18 @@
625             try:
626                 mod_list = [meta.get_app(app_label) for app_label in args[1:]]
627             except ImportError, e:
628-                sys.stderr.write("Error: %s. Are you sure your INSTALLED_APPS setting is correct?\n" % e)
629+                sys.stderr.write(J(style.ERROR("Error: %s. Are you sure your INSTALLED_APPS setting is correct?"),"\n") % e)
630                 sys.exit(1)
631             if not mod_list:
632                 parser.print_usage_and_exit()
633         if action not in NO_SQL_TRANSACTION:
634-            print "BEGIN;"
635+            print J(style.SQL_TRANS("BEGIN"), ';')
636         for mod in mod_list:
637             output = action_mapping[action](mod)
638             if output:
639                 print '\n'.join(output)
640         if action not in NO_SQL_TRANSACTION:
641-            print "COMMIT;"
642+            print J(style.SQL_TRANS("COMMIT"),';')
643 
644 def execute_manager(settings_mod):
645     # Add this project to sys.path so that it's importable in the conventional