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

[07/32] PEP8 cleanup

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeTracker/forgetracker/import_support.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/import_support.py b/ForgeTracker/forgetracker/import_support.py
index b5daa12..c1865e9 100644
--- a/ForgeTracker/forgetracker/import_support.py
+++ b/ForgeTracker/forgetracker/import_support.py
@@ -41,10 +41,13 @@ except ImportError:
 
 log = logging.getLogger(__name__)
 
+
 class ImportException(Exception):
     pass
 
+
 class ResettableStream(object):
+
     '''Class supporting seeks within a header of otherwise
     unseekable stream.'''
 
@@ -92,9 +95,10 @@ class ResettableStream(object):
         else:
             return self.stream_pos
 
+
 class ImportSupport(object):
 
-    ATTACHMENT_SIZE_LIMIT = 1024*1024
+    ATTACHMENT_SIZE_LIMIT = 1024 * 1024
 
     def __init__(self):
         # Map JSON interchange format fields to Ticket fields
@@ -102,7 +106,8 @@ class ImportSupport(object):
         #   None - drop
         #   True - map as is
         #   (new_field_name, value_convertor(val)) - use new field name and convert JSON's value
-        #   handler(ticket, field, val) - arbitrary transform, expected to modify ticket in-place
+        # handler(ticket, field, val) - arbitrary transform, expected to modify
+        # ticket in-place
         self.FIELD_MAP = {
             'assigned_to': ('assigned_to_id', self.get_user_id),
             'class': None,
@@ -110,7 +115,8 @@ class ImportSupport(object):
             'date_updated': ('mod_date', self.parse_date),
             'description': True,
             'id': None,
-            'keywords': ('labels', lambda s: s.split()), # default way of handling, see below for overrides
+            # default way of handling, see below for overrides
+            'keywords': ('labels', lambda s: s.split()),
             'status': True,
             'submitter': ('reported_by_id', self.get_user_id),
             'summary': True,
@@ -121,7 +127,6 @@ class ImportSupport(object):
         self.errors = []
         self.options = {}
 
-
     def init_options(self, options_json):
         self.options = json.loads(options_json)
         opt_keywords = self.option('keywords_as', 'split_labels')
@@ -133,7 +138,6 @@ class ImportSupport(object):
     def option(self, name, default=None):
         return self.options.get(name, False)
 
-
     #
     # Field/value convertors
     #
@@ -158,7 +162,8 @@ class ImportSupport(object):
     def check_custom_field(self, field, value, ticket_status):
         field = c.app.globals.get_custom_field(field)
         if (field['type'] == 'select') and value:
-            field_options = h.split_select_field_options(h.really_unicode(field['options']))
+            field_options = h.split_select_field_options(
+                h.really_unicode(field['options']))
             if value not in field_options:
                 field['options'] = ' '.join([field['options'], value])
         elif (field['type'] == 'milestone') and value:
@@ -180,8 +185,10 @@ class ImportSupport(object):
     def custom(self, ticket, field, value, ticket_status):
         field = '_' + field
         if not c.app.has_custom_field(field):
-            log.warning('Custom field %s is not defined, defining as string', field)
-            c.app.globals.custom_fields.append(dict(name=field, label=field[1:].capitalize(), type='string'))
+            log.warning(
+                'Custom field %s is not defined, defining as string', field)
+            c.app.globals.custom_fields.append(
+                dict(name=field, label=field[1:].capitalize(), type='string'))
             ThreadLocalORMSession.flush_all()
         if 'custom_fields' not in ticket:
             ticket['custom_fields'] = {}
@@ -204,23 +211,26 @@ class ImportSupport(object):
                 new_f, conv = transform
                 remapped[new_f] = conv(v)
 
-        description = h.really_unicode(self.description_processing(remapped['description']))
+        description = h.really_unicode(
+            self.description_processing(remapped['description']))
         creator = owner = ''
         if ticket_dict.get('submitter') and not remapped.get('reported_by_id'):
             creator = u'*Originally created by:* {0}\n'.format(
-                    h.really_unicode(ticket_dict['submitter']))
+                h.really_unicode(ticket_dict['submitter']))
         if ticket_dict.get('assigned_to') and not remapped.get('assigned_to_id'):
             owner = u'*Originally owned by:* {0}\n'.format(
                     h.really_unicode(ticket_dict['assigned_to']))
         remapped['description'] = u'{0}{1}{2}{3}'.format(creator, owner,
-                '\n' if creator or owner else '', description)
+                                                         '\n' if creator or owner else '', description)
 
         ticket_num = ticket_dict['id']
         existing_ticket = TM.Ticket.query.get(app_config_id=c.app.config._id,
-                                          ticket_num=ticket_num)
+                                              ticket_num=ticket_num)
         if existing_ticket:
             ticket_num = c.app.globals.next_ticket_num()
-            self.warnings.append('Ticket #%s: Ticket with this id already exists, using next available id: %s' % (ticket_dict['id'], ticket_num))
+            self.warnings.append(
+                'Ticket #%s: Ticket with this id already exists, using next available id: %s' %
+                (ticket_dict['id'], ticket_num))
         else:
             if c.app.globals.last_ticket_num < ticket_num:
                 c.app.globals.last_ticket_num = ticket_num
@@ -245,22 +255,24 @@ class ImportSupport(object):
     def make_comment(self, thread, comment_dict):
         ts = self.parse_date(comment_dict['date'])
         author_id = self.get_user_id(comment_dict['submitter'])
-        text = h.really_unicode(self.comment_processing(comment_dict['comment']))
+        text = h.really_unicode(
+            self.comment_processing(comment_dict['comment']))
         if not author_id and comment_dict['submitter']:
             text = u'*Originally posted by:* {0}\n\n{1}'.format(
-                    h.really_unicode(comment_dict['submitter']), text)
+                h.really_unicode(comment_dict['submitter']), text)
         comment = thread.post(text=text, timestamp=ts)
         comment.author_id = author_id
 
     def make_attachment(self, org_ticket_id, ticket_id, att_dict):
         if att_dict['size'] > self.ATTACHMENT_SIZE_LIMIT:
-            self.errors.append('Ticket #%s: Attachment %s (@ %s) is too large, skipping' %
-                               (org_ticket_id, att_dict['filename'], att_dict['url']))
+            self.errors.append(
+                'Ticket #%s: Attachment %s (@ %s) is too large, skipping' %
+                (org_ticket_id, att_dict['filename'], att_dict['url']))
             return
         f = urlopen(att_dict['url'])
-        TM.TicketAttachment.save_attachment(att_dict['filename'], ResettableStream(f),
-                                            artifact_id=ticket_id)
-
+        TM.TicketAttachment.save_attachment(
+            att_dict['filename'], ResettableStream(f),
+            artifact_id=ticket_id)
 
     #
     # User handling
@@ -298,8 +310,8 @@ class ImportSupport(object):
         for foreign_user, allura_user in self.options['user_map'].iteritems():
             u = M.User.by_username(allura_user)
             if not u:
-                raise ImportException('User mapping %s:%s - target user does not exist' % (foreign_user, allura_user))
-
+                raise ImportException(
+                    'User mapping %s:%s - target user does not exist' % (foreign_user, allura_user))
 
     #
     # Main methods
@@ -354,7 +366,8 @@ option user_map to avoid losing username information. Unknown users: %s''' % unk
                 try:
                     self.make_attachment(a['id'], t._id, a_entry)
                 except Exception, e:
-                    self.warnings.append('Could not import attachment, skipped: %s' % e)
+                    self.warnings.append(
+                        'Could not import attachment, skipped: %s' % e)
             log.info('Imported ticket: %d', t.ticket_num)
         c.app.globals.invalidate_bin_counts()
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 8cde75a..5dfaec0 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -39,25 +39,25 @@ from ming.orm.ormsession import ThreadLocalORMSession
 from tg import config as tg_config
 
 from allura.model import (
-        ACE,
-        DENY_ALL,
-
-        AppConfig,
-        Artifact,
-        BaseAttachment,
-        Feed,
-        Mailbox,
-        MovedArtifact,
-        Notification,
-        ProjectRole,
-        Snapshot,
-        Thread,
-        User,
-        VersionedArtifact,
-        VotableArtifact,
-
-        artifact_orm_session,
-        project_orm_session,
+    ACE,
+    DENY_ALL,
+
+    AppConfig,
+    Artifact,
+    BaseAttachment,
+    Feed,
+    Mailbox,
+    MovedArtifact,
+    Notification,
+    ProjectRole,
+    Snapshot,
+    Thread,
+    User,
+    VersionedArtifact,
+    VotableArtifact,
+
+    artifact_orm_session,
+    project_orm_session,
 )
 from allura.model.timeline import ActivityObject
 from allura.model.notification import MailFooter
@@ -85,29 +85,32 @@ config = utils.ConfigProxy(
     common_suffix='forgemail.domain',
     new_solr='solr.use_new_types')
 
+
 class Globals(MappedClass):
 
     class __mongometa__:
         name = 'globals'
         session = project_orm_session
-        indexes = [ 'app_config_id' ]
+        indexes = ['app_config_id']
 
     type_s = 'Globals'
     _id = FieldProperty(schema.ObjectId)
-    app_config_id = ForeignIdProperty(AppConfig, if_missing=lambda:c.app.config._id)
+    app_config_id = ForeignIdProperty(
+        AppConfig, if_missing=lambda: c.app.config._id)
     app_config = RelationProperty(AppConfig, via='app_config_id')
     last_ticket_num = FieldProperty(int)
     status_names = FieldProperty(str)
     open_status_names = FieldProperty(str)
     closed_status_names = FieldProperty(str)
     milestone_names = FieldProperty(str, if_missing='')
-    custom_fields = FieldProperty([{str:None}])
-    _bin_counts = FieldProperty(schema.Deprecated) # {str:int})
+    custom_fields = FieldProperty([{str: None}])
+    _bin_counts = FieldProperty(schema.Deprecated)  # {str:int})
     _bin_counts_data = FieldProperty([dict(summary=str, hits=int)])
     _bin_counts_expire = FieldProperty(datetime)
     _bin_counts_invalidated = FieldProperty(datetime)
-    _milestone_counts = FieldProperty(schema.Deprecated) #[dict(name=str,hits=int,closed=int)])
-    _milestone_counts_expire = FieldProperty(schema.Deprecated) #datetime)
+    # [dict(name=str,hits=int,closed=int)])
+    _milestone_counts = FieldProperty(schema.Deprecated)
+    _milestone_counts_expire = FieldProperty(schema.Deprecated)  # datetime)
     show_in_search = FieldProperty({str: bool}, if_missing={'ticket_num': True,
                                                             'summary': True,
                                                             '_milestone': True,
@@ -122,7 +125,7 @@ class Globals(MappedClass):
     def next_ticket_num(self):
         gbl = Globals.query.find_and_modify(
             query=dict(app_config_id=self.app_config_id),
-            update={'$inc': { 'last_ticket_num': 1}},
+            update={'$inc': {'last_ticket_num': 1}},
             new=True)
         session(gbl).expunge(gbl)
         return gbl.last_ticket_num
@@ -145,7 +148,7 @@ class Globals(MappedClass):
 
     @property
     def not_closed_query(self):
-        return ' && '.join(['!status:'+name for name in self.set_of_closed_status_names])
+        return ' && '.join(['!status:' + name for name in self.set_of_closed_status_names])
 
     @property
     def not_closed_mongo_query(self):
@@ -154,11 +157,11 @@ class Globals(MappedClass):
 
     @property
     def closed_query(self):
-        return ' or '.join(['status:'+name for name in self.set_of_closed_status_names])
+        return ' or '.join(['status:' + name for name in self.set_of_closed_status_names])
 
     @property
     def milestone_fields(self):
-        return [ fld for fld in self.custom_fields if fld['type'] == 'milestone' ]
+        return [fld for fld in self.custom_fields if fld['type'] == 'milestone']
 
     def get_custom_field(self, name):
         for fld in self.custom_fields:
@@ -186,7 +189,9 @@ class Globals(MappedClass):
         for b in Bin.query.find(dict(
                 app_config_id=self.app_config_id)):
             if b.terms and '$USER' in b.terms:
-                continue  # skip queries with $USER variable, hits will be inconsistent for them
+                # skip queries with $USER variable, hits will be inconsistent
+                # for them
+                continue
             r = search_artifact(Ticket, b.terms, rows=0, short_timeout=False)
             hits = r is not None and r.hits or 0
             self._bin_counts_data.append(dict(summary=b.summary, hits=hits))
@@ -200,7 +205,8 @@ class Globals(MappedClass):
         if self._bin_counts_expire < datetime.utcnow():
             self.invalidate_bin_counts()
         for d in self._bin_counts_data:
-            if d['summary'] == name: return d
+            if d['summary'] == name:
+                return d
         return dict(summary=name, hits=0)
 
     def milestone_count(self, name):
@@ -265,13 +271,14 @@ class Globals(MappedClass):
             moved = ticket.move(tracker, notify=False)
             moved_tickets[moved._id] = moved
         mail = dict(
-            sender = c.project.app_instance(self.app_config).email_address,
-            fromaddr = str(c.user.email_address_header()),
-            reply_to = str(c.user.email_address_header()),
-            subject = '[%s:%s] Mass ticket moving by %s' % (c.project.shortname,
+            sender=c.project.app_instance(self.app_config).email_address,
+            fromaddr=str(c.user.email_address_header()),
+            reply_to=str(c.user.email_address_header()),
+            subject='[%s:%s] Mass ticket moving by %s' % (c.project.shortname,
                                                           self.app_config.options.mount_point,
                                                           c.user.display_name))
-        tmpl = g.jinja2_env.get_template('forgetracker:data/mass_move_report.html')
+        tmpl = g.jinja2_env.get_template(
+            'forgetracker:data/mass_move_report.html')
 
         tmpl_context = {
             'original_tracker': '%s:%s' % (c.project.shortname,
@@ -282,44 +289,49 @@ class Globals(MappedClass):
         }
         for user in users:
             tmpl_context['tickets'] = ({
-                    'original_num': original_ticket_nums[_id],
-                    'destination_num': moved_tickets[_id].ticket_num,
-                    'summary': moved_tickets[_id].summary
-                } for _id in filtered.get(user._id, []))
+                'original_num': original_ticket_nums[_id],
+                'destination_num': moved_tickets[_id].ticket_num,
+                'summary': moved_tickets[_id].summary
+            } for _id in filtered.get(user._id, []))
             mail.update(dict(
-                message_id = h.gen_message_id(),
-                text = tmpl.render(tmpl_context),
-                destinations = [str(user._id)]))
+                message_id=h.gen_message_id(),
+                text=tmpl.render(tmpl_context),
+                destinations=[str(user._id)]))
             mail_tasks.sendmail.post(**mail)
 
         if self.app_config.options.get('TicketMonitoringType') in (
                 'AllTicketChanges', 'AllPublicTicketChanges'):
-            monitoring_email = self.app_config.options.get('TicketMonitoringEmail')
+            monitoring_email = self.app_config.options.get(
+                'TicketMonitoringEmail')
             tmpl_context['tickets'] = [{
-                    'original_num': original_ticket_nums[_id],
-                    'destination_num': moved_tickets[_id].ticket_num,
-                    'summary': moved_tickets[_id].summary
-                } for _id, t in moved_tickets.iteritems()
-                  if (not t.private or
-                      self.app_config.options.get('TicketMonitoringType') ==
-                      'AllTicketChanges')]
+                'original_num': original_ticket_nums[_id],
+                'destination_num': moved_tickets[_id].ticket_num,
+                'summary': moved_tickets[_id].summary
+            } for _id, t in moved_tickets.iteritems()
+                if (not t.private or
+                    self.app_config.options.get('TicketMonitoringType') ==
+                    'AllTicketChanges')]
             if len(tmpl_context['tickets']) > 0:
                 mail.update(dict(
-                    message_id = h.gen_message_id(),
-                    text = tmpl.render(tmpl_context),
-                    destinations = [monitoring_email]))
+                    message_id=h.gen_message_id(),
+                    text=tmpl.render(tmpl_context),
+                    destinations=[monitoring_email]))
                 mail_tasks.sendmail.post(**mail)
 
-        moved_from = '%s/%s' % (c.project.shortname, self.app_config.options.mount_point)
-        moved_to = '%s/%s' % (tracker.project.shortname, tracker.options.mount_point)
+        moved_from = '%s/%s' % (c.project.shortname,
+                                self.app_config.options.mount_point)
+        moved_to = '%s/%s' % (tracker.project.shortname,
+                              tracker.options.mount_point)
         text = 'Tickets moved from %s to %s' % (moved_from, moved_to)
         Notification.post_user(c.user, None, 'flash', text=text)
 
     def update_tickets(self, **post_data):
         from forgetracker.tracker_main import get_change_text, get_label
         tickets = Ticket.query.find(dict(
-                _id={'$in':[ObjectId(id) for id in aslist(post_data['__ticket_ids'])]},
-                app_config_id=self.app_config_id)).all()
+            _id={'$in': [ObjectId(id)
+                         for id in aslist(
+                             post_data['__ticket_ids'])]},
+            app_config_id=self.app_config_id)).all()
 
         fields = set(['status', 'private'])
         values = {}
@@ -327,7 +339,8 @@ class Globals(MappedClass):
 
         for k in fields:
             v = post_data.get(k)
-            if v: values[k] = v
+            if v:
+                values[k] = v
         assigned_to = post_data.get('assigned_to')
         if assigned_to == '-':
             values['assigned_to_id'] = None
@@ -352,7 +365,8 @@ class Globals(MappedClass):
         for ticket in tickets:
             message = ''
             if labels:
-                values['labels'] = self.append_new_labels(ticket.labels, labels.split(','))
+                values['labels'] = self.append_new_labels(
+                    ticket.labels, labels.split(','))
             for k, v in sorted(values.iteritems()):
                 if k == 'assigned_to_id':
                     new_user = User.query.get(_id=v)
@@ -381,8 +395,8 @@ class Globals(MappedClass):
             for k, v in sorted(custom_values.iteritems()):
                 def cf_val(cf):
                     return ticket.get_custom_user(cf.name) \
-                           if cf.type == 'user' \
-                           else ticket.custom_fields.get(cf.name)
+                        if cf.type == 'user' \
+                        else ticket.custom_fields.get(cf.name)
                 cf = custom_fields[k]
                 old_value = cf_val(cf)
                 if cf.type == 'boolean':
@@ -400,19 +414,22 @@ class Globals(MappedClass):
                 ticket.commit()
 
         filtered_changes = self.filtered_by_subscription(changed_tickets)
-        users = User.query.find({'_id': {'$in': filtered_changes.keys()}}).all()
+        users = User.query.find(
+            {'_id': {'$in': filtered_changes.keys()}}).all()
+
         def changes_iter(user):
             for t_id in filtered_changes.get(user._id, []):
                 # mark changes text as safe, thus it wouldn't be escaped in plain-text emails
-                # html part of email is handled by markdown and it'll be properly escaped
+                # html part of email is handled by markdown and it'll be
+                # properly escaped
                 yield (changed_tickets[t_id], jinja2.Markup(changes[t_id]))
         mail = dict(
-            sender = c.project.app_instance(self.app_config).email_address,
-            fromaddr = str(c.user._id),
-            reply_to = tg_config['forgemail.return_path'],
-            subject = '[%s:%s] Mass edit changes by %s' % (c.project.shortname,
-                                                           self.app_config.options.mount_point,
-                                                           c.user.display_name),
+            sender=c.project.app_instance(self.app_config).email_address,
+            fromaddr=str(c.user._id),
+            reply_to=tg_config['forgemail.return_path'],
+            subject='[%s:%s] Mass edit changes by %s' % (c.project.shortname,
+                                                         self.app_config.options.mount_point,
+                                                         c.user.display_name),
         )
         tmpl = g.jinja2_env.get_template('forgetracker:data/mass_report.html')
         head = []
@@ -427,45 +444,50 @@ class Globals(MappedClass):
                 user = User.by_username(v)
                 v = user.display_name if user else v
             head.append('- **%s**: %s' % (cf.label, v))
-        tmpl_context = {'context': c, 'data': {'header': jinja2.Markup('\n'.join(['Mass edit changing:', ''] + head))}}
+        tmpl_context = {'context': c, 'data':
+                        {'header': jinja2.Markup('\n'.join(['Mass edit changing:', ''] + head))}}
         for user in users:
             tmpl_context['data'].update({'changes': changes_iter(user)})
             mail.update(dict(
-                message_id = h.gen_message_id(),
-                text = tmpl.render(tmpl_context),
-                destinations = [str(user._id)]))
+                message_id=h.gen_message_id(),
+                text=tmpl.render(tmpl_context),
+                destinations=[str(user._id)]))
             mail_tasks.sendmail.post(**mail)
 
         if self.app_config.options.get('TicketMonitoringType') in (
                 'AllTicketChanges', 'AllPublicTicketChanges'):
-            monitoring_email = self.app_config.options.get('TicketMonitoringEmail')
+            monitoring_email = self.app_config.options.get(
+                'TicketMonitoringEmail')
             visible_changes = []
             for t_id, t in changed_tickets.items():
                 if (not t.private or
                         self.app_config.options.get('TicketMonitoringType') ==
                         'AllTicketChanges'):
                     visible_changes.append(
-                            (changed_tickets[t_id], jinja2.Markup(changes[t_id])))
+                        (changed_tickets[t_id], jinja2.Markup(changes[t_id])))
             if visible_changes:
                 tmpl_context['data'].update({'changes': visible_changes})
                 mail.update(dict(
-                    message_id = h.gen_message_id(),
-                    text = tmpl.render(tmpl_context),
-                    destinations = [monitoring_email]))
+                    message_id=h.gen_message_id(),
+                    text=tmpl.render(tmpl_context),
+                    destinations=[monitoring_email]))
                 mail_tasks.sendmail.post(**mail)
 
         self.invalidate_bin_counts()
         ThreadLocalORMSession.flush_all()
-        app = '%s/%s' % (c.project.shortname, self.app_config.options.mount_point)
+        app = '%s/%s' % (c.project.shortname,
+                         self.app_config.options.mount_point)
         count = len(tickets)
-        text = 'Updated {} ticket{} in {}'.format(count, 's' if count != 1 else '', app)
+        text = 'Updated {} ticket{} in {}'.format(
+            count, 's' if count != 1 else '', app)
         Notification.post_user(c.user, None, 'flash', text=text)
 
     def filtered_by_subscription(self, tickets, project_id=None, app_config_id=None):
         p_id = project_id if project_id else c.project._id
         ac_id = app_config_id if app_config_id else self.app_config_id
         ticket_ids = tickets.keys()
-        tickets_index_id = {ticket.index_id(): t_id for t_id, ticket in tickets.iteritems()}
+        tickets_index_id = {
+            ticket.index_id(): t_id for t_id, ticket in tickets.iteritems()}
         subscriptions = Mailbox.query.find({
             'project_id': p_id,
             'app_config_id': ac_id,
@@ -527,7 +549,9 @@ class TicketHistory(Snapshot):
         result['text'] += pformat(result.values())
         return result
 
+
 class Bin(Artifact, ActivityObject):
+
     class __mongometa__:
         name = 'bin'
 
@@ -567,7 +591,9 @@ class Bin(Artifact, ActivityObject):
             sort=self.sort,
         )
 
+
 class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
+
     class __mongometa__:
         name = 'ticket'
         history_class = TicketHistory
@@ -575,10 +601,10 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             'ticket_num',
             ('app_config_id', 'custom_fields._milestone'),
             'import_id',
-            ]
+        ]
         unique_indexes = [
             ('app_config_id', 'ticket_num'),
-            ]
+        ]
 
     type_s = 'Ticket'
     _id = FieldProperty(schema.ObjectId)
@@ -588,11 +614,11 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
     summary = FieldProperty(str)
     description = FieldProperty(str, if_missing='')
     description_cache = FieldProperty(MarkdownCache)
-    reported_by_id = ForeignIdProperty(User, if_missing=lambda:c.user._id)
+    reported_by_id = ForeignIdProperty(User, if_missing=lambda: c.user._id)
     assigned_to_id = ForeignIdProperty(User, if_missing=None)
     milestone = FieldProperty(str, if_missing='')
     status = FieldProperty(str, if_missing='')
-    custom_fields = FieldProperty({str:None})
+    custom_fields = FieldProperty({str: None})
 
     reported_by = RelationProperty(User, via='reported_by_id')
 
@@ -621,7 +647,8 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
                 return ticket
             except OperationFailure, err:
                 if 'duplicate' in err.args[0]:
-                    log.warning('Try to create duplicate ticket %s', ticket.url())
+                    log.warning('Try to create duplicate ticket %s',
+                                ticket.url())
                     session(ticket).expunge(ticket)
                     continue
                 raise
@@ -644,7 +671,7 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             votes_down_i=self.votes_down,
             votes_total_i=(self.votes_up - self.votes_down),
             import_id_s=ImportIdConverter.get().simplify(self.import_id)
-            )
+        )
         for k, v in self.custom_fields.iteritems():
             # Pre solr-4.2.1 code expects all custom fields to be indexed
             # as strings.
@@ -655,7 +682,7 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             solr_type = self.app.globals.get_custom_field_solr_type(k)
             if solr_type:
                 result[k + solr_type] = (v or
-                        get_default_for_solr_type(solr_type))
+                                         get_default_for_solr_type(solr_type))
 
         if self.reported_by:
             result['reported_by_s'] = self.reported_by.username
@@ -682,7 +709,7 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             # can search on those instead of the old string-type solr fields.
             if config.get_bool('new_solr'):
                 solr_type = (c.app.globals.get_custom_field_solr_type(f)
-                        or solr_type)
+                             or solr_type)
             actual = solr_field.format(f, solr_type)
             q = q.replace(f + ':', actual + ':')
         return q
@@ -697,7 +724,8 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
 
     @property
     def assigned_to(self):
-        if self.assigned_to_id is None: return None
+        if self.assigned_to_id is None:
+            return None
         return User.query.get(_id=self.assigned_to_id)
 
     @property
@@ -714,7 +742,8 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
 
     @property
     def email_address(self):
-        domain = '.'.join(reversed(self.app.url[1:-1].split('/'))).replace('_', '-')
+        domain = '.'.join(
+            reversed(self.app.url[1:-1].split('/'))).replace('_', '-')
         return '%s@%s%s' % (self.ticket_num, domain, config.common_suffix)
 
     @property
@@ -737,8 +766,8 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
     def notify_post(self):
         monitoring_type = self.app_config.options.get('TicketMonitoringType')
         return monitoring_type == 'AllTicketChanges' or (
-                monitoring_type == 'AllPublicTicketChanges' and
-                not self.private)
+            monitoring_type == 'AllPublicTicketChanges' and
+            not self.private)
 
     def get_custom_user(self, custom_user_field_name):
         fld = None
@@ -750,7 +779,8 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             raise KeyError, 'Custom field "%s" does not exist.' % custom_user_field_name
         if fld.type != 'user':
             raise TypeError, 'Custom field "%s" is of type "%s"; expected ' \
-                             'type "user".' % (custom_user_field_name, fld.type)
+                             'type "user".' % (
+                                 custom_user_field_name, fld.type)
         username = self.custom_fields.get(custom_user_field_name)
         if not username:
             return None
@@ -766,12 +796,13 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
         if bool_flag:
             role_developer = ProjectRole.by_name('Developer')
             role_creator = ProjectRole.by_user(self.reported_by, upsert=True)
-            _allow_all = lambda role, perms: [ACE.allow(role._id, perm) for perm in perms]
+            _allow_all = lambda role, perms: [
+                ACE.allow(role._id, perm) for perm in perms]
             # maintain existing access for developers and the ticket creator,
             # but revoke all access for everyone else
             self.acl = _allow_all(role_developer, security.all_allowed(self, role_developer)) \
-                     + _allow_all(role_creator, security.all_allowed(self, role_creator)) \
-                     + [DENY_ALL]
+                + _allow_all(role_creator, security.all_allowed(self, role_creator)) \
+                + [DENY_ALL]
         else:
             self.acl = []
     private = property(_get_private, _set_private)
@@ -780,62 +811,67 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
         VersionedArtifact.commit(self)
         monitoring_email = self.app.config.options.get('TicketMonitoringEmail')
         if self.version > 1:
-            hist = TicketHistory.query.get(artifact_id=self._id, version=self.version-1)
+            hist = TicketHistory.query.get(
+                artifact_id=self._id, version=self.version - 1)
             old = hist.data
             changes = ['Ticket %s has been modified: %s' % (
-                    self.ticket_num, self.summary),
-                       'Edited By: %s (%s)' % (c.user.get_pref('display_name'), c.user.username)]
+                self.ticket_num, self.summary),
+                'Edited By: %s (%s)' % (c.user.get_pref('display_name'), c.user.username)]
             fields = [
                 ('Summary', old.summary, self.summary),
-                ('Status', old.status, self.status) ]
+                ('Status', old.status, self.status)]
             if old.status != self.status and self.status in c.app.globals.set_of_closed_status_names:
                 h.log_action(log, 'closed').info('')
-                g.statsUpdater.ticketEvent("closed", self, self.project, self.assigned_to)
+                g.statsUpdater.ticketEvent(
+                    "closed", self, self.project, self.assigned_to)
             for key in self.custom_fields:
-                fields.append((key, old.custom_fields.get(key, ''), self.custom_fields[key]))
+                fields.append(
+                    (key, old.custom_fields.get(key, ''), self.custom_fields[key]))
             for title, o, n in fields:
                 if o != n:
                     changes.append('%s updated: %r => %r' % (
-                            title, o, n))
+                        title, o, n))
             o = hist.assigned_to
             n = self.assigned_to
             if o != n:
                 changes.append('Owner updated: %r => %r' % (
-                        o and o.username, n and n.username))
+                    o and o.username, n and n.username))
                 self.subscribe(user=n)
                 g.statsUpdater.ticketEvent("assigned", self, self.project, n)
                 if o:
-                    g.statsUpdater.ticketEvent("revoked", self, self.project, o)
+                    g.statsUpdater.ticketEvent(
+                        "revoked", self, self.project, o)
             if old.description != self.description:
                 changes.append('Description updated:')
                 changes.append('\n'.join(
-                        difflib.unified_diff(
-                            a=old.description.split('\n'),
-                            b=self.description.split('\n'),
-                            fromfile='description-old',
-                            tofile='description-new')))
+                    difflib.unified_diff(
+                        a=old.description.split('\n'),
+                        b=self.description.split('\n'),
+                        fromfile='description-old',
+                        tofile='description-new')))
             description = '\n'.join(changes)
         else:
             self.subscribe()
             if self.assigned_to_id:
                 user = User.query.get(_id=self.assigned_to_id)
-                g.statsUpdater.ticketEvent("assigned", self, self.project, user)
+                g.statsUpdater.ticketEvent(
+                    "assigned", self, self.project, user)
                 self.subscribe(user=user)
             description = ''
             subject = self.email_subject
             Thread.new(discussion_id=self.app_config.discussion_id,
-                   ref_id=self.index_id())
+                       ref_id=self.index_id())
             # First ticket notification. Use persistend Message-ID (self.message_id()).
             # Thus we can group notification emails in one thread later.
             n = Notification.post(
-                    message_id=self.message_id(),
-                    artifact=self,
-                    topic='metadata',
-                    text=description,
-                    subject=subject)
+                message_id=self.message_id(),
+                artifact=self,
+                topic='metadata',
+                text=description,
+                subject=subject)
             if monitoring_email and n and (not self.private or
-                    self.app.config.options.get('TicketMonitoringType') in (
-                        'NewTicketsOnly', 'AllTicketChanges')):
+                                           self.app.config.options.get('TicketMonitoringType') in (
+                                               'NewTicketsOnly', 'AllTicketChanges')):
                 n.send_simple(monitoring_email)
         Feed.post(
             self,
@@ -852,7 +888,8 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
 
     def assigned_to_name(self):
         who = self.assigned_to
-        if who in (None, User.anonymous()): return 'nobody'
+        if who in (None, User.anonymous()):
+            return 'nobody'
         return who.get_pref('display_name')
 
     def update(self, ticket_form):
@@ -866,7 +903,8 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
              other_custom_fields).add(cf['name'])
             if cf['type'] == 'boolean' and 'custom_fields.' + cf['name'] not in ticket_form:
                 self.custom_fields[cf['name']] = 'False'
-        # this has to happen because the milestone custom field has special layout treatment
+        # this has to happen because the milestone custom field has special
+        # layout treatment
         if '_milestone' in ticket_form:
             other_custom_fields.add('_milestone')
             milestone = ticket_form.pop('_milestone', None)
@@ -885,7 +923,7 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             else:
                 setattr(self, k, v)
         if 'custom_fields' in ticket_form:
-            for k,v in ticket_form['custom_fields'].iteritems():
+            for k, v in ticket_form['custom_fields'].iteritems():
                 if k in custom_users:
                     # restrict custom user field values to project members
                     user = self.app_config.project.user_in_project(v)
@@ -903,7 +941,8 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             attach.app_config_id = app_config._id
             if attach.attachment_type == 'DiscussionAttachment':
                 attach.discussion_id = app_config.discussion_id
-            attach_thumb = BaseAttachment.query.get(filename=attach.filename, **attach_metadata)
+            attach_thumb = BaseAttachment.query.get(
+                filename=attach.filename, **attach_metadata)
             if attach_thumb:
                 if attach_thumb.attachment_type == 'DiscussionAttachment':
                     attach_thumb.discussion_id = app_config.discussion_id
@@ -933,18 +972,21 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
         messages = []
         for cf in skipped_fields:
             name = cf[0]
-            messages.append('- **%s**: %s' % (name, self.custom_fields.get(name, '')))
+            messages.append('- **%s**: %s' %
+                            (name, self.custom_fields.get(name, '')))
         for cf in user_fields:
             name = cf[0]
             username = self.custom_fields.get(name, None)
             user = app_config.project.user_in_project(username)
             if not user or user == User.anonymous():
-                messages.append('- **%s**: %s (user not in project)' % (name, username))
+                messages.append('- **%s**: %s (user not in project)' %
+                                (name, username))
                 self.custom_fields[name] = ''
         # special case: not custom user field (assigned_to_id)
         user = self.assigned_to
         if user and not app_config.project.user_in_project(user.username):
-            messages.append('- **assigned_to**: %s (user not in project)' % user.username)
+            messages.append('- **assigned_to**: %s (user not in project)' %
+                            user.username)
             self.assigned_to_id = None
 
         custom_fields = {}
@@ -965,18 +1007,22 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             new_url = app_config.url() + str(self.ticket_num) + '/'
             try:
                 session(self).flush(self)
-                h.log_action(log, 'moved').info('Ticket %s moved to %s' % (prior_url, new_url))
+                h.log_action(log, 'moved').info('Ticket %s moved to %s' %
+                                                (prior_url, new_url))
                 break
             except OperationFailure, err:
                 if 'duplicate' in err.args[0]:
-                    log.warning('Try to create duplicate ticket %s when moving from %s' % (new_url, prior_url))
+                    log.warning(
+                        'Try to create duplicate ticket %s when moving from %s' %
+                        (new_url, prior_url))
                     session(self).expunge(self)
                     continue
 
         attach_metadata['type'] = 'thumbnail'
         self._move_attach(attachments, attach_metadata, app_config)
 
-        # move ticket's discussion thread, thus all new commnets will go to a new ticket's feed
+        # move ticket's discussion thread, thus all new commnets will go to a
+        # new ticket's feed
         self.discussion_thread.app_config_id = app_config._id
         self.discussion_thread.discussion_id = app_config.discussion_id
         for post in self.discussion_thread.posts:
@@ -1015,19 +1061,23 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
                 parents_json.update(parent.__json__(self))
 
         return dict(parents_json,
-            created_date=self.created_date,
-            ticket_num=self.ticket_num,
-            summary=self.summary,
-            description=self.description,
-            reported_by=self.reported_by_username,
-            assigned_to=self.assigned_to_id and self.assigned_to_username or None,
-            reported_by_id=self.reported_by_id and str(self.reported_by_id) or None,
-            assigned_to_id=self.assigned_to_id and str(self.assigned_to_id) or None,
-            status=self.status,
-            private=self.private,
-            attachments=[dict(bytes=attach.length,
-                              url=h.absurl(attach.url())) for attach in self.attachments],
-            custom_fields=dict(self.custom_fields))
+                    created_date=self.created_date,
+                    ticket_num=self.ticket_num,
+                    summary=self.summary,
+                    description=self.description,
+                    reported_by=self.reported_by_username,
+                    assigned_to=self.assigned_to_id and self.assigned_to_username or None,
+                    reported_by_id=self.reported_by_id and str(
+                        self.reported_by_id) or None,
+                    assigned_to_id=self.assigned_to_id and str(
+                        self.assigned_to_id) or None,
+                    status=self.status,
+                    private=self.private,
+                    attachments=[dict(bytes=attach.length,
+                                      url=h.absurl(
+                                          attach.url(
+                                          ))) for attach in self.attachments],
+                    custom_fields=dict(self.custom_fields))
 
     @classmethod
     def paged_query(cls, app_config, user, query, limit=None, page=0, sort=None, deleted=False, **kw):
@@ -1037,7 +1087,8 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
         See also paged_search which does a solr search
         """
         limit, page, start = g.handle_paging(limit, page, default=25)
-        q = cls.query.find(dict(query, app_config_id=app_config._id, deleted=deleted))
+        q = cls.query.find(
+            dict(query, app_config_id=app_config._id, deleted=deleted))
         q = q.sort('ticket_num', pymongo.DESCENDING)
         if sort:
             field, direction = sort.split()
@@ -1055,7 +1106,7 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             if security.has_access(t, 'read', user, app_config.project.root_project):
                 tickets.append(t)
             else:
-                count = count -1
+                count = count - 1
 
         return dict(
             tickets=tickets,
@@ -1088,7 +1139,7 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
         count = 0
         tickets = []
         refined_sort = sort if sort else 'ticket_num_i desc'
-        if  'ticket_num_i' not in refined_sort:
+        if 'ticket_num_i' not in refined_sort:
             refined_sort += ',ticket_num_i asc'
         try:
             if q:
@@ -1106,7 +1157,8 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             # ticket_numbers is in sorted order
             ticket_numbers = [match['ticket_num_i'] for match in matches.docs]
             # but query, unfortunately, returns results in arbitrary order
-            query = cls.query.find(dict(app_config_id=app_config._id, ticket_num={'$in':ticket_numbers}))
+            query = cls.query.find(
+                dict(app_config_id=app_config._id, ticket_num={'$in': ticket_numbers}))
             # so stick all the results in a dictionary...
             ticket_for_num = {}
             for t in query:
@@ -1115,12 +1167,13 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             tickets = []
             for tn in ticket_numbers:
                 if tn in ticket_for_num:
-                    show_deleted = show_deleted and security.has_access(ticket_for_num[tn], 'delete', user, app_config.project.root_project)
+                    show_deleted = show_deleted and security.has_access(
+                        ticket_for_num[tn], 'delete', user, app_config.project.root_project)
                     if (security.has_access(ticket_for_num[tn], 'read', user, app_config.project.root_project) and
-                        (show_deleted or ticket_for_num[tn].deleted==False)):
+                            (show_deleted or ticket_for_num[tn].deleted == False)):
                         tickets.append(ticket_for_num[tn])
                     else:
-                        count = count -1
+                        count = count - 1
         return dict(tickets=tickets,
                     count=count, q=q, limit=limit, page=page, sort=sort,
                     solr_error=solr_error, **kw)
@@ -1135,19 +1188,21 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
                     self.app.config.options.mount_point)))
         return super(Ticket, self).get_mail_footer(notification, toaddr)
 
+
 class TicketAttachment(BaseAttachment):
     thumbnail_size = (100, 100)
-    ArtifactType=Ticket
+    ArtifactType = Ticket
+
     class __mongometa__:
-        polymorphic_identity='TicketAttachment'
-    attachment_type=FieldProperty(str, if_missing='TicketAttachment')
+        polymorphic_identity = 'TicketAttachment'
+    attachment_type = FieldProperty(str, if_missing='TicketAttachment')
 
 
 class MovedTicket(MovedArtifact):
 
     class __mongometa__:
         session = artifact_orm_session
-        name='moved_ticket'
+        name = 'moved_ticket'
         indexes = [
             ('app_config_id', 'ticket_num'),
         ]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeTracker/forgetracker/plugins.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/plugins.py b/ForgeTracker/forgetracker/plugins.py
index 3afbca2..c610de8 100644
--- a/ForgeTracker/forgetracker/plugins.py
+++ b/ForgeTracker/forgetracker/plugins.py
@@ -21,4 +21,3 @@ from tg import config
 from pylons import app_globals as g
 
 log = logging.getLogger(__name__)
-

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeTracker/forgetracker/scripts/import_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/scripts/import_tracker.py b/ForgeTracker/forgetracker/scripts/import_tracker.py
index c60a775..ba8e93f 100644
--- a/ForgeTracker/forgetracker/scripts/import_tracker.py
+++ b/ForgeTracker/forgetracker/scripts/import_tracker.py
@@ -25,8 +25,9 @@ from allura.lib.import_api import AlluraImportApiClient
 
 log = logging.getLogger(__name__)
 
+
 def import_tracker(cli, project, tool, import_options, doc_txt,
-        validate=True, verbose=False, cont=False):
+                   validate=True, verbose=False, cont=False):
     url = '/rest/p/' + project + '/' + tool
     if validate:
         url += '/validate_import'
@@ -35,7 +36,8 @@ def import_tracker(cli, project, tool, import_options, doc_txt,
 
     existing_map = {}
     if cont:
-        existing_tickets = cli.call('/rest/p/' + project + '/' + tool + '/')['tickets']
+        existing_tickets = cli.call(
+            '/rest/p/' + project + '/' + tool + '/')['tickets']
         for t in existing_tickets:
             existing_map[t['ticket_num']] = t['summary']
 
@@ -55,11 +57,12 @@ def import_tracker(cli, project, tool, import_options, doc_txt,
             if verbose:
                 print 'Ticket id %d already exists, skipping' % ticket_in['id']
             continue
-        doc_import={}
+        doc_import = {}
         doc_import['trackers'] = {}
         doc_import['trackers']['default'] = {}
         doc_import['trackers']['default']['artifacts'] = [ticket_in]
-        res = cli.call(url, doc=json.dumps(doc_import), options=json.dumps(import_options))
+        res = cli.call(url, doc=json.dumps(doc_import),
+                       options=json.dumps(import_options))
         assert res['status'] and not res['errors'], res['errors']
         if validate:
             if res['warnings']:
@@ -67,7 +70,9 @@ def import_tracker(cli, project, tool, import_options, doc_txt,
         else:
             print "Imported ticket id %s" % (ticket_in['id'])
 
+
 class ImportTracker(ScriptTask):
+
     @classmethod
     def execute(cls, options):
         user_map = {}
@@ -92,29 +97,43 @@ class ImportTracker(ScriptTask):
             finally:
                 f.close()
         import_options['user_map'] = user_map
-        cli = AlluraImportApiClient(options.base_url, options.api_key, options.secret_key, options.verbose)
+        cli = AlluraImportApiClient(
+            options.base_url, options.api_key, options.secret_key, options.verbose)
         doc_txt = open(options.file_data).read()
-        import_tracker(cli, options.project, options.tracker, import_options, doc_txt,
-                       validate=options.validate,
-                       verbose=options.verbose,
-                       cont=options.cont)
+        import_tracker(
+            cli, options.project, options.tracker, import_options, doc_txt,
+            validate=options.validate,
+            verbose=options.verbose,
+            cont=options.cont)
 
     @classmethod
     def parser(cls):
-        parser = argparse.ArgumentParser(description='import tickets from json')
+        parser = argparse.ArgumentParser(
+            description='import tickets from json')
         parser.add_argument('--nbhd', action='store', default='', dest='nbhd',
-                help='Restrict update to a particular neighborhood, e.g. /p/.')
-        parser.add_argument('-a', '--api-ticket', action='store', dest='api_key', help='API ticket')
-        parser.add_argument('-s', '--secret-key', action='store', dest='secret_key', help='Secret key')
-        parser.add_argument('-p', '--project', action='store', dest='project', help='Project to import to')
-        parser.add_argument('-t', '--tracker', action='store', dest='tracker', help='Tracker to import to')
-        parser.add_argument('-u', '--base-url', dest='base_url', default='https://sourceforge.net', help='Base Allura URL (https://sourceforge.net)')
-        parser.add_argument('-o', dest='import_opts', default=[], action='store',  help='Specify import option(s)', metavar='opt=val')
-        parser.add_argument('--user-map', dest='user_map_file', help='Map original users to SF.net users', metavar='JSON_FILE')
-        parser.add_argument('--file_data', dest='file_data', help='json file', metavar='JSON_FILE')
-        parser.add_argument('--validate', dest='validate', action='store_true', help='Validate import data')
-        parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='Verbose operation')
-        parser.add_argument('-c', '--continue', dest='cont', action='store_true', help='Continue import into existing tracker')
+                            help='Restrict update to a particular neighborhood, e.g. /p/.')
+        parser.add_argument('-a', '--api-ticket',
+                            action='store', dest='api_key', help='API ticket')
+        parser.add_argument('-s', '--secret-key', action='store',
+                            dest='secret_key', help='Secret key')
+        parser.add_argument('-p', '--project', action='store',
+                            dest='project', help='Project to import to')
+        parser.add_argument('-t', '--tracker', action='store',
+                            dest='tracker', help='Tracker to import to')
+        parser.add_argument('-u', '--base-url', dest='base_url',
+                            default='https://sourceforge.net', help='Base Allura URL (https://sourceforge.net)')
+        parser.add_argument('-o', dest='import_opts',
+                            default=[], action='store',  help='Specify import option(s)', metavar='opt=val')
+        parser.add_argument('--user-map', dest='user_map_file',
+                            help='Map original users to SF.net users', metavar='JSON_FILE')
+        parser.add_argument('--file_data', dest='file_data',
+                            help='json file', metavar='JSON_FILE')
+        parser.add_argument('--validate', dest='validate',
+                            action='store_true', help='Validate import data')
+        parser.add_argument('-v', '--verbose', dest='verbose',
+                            action='store_true', help='Verbose operation')
+        parser.add_argument('-c', '--continue', dest='cont',
+                            action='store_true', help='Continue import into existing tracker')
         return parser
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeTracker/forgetracker/tests/command/test_fix_discussion.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/command/test_fix_discussion.py b/ForgeTracker/forgetracker/tests/command/test_fix_discussion.py
index d0cc4d3..8560556 100644
--- a/ForgeTracker/forgetracker/tests/command/test_fix_discussion.py
+++ b/ForgeTracker/forgetracker/tests/command/test_fix_discussion.py
@@ -26,7 +26,8 @@ from allura import model as M
 from forgetracker import model as TM
 
 
-test_config = pkg_resources.resource_filename('allura', '../test.ini') + '#main'
+test_config = pkg_resources.resource_filename(
+    'allura', '../test.ini') + '#main'
 
 
 def setUp(self):
@@ -62,13 +63,15 @@ def break_discussion():
     t.discussion_thread.add_post(text='comment 2')
     session(t).flush(t)
 
+
 def test_fix_discussion():
     break_discussion()
 
     tracker = M.AppConfig.query.find({'options.mount_point': 'bugs'}).first()
     t1 = TM.Ticket.query.get(ticket_num=1)
     t2 = TM.Ticket.query.get(ticket_num=2)
-    assert_not_equal(t1.discussion_thread.discussion.app_config_id, tracker._id)
+    assert_not_equal(
+        t1.discussion_thread.discussion.app_config_id, tracker._id)
     assert_not_equal(t2.discussion_thread.discussion_id, tracker.discussion_id)
 
     cmd = fix_discussion.FixDiscussion('fix-discussion')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeTracker/forgetracker/tests/functional/test_import.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_import.py b/ForgeTracker/forgetracker/tests/functional/test_import.py
index da26ecf..9d47543 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_import.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_import.py
@@ -45,7 +45,7 @@ class TestImportController(TestRestApiBase):
             assert 0, "form error?"
         return resp.follow()
 
-    def set_api_ticket(self, caps={'import': ['Projects','test']}):
+    def set_api_ticket(self, caps={'import': ['Projects', 'test']}):
         api_ticket = M.ApiTicket(user_id=c.user._id, capabilities=caps,
                                  expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
@@ -55,19 +55,19 @@ class TestImportController(TestRestApiBase):
     def test_no_capability(self):
         here_dir = os.path.dirname(__file__)
 
-        self.set_api_ticket({'import2': ['Projects','test']})
+        self.set_api_ticket({'import2': ['Projects', 'test']})
         resp = self.api_post('/rest/p/test/bugs/perform_import',
-            doc=open(here_dir + '/data/sf.json').read(), options='{}')
+                             doc=open(here_dir + '/data/sf.json').read(), options='{}')
         assert resp.status_int == 403
 
         self.set_api_ticket({'import': ['Projects', 'test2']})
         resp = self.api_post('/rest/p/test/bugs/perform_import',
-            doc=open(here_dir + '/data/sf.json').read(), options='{}')
+                             doc=open(here_dir + '/data/sf.json').read(), options='{}')
         assert resp.status_int == 403
 
         self.set_api_ticket({'import': ['Projects', 'test']})
         resp = self.api_post('/rest/p/test/bugs/perform_import',
-            doc=open(here_dir + '/data/sf.json').read(), options='{}')
+                             doc=open(here_dir + '/data/sf.json').read(), options='{}')
         assert resp.status_int == 200
 
     @staticmethod
@@ -79,9 +79,12 @@ class TestImportController(TestRestApiBase):
         assert_equal(from_api['description'], org['description'])
         assert_equal(from_api['summary'], org['summary'])
         assert_equal(from_api['ticket_num'], org['id'])
-        assert_equal(from_api['created_date'], self.time_normalize(org['date']))
-        assert_equal(from_api['mod_date'], self.time_normalize(org['date_updated']))
-        assert_equal(from_api['custom_fields']['_resolution'], org['resolution'])
+        assert_equal(from_api['created_date'],
+                     self.time_normalize(org['date']))
+        assert_equal(from_api['mod_date'],
+                     self.time_normalize(org['date_updated']))
+        assert_equal(from_api['custom_fields']
+                     ['_resolution'], org['resolution'])
         assert_false('_cc' in from_api['custom_fields'])
         assert_equal(from_api['custom_fields']['_private'], org['private'])
 
@@ -90,7 +93,7 @@ class TestImportController(TestRestApiBase):
         here_dir = os.path.dirname(__file__)
         doc_text = open(here_dir + '/data/sf.json').read()
         r = self.api_post('/rest/p/test/bugs/validate_import',
-            doc=doc_text, options='{}')
+                          doc=doc_text, options='{}')
         assert not r.json['errors']
 
     @td.with_tracker
@@ -99,16 +102,17 @@ class TestImportController(TestRestApiBase):
             custom_fields=[
                 dict(name='_resolution', label='Resolution', type='select',
                      options='oné "one and á half" two'),
-               ],
+            ],
             open_status_names='aa bb',
             closed_status_names='cc',
-            )
+        )
         self.app.post(
             '/admin/bugs/set_custom_fields',
             params=variable_encode(params))
         here_dir = os.path.dirname(__file__)
-        api_ticket = M.ApiTicket(user_id=c.user._id, capabilities={'import': ['Projects','test']},
-                                 expires=datetime.utcnow() + timedelta(days=1))
+        api_ticket = M.ApiTicket(
+            user_id=c.user._id, capabilities={'import': ['Projects', 'test']},
+            expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
         self.set_api_token(api_ticket)
 
@@ -116,7 +120,7 @@ class TestImportController(TestRestApiBase):
         doc_json = json.loads(doc_text)
         ticket_json = doc_json['trackers']['default']['artifacts'][0]
         r = self.api_post('/rest/p/test/bugs/perform_import',
-            doc=doc_text, options='{"user_map": {"hinojosa4": "test-admin", "ma_boehm": "test-user"}}')
+                          doc=doc_text, options='{"user_map": {"hinojosa4": "test-admin", "ma_boehm": "test-user"}}')
         assert r.json['status'], r.json
 
         ming.orm.ThreadLocalORMSession.flush_all()
@@ -130,8 +134,9 @@ class TestImportController(TestRestApiBase):
     @td.with_tracker
     def test_import(self):
         here_dir = os.path.dirname(__file__)
-        api_ticket = M.ApiTicket(user_id=c.user._id, capabilities={'import': ['Projects','test']},
-                                 expires=datetime.utcnow() + timedelta(days=1))
+        api_ticket = M.ApiTicket(
+            user_id=c.user._id, capabilities={'import': ['Projects', 'test']},
+            expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
         self.set_api_token(api_ticket)
 
@@ -139,7 +144,7 @@ class TestImportController(TestRestApiBase):
         doc_json = json.loads(doc_text)
         ticket_json = doc_json['trackers']['default']['artifacts'][0]
         r = self.api_post('/rest/p/test/bugs/perform_import',
-            doc=doc_text, options='{"user_map": {"hinojosa4": "test-admin", "ma_boehm": "test-user"}}')
+                          doc=doc_text, options='{"user_map": {"hinojosa4": "test-admin", "ma_boehm": "test-user"}}')
         assert r.json['status']
         assert r.json['errors'] == []
 
@@ -147,7 +152,8 @@ class TestImportController(TestRestApiBase):
         M.MonQTask.run_ready()
         ming.orm.ThreadLocalORMSession.flush_all()
 
-        indexed_tickets = filter(lambda a: a['type_s'] == 'Ticket', g.solr.db.values())
+        indexed_tickets = filter(
+            lambda a: a['type_s'] == 'Ticket', g.solr.db.values())
         assert_equal(len(indexed_tickets), 1)
         assert_equal(indexed_tickets[0]['summary_t'], ticket_json['summary'])
         assert_equal(indexed_tickets[0]['ticket_num_i'], ticket_json['id'])
@@ -176,14 +182,15 @@ class TestImportController(TestRestApiBase):
 
         """
         here_dir = os.path.dirname(__file__)
-        api_ticket = M.ApiTicket(user_id=c.user._id, capabilities={'import': ['Projects','test']},
-                                 expires=datetime.utcnow() + timedelta(days=1))
+        api_ticket = M.ApiTicket(
+            user_id=c.user._id, capabilities={'import': ['Projects', 'test']},
+            expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
         self.set_api_token(api_ticket)
 
         doc_text = open(here_dir + '/data/milestone-tickets.json').read()
         r = self.api_post('/rest/p/test/bugs/perform_import', doc=doc_text,
-            options='{"user_map": {"hinojosa4": "test-admin", "ma_boehm": "test-user"}}')
+                          options='{"user_map": {"hinojosa4": "test-admin", "ma_boehm": "test-user"}}')
         assert r.json['status'], r.json
 
         ming.orm.ThreadLocalORMSession.flush_all()
@@ -192,7 +199,8 @@ class TestImportController(TestRestApiBase):
 
         with h.push_context('test', mount_point='bugs', neighborhood='Projects'):
             for milestone_fld in c.app.globals.milestone_fields:
-                milestone_names = [ms['name'] for ms in milestone_fld['milestones']]
+                milestone_names = [ms['name']
+                                   for ms in milestone_fld['milestones']]
                 assert 'open_milestone' in milestone_names, milestone_names
                 assert 'closed_milestone' in milestone_names, milestone_names
                 for milestone in milestone_fld['milestones']:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeTracker/forgetracker/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_rest.py b/ForgeTracker/forgetracker/tests/functional/test_rest.py
index aad1401..b7f4101 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_rest.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_rest.py
@@ -27,6 +27,7 @@ from alluratest.controller import TestRestApiBase
 
 from forgetracker import model as TM
 
+
 class TestTrackerApiBase(TestRestApiBase):
 
     def setUp(self):
@@ -34,8 +35,8 @@ class TestTrackerApiBase(TestRestApiBase):
         self.setup_with_tools()
 
     @td.with_tool('test', 'Tickets', 'bugs',
-            TicketMonitoringEmail='test@localhost',
-            TicketMonitoringType='AllTicketChanges')
+                  TicketMonitoringEmail='test@localhost',
+                  TicketMonitoringType='AllTicketChanges')
     def setup_with_tools(self):
         h.set_context('test', 'bugs', neighborhood='Projects')
         self.tracker_globals = c.app.globals
@@ -50,8 +51,8 @@ class TestTrackerApiBase(TestRestApiBase):
                 labels='',
                 description='',
                 assigned_to='',
-                **{'custom_fields._milestone':''})
-            )
+                **{'custom_fields._milestone': ''})
+        )
 
 
 class TestRestNewTicket(TestTrackerApiBase):
@@ -67,7 +68,7 @@ class TestRestNewTicket(TestTrackerApiBase):
                 labels='foo,bar',
                 description='descr',
                 assigned_to='',
-                **{'custom_fields._milestone':''}
+                **{'custom_fields._milestone': ''}
             ))
         json = ticket_view.json['ticket']
         assert json['status'] == 'open', json
@@ -80,6 +81,7 @@ class TestRestNewTicket(TestTrackerApiBase):
     def test_invalid_ticket(self):
         self.app.get('/rest/p/test/bugs/2', status=404)
 
+
 class TestRestUpdateTicket(TestTrackerApiBase):
 
     def setUp(self):
@@ -91,10 +93,11 @@ class TestRestUpdateTicket(TestTrackerApiBase):
         args = dict(self.ticket_args, summary='test update ticket', labels='',
                     assigned_to=self.ticket_args['assigned_to_id'] or '')
         for bad_key in ('ticket_num', 'assigned_to_id', 'created_date',
-                'reported_by', 'reported_by_id', '_id', 'votes_up', 'votes_down'):
+                        'reported_by', 'reported_by_id', '_id', 'votes_up', 'votes_down'):
             del args[bad_key]
         args['private'] = str(args['private'])
-        ticket_view = self.api_post('/rest/p/test/bugs/1/save', wrap_args='ticket_form', params=h.encode_keys(args))
+        ticket_view = self.api_post(
+            '/rest/p/test/bugs/1/save', wrap_args='ticket_form', params=h.encode_keys(args))
         assert ticket_view.status_int == 200, ticket_view.showbrowser()
         json = ticket_view.json['ticket']
         assert int(json['ticket_num']) == 1
@@ -112,13 +115,18 @@ class TestRestIndex(TestTrackerApiBase):
         assert len(tickets.json['tickets']) == 1, tickets.json
         assert (tickets.json['tickets'][0]
                 == dict(ticket_num=1, summary='test new ticket')), tickets.json['tickets'][0]
-        assert tickets.json['tracker_config']['options']['mount_point'] == 'bugs'
-        assert tickets.json['tracker_config']['options']['TicketMonitoringType'] == 'AllTicketChanges'
+        assert tickets.json['tracker_config'][
+            'options']['mount_point'] == 'bugs'
+        assert tickets.json['tracker_config']['options'][
+            'TicketMonitoringType'] == 'AllTicketChanges'
         assert not tickets.json['tracker_config']['options']['EnableVoting']
-        assert tickets.json['tracker_config']['options']['TicketMonitoringEmail'] == 'test@localhost'
-        assert tickets.json['tracker_config']['options']['mount_label'] == 'Tickets'
+        assert tickets.json['tracker_config']['options'][
+            'TicketMonitoringEmail'] == 'test@localhost'
+        assert tickets.json['tracker_config'][
+            'options']['mount_label'] == 'Tickets'
         assert tickets.json['saved_bins'][0]['sort'] == 'mod_date_dt desc'
-        assert tickets.json['saved_bins'][0]['terms'] == '!status:wont-fix && !status:closed'
+        assert tickets.json['saved_bins'][0][
+            'terms'] == '!status:wont-fix && !status:closed'
         assert tickets.json['saved_bins'][0]['summary'] == 'Changes'
         assert len(tickets.json['saved_bins'][0]) == 4
         assert tickets.json['milestones'][0]['name'] == '1.0'
@@ -126,10 +134,13 @@ class TestRestIndex(TestTrackerApiBase):
 
     def test_ticket_index_noauth(self):
         tickets = self.api_get('/rest/p/test/bugs', user='*anonymous')
-        assert 'TicketMonitoringEmail' not in tickets.json['tracker_config']['options']
+        assert 'TicketMonitoringEmail' not in tickets.json[
+            'tracker_config']['options']
         # make sure it didn't get removed from the db too
-        ticket_config = M.AppConfig.query.get(project_id=c.project._id, tool_name='tickets')
-        assert_equal(ticket_config.options.get('TicketMonitoringEmail'), 'test@localhost')
+        ticket_config = M.AppConfig.query.get(
+            project_id=c.project._id, tool_name='tickets')
+        assert_equal(ticket_config.options.get('TicketMonitoringEmail'),
+                     'test@localhost')
 
     @td.with_tool('test', 'Tickets', 'dummy')
     def test_move_ticket_redirect(self):
@@ -154,23 +165,30 @@ class TestRestDiscussion(TestTrackerApiBase):
         r = self.api_get('/rest/p/test/bugs/_discuss/')
         assert len(r.json['discussion']['threads']) == 1, r.json
         for t in r.json['discussion']['threads']:
-            r = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' % t['_id'])
+            r = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' %
+                             t['_id'])
             assert len(r.json['thread']['posts']) == 0, r.json
 
     def test_post(self):
-        discussion = self.api_get('/rest/p/test/bugs/_discuss/').json['discussion']
-        post = self.api_post('/rest/p/test/bugs/_discuss/thread/%s/new' % discussion['threads'][0]['_id'],
-                             text='This is a comment', wrap_args=None)
-        thread = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' % discussion['threads'][0]['_id'])
+        discussion = self.api_get(
+            '/rest/p/test/bugs/_discuss/').json['discussion']
+        post = self.api_post(
+            '/rest/p/test/bugs/_discuss/thread/%s/new' % discussion['threads'][0]['_id'],
+            text='This is a comment', wrap_args=None)
+        thread = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' %
+                              discussion['threads'][0]['_id'])
         assert len(thread.json['thread']['posts']) == 1, thread.json
         assert post.json['post']['text'] == 'This is a comment', post.json
         reply = self.api_post(
-            '/rest/p/test/bugs/_discuss/thread/%s/%s/reply' % (thread.json['thread']['_id'], post.json['post']['slug']),
+            '/rest/p/test/bugs/_discuss/thread/%s/%s/reply' % (thread.json['thread']
+                                                               ['_id'], post.json['post']['slug']),
             text='This is a reply', wrap_args=None)
         assert reply.json['post']['text'] == 'This is a reply', reply.json
-        thread = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' % discussion['threads'][0]['_id'])
+        thread = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' %
+                              discussion['threads'][0]['_id'])
         assert len(thread.json['thread']['posts']) == 2, thread.json
 
+
 class TestRestSearch(TestTrackerApiBase):
 
     @patch('forgetracker.model.Ticket.paged_search')
@@ -180,7 +198,7 @@ class TestRestSearch(TestTrackerApiBase):
         ])
         r = self.api_get('/rest/p/test/bugs/search')
         assert_equal(r.status_int, 200)
-        assert_equal(r.json, {'tickets':[
+        assert_equal(r.json, {'tickets': [
             {'summary': 'our test ticket', 'ticket_num': 5},
         ]})
 
@@ -188,18 +206,20 @@ class TestRestSearch(TestTrackerApiBase):
     def test_some_criteria(self, paged_search):
         q = 'labels:testing && status:open'
         paged_search.return_value = dict(tickets=[
-                TM.Ticket(ticket_num=5, summary='our test ticket'),
-            ],
+            TM.Ticket(ticket_num=5, summary='our test ticket'),
+        ],
             sort='status',
             limit=2,
             count=1,
             page=0,
             q=q,
         )
-        r = self.api_get('/rest/p/test/bugs/search', q=q, sort='status', limit='2')
+        r = self.api_get('/rest/p/test/bugs/search',
+                         q=q, sort='status', limit='2')
         assert_equal(r.status_int, 200)
-        assert_equal(r.json, {'limit': 2, 'q': q, 'sort':'status', 'count': 1,
-                               'page': 0, 'tickets':[
-                {'summary': 'our test ticket', 'ticket_num': 5},
-            ]
-        })
+        assert_equal(r.json, {'limit': 2, 'q': q, 'sort': 'status', 'count': 1,
+                              'page': 0, 'tickets': [
+                                  {'summary': 'our test ticket',
+                                   'ticket_num': 5},
+                              ]
+                              })