You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by jo...@apache.org on 2014/01/10 22:22:58 UTC

[02/36] PEP8 cleanup

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/000-fix-tracker-fields.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/000-fix-tracker-fields.py b/scripts/migrations/000-fix-tracker-fields.py
index d9911c3..fc9d77a 100644
--- a/scripts/migrations/000-fix-tracker-fields.py
+++ b/scripts/migrations/000-fix-tracker-fields.py
@@ -28,19 +28,25 @@ from forgetracker import model as TM
 
 log = logging.getLogger(__name__)
 
+
 def main():
     test = sys.argv[-1] == 'test'
     projects = M.Project.query.find().all()
     log.info('Fixing tracker fields')
     for p in projects:
-        if p.parent_id: continue
+        if p.parent_id:
+            continue
         c.project = p
         q = TM.Globals.query.find()
-        if not q.count(): continue
+        if not q.count():
+            continue
         for g in q:
-            if g.open_status_names: continue
-            if g.status_names is None: old_names = ['open', 'closed']
-            else: old_names = g.status_names.split() or ['open', 'closed']
+            if g.open_status_names:
+                continue
+            if g.status_names is None:
+                old_names = ['open', 'closed']
+            else:
+                old_names = g.status_names.split() or ['open', 'closed']
             if g.open_status_names is None:
                 g.open_status_names = ' '.join(
                     name for name in old_names if name != 'closed')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/001-restore-labels.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/001-restore-labels.py b/scripts/migrations/001-restore-labels.py
index 92814c9..ef68c09 100644
--- a/scripts/migrations/001-restore-labels.py
+++ b/scripts/migrations/001-restore-labels.py
@@ -27,6 +27,7 @@ from allura import model as M
 
 log = logging.getLogger(__name__)
 
+
 def main():
     test = sys.argv[-1] == 'test'
     projects = M.Project.query.find().all()
@@ -37,25 +38,33 @@ def main():
         session(p).flush()
     log.info('Restoring labels on artifacts')
     for p in projects:
-        if p.parent_id: continue
+        if p.parent_id:
+            continue
         c.project = p
         for name, cls in MappedClass._registry.iteritems():
-            if not issubclass(cls, M.Artifact): continue
-            if session(cls) is None: continue
+            if not issubclass(cls, M.Artifact):
+                continue
+            if session(cls) is None:
+                continue
             for a in cls.query.find():
                 restore_labels(a, test)
         if not test:
             M.artifact_orm_session.flush()
         M.artifact_orm_session.clear()
 
+
 def restore_labels(obj, test=True):
-    if not obj.labels: return
+    if not obj.labels:
+        return
     labels = obj.labels
     while True:
-        if not labels or labels[0] != '[': return
+        if not labels or labels[0] != '[':
+            return
         lbllen = map(len, labels)
-        if max(lbllen) != 1: return
-        if min(lbllen) != 1: return
+        if max(lbllen) != 1:
+            return
+        if min(lbllen) != 1:
+            return
         s = ''.join(labels)
         s = s.replace("u'", "'")
         s = s.replace('u"', '"')
@@ -65,13 +74,15 @@ def restore_labels(obj, test=True):
         except ValueError:
             # some weird problem with json decoding, just erase the labels
             new_labels = []
-        if not isinstance(new_labels, list): return
+        if not isinstance(new_labels, list):
+            return
         for lbl in new_labels:
-            if not isinstance(lbl, basestring): return
+            if not isinstance(lbl, basestring):
+                return
         log.info('%s: %s => %s', obj.__class__, labels, new_labels)
         labels = new_labels
         if not test:
-            log.info('...actually restoring labels') 
+            log.info('...actually restoring labels')
             obj.labels = new_labels
 
 if __name__ == '__main__':

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/002-fix-tracker-thread-subjects.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/002-fix-tracker-thread-subjects.py b/scripts/migrations/002-fix-tracker-thread-subjects.py
index 45824cd..81861a0 100644
--- a/scripts/migrations/002-fix-tracker-thread-subjects.py
+++ b/scripts/migrations/002-fix-tracker-thread-subjects.py
@@ -27,15 +27,19 @@ from forgetracker import model as TM
 
 log = logging.getLogger(__name__)
 
+
 def main():
     test = sys.argv[-1] == 'test'
     all_projects = M.Project.query.find().all()
     log.info('Fixing tracker thread subjects')
     for project in all_projects:
-        if project.parent_id: continue
+        if project.parent_id:
+            continue
         c.project = project
-        all_tickets = TM.Ticket.query.find() # will find all tickets for all trackers in this project
-        if not all_tickets.count(): continue
+        # will find all tickets for all trackers in this project
+        all_tickets = TM.Ticket.query.find()
+        if not all_tickets.count():
+            continue
         for ticket in all_tickets:
             thread = ticket.get_discussion_thread()
             thread.subject = ''

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/003-migrate_project_roles.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/003-migrate_project_roles.py b/scripts/migrations/003-migrate_project_roles.py
index 580f93f..32bcc57 100644
--- a/scripts/migrations/003-migrate_project_roles.py
+++ b/scripts/migrations/003-migrate_project_roles.py
@@ -24,7 +24,8 @@ from allura import model as M
 
 log = logging.getLogger(__name__)
 
-log.info('Moving project roles in database %s to main DB', M.Project.database_uri())
+log.info('Moving project roles in database %s to main DB',
+         M.Project.database_uri())
 for opr in M.OldProjectRole.query.find():
     pr = M.ProjectRole(**state(opr).document)
 session(opr).clear()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/004-make-attachments-polymorphic.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/004-make-attachments-polymorphic.py b/scripts/migrations/004-make-attachments-polymorphic.py
index 0c34d58..e6133ec 100644
--- a/scripts/migrations/004-make-attachments-polymorphic.py
+++ b/scripts/migrations/004-make-attachments-polymorphic.py
@@ -25,6 +25,7 @@ from forgediscussion import model as DM
 
 log = logging.getLogger(__name__)
 
+
 def main():
     db = M.project_doc_session.db
     log.info('=== Making attachments in %s polymorphic ===', db)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/005-remove_duplicate_ticket_notifications.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/005-remove_duplicate_ticket_notifications.py b/scripts/migrations/005-remove_duplicate_ticket_notifications.py
index ba6f04c..716c604 100644
--- a/scripts/migrations/005-remove_duplicate_ticket_notifications.py
+++ b/scripts/migrations/005-remove_duplicate_ticket_notifications.py
@@ -29,6 +29,8 @@ log = logging.getLogger(__name__)
 
 # Given a list of subscriptions, try to find one with a proper artifact_url, and delete the rest
 # If none of them have artifact_urls, delete them all
+
+
 def trim_subs(subs, test):
     prime = False
 
@@ -42,22 +44,25 @@ def trim_subs(subs, test):
                 print "   Found subscription with no artifact URL, deleting."
             else:
                 print "   Subscription has URL, but is a duplicate, deleting."
-            if not test: sub.delete()
+            if not test:
+                sub.delete()
 
 
 def main():
     test = sys.argv[-1] == 'test'
     title = re.compile('Ticket .*')
-    all_subscriptions = M.Mailbox.query.find(dict(artifact_title=title, type='direct')).sort([ ('artifact_title', pymongo.ASCENDING), ('user_id', pymongo.DESCENDING) ]).all()
+    all_subscriptions = M.Mailbox.query.find(dict(artifact_title=title, type='direct')).sort(
+        [('artifact_title', pymongo.ASCENDING), ('user_id', pymongo.DESCENDING)]).all()
     log.info('Fixing duplicate tracker subscriptions')
 
     for (key, group) in groupby(
-        all_subscriptions,
-        key=lambda sub:(sub.artifact_title, sub.user_id)):
+            all_subscriptions,
+            key=lambda sub: (sub.artifact_title, sub.user_id)):
         group = list(group)
         if group:
             trim_subs(group, test)
-    if not test: ThreadLocalORMSession.flush_all()
+    if not test:
+        ThreadLocalORMSession.flush_all()
 
 
 if __name__ == '__main__':

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/006-migrate-artifact-refs.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/006-migrate-artifact-refs.py b/scripts/migrations/006-migrate-artifact-refs.py
index dc9149c..aeae677 100644
--- a/scripts/migrations/006-migrate-artifact-refs.py
+++ b/scripts/migrations/006-migrate-artifact-refs.py
@@ -24,13 +24,16 @@ from allura import model as M
 log = logging.getLogger('allura.migrate-artifact-refs')
 
 # Threads have artifact references that must be migrated to the new system
+
+
 def main():
     test = sys.argv[-1] == 'test'
     log.info('Fixing artifact references in threads')
     db = M.project_doc_session.db
     for thread in db.thread.find():
         ref = thread.pop('artifact_reference', None)
-        if ref is None: continue
+        if ref is None:
+            continue
         Artifact = loads(ref['artifact_type'])
         artifact = Artifact.query.get(_id=ref['artifact_id'])
         M.ArtifactReference.from_artifact(artifact)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/007-update-acls.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/007-update-acls.py b/scripts/migrations/007-update-acls.py
index 16e28a8..0f97ee1 100644
--- a/scripts/migrations/007-update-acls.py
+++ b/scripts/migrations/007-update-acls.py
@@ -29,12 +29,13 @@ from allura.command.show_models import dfs, build_model_inheritance_graph
 log = logging.getLogger('update-acls')
 
 options = None
-optparser = OptionParser(usage='allurapaste script <ini file> -- %prog [options] [neighborhood1...]')
+optparser = OptionParser(
+    usage='allurapaste script <ini file> -- %prog [options] [neighborhood1...]')
 optparser.add_option('-t', '--test',  dest='test', action='store_true')
 
 main_db = M.main_doc_session.db
-c_neighborhood =  main_db.neighborhood
-c_project =  main_db.project
+c_neighborhood = main_db.neighborhood
+c_project = main_db.project
 c_user = main_db.user
 c_project_role = main_db.project_role
 c.project = Object(
@@ -43,16 +44,20 @@ c.project = Object(
 project_db = M.project_doc_session.db
 c_app_config = project_db.config
 
+
 def main():
     global options
     options, neighborhoods = optparser.parse_args()
     if neighborhoods:
         log.info('Updating neighborhoods: %s', neighborhoods)
-        q_neighborhoods = list(c_neighborhood.find(dict(name={'$in': neighborhoods })))
-        neighborhood_ids=[ n['_id'] for n in q_neighborhoods ]
-        q_projects = list(c_project.find(dict(neighborhood_id={'$in': neighborhood_ids})))
+        q_neighborhoods = list(
+            c_neighborhood.find(dict(name={'$in': neighborhoods})))
+        neighborhood_ids = [n['_id'] for n in q_neighborhoods]
+        q_projects = list(
+            c_project.find(dict(neighborhood_id={'$in': neighborhood_ids})))
         project_ids = list(p['_id'] for p in q_projects)
-        q_app_config = list(c_app_config.find(dict(project_id={'$in': project_ids})))
+        q_app_config = list(
+            c_app_config.find(dict(project_id={'$in': project_ids})))
         log.info('... %d neighborhoods', len(q_neighborhoods))
         log.info('... %d projects', len(q_projects))
         log.info('... %d app configs', len(q_app_config))
@@ -66,14 +71,15 @@ def main():
     log.info('Update project ACLs')
     for p in q_projects:
         update_project_acl(p)
-        if not options.test: c_project.save(p)
+        if not options.test:
+            c_project.save(p)
     # Update neighborhood acls
     log.info('====================================')
     log.info('Update neighborhood ACLs')
     for n in q_neighborhoods:
         p = c_project.find(dict(
-                neighborhood_id=n['_id'], shortname='--init--')).next()
-        update_neighborhood_acl(n,p)
+            neighborhood_id=n['_id'], shortname='--init--')).next()
+        update_neighborhood_acl(n, p)
         if not options.test:
             c_neighborhood.save(n)
             c_project.save(p)
@@ -83,7 +89,8 @@ def main():
     log.info('Update appconfig ACLs')
     for ac in q_app_config:
         simple_acl_update(ac, 'app_config')
-        if not options.test: c_app_config.save(ac)
+        if not options.test:
+            c_app_config.save(ac)
         # Update artifact acls
         log.info('====================================')
         log.info('Update artifact ACLs for %s', ac['_id'])
@@ -92,7 +99,9 @@ def main():
             for a in c_artifact.find(dict(app_config_id=ac['_id'])):
                 empty_acl = a['acl'] == []
                 simple_acl_update(a, a_cls.__mongometa__.name)
-                if not options.test and not empty_acl: c_artifact.save(a)
+                if not options.test and not empty_acl:
+                    c_artifact.save(a)
+
 
 def update_project_acl(project_doc):
     '''Convert the old dict-style ACL to a list of ALLOW ACEs. Also move the
@@ -112,7 +121,8 @@ def update_project_acl(project_doc):
     for perm, role_ids in sorted(project_doc['acl'].iteritems()):
         perm = perm_map[perm]
         for rid in role_ids:
-            if c_project_role.find(dict(_id=rid)).count() == 0: continue
+            if c_project_role.find(dict(_id=rid)).count() == 0:
+                continue
             _grant(new_acl, perm, rid)
     if options.test:
         log.info('--- update %s\n%s\n%s\n---',
@@ -121,34 +131,38 @@ def update_project_acl(project_doc):
                  pformat(map(_format_ace, new_acl)))
     project_doc['acl'] = new_acl
 
+
 def update_neighborhood_acl(neighborhood_doc, init_doc):
     '''Convert nbhd admins users to --init-- project admins'''
-    if options.test: log.info('Update nbhd %s', neighborhood_doc['name'])
+    if options.test:
+        log.info('Update nbhd %s', neighborhood_doc['name'])
     if 'acl' not in neighborhood_doc:
-        log.warning('Neighborhood %s already updated', neighborhood_doc['name'])
+        log.warning('Neighborhood %s already updated',
+                    neighborhood_doc['name'])
         return
     p = Object(init_doc)
-    p.root_project=p
+    p.root_project = p
     r_anon = _project_role(init_doc['_id'], '*anonymous')
     r_auth = _project_role(init_doc['_id'], '*authenticated')
     r_admin = _project_role(init_doc['_id'], 'Admin')
     acl = neighborhood_doc['acl']
     new_acl = list(init_doc['acl'])
-    assert acl['read'] == [None] # nbhd should be public
+    assert acl['read'] == [None]  # nbhd should be public
     for uid in acl['admin'] + acl['moderate']:
         u = c_user.find(dict(_id=uid)).next()
         if options.test:
             log.info('... grant nbhd admin to: %s', u['username'])
             continue
-        role =  _project_role(init_doc['_id'], user_id=uid)
+        role = _project_role(init_doc['_id'], user_id=uid)
         if r_admin['_id'] not in role['roles']:
             role['roles'].append(r_admin['_id'])
             c_project_role.save(role)
     _grant(new_acl, 'read', r_anon['_id'])
     _grant(new_acl, 'admin', r_admin['_id'])
     _grant(new_acl, 'register', r_admin['_id'])
-    if acl['create'] == [ ]:
-        if options.test: log.info('grant register to auth')
+    if acl['create'] == []:
+        if options.test:
+            log.info('grant register to auth')
         _grant(new_acl, 'register', r_auth['_id'])
     del neighborhood_doc['acl']
     if options.test:
@@ -157,6 +171,7 @@ def update_neighborhood_acl(neighborhood_doc, init_doc):
                  pformat(map(_format_ace, new_acl)))
     init_doc['acl'] = new_acl
 
+
 def _project_role(project_id, name=None, user_id=None):
     doc = dict(project_id=project_id)
     if name:
@@ -190,6 +205,7 @@ def simple_acl_update(doc, collection_name):
                  pformat(map(_format_ace, new_acl)))
     doc['acl'] = new_acl
 
+
 def _grant(acl, permission, role_id):
     ace = dict(
         access='ALLOW',
@@ -198,11 +214,14 @@ def _grant(acl, permission, role_id):
     if ace not in acl:
         acl.append(ace)
 
+
 def _format_ace(ace):
-    if isinstance(ace, basestring): return ace
+    if isinstance(ace, basestring):
+        return ace
     return '(%s, %s, %s)' % (
         ace['access'], ace['permission'], _format_role(ace['role_id']))
 
+
 def _format_role(rid):
     for role in c_project_role.find(dict(_id=rid)):
         if role['name']:
@@ -213,10 +232,11 @@ def _format_role(rid):
         break
     return '--invalid--'
 
+
 def _format_acd(acd):
     return dict(
         (k, map(_format_role, v))
-        for k,v in acd.iteritems())
+        for k, v in acd.iteritems())
 
 if __name__ == '__main__':
     main()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/008-remove-forumpost-subject.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/008-remove-forumpost-subject.py b/scripts/migrations/008-remove-forumpost-subject.py
index ae91511..892eb61 100644
--- a/scripts/migrations/008-remove-forumpost-subject.py
+++ b/scripts/migrations/008-remove-forumpost-subject.py
@@ -31,6 +31,7 @@ log = logging.getLogger(__name__)
 
 c_forumpost = M.project_doc_session.db.forum_post
 
+
 def main():
     test = sys.argv[-1] == 'test'
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/010-fix-home-permissions.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/010-fix-home-permissions.py b/scripts/migrations/010-fix-home-permissions.py
index f4fb852..4506a17 100644
--- a/scripts/migrations/010-fix-home-permissions.py
+++ b/scripts/migrations/010-fix-home-permissions.py
@@ -33,6 +33,7 @@ log.addHandler(handler)
 
 TEST = sys.argv[-1].lower() == 'test'
 
+
 def main():
 
     if TEST:
@@ -41,15 +42,17 @@ def main():
         log.info('Fixing permissions for all Home Wikis')
 
     for some_projects in utils.chunked_find(M.Project, {'neighborhood_id': {
-                '$nin': [ObjectId('4be2faf8898e33156f00003e'),      # /u
-                         ObjectId('4dbf2563bfc09e6362000005')]}}):  # /motorola
+        '$nin': [ObjectId('4be2faf8898e33156f00003e'),      # /u
+                 ObjectId('4dbf2563bfc09e6362000005')]}}):  # /motorola
         for project in some_projects:
             c.project = project
             home_app = project.app_instance('home')
             if isinstance(home_app, ForgeWikiApp):
-                log.info('Examining permissions in project "%s".' % project.shortname)
+                log.info('Examining permissions in project "%s".' %
+                         project.shortname)
                 root_project = project.root_project or project
-                authenticated_role = project_role(root_project, '*authenticated')
+                authenticated_role = project_role(
+                    root_project, '*authenticated')
                 member_role = project_role(root_project, 'Member')
 
                 # remove *authenticated create/update permissions
@@ -57,24 +60,32 @@ def main():
                     ((ace.role_id, ace.access, ace.permission), ace)
                     for ace in home_app.acl
                     if not (
-                        ace.role_id==authenticated_role._id and ace.access==M.ACE.ALLOW and ace.permission in ('create', 'edit', 'delete', 'unmoderated_post')
+                        ace.role_id == authenticated_role._id and ace.access == M.ACE.ALLOW and ace.permission in (
+                            'create', 'edit', 'delete', 'unmoderated_post')
                     )
                 )
                 if (member_role._id, M.ACE.ALLOW, 'update') in new_acl:
                     del new_acl[(member_role._id, M.ACE.ALLOW, 'update')]
 
                 # add member create/edit permissions
-                new_acl[(member_role._id, M.ACE.ALLOW, 'create')] = M.ACE.allow(member_role._id, 'create')
-                new_acl[(member_role._id, M.ACE.ALLOW, 'edit')] = M.ACE.allow(member_role._id, 'edit')
-                new_acl[(member_role._id, M.ACE.ALLOW, 'unmoderated_post')] = M.ACE.allow(member_role._id, 'unmoderated_post')
+                new_acl[(member_role._id, M.ACE.ALLOW, 'create')
+                        ] = M.ACE.allow(member_role._id, 'create')
+                new_acl[(member_role._id, M.ACE.ALLOW, 'edit')
+                        ] = M.ACE.allow(member_role._id, 'edit')
+                new_acl[(member_role._id, M.ACE.ALLOW, 'unmoderated_post')] = M.ACE.allow(
+                    member_role._id, 'unmoderated_post')
 
                 if TEST:
-                    log.info('...would update acl for home app in project "%s".' % project.shortname)
+                    log.info(
+                        '...would update acl for home app in project "%s".' %
+                        project.shortname)
                 else:
-                    log.info('...updating acl for home app in project "%s".' % project.shortname)
+                    log.info('...updating acl for home app in project "%s".' %
+                             project.shortname)
                     home_app.config.acl = map(dict, new_acl.values())
                     session(home_app.config).flush()
 
+
 def project_role(project, name):
     role = M.ProjectRole.query.get(project_id=project._id, name=name)
     if role is None:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/011-fix-subroles.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/011-fix-subroles.py b/scripts/migrations/011-fix-subroles.py
index 4da0129..cb63c6b 100644
--- a/scripts/migrations/011-fix-subroles.py
+++ b/scripts/migrations/011-fix-subroles.py
@@ -38,15 +38,17 @@ from allura.lib import utils
 log = logging.getLogger('fix-subroles')
 log.addHandler(logging.StreamHandler(sys.stdout))
 
+
 def main():
     test = sys.argv[-1] == 'test'
     num_projects_examined = 0
     log.info('Examining subroles in all non-user projects.')
     n_users = M.Neighborhood.query.get(name='Users')
-    project_filter = dict(neighborhood_id={'$ne':n_users._id})
+    project_filter = dict(neighborhood_id={'$ne': n_users._id})
     for some_projects in utils.chunked_find(M.Project, project_filter):
         for project in some_projects:
-            project_name = '%s.%s' % (project.neighborhood.name, project.shortname)
+            project_name = '%s.%s' % (
+                project.neighborhood.name, project.shortname)
             project_roles = {}
             for parent, child in [('Admin', 'Developer'), ('Developer', 'Member')]:
                 parent_role = M.ProjectRole.by_name(parent, project=project)
@@ -57,31 +59,38 @@ def main():
                     break
                 if len(parent_role.roles) != 1 or parent_role.roles[0] != child_role._id:
                     if test:
-                        log.info('Would reset %s subroles for project "%s".' % (parent, project_name))
-                        log.info('- Existing %s subrole(s): %s' % (parent, parent_role.roles))
+                        log.info('Would reset %s subroles for project "%s".' %
+                                 (parent, project_name))
+                        log.info('- Existing %s subrole(s): %s' %
+                                 (parent, parent_role.roles))
                     else:
-                        log.info('Resetting %s subroles for project "%s".' % (parent, project_name))
+                        log.info('Resetting %s subroles for project "%s".' %
+                                 (parent, project_name))
                         parent_role.roles = [child_role._id]
                         ThreadLocalORMSession.flush_all()
-            if not (project_roles['Admin'] and project_roles['Developer'] \
-                and project_roles['Member']):
-                log.info('Skipping "%s": missing Admin, Developer, or Member roles' % project_name)
+            if not (project_roles['Admin'] and project_roles['Developer']
+                    and project_roles['Member']):
+                log.info(
+                    'Skipping "%s": missing Admin, Developer, or Member roles' %
+                    project_name)
                 continue
             for user in project.users():
                 pr = user.project_role(project=project)
-                if not pr.roles: continue
+                if not pr.roles:
+                    continue
                 for parent, children in [('Admin', ('Developer', 'Member')),
                                          ('Developer', ('Member',))]:
-                    if project_roles[parent]._id not in pr.roles: continue
+                    if project_roles[parent]._id not in pr.roles:
+                        continue
                     for role_name in children:
                         extra_role = project_roles[role_name]
                         if extra_role._id in pr.roles:
                             if test:
-                                log.info('Would remove %s role from user "%s" in project "%s" (already has %s role).' \
+                                log.info('Would remove %s role from user "%s" in project "%s" (already has %s role).'
                                          % (role_name, user.username, project_name, parent))
                                 pr.roles.remove(extra_role._id)
                             else:
-                                log.info('Removing %s role from user "%s" in project "%s" (already has %s role).' \
+                                log.info('Removing %s role from user "%s" in project "%s" (already has %s role).'
                                          % (role_name, user.username, project_name, parent))
                                 pr.roles.remove(extra_role._id)
                                 ThreadLocalORMSession.flush_all()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/012-uninstall-home.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/012-uninstall-home.py b/scripts/migrations/012-uninstall-home.py
index 46ebc9b..c59fdb2 100644
--- a/scripts/migrations/012-uninstall-home.py
+++ b/scripts/migrations/012-uninstall-home.py
@@ -32,6 +32,7 @@ from allura.ext.project_home import ProjectHomeApp
 log = logging.getLogger('uninstall-home')
 log.addHandler(logging.StreamHandler(sys.stdout))
 
+
 def main():
     test = sys.argv[-1] == 'test'
     log.info('Removing "home" tools')
@@ -48,7 +49,8 @@ def main():
 
                 # would we actually be able to install a wiki?
                 if M.ProjectRole.by_name('Admin') is None:
-                    log.warning('project %s may be orphaned' % project.shortname)
+                    log.warning('project %s may be orphaned' %
+                                project.shortname)
                     possibly_orphaned_projects += 1
                     continue
 
@@ -56,17 +58,21 @@ def main():
 
                 # remove the existing home tool
                 if test:
-                    log.info('would remove "home" tool from project ' + project.shortname)
+                    log.info('would remove "home" tool from project ' +
+                             project.shortname)
                 else:
-                    log.info('removing "home" tool from project ' + project.shortname)
+                    log.info('removing "home" tool from project ' +
+                             project.shortname)
                     with patch('allura.app.g.solr.delete', solr_delete):
                         project.uninstall_app('home')
 
                 # ...and put a Wiki in its place (note we only create a Wiki if we deleted the old home)
                 if test:
-                    log.info('would create Wiki "home" for project ' + project.shortname)
+                    log.info('would create Wiki "home" for project ' +
+                             project.shortname)
                 else:
-                    log.info('creating Wiki "home" for project ' + project.shortname)
+                    log.info('creating Wiki "home" for project ' +
+                             project.shortname)
                     home_title = project.homepage_title or 'Home'
                     wiki_text = project.description or ''
                     if wiki_text == 'You can edit this description in the admin page':
@@ -75,8 +81,10 @@ def main():
                     # re-number all the mounts so the new Wiki comes first
                     mounts = project.ordered_mounts()
                     with patch('forgewiki.model.wiki.Notification.post', notification_post):
-                        new_home_app = project.install_app('Wiki', 'home', 'Home')
-                    mounts = [{'ordinal':0, 'ac':new_home_app.config}] + mounts
+                        new_home_app = project.install_app(
+                            'Wiki', 'home', 'Home')
+                    mounts = [{'ordinal': 0, 'ac': new_home_app.config}] + \
+                        mounts
                     for i, mount in enumerate(mounts):
                         if 'ac' in mount:
                             mount['ac'].options['ordinal'] = i
@@ -91,11 +99,14 @@ def main():
 
                     # now let's fix the home page itself
                     log.info('updating home page to "%s"' % home_title)
-                    new_home_page = WM.Page.query.find(dict(app_config_id=new_home_app.config._id)).first()
+                    new_home_page = WM.Page.query.find(
+                        dict(app_config_id=new_home_app.config._id)).first()
                     with h.push_config(c, app=new_home_app):
                         if new_home_page is None:
                             # weird: we didn't find the existing home page
-                            log.warning('hmmm, actually creating the home page ("%s") for project "%s" from scratch' % (home_title, project.shortname))
+                            log.warning(
+                                'hmmm, actually creating the home page ("%s") for project "%s" from scratch' %
+                                (home_title, project.shortname))
                             new_home_page = WM.Page.upsert(home_title)
                             new_home_page.viewable_by = ['all']
                         new_home_page.title = home_title
@@ -106,7 +117,8 @@ def main():
                     assert new_home_page.title == home_title
                     assert new_home_page.version == 2
 
-                    # if we changed the home page name, make sure the Wiki knows that's the root page
+                    # if we changed the home page name, make sure the Wiki
+                    # knows that's the root page
                     new_home_app.root_page_name = home_title
 
                 session(project).flush()
@@ -116,10 +128,12 @@ def main():
     else:
         log.info('%s projects were updated' % affected_projects)
     if possibly_orphaned_projects:
-        log.warning('%s possibly orphaned projects found' % possibly_orphaned_projects)
+        log.warning('%s possibly orphaned projects found' %
+                    possibly_orphaned_projects)
     if not test:
         assert solr_delete.call_count == affected_projects, solr_delete.call_count
-        assert notification_post.call_count == 2 * affected_projects, notification_post.call_count
+        assert notification_post.call_count == 2 * \
+            affected_projects, notification_post.call_count
 
 if __name__ == '__main__':
     main()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/013-update-ordinals.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/013-update-ordinals.py b/scripts/migrations/013-update-ordinals.py
index 1ddef2e..f26f112 100644
--- a/scripts/migrations/013-update-ordinals.py
+++ b/scripts/migrations/013-update-ordinals.py
@@ -28,6 +28,7 @@ from allura.lib import utils
 log = logging.getLogger('update-ordinals')
 log.addHandler(logging.StreamHandler(sys.stdout))
 
+
 def main():
     test = sys.argv[-1] == 'test'
     num_projects_examined = 0
@@ -37,7 +38,8 @@ def main():
             c.project = project
             mounts = project.ordered_mounts(include_hidden=True)
 
-            # ordered_mounts() means duplicate ordinals (if any) will be next to each other
+            # ordered_mounts() means duplicate ordinals (if any) will be next
+            # to each other
             duplicates_found = False
             prev_ordinal = None
             for mount in mounts:
@@ -48,9 +50,11 @@ def main():
 
             if duplicates_found:
                 if test:
-                    log.info('Would renumber mounts for project "%s".' % project.shortname)
+                    log.info('Would renumber mounts for project "%s".' %
+                             project.shortname)
                 else:
-                    log.info('Renumbering mounts for project "%s".' % project.shortname)
+                    log.info('Renumbering mounts for project "%s".' %
+                             project.shortname)
                     for i, mount in enumerate(mounts):
                         if 'ac' in mount:
                             mount['ac'].options['ordinal'] = i

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/015-add-neighborhood_id-to-blog-posts.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/015-add-neighborhood_id-to-blog-posts.py b/scripts/migrations/015-add-neighborhood_id-to-blog-posts.py
index b0fd9f5..48b0deb 100644
--- a/scripts/migrations/015-add-neighborhood_id-to-blog-posts.py
+++ b/scripts/migrations/015-add-neighborhood_id-to-blog-posts.py
@@ -26,6 +26,7 @@ from forgeblog import model as BM
 
 log = logging.getLogger(__name__)
 
+
 def main():
     broken_posts = BM.BlogPost.query.find(dict(neighborhood_id=None)).all()
     for post in broken_posts:
@@ -36,4 +37,4 @@ def main():
     ThreadLocalORMSession.close_all()
 
 if __name__ == '__main__':
-    main()
\ No newline at end of file
+    main()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/018-add-svn-checkout-url.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/018-add-svn-checkout-url.py b/scripts/migrations/018-add-svn-checkout-url.py
index 3656f0b..2a5469c 100644
--- a/scripts/migrations/018-add-svn-checkout-url.py
+++ b/scripts/migrations/018-add-svn-checkout-url.py
@@ -20,5 +20,5 @@ from ming.orm import ThreadLocalORMSession
 
 for app in M.AppConfig.query.find(dict(tool_name="svn")).all():
     if 'checkout_url' not in app.options:
-        app.options.checkout_url='trunk'
+        app.options.checkout_url = 'trunk'
     ThreadLocalORMSession.flush_all()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/020-remove-wiki-title-slashes.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/020-remove-wiki-title-slashes.py b/scripts/migrations/020-remove-wiki-title-slashes.py
index 27df1a9..34db4ce 100644
--- a/scripts/migrations/020-remove-wiki-title-slashes.py
+++ b/scripts/migrations/020-remove-wiki-title-slashes.py
@@ -25,6 +25,7 @@ from forgewiki import model as WM
 
 log = logging.getLogger(__name__)
 
+
 def main():
     c.project = None
     pages = WM.Page.query.find({'title': {'$regex': '\/'}}).all()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/022-change-anon-display-name.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/022-change-anon-display-name.py b/scripts/migrations/022-change-anon-display-name.py
index 0bae22e..dbe9911 100644
--- a/scripts/migrations/022-change-anon-display-name.py
+++ b/scripts/migrations/022-change-anon-display-name.py
@@ -18,6 +18,7 @@
 from ming.orm.ormsession import ThreadLocalORMSession
 from allura import model as M
 
+
 def main():
     u = M.User.query.get(username='*anonymous')
     u.display_name = 'Anonymous'
@@ -26,4 +27,4 @@ def main():
     ThreadLocalORMSession.close_all()
 
 if __name__ == '__main__':
-    main()
\ No newline at end of file
+    main()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/024-migrate-custom-profile-text.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/024-migrate-custom-profile-text.py b/scripts/migrations/024-migrate-custom-profile-text.py
index e02fc6b..b69b5f8 100644
--- a/scripts/migrations/024-migrate-custom-profile-text.py
+++ b/scripts/migrations/024-migrate-custom-profile-text.py
@@ -32,9 +32,10 @@ log = logging.getLogger(__name__)
 default_description = r'^\s*(?:You can edit this description in the admin page)?\s*$'
 
 default_personal_project_tmpl = ("This is the personal project of %s."
-            " This project is created automatically during user registration"
-            " as an easy place to store personal data that doesn't need its own"
-            " project such as cloned repositories.\n\n%s")
+                                 " This project is created automatically during user registration"
+                                 " as an easy place to store personal data that doesn't need its own"
+                                 " project such as cloned repositories.\n\n%s")
+
 
 def main():
     users = M.Neighborhood.query.get(name='Users')
@@ -53,10 +54,12 @@ def main():
                 try:
                     app = p.install_app('wiki')
                 except Exception as e:
-                    log.error("Unable to install wiki for user %s: %s" % (user.username, str(e)))
+                    log.error("Unable to install wiki for user %s: %s" %
+                              (user.username, str(e)))
                     continue
 
-            page = WM.Page.query.get(app_config_id=app.config._id, title='Home')
+            page = WM.Page.query.get(
+                app_config_id=app.config._id, title='Home')
             if page is None:
                 continue
 
@@ -67,9 +70,11 @@ def main():
             if "This is the personal project of" in page.text:
                 if description not in page.text:
                     page.text = "%s\n\n%s" % (page.text, description)
-                    log.info("Update wiki home page text for %s" % user.username)
+                    log.info("Update wiki home page text for %s" %
+                             user.username)
             elif "This is the default page" in page.text:
-                page.text = default_personal_project_tmpl % (user.display_name, description)
+                page.text = default_personal_project_tmpl % (
+                    user.display_name, description)
                 log.info("Update wiki home page text for %s" % user.username)
             else:
                 pass

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/025-add-is-nbhd-project.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/025-add-is-nbhd-project.py b/scripts/migrations/025-add-is-nbhd-project.py
index 8fc24f5..85bb07b 100644
--- a/scripts/migrations/025-add-is-nbhd-project.py
+++ b/scripts/migrations/025-add-is-nbhd-project.py
@@ -26,9 +26,12 @@ from allura import model as M
 
 log = logging.getLogger(__name__)
 
+
 def main():
-    M.Project.query.update({'shortname': '--init--'}, {'$set': {'is_nbhd_project': True}}, multi=True)
-    M.Project.query.update({'shortname': {'$ne': '--init--'}}, {'$set': {'is_nbhd_project': False}}, multi=True)
+    M.Project.query.update({'shortname': '--init--'},
+                           {'$set': {'is_nbhd_project': True}}, multi=True)
+    M.Project.query.update({'shortname': {'$ne': '--init--'}},
+                           {'$set': {'is_nbhd_project': False}}, multi=True)
 
 if __name__ == '__main__':
     main()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/026-install-activity-tool.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/026-install-activity-tool.py b/scripts/migrations/026-install-activity-tool.py
index e16973d..c7eb39f 100644
--- a/scripts/migrations/026-install-activity-tool.py
+++ b/scripts/migrations/026-install-activity-tool.py
@@ -24,6 +24,7 @@ from allura import model as M
 
 log = logging.getLogger(__name__)
 
+
 def main():
     for chunk in utils.chunked_find(M.Project):
         for p in chunk:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/027-change-ticket-write-permissions.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/027-change-ticket-write-permissions.py b/scripts/migrations/027-change-ticket-write-permissions.py
index 29258d6..1e64504 100644
--- a/scripts/migrations/027-change-ticket-write-permissions.py
+++ b/scripts/migrations/027-change-ticket-write-permissions.py
@@ -36,12 +36,15 @@ def add(acl, role):
         acl.append(role)
 
 # migration script for change write permission to create + update
+
+
 def main():
     query = {'tool_name': {'$regex': '^tickets$', '$options': 'i'}}
     for chunk in utils.chunked_find(M.AppConfig, query):
         for a in chunk:
             # change 'deny write' and 'write' permission
-            role_ids = [(p.role_id, p.access) for p in a.acl if p.permission == 'write']
+            role_ids = [(p.role_id, p.access)
+                        for p in a.acl if p.permission == 'write']
             for role_id, access in role_ids:
                 if access == M.ACE.DENY:
                     add(a.acl, M.ACE.deny(role_id, 'create'))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/migrations/028-remove-svn-trees.py
----------------------------------------------------------------------
diff --git a/scripts/migrations/028-remove-svn-trees.py b/scripts/migrations/028-remove-svn-trees.py
index 6630c3a..5b9a413 100644
--- a/scripts/migrations/028-remove-svn-trees.py
+++ b/scripts/migrations/028-remove-svn-trees.py
@@ -25,6 +25,7 @@ from forgesvn import model as SM
 
 log = logging.getLogger(__name__)
 
+
 def kill_tree(repo, commit_id, path, tree):
     '''They were arboring terrorists, I swear.'''
     M.repo.Tree.query.remove(dict(_id=tree._id))
@@ -37,13 +38,14 @@ def kill_tree(repo, commit_id, path, tree):
         else:
             print '  Missing {0}'.format((path + '/' + tree_rec.name).encode('utf8'))
 
+
 def main():
     for chunk in utils.chunked_find(SM.Repository):
         for r in chunk:
             print 'Processing {0}'.format(r)
             all_commit_ids = r._impl.all_commit_ids()
             if all_commit_ids:
-                for commit in M.repo.Commit.query.find({'_id':{'$in':all_commit_ids}}):
+                for commit in M.repo.Commit.query.find({'_id': {'$in': all_commit_ids}}):
                     if commit.tree_id and M.repo.Tree.query.get(_id=commit.tree_id):
                         kill_tree(r._impl, commit._id, '', commit.tree)
                 ThreadLocalORMSession.flush_all()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/new_ticket.py
----------------------------------------------------------------------
diff --git a/scripts/new_ticket.py b/scripts/new_ticket.py
index 33d6788..9b23328 100755
--- a/scripts/new_ticket.py
+++ b/scripts/new_ticket.py
@@ -21,13 +21,16 @@ import argparse
 import requests
 from pprint import pprint
 
+
 def get_opts():
-    parser = argparse.ArgumentParser(description='Post a new ticket using the API')
+    parser = argparse.ArgumentParser(
+        description='Post a new ticket using the API')
     parser.add_argument('project', help='Project shortname')
     parser.add_argument('mount_point', help='Tracker mount point')
     parser.add_argument('-H', '--host', default='sourceforge.net')
     opts = parser.parse_args()
-    opts.url = 'https://{}/rest/p/{}/{}/new'.format(opts.host, opts.project, opts.mount_point)
+    opts.url = 'https://{}/rest/p/{}/{}/new'.format(opts.host,
+                                                    opts.project, opts.mount_point)
     return opts
 
 opts = get_opts()
@@ -39,10 +42,10 @@ description = sys.stdin.read()
 print '-----------------------------------------------'
 
 r = requests.post(opts.url, params={
-        'access_token': access_token,
-        'ticket_form.summary': summary,
-        'ticket_form.description': description,
-    })
+    'access_token': access_token,
+    'ticket_form.summary': summary,
+    'ticket_form.description': description,
+})
 if r.status_code == 200:
     print 'Ticket created at: %s' % r.url
     pprint(r.json())

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/open_relay.py
----------------------------------------------------------------------
diff --git a/scripts/open_relay.py b/scripts/open_relay.py
index 0a392d3..ba21862 100644
--- a/scripts/open_relay.py
+++ b/scripts/open_relay.py
@@ -26,14 +26,16 @@ from ConfigParser import ConfigParser
 
 log = logging.getLogger(__name__)
 
+
 def main():
     cp = ConfigParser()
-    log.info('Read config from: %s', cp.read([os.path.join(os.environ['HOME'], '.open_relay.ini')]))
+    log.info('Read config from: %s',
+             cp.read([os.path.join(os.environ['HOME'], '.open_relay.ini')]))
     host = cp.get('open_relay', 'host')
     port = cp.getint('open_relay', 'port')
     ssl = cp.getboolean('open_relay', 'ssl')
     tls = cp.getboolean('open_relay', 'tls')
-    username=cp.get('open_relay', 'username')
+    username = cp.get('open_relay', 'username')
     password = cp.get('open_relay', 'password')
     smtp_client = MailClient(host,
                              port,
@@ -43,6 +45,7 @@ def main():
                smtp_client=smtp_client)
     asyncore.loop()
 
+
 class MailClient(object):
 
     def __init__(self, host, port, ssl, tls, username, password):
@@ -52,7 +55,8 @@ class MailClient(object):
         self._connect()
 
     def sendmail(self, mailfrom, rcpttos, data):
-        if str(mailfrom) == 'None': mailfrom = rcpttos[0]
+        if str(mailfrom) == 'None':
+            mailfrom = rcpttos[0]
         log.info('Sending mail to %s' % rcpttos)
         log.info('Sending mail from %s' % mailfrom)
         try:
@@ -71,6 +75,7 @@ class MailClient(object):
         if self.username:
             self._client.login(self.username, self.password)
 
+
 class MailServer(smtpd.SMTPServer):
 
     def __init__(self, *args, **kwargs):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/perf/benchmark-scm.py
----------------------------------------------------------------------
diff --git a/scripts/perf/benchmark-scm.py b/scripts/perf/benchmark-scm.py
index 0a4e9eb..be9b93a 100755
--- a/scripts/perf/benchmark-scm.py
+++ b/scripts/perf/benchmark-scm.py
@@ -42,8 +42,10 @@ def main(opts):
         repo = hg.repository(HgUI(), opts.repo_path)
         cid = None if opts.cid == 'HEAD' else ['%s:0' % opts.cid]
         path = opts.path.strip('/')
-        filenames = repo['tip' if opts.cid == 'HEAD' else opts.cid].manifest().keys()
-        filenames = [name for name in filenames if name.startswith(('%s/' % path).lstrip('/'))]
+        filenames = repo[
+            'tip' if opts.cid == 'HEAD' else opts.cid].manifest().keys()
+        filenames = [
+            name for name in filenames if name.startswith(('%s/' % path).lstrip('/'))]
         names = set()
         for name in filenames:
             names.add(name.split('/')[0])
@@ -78,11 +80,13 @@ def impl_git_tree(repo, cid, path, names, *args):
     data = {}
     for name in names:
         #data[name] = repo.git.rev_list(cid, '--', os.path.join(path, name), max_count=1)
-        data[name] = git.Commit.iter_items(repo, cid, os.path.join(path, name), max_count=1).next().hexsha
+        data[name] = git.Commit.iter_items(
+            repo, cid, os.path.join(path, name), max_count=1).next().hexsha
     return data
 
+
 def impl_git_node(repo, cid, path, *args):
-    #return repo.git.rev_list(cid, '--', path, max_count=1)
+    # return repo.git.rev_list(cid, '--', path, max_count=1)
     return git.Commit.iter_items(repo, cid, path, max_count=1).next().hexsha
 
 
@@ -90,53 +94,62 @@ def impl_hg_tree(repo, cid, path, names, *args):
     m = cmdutil.match(repo, pats=[path], default=path)
     data = {}
     for name in names:
-        rev_iter = cmdutil.walkchangerevs(repo, m, {'rev': cid}, lambda c,f: None)
+        rev_iter = cmdutil.walkchangerevs(
+            repo, m, {'rev': cid}, lambda c, f: None)
         data[name] = rev_iter.next().hex()
     return data
 
+
 def impl_hg_node(repo, cid, path, *args):
     m = cmdutil.match(repo, pats=[path], default=path)
-    rev_iter = cmdutil.walkchangerevs(repo, m, {'rev': cid}, lambda c,f: None)
+    rev_iter = cmdutil.walkchangerevs(repo, m, {'rev': cid}, lambda c, f: None)
     return rev_iter.next().hex()
 
+
 def impl_svn_tree(repo, cid, path, names, repo_path, *args):
     infos = repo.info2(
-            'file://%s/%s' % (repo_path, path),
-            revision=cid,
-            depth=pysvn.depth.immediates)
+        'file://%s/%s' % (repo_path, path),
+        revision=cid,
+        depth=pysvn.depth.immediates)
     data = {}
     for name, info in infos[1:]:
         data[name] = info.last_changed_rev
     return data
 
+
 def impl_svn_node(repo, cid, path, names, repo_path, *args):
     logs = repo.log(
-            'file://%s/%s' % (repo_path, path),
-            revision_start=cid,
-            limit=1)
+        'file://%s/%s' % (repo_path, path),
+        revision_start=cid,
+        limit=1)
     return logs[0].revision.number
 
 
 class HgUI(ui.ui):
+
     '''Hg UI subclass that suppresses reporting of untrusted hgrc files.'''
+
     def __init__(self, *args, **kwargs):
         super(HgUI, self).__init__(*args, **kwargs)
         self._reportuntrusted = False
 
+
 def parse_opts():
-    parser = argparse.ArgumentParser(description='Benchmark getting LCD from repo tool')
+    parser = argparse.ArgumentParser(
+        description='Benchmark getting LCD from repo tool')
     parser.add_argument('--type', default='git', dest='type',
-            help='Type of repository being tested.')
+                        help='Type of repository being tested.')
     parser.add_argument('--repo-path', dest='repo_path', required=True,
-            help='Path to the repository to test against')
+                        help='Path to the repository to test against')
     parser.add_argument('--commit', default='HEAD', dest='cid',
-            help='Commit ID or revision number to test against')
+                        help='Commit ID or revision number to test against')
     parser.add_argument('--path', default='', dest='path',
-            help='Path within the repository to test against')
+                        help='Path within the repository to test against')
     parser.add_argument('--count', type=int, default=100, dest='count',
-            help='Number of times to execute')
-    parser.add_argument('--full-tree', action='store_true', default=False, dest='full_tree',
-            help='Time full tree listing instead of just the single node')
+                        help='Number of times to execute')
+    parser.add_argument(
+        '--full-tree', action='store_true', default=False, dest='full_tree',
+        help='Time full tree listing instead of just the single node')
     return parser.parse_args()
 
 if __name__ == '__main__':

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/perf/call_count.py
----------------------------------------------------------------------
diff --git a/scripts/perf/call_count.py b/scripts/perf/call_count.py
index f965294..1d4ef6d 100755
--- a/scripts/perf/call_count.py
+++ b/scripts/perf/call_count.py
@@ -49,8 +49,9 @@ def parse_args():
                         help='Show call details.  Note that Timers with debug_each_call=False (like ming\'s Cursor.next) are not displayed in verbose mode (but they are counted).')
     parser.add_argument('--debug-html', action='store_true', default=False,
                         help='Save HTML responses as local files')
-    parser.add_argument('--data-file', default='call_counts.csv', type=argparse.FileType('a'),
-                        help='CSV file that is appended to')
+    parser.add_argument(
+        '--data-file', default='call_counts.csv', type=argparse.FileType('a'),
+        help='CSV file that is appended to')
     parser.add_argument('--id', default='',
                         help='An identifier for this run.  Examples:\n'
                              '`git rev-parse --short HEAD` for current hash\n'
@@ -63,9 +64,11 @@ def main(args):
     setup(test)
 
     url = generate_wiki_thread(test)
-    ThreadLocalODMSession.close_all()  # make sure ODM sessions won't get re-used
+    # make sure ODM sessions won't get re-used
+    ThreadLocalODMSession.close_all()
 
-    counts = count_page(test, url, verbose=args.verbose, debug_html=args.debug_html)
+    counts = count_page(test, url, verbose=args.verbose,
+                        debug_html=args.debug_html)
     print json.dumps(counts)
     write_csv(counts, args.id, args.data_file)
     test.tearDown()
@@ -76,7 +79,7 @@ def setup(test):
     with patch_middleware_config({'stats.sample_rate': 1,
                                   'stats.debug_line_length': 1000,
                                   }), \
-         patch('timermiddleware.log.isEnabledFor', return_value=True):  # can't set this via logging configuration since setUp() will load a logging config and then start using it before we have a good place to tweak it
+            patch('timermiddleware.log.isEnabledFor', return_value=True):  # can't set this via logging configuration since setUp() will load a logging config and then start using it before we have a good place to tweak it
         test.setUp()
 
     tmw_log = logging.getLogger('timermiddleware')
@@ -95,8 +98,8 @@ def generate_wiki_thread(test):
     thread = page.discussion_thread
     # create a few posts by a few users
     with push_config(c, user=M.User.query.get(username='test-admin'),
-                        app=app,
-                        project=project):
+                     app=app,
+                     project=project):
         thread.add_post(text='This is very helpful')
         thread.add_post(text="But it's not **super** helpful")
         with push_config(c, user=M.User.query.get(username='test-user')):
@@ -116,7 +119,8 @@ def count_page(test, url, verbose=False, debug_html=False):
         resp = test.app.get(url, extra_environ=dict(username='*anonymous'))
         print url, resp.status
         if debug_html:
-            debug_filename = 'call-{}.html'.format(''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(10)]))
+            debug_filename = 'call-{}.html'.format(''.join([random.choice(string.ascii_letters + string.digits)
+                                                   for n in xrange(10)]))
             with open(debug_filename, 'w') as out:
                 out.write(resp.body)
             print debug_filename
@@ -127,7 +131,8 @@ def count_page(test, url, verbose=False, debug_html=False):
 
     assert len(stats.records) == 1
     timings = json.loads(stats.records[0].getMessage())
-    del timings['call_counts']['total']  # total is always 1, which is misleading
+    # total is always 1, which is misleading
+    del timings['call_counts']['total']
     return timings['call_counts']
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/perf/md_perf.py
----------------------------------------------------------------------
diff --git a/scripts/perf/md_perf.py b/scripts/perf/md_perf.py
index 708a296..e40cb66 100644
--- a/scripts/perf/md_perf.py
+++ b/scripts/perf/md_perf.py
@@ -69,7 +69,7 @@ DUMMYTEXT = None
 def get_artifact():
     from forgeblog import model as BM
     return BM.BlogPost.query.get(
-            slug='2013/09/watch-breaking-bad-season-5-episode-16-felina-live-streaming')
+        slug='2013/09/watch-breaking-bad-season-5-episode-16-felina-live-streaming')
 
 
 def main(opts):
@@ -81,7 +81,7 @@ def main(opts):
         'markdown_safe': lambda: markdown.Markdown(safe_mode=True),
         'markdown_escape': lambda: markdown.Markdown(safe_mode='escape'),
         'forge': lambda: g.markdown,
-        }
+    }
     md = converters[opts.converter]()
     artifact = get_artifact()
     return render(artifact, md, opts)
@@ -113,11 +113,16 @@ def render(artifact, md, opts):
 def parse_options():
     parser = argparse.ArgumentParser()
     parser.add_argument('--converter', default='markdown')
-    parser.add_argument('--profile', action='store_true', help='Run profiler and output timings')
-    parser.add_argument('--output', action='store_true', help='Print result of markdown conversion')
-    parser.add_argument('--re2', action='store_true', help='Run with re2 instead of re')
-    parser.add_argument('--compare', action='store_true', help='Run with re and re2, and compare results')
-    parser.add_argument('-n', '--n', nargs='+', type=int, help='Only convert nth post(s) in thread')
+    parser.add_argument('--profile', action='store_true',
+                        help='Run profiler and output timings')
+    parser.add_argument('--output', action='store_true',
+                        help='Print result of markdown conversion')
+    parser.add_argument('--re2', action='store_true',
+                        help='Run with re2 instead of re')
+    parser.add_argument('--compare', action='store_true',
+                        help='Run with re and re2, and compare results')
+    parser.add_argument('-n', '--n', nargs='+', type=int,
+                        help='Only convert nth post(s) in thread')
     return parser.parse_args()
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/perf/sstress.py
----------------------------------------------------------------------
diff --git a/scripts/perf/sstress.py b/scripts/perf/sstress.py
index 5e53a52..3f1a1b1 100644
--- a/scripts/perf/sstress.py
+++ b/scripts/perf/sstress.py
@@ -30,11 +30,12 @@ N = 1000
 TOADDR = 'nobody@localhost'
 SERVER = 'localhost'
 PORT = 8825
-SIZE = 10 * (2**10)
+SIZE = 10 * (2 ** 10)
 EMAIL_TEXT = 'X' * SIZE
 
+
 def main():
-    threads = [ threading.Thread(target=stress) for x in xrange(C) ]
+    threads = [threading.Thread(target=stress) for x in xrange(C)]
     begin = time.time()
     for t in threads:
         t.start()
@@ -43,11 +44,12 @@ def main():
     end = time.time()
     elapsed = end - begin
     print '%d requests completed in %f seconds' % (N, elapsed)
-    print '%f requests/second' % (N/elapsed)
+    print '%f requests/second' % (N / elapsed)
+
 
 def stress():
     server = smtplib.SMTP(SERVER, PORT)
-    for x in xrange(N/C):
+    for x in xrange(N / C):
         server.sendmail('sstress@localhost', TOADDR, EMAIL_TEXT)
 
 if __name__ == '__main__':

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/perf/test_git_lcd.py
----------------------------------------------------------------------
diff --git a/scripts/perf/test_git_lcd.py b/scripts/perf/test_git_lcd.py
index aca0288..8d75e54 100644
--- a/scripts/perf/test_git_lcd.py
+++ b/scripts/perf/test_git_lcd.py
@@ -41,7 +41,7 @@ def main(repo_dir, sub_dir='', commit=None):
     git = GitImplementation(Mock(full_fs_path=repo_dir))
     commit = Mock(_id=commit or git.head)
     paths = glob(os.path.join(repo_dir, sub_dir, '*'))
-    paths = [path.replace(repo_dir+'/', '', 1) for path in paths]
+    paths = [path.replace(repo_dir + '/', '', 1) for path in paths]
     print "Timing LCDs for %s at %s" % (paths, commit._id)
     with benchmark() as timer:
         result = git.last_commit_ids(commit, paths)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/prep-scm-sandbox.py
----------------------------------------------------------------------
diff --git a/scripts/prep-scm-sandbox.py b/scripts/prep-scm-sandbox.py
index e60d7c6..414280f 100644
--- a/scripts/prep-scm-sandbox.py
+++ b/scripts/prep-scm-sandbox.py
@@ -18,16 +18,17 @@
 import os
 import string
 
-HOME=os.environ['HOME']
+HOME = os.environ['HOME']
 
-USERS=['user%.2d' % i for i in range(1, 21) ]
+USERS = ['user%.2d' % i for i in range(1, 21)]
 USERS += [
     'admin1', 'admin2',
     'dovethunder', 'dovetail', 'dovestream', 'dovetree', 'dovespangle',
-    'dovemeade', 'dovestar', 'dovebuyer', 'dovesomething', 'dovesweet', 'dovewood' ]
+    'dovemeade', 'dovestar', 'dovebuyer', 'dovesomething', 'dovesweet', 'dovewood']
 SSH_CONFIG = '%s/.ssh/config' % HOME
 LDIF_FILE = '%s/users.ldif' % HOME
-KEYFILE='%s/.ssh/allura_rsa' % HOME
+KEYFILE = '%s/.ssh/allura_rsa' % HOME
+
 
 def main():
 
@@ -40,8 +41,8 @@ def main():
             sb_host=sb_host,
             sb=sb,
             veid='%d0%.2d' % (sb_host, sb))
-        for sb_host in 5,6,7,9
-        for sb in range(99) ]
+        for sb_host in 5, 6, 7, 9
+        for sb in range(99)]
     new_lines = '\n'.join(new_lines)
     found_star = False
     with open(SSH_CONFIG, 'w') as fp:
@@ -62,9 +63,10 @@ def main():
                 user=user, pubkey=pubkey)
 
     # Update LDAP
-    assert 0 == os.system('/usr/local/sbin/ldaptool modify -v -f %s' % LDIF_FILE)
+    assert 0 == os.system('/usr/local/sbin/ldaptool modify -v -f %s' %
+                          LDIF_FILE)
 
-SSH_TMPL=string.Template('''
+SSH_TMPL = string.Template('''
 Host hg*-$veid hg*-${veid}.sb.sf.net
   Hostname 10.58.${sb_host}.${sb}
   Port 17
@@ -81,7 +83,7 @@ Host git*-$veid git*-${veid}.sb.sf.net
   IdentityFile ~/.ssh/allura_rsa
 ''')
 
-LDIF_TMPL=string.Template('''
+LDIF_TMPL = string.Template('''
 dn: cn=$user,ou=users,dc=sf,dc=net
 changetype: modify
 add: sshPublicKey

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/project-import.py
----------------------------------------------------------------------
diff --git a/scripts/project-import.py b/scripts/project-import.py
index f4ba62f..7e6257a 100644
--- a/scripts/project-import.py
+++ b/scripts/project-import.py
@@ -35,7 +35,9 @@ from allura.lib import helpers as h
 
 log = logging.getLogger(__name__)
 
+
 class TroveCategory():
+
     def __init__(self, root_type=''):
         self.root_type = root_type
 
@@ -47,29 +49,35 @@ class TroveCategory():
             cat = M.TroveCategory.query.get(fullname=cstruct)
         if not cat:
             raise col.Invalid(node,
-                    '"%s" is not a valid trove category.' % cstruct)
+                              '"%s" is not a valid trove category.' % cstruct)
         if not cat.fullpath.startswith(self.root_type):
             raise col.Invalid(node,
-                    '"%s" is not a valid "%s" trove category.' %
-                    (cstruct, self.root_type))
+                              '"%s" is not a valid "%s" trove category.' %
+                              (cstruct, self.root_type))
         return cat
 
+
 class User():
+
     def deserialize(self, node, cstruct):
         if cstruct is col.null:
             return col.null
         user = M.User.by_username(cstruct)
         if not user:
             raise col.Invalid(node,
-                    'Invalid username "%s".' % cstruct)
+                              'Invalid username "%s".' % cstruct)
         return user
 
+
 class ProjectName(object):
+
     def __init__(self, name, shortname):
         self.name = name
         self.shortname = shortname
 
+
 class ProjectNameType():
+
     def deserialize(self, node, cstruct):
         if cstruct is col.null:
             return col.null
@@ -78,18 +86,22 @@ class ProjectNameType():
         shortname = re.sub(" ", "-", shortname)
         return ProjectName(name, shortname)
 
+
 class ProjectShortnameType():
+
     def deserialize(self, node, cstruct):
         if cstruct is col.null:
             return col.null
         col.Length(min=3, max=15)(node, cstruct)
         col.Regex(r'^[A-z][-A-z0-9]{2,}$',
-            msg='Project shortname must begin with a letter, can '
-                'contain letters, numbers, and dashes, and must be '
-                '3-15 characters in length.')(node, cstruct)
+                  msg='Project shortname must begin with a letter, can '
+                  'contain letters, numbers, and dashes, and must be '
+                  '3-15 characters in length.')(node, cstruct)
         return cstruct.lower()
 
+
 class Award():
+
     def __init__(self, nbhd):
         self.nbhd = nbhd
 
@@ -97,46 +109,57 @@ class Award():
         if cstruct is col.null:
             return col.null
         award = M.Award.query.find(dict(short=cstruct,
-            created_by_neighborhood_id=self.nbhd._id)).first()
+                                        created_by_neighborhood_id=self.nbhd._id)).first()
         if not award:
             # try to look up the award by _id
             award = M.Award.query.find(dict(_id=bson.ObjectId(cstruct),
-                created_by_neighborhood_id=self.nbhd._id)).first()
+                                            created_by_neighborhood_id=self.nbhd._id)).first()
         if not award:
             raise col.Invalid(node,
-                    'Invalid award "%s".' % cstruct)
+                              'Invalid award "%s".' % cstruct)
         return award
 
+
 class TroveTopics(col.SequenceSchema):
     trove_topics = col.SchemaNode(TroveCategory("Topic"))
 
+
 class TroveLicenses(col.SequenceSchema):
     trove_license = col.SchemaNode(TroveCategory("License"))
 
+
 class TroveDatabases(col.SequenceSchema):
     trove_databases = col.SchemaNode(TroveCategory("Database Environment"))
 
+
 class TroveStatuses(col.SequenceSchema):
     trove_statuses = col.SchemaNode(TroveCategory("Development Status"))
 
+
 class TroveAudiences(col.SequenceSchema):
     trove_audience = col.SchemaNode(TroveCategory("Intended Audience"))
 
+
 class TroveOSes(col.SequenceSchema):
     trove_oses = col.SchemaNode(TroveCategory("Operating System"))
 
+
 class TroveLanguages(col.SequenceSchema):
     trove_languages = col.SchemaNode(TroveCategory("Programming Language"))
 
+
 class TroveTranslations(col.SequenceSchema):
     trove_translations = col.SchemaNode(TroveCategory("Translations"))
 
+
 class TroveUIs(col.SequenceSchema):
     trove_uis = col.SchemaNode(TroveCategory("User Interface"))
 
+
 class Labels(col.SequenceSchema):
     label = col.SchemaNode(col.Str())
 
+
 class Project(col.MappingSchema):
     name = col.SchemaNode(ProjectNameType())
     shortname = col.SchemaNode(ProjectShortnameType(), missing=None)
@@ -147,7 +170,8 @@ class Project(col.MappingSchema):
     labels = Labels(missing=[])
     external_homepage = col.SchemaNode(col.Str(), missing='')
     trove_root_databases = TroveDatabases(missing=None)
-    trove_developmentstatuses = TroveStatuses(validator=col.Length(max=6), missing=None)
+    trove_developmentstatuses = TroveStatuses(
+        validator=col.Length(max=6), missing=None)
     trove_audiences = TroveAudiences(validator=col.Length(max=6), missing=None)
     trove_licenses = TroveLicenses(validator=col.Length(max=6), missing=None)
     trove_oses = TroveOSes(missing=None)
@@ -156,6 +180,7 @@ class Project(col.MappingSchema):
     trove_natlanguages = TroveTranslations(missing=None)
     trove_environments = TroveUIs(missing=None)
 
+
 def valid_shortname(project):
     if project.shortname:
         # already validated in ProjectShortnameType validator
@@ -164,25 +189,31 @@ def valid_shortname(project):
         return True
     else:
         return 'Project shortname "%s" must be between 3 and 15 characters' \
-                % project.name.shortname
+            % project.name.shortname
+
 
 class Projects(col.SequenceSchema):
     project = Project(validator=col.Function(valid_shortname))
 
+
 class Object(object):
+
     def __init__(self, d):
         self.__dict__.update(d)
 
+
 def trove_ids(orig, new_):
-    if new_ is None: return orig
+    if new_ is None:
+        return orig
     return list(set(t._id for t in list(new_)))
 
+
 def create_project(p, nbhd, user, options):
     worker_name = multiprocessing.current_process().name
     M.session.artifact_orm_session._get().skip_mod_date = True
     shortname = p.shortname or p.name.shortname
     project = M.Project.query.get(shortname=shortname,
-            neighborhood_id=nbhd._id)
+                                  neighborhood_id=nbhd._id)
     project_template = nbhd.get_project_template()
 
     if project and not (options.update and p.shortname):
@@ -196,8 +227,8 @@ def create_project(p, nbhd, user, options):
         try:
                 project = nbhd.register_project(shortname,
                                                 p.admin,
-                                            project_name=p.name.name,
-                                            private_project=p.private)
+                                                project_name=p.name.name,
+                                                private_project=p.private)
         except Exception, e:
             log.error('[%s] %s' % (worker_name, str(e)))
             return 0
@@ -217,9 +248,9 @@ def create_project(p, nbhd, user, options):
                     tool_options[k] = string.Template(v).safe_substitute(
                         project.root_project.__dict__.get('root_project', {}))
             project.install_app(tool,
-                    mount_label=tool_config['label'],
-                    mount_point=tool_config['mount_point'],
-                    **tool_options)
+                                mount_label=tool_config['label'],
+                                mount_point=tool_config['mount_point'],
+                                **tool_options)
 
     project.summary = p.summary
     project.short_description = p.description
@@ -228,21 +259,27 @@ def create_project(p, nbhd, user, options):
     # These properties may have been populated by nbhd template defaults in
     # register_project(). Overwrite if we have data, otherwise keep defaults.
     project.labels = p.labels or project.labels
-    project.trove_root_database = trove_ids(project.trove_root_database, p.trove_root_databases)
-    project.trove_developmentstatus = trove_ids(project.trove_developmentstatus, p.trove_developmentstatuses)
-    project.trove_audience = trove_ids(project.trove_audience, p.trove_audiences)
+    project.trove_root_database = trove_ids(
+        project.trove_root_database, p.trove_root_databases)
+    project.trove_developmentstatus = trove_ids(
+        project.trove_developmentstatus, p.trove_developmentstatuses)
+    project.trove_audience = trove_ids(
+        project.trove_audience, p.trove_audiences)
     project.trove_license = trove_ids(project.trove_license, p.trove_licenses)
     project.trove_os = trove_ids(project.trove_os, p.trove_oses)
-    project.trove_language = trove_ids(project.trove_language, p.trove_languages)
+    project.trove_language = trove_ids(
+        project.trove_language, p.trove_languages)
     project.trove_topic = trove_ids(project.trove_topic, p.trove_topics)
-    project.trove_natlanguage = trove_ids(project.trove_natlanguage, p.trove_natlanguages)
-    project.trove_environment = trove_ids(project.trove_environment, p.trove_environments)
+    project.trove_natlanguage = trove_ids(
+        project.trove_natlanguage, p.trove_natlanguages)
+    project.trove_environment = trove_ids(
+        project.trove_environment, p.trove_environments)
 
     for a in p.awards:
         M.AwardGrant(app_config_id=bson.ObjectId(),
-                award_id=a._id,
-                granted_to_project_id=project._id,
-                granted_by_neighborhood_id=nbhd._id)
+                     award_id=a._id,
+                     granted_to_project_id=project._id,
+                     granted_by_neighborhood_id=nbhd._id)
     project.notifications_disabled = False
     with h.push_config(c, project=project, user=user):
         ThreadLocalORMSession.flush_all()
@@ -250,12 +287,14 @@ def create_project(p, nbhd, user, options):
     session(project).clear()
     return 0
 
+
 def create_projects(projects, nbhd, user, options):
     for p in projects:
         r = create_project(Object(p), nbhd, user, options)
         if r != 0:
             sys.exit(r)
 
+
 def main(options):
     log.addHandler(logging.StreamHandler(sys.stdout))
     log.setLevel(getattr(logging, options.log_level.upper()))
@@ -264,7 +303,8 @@ def main(options):
     nbhd = M.Neighborhood.query.get(name=options.neighborhood)
     if not nbhd:
         return 'Invalid neighborhood "%s".' % options.neighborhood
-    admin = M.User.query.get(username=config.get('sfx.api.siteadmin', 'sf-robot'))
+    admin = M.User.query.get(
+        username=config.get('sfx.api.siteadmin', 'sf-robot'))
 
     data = json.load(open(options.file, 'r'))
     project = Project()
@@ -279,36 +319,39 @@ def main(options):
     jobs = []
     for i in range(options.nprocs):
         p = multiprocessing.Process(target=create_projects,
-                args=(chunks[i], nbhd, admin, options), name='worker-' + str(i+1))
+                                    args=(chunks[i], nbhd, admin, options), name='worker-' + str(i + 1))
         jobs.append(p)
         p.start()
 
     for j in jobs:
         j.join()
-        if j.exitcode <> 0: return j.exitcode
+        if j.exitcode <> 0:
+            return j.exitcode
     return 0
 
+
 def parse_options():
     import argparse
     parser = argparse.ArgumentParser(
-            description='Import Allura project(s) from JSON file')
+        description='Import Allura project(s) from JSON file')
     parser.add_argument('file', metavar='JSON_FILE', type=str,
-            help='Path to JSON file containing project data.')
+                        help='Path to JSON file containing project data.')
     parser.add_argument('neighborhood', metavar='NEIGHBORHOOD', type=str,
-            help='Destination Neighborhood shortname.')
+                        help='Destination Neighborhood shortname.')
     parser.add_argument('--log', dest='log_level', default='INFO',
-            help='Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL).')
+                        help='Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL).')
     parser.add_argument('--update', dest='update', default=False,
-            action='store_true',
-            help='Update existing projects. Without this option, existing '
-                 'projects will be skipped.')
+                        action='store_true',
+                        help='Update existing projects. Without this option, existing '
+                        'projects will be skipped.')
     parser.add_argument('--ensure-tools', dest='ensure_tools', default=False,
-            action='store_true',
-            help='Check nbhd project template for default tools, and install '
-                 'them on the project(s) if not already installed.')
-    parser.add_argument('--nprocs', '-n', action='store', dest='nprocs', type=int,
-            help='Number of processes to divide the work among.',
-            default=multiprocessing.cpu_count())
+                        action='store_true',
+                        help='Check nbhd project template for default tools, and install '
+                        'them on the project(s) if not already installed.')
+    parser.add_argument(
+        '--nprocs', '-n', action='store', dest='nprocs', type=int,
+        help='Number of processes to divide the work among.',
+        default=multiprocessing.cpu_count())
     return parser.parse_args()
 
 if __name__ == '__main__':

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/publicize-neighborhood.py
----------------------------------------------------------------------
diff --git a/scripts/publicize-neighborhood.py b/scripts/publicize-neighborhood.py
index 68ed679..c32d384 100644
--- a/scripts/publicize-neighborhood.py
+++ b/scripts/publicize-neighborhood.py
@@ -27,6 +27,7 @@ from allura.lib import utils
 
 log = logging.getLogger(__name__)
 
+
 def main(options):
     log.addHandler(logging.StreamHandler(sys.stdout))
     log.setLevel(getattr(logging, options.log_level.upper()))
@@ -34,17 +35,19 @@ def main(options):
     nbhd = M.Neighborhood.query.get(name=options.neighborhood)
     if not nbhd:
         return 'Invalid neighborhood "%s".' % options.neighborhood
-    admin_role = M.ProjectRole.by_name('Admin', project=nbhd.neighborhood_project)
-    nbhd_admin = admin_role.users_with_role(project=nbhd.neighborhood_project)[0].user
+    admin_role = M.ProjectRole.by_name(
+        'Admin', project=nbhd.neighborhood_project)
+    nbhd_admin = admin_role.users_with_role(
+        project=nbhd.neighborhood_project)[0].user
     log.info('Making updates as neighborhood admin "%s"' % nbhd_admin.username)
 
     q = {'neighborhood_id': nbhd._id,
-            'is_nbhd_project': False, 'deleted':False}
+         'is_nbhd_project': False, 'deleted': False}
     private_count = public_count = 0
     for projects in utils.chunked_find(M.Project, q):
         for p in projects:
             role_anon = M.ProjectRole.upsert(name='*anonymous',
-                    project_id=p.root_project._id)
+                                             project_id=p.root_project._id)
             if M.ACE.allow(role_anon._id, 'read') not in p.acl:
                 if options.test:
                     log.info('Would be made public: "%s"' % p.shortname)
@@ -66,17 +69,18 @@ def main(options):
         log.info('Made public: %s' % private_count)
     return 0
 
+
 def parse_options():
     import argparse
     parser = argparse.ArgumentParser(
-            description='Make all projects in a neighborhood public.')
+        description='Make all projects in a neighborhood public.')
     parser.add_argument('neighborhood', metavar='NEIGHBORHOOD', type=str,
-            help='Neighborhood name.')
+                        help='Neighborhood name.')
     parser.add_argument('--test', dest='test', default=False,
-            action='store_true',
-            help='Run in test mode (no updates will be applied).')
+                        action='store_true',
+                        help='Run in test mode (no updates will be applied).')
     parser.add_argument('--log', dest='log_level', default='INFO',
-            help='Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL).')
+                        help='Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL).')
     return parser.parse_args()
 
 if __name__ == '__main__':

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/recover-user-databases.py
----------------------------------------------------------------------
diff --git a/scripts/recover-user-databases.py b/scripts/recover-user-databases.py
index f55f13b..5abf6f3 100644
--- a/scripts/recover-user-databases.py
+++ b/scripts/recover-user-databases.py
@@ -30,12 +30,15 @@ IGNORED_COLLECTIONS = [
     'config',
     'system.indexes']
 
+
 def main():
     conn = M.session.main_doc_session.bind.conn
     n = M.Neighborhood.query.get(url_prefix='/u/')
     for p in M.Project.query.find(dict(neighborhood_id=n._id)):
-        if not p.database_configured: continue
-        if not p.shortname.startswith('u/'): continue
+        if not p.database_configured:
+            continue
+        if not p.shortname.startswith('u/'):
+            continue
         log.info('Checking to see if %s is configured...', p.database)
         db = conn[p.database]
         if is_unconfigured(db):
@@ -49,10 +52,12 @@ def main():
         else:
             log.info('... it is.')
 
+
 def is_unconfigured(db):
     # Check for data in collections other than those we pre-fill with data
     for collection_name in db.collection_names():
-        if collection_name in IGNORED_COLLECTIONS: continue
+        if collection_name in IGNORED_COLLECTIONS:
+            continue
         collection = db[collection_name]
         if collection.count():
             log.info('...%s has data', collection_name)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/scripts/rethumb.py
----------------------------------------------------------------------
diff --git a/scripts/rethumb.py b/scripts/rethumb.py
index 6ee190a..cbda4d7 100644
--- a/scripts/rethumb.py
+++ b/scripts/rethumb.py
@@ -32,8 +32,8 @@ import forgetracker.model
 
 
 class RethumbCommand(base.Command):
-    min_args=1
-    max_args=2
+    min_args = 1
+    max_args = 2
     usage = '<ini file> [<project name>]'
     summary = 'Recreate thumbnails for attachment images'
     parser = base.Command.standard_parser(verbose=True)
@@ -44,23 +44,27 @@ class RethumbCommand(base.Command):
 
     def create_thumbnail(self, attachment, att_cls):
         if attachment.is_image():
-            base.log.info("Processing image attachment '%s'", attachment.filename)
+            base.log.info("Processing image attachment '%s'",
+                          attachment.filename)
             doc = state(attachment).document.deinstrumented_clone()
             del doc['_id']
             del doc['file_id']
             doc['type'] = 'thumbnail'
             count = att_cls.query.find(doc).count()
             if count == 1:
-                base.log.info("Thumbnail already exists for '%s' - skipping", attachment.filename)
+                base.log.info(
+                    "Thumbnail already exists for '%s' - skipping", attachment.filename)
                 return
             elif count > 1:
-                base.log.warning("There are %d thumbnails for '%s' - consider clearing them with --force", count, attachment.filename)
+                base.log.warning(
+                    "There are %d thumbnails for '%s' - consider clearing them with --force", count, attachment.filename)
                 return
 
             image = PIL.Image.open(attachment.rfile())
             del doc['content_type']
             del doc['filename']
-            att_cls.save_thumbnail(attachment.filename, image, attachment.content_type, att_cls.thumbnail_size, doc, square=True)
+            att_cls.save_thumbnail(attachment.filename, image,
+                                   attachment.content_type, att_cls.thumbnail_size, doc, square=True)
             base.log.info("Created thumbnail for '%s'", attachment.filename)
             self.created_thumbs += 1
 
@@ -97,20 +101,27 @@ class RethumbCommand(base.Command):
             c.project = p
 
             if self.options.force:
-                existing_thumbs += M.BaseAttachment.query.find({'type': 'thumbnail'}).count()
-                base.log.info('Removing %d current thumbnails (per --force)', existing_thumbs)
+                existing_thumbs += M.BaseAttachment.query.find({'type': 'thumbnail'}
+                                                               ).count()
+                base.log.info(
+                    'Removing %d current thumbnails (per --force)', existing_thumbs)
                 M.BaseAttachment.query.remove({'type': 'thumbnail'})
 
             # ProjectFile's live in main collection (unlike File's)
             # M.ProjectFile.query.find({'app_config_id': None, 'type': 'attachment'}).all()
 
             for app in p.app_configs:
-                base.log.info("Processing application '%s' mounted at '%s' of type '%s'", app.options['mount_label'], app.options['mount_point'], app.tool_name)
+                base.log.info(
+                    "Processing application '%s' mounted at '%s' of type '%s'",
+                    app.options['mount_label'], app.options['mount_point'], app.tool_name)
 
-                # Any application may contain DiscussionAttachment's, it has discussion_id field
-                self.process_att_of_type(M.DiscussionAttachment, {'app_config_id': app._id, 'discussion_id': {'$ne': None}})
+                # Any application may contain DiscussionAttachment's, it has
+                # discussion_id field
+                self.process_att_of_type(
+                    M.DiscussionAttachment, {'app_config_id': app._id, 'discussion_id': {'$ne': None}})
 
-                # Otherwise, we'll take attachment classes belonging to app's package
+                # Otherwise, we'll take attachment classes belonging to app's
+                # package
                 ep = iter_entry_points('allura', app.tool_name).next()
                 app_package = ep.module_name.split('.', 1)[0]
                 if app_package == 'allura':
@@ -119,14 +130,17 @@ class RethumbCommand(base.Command):
 
                 classes = package_model_map.get(app_package, [])
                 for cls in classes:
-                    self.process_att_of_type(cls, {'app_config_id': app._id, 'discussion_id': None})
+                    self.process_att_of_type(
+                        cls, {'app_config_id': app._id, 'discussion_id': None})
 
                 base.log.info('-' * 10)
 
         base.log.info('Recreated %d thumbs', self.created_thumbs)
         if self.options.force:
             if existing_thumbs != self.created_thumbs:
-                base.log.warning('There were %d thumbs before --force operation started, but %d recreated', existing_thumbs, self.created_thumbs)
+                base.log.warning(
+                    'There were %d thumbs before --force operation started, but %d recreated',
+                    existing_thumbs, self.created_thumbs)
 
         ThreadLocalORMSession.flush_all()