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:23:19 UTC
[23/36] PEP8 cleanup
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/Allura/allura/model/notification.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index 5743ffe..10689f1 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -58,9 +58,11 @@ from .auth import User
log = logging.getLogger(__name__)
-MAILBOX_QUIESCENT=None # Re-enable with [#1384]: timedelta(minutes=10)
+MAILBOX_QUIESCENT = None # Re-enable with [#1384]: timedelta(minutes=10)
+
class Notification(MappedClass):
+
'''
Temporarily store notifications that will be emailed or displayed as a web flash.
This does not contain any recipient information.
@@ -74,31 +76,33 @@ class Notification(MappedClass):
_id = FieldProperty(str, if_missing=h.gen_message_id)
# Classify notifications
- neighborhood_id = ForeignIdProperty('Neighborhood', if_missing=lambda:c.project.neighborhood._id)
- project_id = ForeignIdProperty('Project', if_missing=lambda:c.project._id)
- app_config_id = ForeignIdProperty('AppConfig', if_missing=lambda:c.app.config._id)
- tool_name = FieldProperty(str, if_missing=lambda:c.app.config.tool_name)
+ neighborhood_id = ForeignIdProperty(
+ 'Neighborhood', if_missing=lambda: c.project.neighborhood._id)
+ project_id = ForeignIdProperty('Project', if_missing=lambda: c.project._id)
+ app_config_id = ForeignIdProperty(
+ 'AppConfig', if_missing=lambda: c.app.config._id)
+ tool_name = FieldProperty(str, if_missing=lambda: c.app.config.tool_name)
ref_id = ForeignIdProperty('ArtifactReference')
topic = FieldProperty(str)
# Notification Content
- in_reply_to=FieldProperty(str)
- references=FieldProperty([str])
- from_address=FieldProperty(str)
- reply_to_address=FieldProperty(str)
- subject=FieldProperty(str)
- text=FieldProperty(str)
- link=FieldProperty(str)
- author_id=ForeignIdProperty('User')
- feed_meta=FieldProperty(S.Deprecated)
+ in_reply_to = FieldProperty(str)
+ references = FieldProperty([str])
+ from_address = FieldProperty(str)
+ reply_to_address = FieldProperty(str)
+ subject = FieldProperty(str)
+ text = FieldProperty(str)
+ link = FieldProperty(str)
+ author_id = ForeignIdProperty('User')
+ feed_meta = FieldProperty(S.Deprecated)
artifact_reference = FieldProperty(S.Deprecated)
pubdate = FieldProperty(datetime, if_missing=datetime.utcnow)
ref = RelationProperty('ArtifactReference')
view = jinja2.Environment(
- loader=jinja2.PackageLoader('allura', 'templates'),
- auto_reload=asbool(config.get('auto_reload_templates', True)),
+ loader=jinja2.PackageLoader('allura', 'templates'),
+ auto_reload=asbool(config.get('auto_reload_templates', True)),
)
@classmethod
@@ -155,19 +159,24 @@ class Notification(MappedClass):
attach.file.seek(0, 2)
bytecount = attach.file.tell()
attach.file.seek(0)
- text = "%s %s (%s; %s) " % (text, attach.filename, h.do_filesizeformat(bytecount), attach.type)
+ text = "%s %s (%s; %s) " % (
+ text, attach.filename, h.do_filesizeformat(bytecount), attach.type)
subject = post.subject or ''
if post.parent_id and not subject.lower().startswith('re:'):
subject = 'Re: ' + subject
author = post.author()
msg_id = artifact.url() + post._id
- parent_msg_id = artifact.url() + post.parent_id if post.parent_id else artifact.message_id()
+ parent_msg_id = artifact.url() + \
+ post.parent_id if post.parent_id else artifact.message_id(
+ )
d = dict(
_id=msg_id,
- from_address=str(author._id) if author != User.anonymous() else None,
+ from_address=str(
+ author._id) if author != User.anonymous() else None,
reply_to_address='"%s" <%s>' % (
- subject_prefix, getattr(artifact, 'email_address', u'noreply@in.sf.net')),
+ subject_prefix, getattr(
+ artifact, 'email_address', u'noreply@in.sf.net')),
subject=subject_prefix + subject,
text=text,
in_reply_to=parent_msg_id,
@@ -181,7 +190,7 @@ class Notification(MappedClass):
return n
else:
subject = kwargs.pop('subject', '%s modified by %s' % (
- h.get_first(idx, 'title'),c.user.get_pref('display_name')))
+ h.get_first(idx, 'title'), c.user.get_pref('display_name')))
reply_to = '"%s" <%s>' % (
h.get_first(idx, 'title'),
getattr(artifact, 'email_address', u'noreply@in.sf.net'))
@@ -206,23 +215,27 @@ class Notification(MappedClass):
d['text'] = ''
try:
''' Add addional text to the notification e-mail based on the artifact type '''
- template = cls.view.get_template('mail/' + artifact.type_s + '.txt')
- d['text'] += template.render(dict(c=c, g=g, config=config, data=artifact, post=post, h=h))
+ template = cls.view.get_template(
+ 'mail/' + artifact.type_s + '.txt')
+ d['text'] += template.render(dict(c=c, g=g,
+ config=config, data=artifact, post=post, h=h))
except jinja2.TemplateNotFound:
pass
except:
''' Catch any errors loading or rendering the template,
but the notification still gets sent if there is an error
'''
- log.warn('Could not render notification template %s' % artifact.type_s, exc_info=True)
+ log.warn('Could not render notification template %s' %
+ artifact.type_s, exc_info=True)
assert d['reply_to_address'] is not None
project = c.project
if d.get('project_id', c.project._id) != c.project._id:
project = Project.query.get(_id=d['project_id'])
if project.notifications_disabled:
- log.info('Notifications disabled for project %s, not sending %s(%r)',
- project.shortname, topic, artifact)
+ log.info(
+ 'Notifications disabled for project %s, not sending %s(%r)',
+ project.shortname, topic, artifact)
return None
n = cls(ref_id=artifact.index_id(),
topic=topic,
@@ -264,10 +277,12 @@ class Notification(MappedClass):
def send_direct(self, user_id):
user = User.query.get(_id=ObjectId(user_id), disabled=False)
artifact = self.ref.artifact
- log.debug('Sending direct notification %s to user %s', self._id, user_id)
+ log.debug('Sending direct notification %s to user %s',
+ self._id, user_id)
# Don't send if user disabled
if not user:
- log.debug("Skipping notification - enabled user %s not found" % user_id)
+ log.debug("Skipping notification - enabled user %s not found" %
+ user_id)
return
# Don't send if user doesn't have read perms to the artifact
if user and artifact and \
@@ -275,9 +290,10 @@ class Notification(MappedClass):
log.debug("Skipping notification - User %s doesn't have read "
"access to artifact %s" % (user_id, str(self.ref_id)))
log.debug("User roles [%s]; artifact ACL [%s]; PSC ACL [%s]",
- ', '.join([str(r) for r in security.Credentials.get().user_roles(user_id=user_id, project_id=artifact.project._id).reaching_ids]),
- ', '.join([str(a) for a in artifact.acl]),
- ', '.join([str(a) for a in artifact.parent_security_context().acl]))
+ ', '.join([str(r) for r in security.Credentials.get().user_roles(
+ user_id=user_id, project_id=artifact.project._id).reaching_ids]),
+ ', '.join([str(a) for a in artifact.acl]),
+ ', '.join([str(a) for a in artifact.parent_security_context().acl]))
return
allura.tasks.mail_tasks.sendmail.post(
destinations=[str(user_id)],
@@ -293,23 +309,27 @@ class Notification(MappedClass):
@classmethod
def send_digest(self, user_id, from_address, subject, notifications,
reply_to_address=None):
- if not notifications: return
+ if not notifications:
+ return
user = User.query.get(_id=ObjectId(user_id), disabled=False)
if not user:
- log.debug("Skipping notification - enabled user %s not found " % user_id)
+ log.debug("Skipping notification - enabled user %s not found " %
+ user_id)
return
# Filter out notifications for which the user doesn't have read
# permissions to the artifact.
artifact = self.ref.artifact
+
def perm_check(notification):
return not (user and artifact) or \
- security.has_access(artifact, 'read', user)()
+ security.has_access(artifact, 'read', user)()
notifications = filter(perm_check, notifications)
- log.debug('Sending digest of notifications [%s] to user %s', ', '.join([n._id for n in notifications]), user_id)
+ log.debug('Sending digest of notifications [%s] to user %s', ', '.join(
+ [n._id for n in notifications]), user_id)
if reply_to_address is None:
reply_to_address = from_address
- text = [ 'Digest of %s' % subject ]
+ text = ['Digest of %s' % subject]
for n in notifications:
text.append('From: %s' % n.from_address)
text.append('Subject: %s' % (n.subject or '(no subject)'))
@@ -328,9 +348,11 @@ class Notification(MappedClass):
@classmethod
def send_summary(self, user_id, from_address, subject, notifications):
- if not notifications: return
- log.debug('Sending summary of notifications [%s] to user %s', ', '.join([n._id for n in notifications]), user_id)
- text = [ 'Digest of %s' % subject ]
+ if not notifications:
+ return
+ log.debug('Sending summary of notifications [%s] to user %s', ', '.join(
+ [n._id for n in notifications]), user_id)
+ text = ['Digest of %s' % subject]
for n in notifications:
text.append('From: %s' % n.from_address)
text.append('Subject: %s' % (n.subject or '(no subject)'))
@@ -349,6 +371,7 @@ class Notification(MappedClass):
class Mailbox(MappedClass):
+
'''
Holds a queue of notifications for an artifact, or a user (webflash messages)
for a subscriber.
@@ -361,19 +384,21 @@ class Mailbox(MappedClass):
unique_indexes = [
('user_id', 'project_id', 'app_config_id',
'artifact_index_id', 'topic', 'is_flash'),
- ]
+ ]
indexes = [
('project_id', 'artifact_index_id'),
('is_flash', 'user_id'),
('type', 'next_scheduled'), # for q_digest
('type', 'queue_empty'), # for q_direct
- ('project_id', 'app_config_id', 'artifact_index_id', 'topic'), # for deliver()
+ # for deliver()
+ ('project_id', 'app_config_id', 'artifact_index_id', 'topic'),
]
_id = FieldProperty(S.ObjectId)
- user_id = ForeignIdProperty('User', if_missing=lambda:c.user._id)
- project_id = ForeignIdProperty('Project', if_missing=lambda:c.project._id)
- app_config_id = ForeignIdProperty('AppConfig', if_missing=lambda:c.app.config._id)
+ user_id = ForeignIdProperty('User', if_missing=lambda: c.user._id)
+ project_id = ForeignIdProperty('Project', if_missing=lambda: c.project._id)
+ app_config_id = ForeignIdProperty(
+ 'AppConfig', if_missing=lambda: c.app.config._id)
# Subscription filters
artifact_title = FieldProperty(str)
@@ -385,9 +410,9 @@ class Mailbox(MappedClass):
is_flash = FieldProperty(bool, if_missing=False)
type = FieldProperty(S.OneOf('direct', 'digest', 'summary', 'flash'))
frequency = FieldProperty(dict(
- n=int,unit=S.OneOf('day', 'week', 'month')))
+ n=int, unit=S.OneOf('day', 'week', 'month')))
next_scheduled = FieldProperty(datetime, if_missing=datetime.utcnow)
- last_modified = FieldProperty(datetime, if_missing=datetime(2000,1,1))
+ last_modified = FieldProperty(datetime, if_missing=datetime(2000, 1, 1))
# a list of notification _id values
queue = FieldProperty([str])
@@ -398,17 +423,20 @@ class Mailbox(MappedClass):
@classmethod
def subscribe(
- cls,
- user_id=None, project_id=None, app_config_id=None,
- artifact=None, topic=None,
- type='direct', n=1, unit='day'):
- if user_id is None: user_id = c.user._id
- if project_id is None: project_id = c.project._id
- if app_config_id is None: app_config_id = c.app.config._id
+ cls,
+ user_id=None, project_id=None, app_config_id=None,
+ artifact=None, topic=None,
+ type='direct', n=1, unit='day'):
+ if user_id is None:
+ user_id = c.user._id
+ if project_id is None:
+ project_id = c.project._id
+ if app_config_id is None:
+ app_config_id = c.app.config._id
tool_already_subscribed = cls.query.get(user_id=user_id,
- project_id=project_id,
- app_config_id=app_config_id,
- artifact_index_id=None)
+ project_id=project_id,
+ app_config_id=app_config_id,
+ artifact_index_id=None)
if tool_already_subscribed:
return
if artifact is None:
@@ -421,13 +449,14 @@ class Mailbox(MappedClass):
artifact_url = artifact.url()
artifact_index_id = i['id']
artifact_already_subscribed = cls.query.get(user_id=user_id,
- project_id=project_id,
- app_config_id=app_config_id,
- artifact_index_id=artifact_index_id)
+ project_id=project_id,
+ app_config_id=app_config_id,
+ artifact_index_id=artifact_index_id)
if artifact_already_subscribed:
return
- d = dict(user_id=user_id, project_id=project_id, app_config_id=app_config_id,
- artifact_index_id=artifact_index_id, topic=topic)
+ d = dict(
+ user_id=user_id, project_id=project_id, app_config_id=app_config_id,
+ artifact_index_id=artifact_index_id, topic=topic)
sess = session(cls)
try:
mbox = cls(
@@ -446,44 +475,51 @@ class Mailbox(MappedClass):
mbox.frequency.unit = unit
sess.flush(mbox)
if not artifact_index_id:
- # Unsubscribe from individual artifacts when subscribing to the tool
+ # Unsubscribe from individual artifacts when subscribing to the
+ # tool
for other_mbox in cls.query.find(dict(
- user_id=user_id, project_id=project_id, app_config_id=app_config_id)):
+ user_id=user_id, project_id=project_id, app_config_id=app_config_id)):
if other_mbox is not mbox:
other_mbox.delete()
@classmethod
def unsubscribe(
- cls,
- user_id=None, project_id=None, app_config_id=None,
- artifact_index_id=None, topic=None):
- if user_id is None: user_id = c.user._id
- if project_id is None: project_id = c.project._id
- if app_config_id is None: app_config_id = c.app.config._id
+ cls,
+ user_id=None, project_id=None, app_config_id=None,
+ artifact_index_id=None, topic=None):
+ if user_id is None:
+ user_id = c.user._id
+ if project_id is None:
+ project_id = c.project._id
+ if app_config_id is None:
+ app_config_id = c.app.config._id
cls.query.remove(dict(
- user_id=user_id,
- project_id=project_id,
- app_config_id=app_config_id,
- artifact_index_id=artifact_index_id,
- topic=topic))
+ user_id=user_id,
+ project_id=project_id,
+ app_config_id=app_config_id,
+ artifact_index_id=artifact_index_id,
+ topic=topic))
@classmethod
def subscribed(
- cls, user_id=None, project_id=None, app_config_id=None,
- artifact=None, topic=None):
- if user_id is None: user_id = c.user._id
- if project_id is None: project_id = c.project._id
- if app_config_id is None: app_config_id = c.app.config._id
+ cls, user_id=None, project_id=None, app_config_id=None,
+ artifact=None, topic=None):
+ if user_id is None:
+ user_id = c.user._id
+ if project_id is None:
+ project_id = c.project._id
+ if app_config_id is None:
+ app_config_id = c.app.config._id
if artifact is None:
artifact_index_id = None
else:
i = artifact.index()
artifact_index_id = i['id']
return cls.query.find(dict(
- user_id=user_id,
- project_id=project_id,
- app_config_id=app_config_id,
- artifact_index_id=artifact_index_id)).count() != 0
+ user_id=user_id,
+ project_id=project_id,
+ app_config_id=app_config_id,
+ artifact_index_id=artifact_index_id)).count() != 0
@classmethod
def deliver(cls, nid, artifact_index_id, topic):
@@ -492,20 +528,21 @@ class Mailbox(MappedClass):
to the appropriate mailboxes.
'''
d = {
- 'project_id':c.project._id,
- 'app_config_id':c.app.config._id,
- 'artifact_index_id':{'$in':[None, artifact_index_id]},
- 'topic':{'$in':[None, topic]}
- }
+ 'project_id': c.project._id,
+ 'app_config_id': c.app.config._id,
+ 'artifact_index_id': {'$in': [None, artifact_index_id]},
+ 'topic': {'$in': [None, topic]}
+ }
mboxes = cls.query.find(d).all()
- log.debug('Delivering notification %s to mailboxes [%s]', nid, ', '.join([str(m._id) for m in mboxes]))
+ log.debug('Delivering notification %s to mailboxes [%s]', nid, ', '.join(
+ [str(m._id) for m in mboxes]))
for mbox in mboxes:
try:
mbox.query.update(
- {'$push':dict(queue=nid),
- '$set':dict(last_modified=datetime.utcnow(),
- queue_empty=False),
- })
+ {'$push': dict(queue=nid),
+ '$set': dict(last_modified=datetime.utcnow(),
+ queue_empty=False),
+ })
# Make sure the mbox doesn't stick around to be flush()ed
session(mbox).expunge(mbox)
except:
@@ -528,26 +565,29 @@ class Mailbox(MappedClass):
queue_empty=False,
)
if MAILBOX_QUIESCENT:
- q_direct['last_modified']={'$lt':now - MAILBOX_QUIESCENT}
+ q_direct['last_modified'] = {'$lt': now - MAILBOX_QUIESCENT}
q_digest = dict(
type={'$in': ['digest', 'summary']},
- next_scheduled={'$lt':now})
+ next_scheduled={'$lt': now})
def find_and_modify_direct_mbox():
return cls.query.find_and_modify(
query=q_direct,
update={'$set': dict(
- queue=[],
- queue_empty=True,
- )},
+ queue=[],
+ queue_empty=True,
+ )},
new=False)
for mbox in take_while_true(find_and_modify_direct_mbox):
try:
mbox.fire(now)
except:
- log.exception('Error firing mbox: %s with queue: [%s]', str(mbox._id), ', '.join(mbox.queue))
- raise # re-raise so we don't keep (destructively) trying to process mboxes
+ log.exception(
+ 'Error firing mbox: %s with queue: [%s]', str(mbox._id), ', '.join(mbox.queue))
+ # re-raise so we don't keep (destructively) trying to process
+ # mboxes
+ raise
for mbox in cls.query.find(q_digest):
next_scheduled = now
@@ -571,12 +611,14 @@ class Mailbox(MappedClass):
'''
Send all notifications that this mailbox has enqueued.
'''
- notifications = Notification.query.find(dict(_id={'$in':self.queue}))
+ notifications = Notification.query.find(dict(_id={'$in': self.queue}))
notifications = notifications.all()
if len(notifications) != len(self.queue):
- log.error('Mailbox queue error: Mailbox %s queued [%s], found [%s]', str(self._id), ', '.join(self.queue), ', '.join([n._id for n in notifications]))
+ log.error('Mailbox queue error: Mailbox %s queued [%s], found [%s]', str(
+ self._id), ', '.join(self.queue), ', '.join([n._id for n in notifications]))
else:
- log.debug('Firing mailbox %s notifications [%s], found [%s]', str(self._id), ', '.join(self.queue), ', '.join([n._id for n in notifications]))
+ log.debug('Firing mailbox %s notifications [%s], found [%s]', str(
+ self._id), ', '.join(self.queue), ', '.join([n._id for n in notifications]))
if self.type == 'direct':
ngroups = defaultdict(list)
for n in notifications:
@@ -586,7 +628,8 @@ class Mailbox(MappedClass):
# Messages must be sent individually so they can be replied
# to individually
else:
- key = (n.subject, n.from_address, n.reply_to_address, n.author_id)
+ key = (n.subject, n.from_address,
+ n.reply_to_address, n.author_id)
ngroups[key].append(n)
except:
# log error but keep trying to deliver other notifications,
@@ -633,18 +676,19 @@ class MailFooter(object):
@classmethod
def standard(cls, notification):
return cls._render('mail/footer.txt',
- notification=notification,
- prefix=config.get('forgemail.url', 'https://sourceforge.net'))
+ notification=notification,
+ prefix=config.get('forgemail.url', 'https://sourceforge.net'))
@classmethod
def monitored(cls, toaddr, app_url, setting_url):
return cls._render('mail/monitor_email_footer.txt',
- email=toaddr,
- app_url=app_url,
- setting_url=setting_url)
+ email=toaddr,
+ app_url=app_url,
+ setting_url=setting_url)
class SiteNotification(MappedClass):
+
"""
Storage for site-wide notification.
"""
@@ -656,7 +700,8 @@ class SiteNotification(MappedClass):
_id = FieldProperty(S.ObjectId)
content = FieldProperty(str, if_missing='')
active = FieldProperty(bool, if_missing=True)
- impressions = FieldProperty(int, if_missing=lambda:config.get('site_notification.impressions', 0))
+ impressions = FieldProperty(
+ int, if_missing=lambda: config.get('site_notification.impressions', 0))
@classmethod
def current(cls):
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/Allura/allura/model/oauth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/oauth.py b/Allura/allura/model/oauth.py
index 531fceb..670847a 100644
--- a/Allura/allura/model/oauth.py
+++ b/Allura/allura/model/oauth.py
@@ -31,17 +31,19 @@ from .types import MarkdownCache
log = logging.getLogger(__name__)
+
class OAuthToken(MappedClass):
+
class __mongometa__:
session = main_orm_session
- name='oauth_token'
- indexes = [ 'api_key' ]
- polymorphic_on='type'
- polymorphic_identity=None
+ name = 'oauth_token'
+ indexes = ['api_key']
+ polymorphic_on = 'type'
+ polymorphic_identity = None
_id = FieldProperty(S.ObjectId)
- type=FieldProperty(str)
- api_key = FieldProperty(str, if_missing=lambda:h.nonce(20))
+ type = FieldProperty(str)
+ api_key = FieldProperty(str, if_missing=lambda: h.nonce(20))
secret_key = FieldProperty(str, if_missing=h.cryptographic_nonce)
def to_string(self):
@@ -50,19 +52,20 @@ class OAuthToken(MappedClass):
def as_token(self):
return oauth.Token(self.api_key, self.secret_key)
+
class OAuthConsumerToken(OAuthToken):
+
class __mongometa__:
- polymorphic_identity='consumer'
- name='oauth_consumer_token'
- unique_indexes = [ 'name' ]
+ polymorphic_identity = 'consumer'
+ name = 'oauth_consumer_token'
+ unique_indexes = ['name']
type = FieldProperty(str, if_missing='consumer')
- user_id = ForeignIdProperty('User', if_missing=lambda:c.user._id)
+ user_id = ForeignIdProperty('User', if_missing=lambda: c.user._id)
name = FieldProperty(str)
description = FieldProperty(str)
description_cache = FieldProperty(MarkdownCache)
-
user = RelationProperty('User')
@property
@@ -76,37 +79,43 @@ class OAuthConsumerToken(OAuthToken):
@classmethod
def for_user(cls, user=None):
- if user is None: user = c.user
+ if user is None:
+ user = c.user
return cls.query.find(dict(user_id=user._id)).all()
+
class OAuthRequestToken(OAuthToken):
+
class __mongometa__:
- polymorphic_identity='request'
+ polymorphic_identity = 'request'
type = FieldProperty(str, if_missing='request')
consumer_token_id = ForeignIdProperty('OAuthConsumerToken')
- user_id = ForeignIdProperty('User', if_missing=lambda:c.user._id)
+ user_id = ForeignIdProperty('User', if_missing=lambda: c.user._id)
callback = FieldProperty(str)
validation_pin = FieldProperty(str)
consumer_token = RelationProperty('OAuthConsumerToken')
+
class OAuthAccessToken(OAuthToken):
+
class __mongometa__:
- polymorphic_identity='access'
+ polymorphic_identity = 'access'
type = FieldProperty(str, if_missing='access')
consumer_token_id = ForeignIdProperty('OAuthConsumerToken')
request_token_id = ForeignIdProperty('OAuthToken')
- user_id = ForeignIdProperty('User', if_missing=lambda:c.user._id)
+ user_id = ForeignIdProperty('User', if_missing=lambda: c.user._id)
is_bearer = FieldProperty(bool, if_missing=False)
user = RelationProperty('User')
- consumer_token = RelationProperty('OAuthConsumerToken', via='consumer_token_id')
+ consumer_token = RelationProperty(
+ 'OAuthConsumerToken', via='consumer_token_id')
request_token = RelationProperty('OAuthToken', via='request_token_id')
@classmethod
def for_user(cls, user=None):
- if user is None: user = c.user
+ if user is None:
+ user = c.user
return cls.query.find(dict(user_id=user._id, type='access')).all()
-
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/Allura/allura/model/openid_model.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/openid_model.py b/Allura/allura/model/openid_model.py
index 9c401c9..adcf179 100644
--- a/Allura/allura/model/openid_model.py
+++ b/Allura/allura/model/openid_model.py
@@ -27,14 +27,16 @@ from ming.orm.declarative import MappedClass
from .session import main_doc_session, main_orm_session
from .session import project_doc_session, project_orm_session
+
class OpenIdAssociation(MappedClass):
+
class __mongometa__:
- name='oid_store_assoc'
+ name = 'oid_store_assoc'
session = main_orm_session
- _id = FieldProperty(str) # server url
+ _id = FieldProperty(str) # server url
assocs = FieldProperty([dict(
- key=str, value=str)])
+ key=str, value=str)])
# Mimic openid.store.memstore.ServerAssocs
def set_assoc(self, assoc):
@@ -54,7 +56,7 @@ class OpenIdAssociation(MappedClass):
old_len = len(self.assocs)
self.assocs = [
a for a in self.assocs
- if a['key'] != handle ]
+ if a['key'] != handle]
return old_len != len(self.assocs)
def best_assoc(self):
@@ -70,19 +72,22 @@ class OpenIdAssociation(MappedClass):
def cleanup_assocs(self):
old_len = len(self.assocs)
- self.assocs = [ a for a in self.assocs
- if Association.deserialize(a['value']).getExpiresIn() != 0 ]
+ self.assocs = [a for a in self.assocs
+ if Association.deserialize(a['value']).getExpiresIn() != 0]
new_len = len(self.assocs)
return (old_len - new_len), new_len
+
class OpenIdNonce(MappedClass):
+
class __mongometa__:
- name='oid_store_nonce'
+ name = 'oid_store_nonce'
session = main_orm_session
- _id = FieldProperty(str) # Nonce value
+ _id = FieldProperty(str) # Nonce value
timestamp = FieldProperty(datetime, if_missing=datetime.utcnow)
-
+
+
class OpenIdStore(object):
def _get_assocs(self, server_url):
@@ -90,7 +95,7 @@ class OpenIdStore(object):
if assoc is None:
assoc = OpenIdAssociation(_id=server_url)
return assoc
-
+
def storeAssociation(self, server_url, association):
assocs = self._get_assocs(server_url)
assocs.set_assoc(deepcopy(association))
@@ -120,6 +125,5 @@ class OpenIdStore(object):
now = datetime.utcnow()
cutoff = now - timedelta(seconds=nonce.SKEW)
num_removed = OpenIdNonce.query.remove(dict(
- timestamp={'$lt': cutoff}))
+ timestamp={'$lt': cutoff}))
return num_removed
-
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 36e29ab..1a52092 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -56,26 +56,30 @@ from filesystem import File
log = logging.getLogger(__name__)
+
class ProjectFile(File):
+
class __mongometa__:
session = main_orm_session
indexes = [('project_id', 'category')]
- project_id=FieldProperty(S.ObjectId)
- category=FieldProperty(str)
- caption=FieldProperty(str)
- sort=FieldProperty(int)
+ project_id = FieldProperty(S.ObjectId)
+ category = FieldProperty(str)
+ caption = FieldProperty(str)
+ sort = FieldProperty(int)
+
class ProjectCategory(MappedClass):
+
class __mongometa__:
session = main_orm_session
- name='project_category'
+ name = 'project_category'
- _id=FieldProperty(S.ObjectId)
+ _id = FieldProperty(S.ObjectId)
parent_id = FieldProperty(S.ObjectId, if_missing=None)
- name=FieldProperty(str)
- label=FieldProperty(str, if_missing='')
- description=FieldProperty(str, if_missing='')
+ name = FieldProperty(str)
+ label = FieldProperty(str, if_missing='')
+ description = FieldProperty(str, if_missing='')
@property
def parent_category(self):
@@ -85,13 +89,15 @@ class ProjectCategory(MappedClass):
def subcategories(self):
return self.query.find(dict(parent_id=self._id)).all()
+
class TroveCategory(MappedClass):
+
class __mongometa__:
session = main_orm_session
- name='trove_category'
- indexes = [ 'trove_cat_id', 'trove_parent_id', 'shortname', 'fullpath' ]
+ name = 'trove_category'
+ indexes = ['trove_cat_id', 'trove_parent_id', 'shortname', 'fullpath']
- _id=FieldProperty(S.ObjectId)
+ _id = FieldProperty(S.ObjectId)
trove_cat_id = FieldProperty(int, if_missing=None)
trove_parent_id = FieldProperty(int, if_missing=None)
shortname = FieldProperty(str, if_missing='')
@@ -145,16 +151,20 @@ class TroveCategory(MappedClass):
fullpath=self.fullpath,
)
+
class ProjectMapperExtension(MapperExtension):
+
def after_insert(self, obj, st, sess):
g.zarkov_event('project_create', project=obj)
+
class Project(MappedClass, ActivityNode, ActivityObject):
- _perms_base = [ 'read', 'update', 'admin', 'create']
- _perms_init = _perms_base + [ 'register' ]
+ _perms_base = ['read', 'update', 'admin', 'create']
+ _perms_init = _perms_base + ['register']
+
class __mongometa__:
session = main_orm_session
- name='project'
+ name = 'project'
indexes = [
'name',
'neighborhood_id',
@@ -164,55 +174,55 @@ class Project(MappedClass, ActivityNode, ActivityObject):
('deleted', 'shortname', 'neighborhood_id'),
('neighborhood_id', 'is_nbhd_project', 'deleted')]
unique_indexes = [('neighborhood_id', 'shortname')]
- extensions = [ ProjectMapperExtension ]
+ extensions = [ProjectMapperExtension]
# Project schema
- _id=FieldProperty(S.ObjectId)
+ _id = FieldProperty(S.ObjectId)
parent_id = FieldProperty(S.ObjectId, if_missing=None)
neighborhood_id = ForeignIdProperty(Neighborhood)
shortname = FieldProperty(str)
- name=FieldProperty(str)
- show_download_button=FieldProperty(S.Deprecated)
- short_description=FieldProperty(str, if_missing='')
- summary=FieldProperty(str, if_missing='')
- description=FieldProperty(str, if_missing='')
+ name = FieldProperty(str)
+ show_download_button = FieldProperty(S.Deprecated)
+ short_description = FieldProperty(str, if_missing='')
+ summary = FieldProperty(str, if_missing='')
+ description = FieldProperty(str, if_missing='')
description_cache = FieldProperty(MarkdownCache)
- homepage_title=FieldProperty(str, if_missing='')
- external_homepage=FieldProperty(str, if_missing='')
- support_page=FieldProperty(str, if_missing='')
- support_page_url=FieldProperty(str, if_missing='')
- socialnetworks=FieldProperty([dict(socialnetwork=str,accounturl=str)])
- removal=FieldProperty(str, if_missing='')
- moved_to_url=FieldProperty(str, if_missing='')
+ homepage_title = FieldProperty(str, if_missing='')
+ external_homepage = FieldProperty(str, if_missing='')
+ support_page = FieldProperty(str, if_missing='')
+ support_page_url = FieldProperty(str, if_missing='')
+ socialnetworks = FieldProperty([dict(socialnetwork=str, accounturl=str)])
+ removal = FieldProperty(str, if_missing='')
+ moved_to_url = FieldProperty(str, if_missing='')
removal_changed_date = FieldProperty(datetime, if_missing=datetime.utcnow)
- export_controlled=FieldProperty(bool, if_missing=False)
- export_control_type=FieldProperty(str, if_missing=None)
- database=FieldProperty(S.Deprecated)
- database_uri=FieldProperty(S.Deprecated)
- is_root=FieldProperty(bool)
+ export_controlled = FieldProperty(bool, if_missing=False)
+ export_control_type = FieldProperty(str, if_missing=None)
+ database = FieldProperty(S.Deprecated)
+ database_uri = FieldProperty(S.Deprecated)
+ is_root = FieldProperty(bool)
acl = FieldProperty(ACL(permissions=_perms_init))
- neighborhood_invitations=FieldProperty([S.ObjectId])
+ neighborhood_invitations = FieldProperty([S.ObjectId])
neighborhood = RelationProperty(Neighborhood)
app_configs = RelationProperty('AppConfig')
category_id = FieldProperty(S.ObjectId, if_missing=None)
deleted = FieldProperty(bool, if_missing=False)
labels = FieldProperty([str])
last_updated = FieldProperty(datetime, if_missing=None)
- tool_data = FieldProperty({str:{str:None}}) # entry point: prefs dict
+ tool_data = FieldProperty({str: {str: None}}) # entry point: prefs dict
ordinal = FieldProperty(int, if_missing=0)
database_configured = FieldProperty(bool, if_missing=True)
_extra_tool_status = FieldProperty([str])
- trove_root_database=FieldProperty([S.ObjectId])
- trove_developmentstatus=FieldProperty([S.ObjectId])
- trove_audience=FieldProperty([S.ObjectId])
- trove_license=FieldProperty([S.ObjectId])
- trove_os=FieldProperty([S.ObjectId])
- trove_language=FieldProperty([S.ObjectId])
- trove_topic=FieldProperty([S.ObjectId])
- trove_natlanguage=FieldProperty([S.ObjectId])
- trove_environment=FieldProperty([S.ObjectId])
+ trove_root_database = FieldProperty([S.ObjectId])
+ trove_developmentstatus = FieldProperty([S.ObjectId])
+ trove_audience = FieldProperty([S.ObjectId])
+ trove_license = FieldProperty([S.ObjectId])
+ trove_os = FieldProperty([S.ObjectId])
+ trove_language = FieldProperty([S.ObjectId])
+ trove_topic = FieldProperty([S.ObjectId])
+ trove_natlanguage = FieldProperty([S.ObjectId])
+ trove_environment = FieldProperty([S.ObjectId])
tracking_id = FieldProperty(str, if_missing='')
- is_nbhd_project=FieldProperty(bool, if_missing=False)
+ is_nbhd_project = FieldProperty(bool, if_missing=False)
# transient properties
notifications_disabled = False
@@ -249,13 +259,13 @@ class Project(MappedClass, ActivityNode, ActivityObject):
result.append(SitemapEntry('Child Projects'))
result += [
SitemapEntry(p.name or p.script_name, p.script_name)
- for p in sps ]
+ for p in sps]
return result
def troves_by_type(self, trove_type):
troves = getattr(self, 'trove_%s' % trove_type)
if troves:
- return TroveCategory.query.find({'_id':{'$in': troves}}).all()
+ return TroveCategory.query.find({'_id': {'$in': troves}}).all()
else:
return []
@@ -266,7 +276,7 @@ class Project(MappedClass, ActivityNode, ActivityObject):
troves = {}
for attr in dir(self):
if attr.startswith('trove_'):
- trove_type = attr.replace('trove_','')
+ trove_type = attr.replace('trove_', '')
nice_name = dict(
natlanguage='translation',
root_database='database',
@@ -301,7 +311,7 @@ class Project(MappedClass, ActivityNode, ActivityObject):
if url.startswith('//'):
try:
return request.scheme + ':' + url
- except TypeError: # pragma no cover
+ except TypeError: # pragma no cover
return 'http:' + url
else:
return url
@@ -312,8 +322,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
def get_screenshots(self):
return ProjectFile.query.find(dict(
- project_id=self._id,
- category='screenshot')).sort('sort').all()
+ project_id=self._id,
+ category='screenshot')).sort('sort').all()
@LazyProperty
def icon(self):
@@ -327,20 +337,23 @@ class Project(MappedClass, ActivityNode, ActivityObject):
@property
def parent_project(self):
- if self.is_root: return None
+ if self.is_root:
+ return None
return self.query.get(_id=self.parent_id)
def _get_private(self):
"""Return True if this project is private, else False."""
role_anon = ProjectRole.anonymous(project=self)
return ACE.allow(role_anon._id, 'read') not in self.acl
+
def _set_private(self, val):
"""Set whether this project is private or not."""
new_val = bool(val)
role_anon = ProjectRole.anonymous(project=self)
ace = ACE.allow(role_anon._id, 'read')
curr_val = ace not in self.acl
- if new_val == curr_val: return
+ if new_val == curr_val:
+ return
if new_val:
self.acl.remove(ace)
else:
@@ -358,12 +371,14 @@ class Project(MappedClass, ActivityNode, ActivityObject):
'''
user = None
if self.is_user_project:
- user = plugin.AuthenticationProvider.get(request).user_by_project_shortname(self.shortname[2:])
+ user = plugin.AuthenticationProvider.get(
+ request).user_by_project_shortname(self.shortname[2:])
return user
@LazyProperty
def root_project(self):
- if self.is_root: return self
+ if self.is_root:
+ return self
return self.parent_project.root_project
@LazyProperty
@@ -373,9 +388,10 @@ class Project(MappedClass, ActivityNode, ActivityObject):
projects = set([self])
while True:
new_projects = set(
- self.query.find(dict(parent_id={'$in':[p._id for p in projects]})))
+ self.query.find(dict(parent_id={'$in': [p._id for p in projects]})))
new_projects.update(projects)
- if new_projects == projects: break
+ if new_projects == projects:
+ break
projects = new_projects
return projects
@@ -395,17 +411,17 @@ class Project(MappedClass, ActivityNode, ActivityObject):
def menus(cls, projects):
'''Return a dict[project_id] = sitemap of sitemaps, efficiently'''
from allura.app import SitemapEntry
- pids = [ p._id for p in projects ]
+ pids = [p._id for p in projects]
project_index = dict((p._id, p) for p in projects)
entry_index = dict((pid, []) for pid in pids)
q_subprojects = cls.query.find(dict(
- parent_id={'$in': pids},
- deleted=False))
+ parent_id={'$in': pids},
+ deleted=False))
for sub in q_subprojects:
entry_index[sub.parent_id].append(
dict(ordinal=sub.ordinal, entry=SitemapEntry(sub.name, sub.url())))
q_app_configs = AppConfig.query.find(dict(
- project_id={'$in': pids}))
+ project_id={'$in': pids}))
for ac in q_app_configs:
App = ac.load()
project = project_index[ac.project_id]
@@ -413,13 +429,14 @@ class Project(MappedClass, ActivityNode, ActivityObject):
if app.is_visible_to(c.user):
for sm in app.main_menu():
entry = sm.bind_app(app)
- entry.ui_icon='tool-%s' % ac.tool_name
+ entry.ui_icon = 'tool-%s' % ac.tool_name
ordinal = ac.options.get('ordinal', 0)
- entry_index[ac.project_id].append({'ordinal':ordinal,'entry':entry})
+ entry_index[ac.project_id].append(
+ {'ordinal': ordinal, 'entry': entry})
sitemaps = dict((pid, []) for pid in pids)
for pid, entries in entry_index.iteritems():
- entries.sort(key=lambda e:e['ordinal'])
+ entries.sort(key=lambda e: e['ordinal'])
sitemap = sitemaps[pid]
for e in entries:
sitemap.append(e['entry'])
@@ -433,7 +450,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
for icon in ProjectFile.query.find(dict(
project_id={'$in': result.keys()},
category='icon')):
- result[icon.project_id] = project_index[icon.project_id].url() + 'icon'
+ result[icon.project_id] = project_index[
+ icon.project_id].url() + 'icon'
return result
@classmethod
@@ -467,7 +485,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
ordinal = sub.ordinal + delta_ordinal
if ordinal > max_ordinal:
max_ordinal = ordinal
- entries.append({'ordinal':sub.ordinal + delta_ordinal,'entry':SitemapEntry(sub.name, sub.url())})
+ entries.append({'ordinal': sub.ordinal + delta_ordinal,
+ 'entry': SitemapEntry(sub.name, sub.url())})
for ac in self.app_configs + [a.config for a in new_tools]:
if excluded_tools and ac.tool_name in excluded_tools:
continue
@@ -476,7 +495,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
App = ac.load()
# If so, we don't want it listed
except KeyError as e:
- log.exception('AppConfig %s references invalid tool %s', ac._id, ac.tool_name)
+ log.exception('AppConfig %s references invalid tool %s',
+ ac._id, ac.tool_name)
continue
app = App(self, ac)
if app.is_visible_to(c.user):
@@ -485,19 +505,23 @@ class Project(MappedClass, ActivityNode, ActivityObject):
entry.tool_name = ac.tool_name
entry.ui_icon = 'tool-%s' % entry.tool_name.lower()
if not self.is_nbhd_project and (entry.tool_name.lower() in anchored_tools.keys()):
- ordinal = anchored_tools.keys().index(entry.tool_name.lower())
+ ordinal = anchored_tools.keys().index(
+ entry.tool_name.lower())
elif ac.tool_name == 'admin':
ordinal = 100
else:
- ordinal = int(ac.options.get('ordinal', 0)) + delta_ordinal
+ ordinal = int(ac.options.get('ordinal', 0)) + \
+ delta_ordinal
if self.is_nbhd_project and entry.label == 'Admin':
entry.matching_urls.append('%s_admin/' % self.url())
if ordinal > max_ordinal:
max_ordinal = ordinal
- entries.append({'ordinal':ordinal,'entry':entry})
+ entries.append({'ordinal': ordinal, 'entry': entry})
if self == self.neighborhood.neighborhood_project and h.has_access(self.neighborhood, 'admin'):
- entries.append({'ordinal': max_ordinal + 1,'entry':SitemapEntry('Moderate', "%s_moderate/" % self.neighborhood.url(), ui_icon="tool-admin")})
+ entries.append(
+ {'ordinal': max_ordinal + 1, 'entry': SitemapEntry('Moderate',
+ "%s_moderate/" % self.neighborhood.url(), ui_icon="tool-admin")})
max_ordinal += 1
entries = sorted(entries, key=lambda e: e['ordinal'])
@@ -512,7 +536,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
for tool, label in anchored_tools.iteritems():
if (tool not in installed_tools) and (self.app_instance(tool) is None):
try:
- new_tools.append(self.install_app(tool, tool, label, i))
+ new_tools.append(
+ self.install_app(tool, tool, label, i))
except Exception:
log.error('%s is not available' % tool, exc_info=True)
i += 1
@@ -528,7 +553,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
grouped_nav = OrderedDict()
# count how many tools of each type we have
counts = Counter([e.tool_name.lower() for e in sitemap if e.tool_name])
- grouping_threshold = self.get_tool_data('allura', 'grouping_threshold', 1)
+ grouping_threshold = self.get_tool_data(
+ 'allura', 'grouping_threshold', 1)
for e in sitemap:
# if it's not a tool, add to navbar and continue
if not e.tool_name:
@@ -543,7 +569,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
if tool_name not in grouped_nav:
child = deepcopy(e)
# change label to be the tool name (type)
- e.label = g.entry_points['tool'][tool_name].tool_label + u' \u25be'
+ e.label = g.entry_points['tool'][
+ tool_name].tool_label + u' \u25be'
# add tool url to list of urls that will match this nav entry
# have to do this before changing the url to the list page
e.matching_urls.append(e.url)
@@ -552,7 +579,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
e.children.append(child)
grouped_nav[tool_name] = e
else:
- # add tool url to list of urls that will match this nav entry
+ # add tool url to list of urls that will match this nav
+ # entry
grouped_nav[tool_name].matching_urls.append(e.url)
if len(grouped_nav[tool_name].children) < 10:
grouped_nav[tool_name].children.append(e)
@@ -571,7 +599,7 @@ class Project(MappedClass, ActivityNode, ActivityObject):
@property
def subprojects(self):
- q = self.query.find(dict(shortname={'$gt':self.shortname},
+ q = self.query.find(dict(shortname={'$gt': self.shortname},
neighborhood_id=self.neighborhood._id)).sort('shortname')
for project in q:
if project.shortname.startswith(self.shortname + '/'):
@@ -590,7 +618,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
@property
def named_roles(self):
- roles_ids = [r['_id'] for r in g.credentials.project_roles(self.root_project._id).named]
+ roles_ids = [r['_id']
+ for r in g.credentials.project_roles(self.root_project._id).named]
roles = sorted(
ProjectRole.query.find({'_id': {'$in': roles_ids}}),
key=lambda r: r.name.lower())
@@ -604,10 +633,12 @@ class Project(MappedClass, ActivityNode, ActivityObject):
except fe.Invalid as e:
raise exceptions.ToolError(str(e))
if ordinal is None:
- ordinal = int(self.ordered_mounts(include_hidden=True)[-1]['ordinal']) + 1
+ ordinal = int(self.ordered_mounts(include_hidden=True)
+ [-1]['ordinal']) + 1
options = App.default_options()
options['mount_point'] = mount_point
- options['mount_label'] = mount_label or App.default_mount_label or mount_point
+ options[
+ 'mount_label'] = mount_label or App.default_mount_label or mount_point
options['ordinal'] = int(ordinal)
options.update(override_options)
cfg = AppConfig(
@@ -622,7 +653,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
def uninstall_app(self, mount_point):
app = self.app_instance(mount_point)
- if app is None: return
+ if app is None:
+ return
if self.support_page == app.config.options.mount_point:
self.support_page = ''
with h.push_config(c, project=self, app=app):
@@ -636,15 +668,15 @@ class Project(MappedClass, ActivityNode, ActivityObject):
if app_config is None:
return None
App = app_config.load()
- if App is None: # pragma no cover
+ if App is None: # pragma no cover
return None
else:
return App(self, app_config)
def app_config(self, mount_point):
return AppConfig.query.find({
- 'project_id':self._id,
- 'options.mount_point':mount_point}).first()
+ 'project_id': self._id,
+ 'options.mount_point': mount_point}).first()
def app_config_by_tool_type(self, tool_type):
for ac in self.app_configs:
@@ -654,7 +686,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
def new_subproject(self, name, install_apps=True, user=None, project_name=None):
provider = plugin.ProjectRegistrationProvider.get()
try:
- provider.shortname_validator.to_python(name, check_allowed=False, neighborhood=self.neighborhood)
+ provider.shortname_validator.to_python(
+ name, check_allowed=False, neighborhood=self.neighborhood)
except exceptions.Invalid as e:
raise exceptions.ToolError, 'Mount point "%s" is invalid' % name
return provider.register_subproject(self, name, user or c.user, install_apps, project_name=project_name)
@@ -668,7 +701,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
self.install_anchored_tools()
for sub in self.direct_subprojects:
- result.append({'ordinal': int(sub.ordinal + i), 'sub': sub, 'rank': 1})
+ result.append(
+ {'ordinal': int(sub.ordinal + i), 'sub': sub, 'rank': 1})
for ac in self.app_configs:
App = g.entry_points['tool'].get(ac.tool_name)
if include_hidden or App and not App.hidden:
@@ -676,8 +710,10 @@ class Project(MappedClass, ActivityNode, ActivityObject):
ordinal = anchored_tools.keys().index(ac.tool_name.lower())
else:
ordinal = int(ac.options.get('ordinal', 0)) + i
- rank = 0 if ac.options.get('mount_point', None) == 'home' else 1
- result.append({'ordinal': int(ordinal), 'ac': ac, 'rank': rank})
+ rank = 0 if ac.options.get(
+ 'mount_point', None) == 'home' else 1
+ result.append(
+ {'ordinal': int(ordinal), 'ac': ac, 'rank': rank})
return sorted(result, key=lambda e: (e['ordinal'], e['rank']))
def first_mount_visible(self, user):
@@ -698,7 +734,7 @@ class Project(MappedClass, ActivityNode, ActivityObject):
project.'''
ordered_mounts = self.ordered_mounts(include_hidden=include_hidden)
return int(ordered_mounts[-1]['ordinal']) + 1 \
- if ordered_mounts else 0
+ if ordered_mounts else 0
def delete(self):
# Cascade to subprojects
@@ -710,18 +746,19 @@ class Project(MappedClass, ActivityNode, ActivityObject):
MappedClass.delete(self)
def breadcrumbs(self):
- entry = ( self.name, self.url() )
+ entry = (self.name, self.url())
if self.parent_project:
- return self.parent_project.breadcrumbs() + [ entry ]
+ return self.parent_project.breadcrumbs() + [entry]
else:
- return [ (self.neighborhood.name, self.neighborhood.url())] + [ entry ]
+ return [(self.neighborhood.name, self.neighborhood.url())] + [entry]
def users(self):
'''Find all the users who have named roles for this project'''
named_roles = security.RoleCache(
g.credentials,
g.credentials.project_roles(project_id=self.root_project._id).named)
- uids = [uid for uid in named_roles.userids_that_reach if uid is not None]
+ uids = [
+ uid for uid in named_roles.userids_that_reach if uid is not None]
return list(User.query.find({'_id': {'$in': uids}, 'disabled': False}))
def users_with_role(self, *role_names):
@@ -746,26 +783,29 @@ class Project(MappedClass, ActivityNode, ActivityObject):
u = User.by_username(username)
if not u:
return None
- named_roles = g.credentials.project_roles(project_id=self.root_project._id).named
+ named_roles = g.credentials.project_roles(
+ project_id=self.root_project._id).named
for r in named_roles.roles_that_reach:
- if r.get('user_id') == u._id: return u
+ if r.get('user_id') == u._id:
+ return u
return None
def configure_project(
- self,
- users=None, apps=None,
- is_user_project=False,
- is_private_project=False):
+ self,
+ users=None, apps=None,
+ is_user_project=False,
+ is_private_project=False):
from allura import model as M
self.notifications_disabled = True
- if users is None: users = [ c.user ]
+ if users is None:
+ users = [c.user]
if apps is None:
apps = []
if is_user_project:
apps += [('Wiki', 'wiki', 'Wiki'),
- ('profile', 'profile', 'Profile'),
- ]
+ ('profile', 'profile', 'Profile'),
+ ]
apps += [
('admin', 'admin', 'Admin'),
('search', 'search', 'Search'),
@@ -774,25 +814,30 @@ class Project(MappedClass, ActivityNode, ActivityObject):
apps.append(('activity', 'activity', 'Activity'))
with h.push_config(c, project=self, user=users[0]):
# Install default named roles (#78)
- root_project_id=self.root_project._id
- role_admin = M.ProjectRole.upsert(name='Admin', project_id=root_project_id)
- role_developer = M.ProjectRole.upsert(name='Developer', project_id=root_project_id)
- role_member = M.ProjectRole.upsert(name='Member', project_id=root_project_id)
- role_auth = M.ProjectRole.upsert(name='*authenticated', project_id=root_project_id)
- role_anon = M.ProjectRole.upsert(name='*anonymous', project_id=root_project_id)
+ root_project_id = self.root_project._id
+ role_admin = M.ProjectRole.upsert(
+ name='Admin', project_id=root_project_id)
+ role_developer = M.ProjectRole.upsert(
+ name='Developer', project_id=root_project_id)
+ role_member = M.ProjectRole.upsert(
+ name='Member', project_id=root_project_id)
+ role_auth = M.ProjectRole.upsert(
+ name='*authenticated', project_id=root_project_id)
+ role_anon = M.ProjectRole.upsert(
+ name='*anonymous', project_id=root_project_id)
# Setup subroles
- role_admin.roles = [ role_developer._id ]
- role_developer.roles = [ role_member._id ]
+ role_admin.roles = [role_developer._id]
+ role_developer.roles = [role_member._id]
self.acl = [
ACE.allow(role_developer._id, 'read'),
- ACE.allow(role_member._id, 'read') ]
+ ACE.allow(role_member._id, 'read')]
self.acl += [
M.ACE.allow(role_admin._id, perm)
- for perm in self.permissions ]
+ for perm in self.permissions]
self.private = is_private_project
for user in users:
pr = ProjectRole.by_user(user, project=self, upsert=True)
- pr.roles = [ role_admin._id ]
+ pr.roles = [role_admin._id]
session(self).flush(self)
# Setup apps
for i, (ep_name, mount_point, label) in enumerate(apps):
@@ -818,7 +863,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
def social_account(self, socialnetwork):
try:
- account = (sn for sn in self.socialnetworks if sn.socialnetwork == socialnetwork).next()
+ account = (
+ sn for sn in self.socialnetworks if sn.socialnetwork == socialnetwork).next()
except StopIteration:
return None
else:
@@ -832,7 +878,7 @@ class Project(MappedClass, ActivityNode, ActivityObject):
self.socialnetworks.append(dict(
socialnetwork=socialnetwork,
accounturl=accounturl
- ))
+ ))
def bulk_export_path(self):
shortname = self.shortname
@@ -843,9 +889,9 @@ class Project(MappedClass, ActivityNode, ActivityObject):
elif not self.is_root:
shortname = self.shortname.split('/')[0]
return config['bulk_export_path'].format(
- nbhd=self.neighborhood.url_prefix.strip('/'),
- project=shortname,
- c=c,
+ nbhd=self.neighborhood.url_prefix.strip('/'),
+ project=shortname,
+ c=c,
)
def bulk_export_filename(self):
@@ -878,7 +924,6 @@ class Project(MappedClass, ActivityNode, ActivityObject):
else:
return 'busy'
-
def __json__(self):
return dict(
shortname=self.shortname,
@@ -894,18 +939,23 @@ class Project(MappedClass, ActivityNode, ActivityObject):
moved_to_url=self.moved_to_url,
preferred_support_tool=self.support_page,
preferred_support_url=self.support_page_url,
- developers=[u.__json__() for u in self.users_with_role('Developer')],
+ developers=[u.__json__()
+ for u in self.users_with_role('Developer')],
tools=[dict(name=t.tool_name, mount_point=t.options.mount_point, label=t.options.mount_label)
for t in self.app_configs if h.has_access(t, 'read')],
labels=list(self.labels),
categories={
- n: [t.__json__() for t in ts] for n, ts in self.all_troves().items()},
+ n: [t.__json__(
+ ) for t in ts] for n, ts in self.all_troves().items()},
icon_url=h.absurl(self.url() + 'icon') if self.icon else None,
- screenshots = [
+ screenshots=[
dict(
- url = h.absurl(self.url() + 'screenshot/' + urllib.quote(ss.filename)),
- thumbnail_url = h.absurl(self.url() + 'screenshot/' + urllib.quote(ss.filename) + '/thumb'),
- caption = ss.caption,
+ url=h.absurl(self.url() + 'screenshot/' +
+ urllib.quote(ss.filename)),
+ thumbnail_url=h.absurl(
+ self.url(
+ ) + 'screenshot/' + urllib.quote(ss.filename) + '/thumb'),
+ caption=ss.caption,
)
for ss in self.get_screenshots()
]
@@ -913,6 +963,7 @@ class Project(MappedClass, ActivityNode, ActivityObject):
class AppConfig(MappedClass):
+
"""
Configuration information for an instantiated :class:`Application <allura.app.Application>`
in a project
@@ -923,22 +974,22 @@ class AppConfig(MappedClass):
class __mongometa__:
session = project_orm_session
- name='config'
+ name = 'config'
indexes = [
'project_id',
'options.import_id',
('options.mount_point', 'project_id')]
# AppConfig schema
- _id=FieldProperty(S.ObjectId)
- project_id=ForeignIdProperty(Project)
- discussion_id=ForeignIdProperty('Discussion')
- tool_name=FieldProperty(str)
- version=FieldProperty(str)
- options=FieldProperty(None)
+ _id = FieldProperty(S.ObjectId)
+ project_id = ForeignIdProperty(Project)
+ discussion_id = ForeignIdProperty('Discussion')
+ tool_name = FieldProperty(str)
+ version = FieldProperty(str)
+ options = FieldProperty(None)
project = RelationProperty(Project, via='project_id')
discussion = RelationProperty('Discussion', via='discussion_id')
- tool_data = FieldProperty({str:{str:None}}) # entry point: prefs dict
+ tool_data = FieldProperty({str: {str: None}}) # entry point: prefs dict
acl = FieldProperty(ACL())
@@ -975,10 +1026,11 @@ class AppConfig(MappedClass):
def breadcrumbs(self):
return self.project.breadcrumbs() + [
- (self.options.mount_point, self.url()) ]
+ (self.options.mount_point, self.url())]
def __json__(self):
return dict(
_id=self._id,
- options=self.options._deinstrument(), # strip away the ming instrumentation
+ # strip away the ming instrumentation
+ options=self.options._deinstrument(),
)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/Allura/allura/model/repo.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repo.py b/Allura/allura/model/repo.py
index 9228076..9396151 100644
--- a/Allura/allura/model/repo.py
+++ b/Allura/allura/model/repo.py
@@ -49,14 +49,15 @@ log = logging.getLogger(__name__)
# Some schema types
SUser = dict(name=str, email=str, date=datetime)
-SObjType=S.OneOf('blob', 'tree', 'submodule')
+SObjType = S.OneOf('blob', 'tree', 'submodule')
# Used for when we're going to batch queries using $in
QSIZE = 100
README_RE = re.compile('^README(\.[^.]*)?$', re.IGNORECASE)
-VIEWABLE_EXTENSIONS = ['.php','.py','.js','.java','.html','.htm','.yaml','.sh',
- '.rb','.phtml','.txt','.bat','.ps1','.xhtml','.css','.cfm','.jsp','.jspx',
- '.pl','.php4','.php3','.rhtml','.svg','.markdown','.json','.ini','.tcl','.vbs','.xsl']
+VIEWABLE_EXTENSIONS = [
+ '.php', '.py', '.js', '.java', '.html', '.htm', '.yaml', '.sh',
+ '.rb', '.phtml', '.txt', '.bat', '.ps1', '.xhtml', '.css', '.cfm', '.jsp', '.jspx',
+ '.pl', '.php4', '.php3', '.rhtml', '.svg', '.markdown', '.json', '.ini', '.tcl', '.vbs', '.xsl']
PYPELINE_EXTENSIONS = utils.MARKDOWN_EXTENSIONS + ['.rst']
DIFF_SIMILARITY_THRESHOLD = .5 # used for determining file renames
@@ -73,7 +74,7 @@ CommitDoc = collection(
Field('message', str),
Field('parent_ids', [str], index=True),
Field('child_ids', [str], index=True),
- Field('repo_ids', [ S.ObjectId() ], index=True))
+ Field('repo_ids', [S.ObjectId()], index=True))
# Basic tree information (also see TreesDoc)
TreeDoc = collection(
@@ -109,7 +110,7 @@ DiffInfoDoc = collection(
Field('_id', str),
Field(
'differences',
- [ dict(name=str, lhs_id=str, rhs_id=str)]))
+ [dict(name=str, lhs_id=str, rhs_id=str)]))
# List of commit runs (a run is a linear series of single-parent commits)
# CommitRunDoc.commit_ids = [ CommitDoc._id, ... ]
@@ -120,9 +121,10 @@ CommitRunDoc = collection(
Field('commit_ids', [str], index=True),
Field('commit_times', [datetime]))
+
class RepoObject(object):
- def __repr__(self): # pragma no cover
+ def __repr__(self): # pragma no cover
return '<%s %s>' % (
self.__class__.__name__, self._id)
@@ -143,20 +145,22 @@ class RepoObject(object):
def upsert(cls, id, **kwargs):
isnew = False
r = cls.query.get(_id=id)
- if r is not None: return r, isnew
+ if r is not None:
+ return r, isnew
try:
r = cls(_id=id, **kwargs)
session(r).flush(r)
isnew = True
- except pymongo.errors.DuplicateKeyError: # pragma no cover
+ except pymongo.errors.DuplicateKeyError: # pragma no cover
session(r).expunge(r)
r = cls.query.get(_id=id)
return r, isnew
+
class Commit(RepoObject, ActivityObject):
type_s = 'Commit'
# Ephemeral attrs
- repo=None
+ repo = None
def __init__(self, **kw):
for k, v in kw.iteritems():
@@ -193,12 +197,14 @@ class Commit(RepoObject, ActivityObject):
@LazyProperty
def author_url(self):
u = User.by_email_address(self.authored.email)
- if u: return u.url()
+ if u:
+ return u.url()
@LazyProperty
def committer_url(self):
u = User.by_email_address(self.committed.email)
- if u: return u.url()
+ if u:
+ return u.url()
@LazyProperty
def tree(self):
@@ -226,8 +232,10 @@ class Commit(RepoObject, ActivityObject):
return h.text.truncate(first_line, 50)
def shorthand_id(self):
- if self.repo is None: self.repo = self.guess_repo()
- if self.repo is None: return repr(self)
+ if self.repo is None:
+ self.repo = self.guess_repo()
+ if self.repo is None:
+ return repr(self)
return self.repo.shorthand_for_commit(self._id)
@LazyProperty
@@ -262,13 +270,16 @@ class Commit(RepoObject, ActivityObject):
ancestor = ancestor.get_parent()
def url(self):
- if self.repo is None: self.repo = self.guess_repo()
- if self.repo is None: return '#'
+ if self.repo is None:
+ self.repo = self.guess_repo()
+ if self.repo is None:
+ return '#'
return self.repo.url_for_commit(self)
def guess_repo(self):
import traceback
- log.error('guess_repo: should not be called: %s' % ''.join(traceback.format_stack()))
+ log.error('guess_repo: should not be called: %s' %
+ ''.join(traceback.format_stack()))
for ac in c.project.app_configs:
try:
app = c.project.app_instance(ac)
@@ -290,11 +301,13 @@ class Commit(RepoObject, ActivityObject):
def context(self):
result = dict(prev=None, next=None)
if self.parent_ids:
- result['prev'] = self.query.find(dict(_id={'$in': self.parent_ids })).all()
+ result['prev'] = self.query.find(
+ dict(_id={'$in': self.parent_ids})).all()
for ci in result['prev']:
ci.set_context(self.repo)
if self.child_ids:
- result['next'] = self.query.find(dict(_id={'$in': self.child_ids })).all()
+ result['next'] = self.query.find(
+ dict(_id={'$in': self.child_ids})).all()
for ci in result['next']:
ci.set_context(self.repo)
return result
@@ -463,23 +476,24 @@ class Commit(RepoObject, ActivityObject):
author_url=self.author_url,
shortlink=self.shorthand_id(),
summary=self.summary
- )
+ )
+
class Tree(RepoObject):
# Ephemeral attrs
- repo=None
- commit=None
- parent=None
- name=None
+ repo = None
+ commit = None
+ parent = None
+ name = None
def compute_hash(self):
'''Compute a hash based on the contents of the tree. Note that this
hash does not necessarily correspond to any actual DVCS hash.
'''
lines = (
- [ 'tree' + x.name + x.id for x in self.tree_ids ]
- + [ 'blob' + x.name + x.id for x in self.blob_ids ]
- + [ x.type + x.name + x.id for x in self.other_ids ])
+ ['tree' + x.name + x.id for x in self.tree_ids]
+ + ['blob' + x.name + x.id for x in self.blob_ids]
+ + [x.type + x.name + x.id for x in self.other_ids])
sha_obj = sha1()
for line in sorted(lines):
sha_obj.update(line)
@@ -495,9 +509,11 @@ class Tree(RepoObject):
raise KeyError, name
obj = cache.get(Tree, dict(_id=obj['id']))
if obj is None:
- oid = self.repo.compute_tree_new(self.commit, self.path() + name + '/')
+ oid = self.repo.compute_tree_new(
+ self.commit, self.path() + name + '/')
obj = cache.get(Tree, dict(_id=oid))
- if obj is None: raise KeyError, name
+ if obj is None:
+ raise KeyError, name
obj.set_context(self, name)
return obj
@@ -562,7 +578,8 @@ class Tree(RepoObject):
commit_infos = {c._id: c.info for c in commits}
by_name = lambda n: n.name
tree_names = sorted([n.name for n in self.tree_ids])
- blob_names = sorted([n.name for n in chain(self.blob_ids, self.other_ids)])
+ blob_names = sorted(
+ [n.name for n in chain(self.blob_ids, self.other_ids)])
results = []
for type, names in (('DIR', tree_names), ('BLOB', blob_names)):
@@ -571,21 +588,22 @@ class Tree(RepoObject):
if not commit_info:
commit_info = defaultdict(str)
elif 'id' in commit_info:
- commit_info['href'] = self.repo.url_for_commit(commit_info['id'])
+ commit_info['href'] = self.repo.url_for_commit(
+ commit_info['id'])
results.append(dict(
- kind=type,
- name=name,
- href=name,
- last_commit=dict(
- author=commit_info['author'],
- author_email=commit_info['author_email'],
- author_url=commit_info['author_url'],
- date=commit_info.get('date'),
- href=commit_info.get('href',''),
- shortlink=commit_info['shortlink'],
- summary=commit_info['summary'],
- ),
- ))
+ kind=type,
+ name=name,
+ href=name,
+ last_commit=dict(
+ author=commit_info['author'],
+ author_email=commit_info['author_email'],
+ author_url=commit_info['author_url'],
+ date=commit_info.get('date'),
+ href=commit_info.get('href', ''),
+ shortlink=commit_info['shortlink'],
+ summary=commit_info['summary'],
+ ),
+ ))
return results
def path(self):
@@ -616,7 +634,9 @@ class Tree(RepoObject):
x = self.by_name[name]
return Blob(self, name, x.id)
+
class Blob(object):
+
'''Lightweight object representing a file in the repo'''
def __init__(self, tree, name, _id):
@@ -678,10 +698,10 @@ class Blob(object):
@property
def has_html_view(self):
if (self.content_type.startswith('text/') or
- self.extension in VIEWABLE_EXTENSIONS or
- self.extension in PYPELINE_EXTENSIONS or
- self.extension in self.repo._additional_viewable_extensions or
- utils.is_text_file(self.text)):
+ self.extension in VIEWABLE_EXTENSIONS or
+ self.extension in PYPELINE_EXTENSIONS or
+ self.extension in self.repo._additional_viewable_extensions or
+ utils.is_text_file(self.text)):
return True
return False
@@ -726,7 +746,9 @@ class Blob(object):
differ = SequenceMatcher(v0, v1)
return differ.get_opcodes()
+
class LastCommit(RepoObject):
+
def __repr__(self):
return '<LastCommit /%s %s>' % (self.path, self.commit_id)
@@ -736,7 +758,8 @@ class LastCommit(RepoObject):
rev = commit.repo.log(commit._id, path, id_only=True).next()
return commit.repo.rev_to_commit_id(rev)
except StopIteration:
- log.error('Tree node not recognized by SCM: %s @ %s', path, commit._id)
+ log.error('Tree node not recognized by SCM: %s @ %s',
+ path, commit._id)
return commit._id
@classmethod
@@ -779,10 +802,13 @@ class LastCommit(RepoObject):
prev_lcd = None
prev_lcd_cid = cls._prev_commit_id(tree.commit, path)
if prev_lcd_cid:
- prev_lcd = model_cache.get(cls, {'path': path, 'commit_id': prev_lcd_cid})
+ prev_lcd = model_cache.get(
+ cls, {'path': path, 'commit_id': prev_lcd_cid})
entries = {}
- nodes = set([node.name for node in chain(tree.tree_ids, tree.blob_ids, tree.other_ids)])
- changed = set([node for node in nodes if os.path.join(path, node) in tree.commit.changed_paths])
+ nodes = set(
+ [node.name for node in chain(tree.tree_ids, tree.blob_ids, tree.other_ids)])
+ changed = set(
+ [node for node in nodes if os.path.join(path, node) in tree.commit.changed_paths])
unchanged = [os.path.join(path, node) for node in nodes - changed]
if prev_lcd:
# get unchanged entries from previously computed LCD
@@ -796,16 +822,19 @@ class LastCommit(RepoObject):
# and possibly try again later
entries = {}
# paths are fully-qualified; shorten them back to just node names
- entries = {os.path.basename(path):commit_id for path,commit_id in entries.iteritems()}
+ entries = {
+ os.path.basename(path): commit_id for path, commit_id in entries.iteritems()}
# update with the nodes changed in this tree's commit
entries.update({node: tree.commit._id for node in changed})
- # convert to a list of dicts, since mongo doesn't handle arbitrary keys well (i.e., . and $ not allowed)
- entries = [{'name':name, 'commit_id':value} for name,value in entries.iteritems()]
+ # convert to a list of dicts, since mongo doesn't handle arbitrary keys
+ # well (i.e., . and $ not allowed)
+ entries = [{'name': name, 'commit_id': value}
+ for name, value in entries.iteritems()]
lcd = cls(
- commit_id=tree.commit._id,
- path=path,
- entries=entries,
- )
+ commit_id=tree.commit._id,
+ path=path,
+ entries=entries,
+ )
model_cache.set(cls, {'path': path, 'commit_id': tree.commit._id}, lcd)
return lcd
@@ -819,9 +848,11 @@ mapper(LastCommit, LastCommitDoc, repository_orm_session)
class ModelCache(object):
+
'''
Cache model instances based on query params passed to get.
'''
+
def __init__(self, max_instances=None, max_queries=None):
'''
By default, each model type can have 2000 instances and
@@ -840,14 +871,15 @@ class ModelCache(object):
max_instances_default = max_instances
if isinstance(max_queries, int):
max_queries_default = max_queries
- self._max_instances = defaultdict(lambda:max_instances_default)
- self._max_queries = defaultdict(lambda:max_queries_default)
+ self._max_instances = defaultdict(lambda: max_instances_default)
+ self._max_queries = defaultdict(lambda: max_queries_default)
if hasattr(max_instances, 'items'):
self._max_instances.update(max_instances)
if hasattr(max_queries, 'items'):
self._max_queries.update(max_queries)
- self._query_cache = defaultdict(OrderedDict) # keyed by query, holds _id
+ # keyed by query, holds _id
+ self._query_cache = defaultdict(OrderedDict)
self._instance_cache = defaultdict(OrderedDict) # keyed by _id
self._synthetic_ids = defaultdict(set)
self._synthetic_id_queries = defaultdict(set)
@@ -864,7 +896,8 @@ class ModelCache(object):
elif hasattr(cls, 'm'):
return cls.m
else:
- raise AttributeError('%s has neither "query" nor "m" attribute' % cls)
+ raise AttributeError(
+ '%s has neither "query" nor "m" attribute' % cls)
def get(self, cls, query):
_query = self._normalize_query(query)
@@ -886,9 +919,9 @@ class ModelCache(object):
_query = self._normalize_query(query)
if val is not None:
_id = getattr(val, '_model_cache_id',
- getattr(val, '_id',
- self._query_cache[cls].get(_query,
- None)))
+ getattr(val, '_id',
+ self._query_cache[cls].get(_query,
+ None)))
if _id is None:
_id = val._model_cache_id = bson.ObjectId()
self._synthetic_ids[cls].add(_id)
@@ -924,7 +957,8 @@ class ModelCache(object):
instance = self._instance_cache[cls][_id]
self._try_flush(instance, expunge=False)
if self.num_instances(cls) > self._max_instances[cls]:
- instance = self._remove_least_recently_used(self._instance_cache[cls])
+ instance = self._remove_least_recently_used(
+ self._instance_cache[cls])
self._try_flush(instance, expunge=True)
def _try_flush(self, instance, expunge=False):