class OAuthConsumerToken(OAuthToken): class __mongometa__: 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) name = FieldProperty(str) description = FieldProperty(str) user = RelationProperty('User') @property def description_html(self): return g.markdown.convert(self.description) @property def consumer(self): '''OAuth compatible consumer object''' return oauth.Consumer(self.api_key, self.secret_key) @classmethod def for_user(cls, user=None): if user is None: user = c.user return cls.query.find(dict(user_id=user._id)).all()
class Bin(Artifact, ActivityObject): class __mongometa__: name = 'bin' type_s = 'Bin' _id = FieldProperty(schema.ObjectId) summary = FieldProperty(str, required=True, allow_none=False) terms = FieldProperty(str, if_missing='') sort = FieldProperty(str, if_missing='') @property def activity_name(self): return 'search bin %s' % self.summary def url(self): base = self.app_config.url() + 'search/?' params = dict(q=(h.really_unicode(self.terms).encode('utf-8') or '')) if self.sort: params['sort'] = self.sort return base + urllib.urlencode(params) def shorthand_id(self): return self.summary def index(self): result = Artifact.index(self) result.update(type_s=self.type_s, summary_t=self.summary, terms_s=self.terms) return result
class LastCommitFor(MappedClass): class __mongometa__: session = project_orm_session name='last_commit_for' unique_indexes = [ ('repo_id', 'object_id') ] _id = FieldProperty(S.ObjectId) repo_id = FieldProperty(S.ObjectId) object_id = FieldProperty(str) last_commit = FieldProperty(dict( date=datetime, author=str, author_email=str, author_url=str, id=str, href=str, shortlink=str, summary=str)) @classmethod def upsert(cls, repo_id, object_id): isnew = False r = cls.query.get(repo_id=repo_id, object_id=object_id) if r is not None: return r, isnew try: r = cls(repo_id=repo_id, object_id=object_id) session(r).flush(r) isnew = True except pymongo.errors.DuplicateKeyError: # pragma no cover session(r).expunge(r) r = cls.query.get(repo_id=repo_id, object_id=object_id) return r, isnew
class BaseAttachment(File): thumbnail_size = (255, 255) ArtifactType = None class __mongometa__: name = 'attachment' polymorphic_on = 'attachment_type' polymorphic_identity = None session = project_orm_session indexes = ['artifact_id', 'app_config_id'] artifact_id = FieldProperty(S.ObjectId) app_config_id = FieldProperty(S.ObjectId) type = FieldProperty(str) attachment_type = FieldProperty(str) @property def artifact(self): return self.ArtifactType.query.get(_id=self.artifact_id) def url(self): return self.artifact.url() + 'attachment/' + h.urlquote(self.filename) def is_embedded(self): from pylons import request return self.filename in request.environ.get( 'allura.macro.att_embedded', []) @classmethod def metadata_for(cls, artifact): return dict(artifact_id=artifact._id, app_config_id=artifact.app_config_id) @classmethod def save_attachment(cls, filename, fp, content_type=None, **kwargs): filename = h.really_unicode(filename) thumbnail_meta = dict(type="thumbnail", app_config_id=c.app.config._id) thumbnail_meta.update(kwargs) original_meta = dict(type="attachment", app_config_id=c.app.config._id) original_meta.update(kwargs) # Try to save as image, with thumbnail orig, thumbnail = cls.save_image(filename, fp, content_type=content_type, square=True, thumbnail_size=cls.thumbnail_size, thumbnail_meta=thumbnail_meta, save_original=True, original_meta=original_meta) if orig is not None: return orig, thumbnail else: # No, generic attachment # stream may have been partially consumed in a failed save_image # attempt fp.seek(0) return cls.from_stream(filename, fp, content_type=content_type, **original_meta)
class AuthGlobals(MappedClass): class __mongometa__: name = str('auth_globals') session = main_orm_session _id = FieldProperty(int) next_uid = FieldProperty(int, if_missing=10000) @classmethod def upsert(cls): r = cls.query.get() if r is not None: return r try: r = cls(_id=0) session(r).flush(r) return r except pymongo.errors.DuplicateKeyError: # pragma no cover session(r).flush(r) r = cls.query.get() return r @classmethod def get_next_uid(cls): cls.upsert() g = cls.query.find_and_modify( query={}, update={'$inc': {'next_uid': 1}}, new=True) return g.next_uid
class OAuthAccessToken(OAuthToken): class __mongometa__: polymorphic_identity = 'access' type = FieldProperty(str, if_missing='access') consumer_token_id = ForeignIdProperty('OAuthConsumerToken') request_token_id = ForeignIdProperty('OAuthToken') user_id = AlluraUserProperty(if_missing=lambda: c.user._id) is_bearer = FieldProperty(bool, if_missing=False) user = RelationProperty('User') 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 return cls.query.find(dict(user_id=user._id, type='access')).all() def can_import_forum(self): tokens = aslist(config.get('oauth.can_import_forum', ''), ',') if self.api_key in tokens: return True return False
class OpenId(MappedClass): class __mongometa__: name = 'openid' session = main_orm_session _id = FieldProperty(str) claimed_by_user_id = FieldProperty(S.ObjectId, if_missing=None) display_identifier = FieldProperty(str) @classmethod def upsert(cls, url, display_identifier): result = cls.query.get(_id=url) if not result: result = cls(_id=url, display_identifier=display_identifier) return result def claimed_by_user(self): if self.claimed_by_user_id: result = User.query.get(_id=self.claimed_by_user_id) else: # pragma no cover result = User.register(dict(username=None, password=None, display_name=self.display_identifier, open_ids=[self._id]), make_project=False) self.claimed_by_user_id = result._id return result
class OpenIdNonce(MappedClass): class __mongometa__: name = 'oid_store_nonce' session = main_orm_session _id = FieldProperty(str) # Nonce value timestamp = FieldProperty(datetime, if_missing=datetime.utcnow)
class ProjectFile(File): class __mongometa__: session = main_orm_session indexes = [('project_id', 'category')] project_id = FieldProperty(S.ObjectId) category = FieldProperty(str) caption = FieldProperty(str)
class MovedArtifact(Artifact): class __mongometa__: session = artifact_orm_session name='moved_artifact' _id = FieldProperty(S.ObjectId) app_config_id = ForeignIdProperty('AppConfig', if_missing=lambda:c.app.config._id) app_config = RelationProperty('AppConfig') moved_to_url = FieldProperty(str, required=True, allow_none=False)
class DocumentCategory(SproxTestClass): class __mongometa__: name = 'document_category_rs' _id = FieldProperty(int) document_category_id = FieldProperty(int) department_id = ForeignIdProperty(Department) department = RelationProperty(Department) name = FieldProperty(str)
class Town(SproxTestClass): class __mongometa__: name = 'town_rs' _id = FieldProperty(S.ObjectId) name = FieldProperty(str) country = FieldProperty(str) users = RelationProperty('User')
class Permission(SproxTestClass): class __mongometa__: name = 'tg_permission_rs' unique_indexes = (('permission_name', ), ) _id = FieldProperty(S.ObjectId) permission_name = FieldProperty(str) # unique description = FieldProperty(str) groups = RelationProperty(GroupPermission)
class File(SproxTestClass): class __mongometa__: name = 'attachments_rs' _id = FieldProperty(S.ObjectId) data = FieldProperty(S.Binary) @property def content(self): return self.data
class _TestArtifact(M.Artifact): _shorthand_id = FieldProperty(str) text = FieldProperty(str) def url(self): return '' def shorthand_id(self): return getattr(self, '_shorthand_id', self._id) def index(self): return dict( super(_TestArtifact, self).index(), text=self.text)
class ChatChannel(MappedClass): class __mongometa__: name = 'globals' session = M.main_orm_session unique_indexes = ['channel'] _id = FieldProperty(S.ObjectId) project_id = FieldProperty(S.ObjectId) app_config_id = FieldProperty(S.ObjectId) channel = FieldProperty(str)
class Globals(MappedClass): class __mongometa__: name = 'blog-globals' session = M.project_orm_session indexes = ['app_config_id'] type_s = 'BlogGlobals' _id = FieldProperty(schema.ObjectId) app_config_id = ForeignIdProperty('AppConfig', if_missing=lambda: c.app.config._id) external_feeds = FieldProperty([str])
class OAuthRequestToken(OAuthToken): class __mongometa__: polymorphic_identity = 'request' type = FieldProperty(str, if_missing='request') consumer_token_id = ForeignIdProperty('OAuthConsumerToken') user_id = ForeignIdProperty('User', if_missing=lambda: c.user._id) callback = FieldProperty(str) validation_pin = FieldProperty(str) consumer_token = RelationProperty('OAuthConsumerToken')
class Globals(MappedClass): class __mongometa__: name = 'wiki-globals' session = project_orm_session indexes = ['app_config_id'] type_s = 'WikiGlobals' _id = FieldProperty(schema.ObjectId) app_config_id = ForeignIdProperty( 'AppConfig', if_missing=lambda: context.app.config._id) root = FieldProperty(str)
class Ticket(VersionedArtifact, ActivityObject, VotableArtifact): class __mongometa__: name = 'ticket' history_class = TicketHistory indexes = [ 'ticket_num', 'app_config_id', ('app_config_id', 'custom_fields._milestone'), 'import_id', ] unique_indexes = [ ('app_config_id', 'ticket_num'), ] type_s = 'Ticket' _id = FieldProperty(schema.ObjectId) created_date = FieldProperty(datetime, if_missing=datetime.utcnow) super_id = FieldProperty(schema.ObjectId, if_missing=None) sub_ids = FieldProperty([schema.ObjectId]) ticket_num = FieldProperty(int, required=True, allow_none=False) summary = FieldProperty(str) description = FieldProperty(str, if_missing='') 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}) reported_by = RelationProperty(User, via='reported_by_id') @property def activity_name(self): return 'ticket #%s' % self.ticket_num @classmethod def new(cls): '''Create a new ticket, safely (ensuring a unique ticket_num''' while True: ticket_num = c.app.globals.next_ticket_num() ticket = cls(app_config_id=c.app.config._id, custom_fields=dict(), ticket_num=ticket_num) try: session(ticket).flush(ticket) h.log_action(log, 'opened').info('') return ticket except OperationFailure, err: if 'duplicate' in err.args[0]: log.warning('Try to create duplicate ticket %s', ticket.url()) session(ticket).expunge(ticket) continue raise
class UnrelatedDocument(SproxTestClass): class __mongometa__: name = 'document_unrelated' _id = FieldProperty(S.ObjectId) number = FieldProperty(S.Int) enabled = FieldProperty(S.Bool) password = FieldProperty(str) @property def something(self): return self.enabled
class AwardGrant(Artifact): "An :class:`Award <allura.model.artifact.Award>` can be bestowed upon a project by a neighborhood" class __mongometa__: session = main_orm_session name = 'grant' indexes = ['short'] type_s = 'Generic Award Grant' _id = FieldProperty(S.ObjectId) award_id = ForeignIdProperty(Award, if_missing=None) award = RelationProperty(Award, via='award_id') granted_by_neighborhood_id = ForeignIdProperty('Neighborhood', if_missing=None) granted_by_neighborhood = RelationProperty( 'Neighborhood', via='granted_by_neighborhood_id') granted_to_project_id = ForeignIdProperty('Project', if_missing=None) granted_to_project = RelationProperty('Project', via='granted_to_project_id') award_url = FieldProperty(str, if_missing='') comment = FieldProperty(str, if_missing='') timestamp = FieldProperty(datetime, if_missing=datetime.utcnow) def index(self): result = Artifact.index(self) result.update(_id_s=self._id, short_s=self.short, timestamp_dt=self.timestamp, full_s=self.full) if self.award: result['award_s'] = self.award.short return result @property def icon(self): return AwardFile.query.get(award_id=self.award_id) def url(self): slug = str(self.granted_to_project.shortname).replace('/', '_') return h.urlquote(slug) def longurl(self): slug = str(self.granted_to_project.shortname).replace('/', '_') slug = self.award.longurl() + '/' + slug return h.urlquote(slug) def shorthand_id(self): if self.award: return self.award.short else: return None
class EmailAddress(MappedClass): re_format = re.compile('^.* <(.*)>$') class __mongometa__: name = 'email_address' session = main_orm_session indexes = ['claimed_by_user_id'] _id = FieldProperty(str) claimed_by_user_id = FieldProperty(S.ObjectId, if_missing=None) confirmed = FieldProperty(bool) nonce = FieldProperty(str) def claimed_by_user(self): return User.query.get(_id=self.claimed_by_user_id) @classmethod def upsert(cls, addr): addr = cls.canonical(addr) result = cls.query.get(_id=addr) if not result: result = cls(_id=addr) return result @classmethod def canonical(cls, addr): mo = cls.re_format.match(addr) if mo: addr = mo.group(1) if '@' in addr: user, domain = addr.split('@') return '%s@%s' % (user, domain.lower()) else: return '*****@*****.**' def send_verification_link(self): self.nonce = sha256(os.urandom(10)).hexdigest() log.info('Sending verification link to %s', self._id) text = ''' To verify the email address %s belongs to the user %s, please visit the following URL: %s ''' % (self._id, self.claimed_by_user().username, g.url('/auth/verify_addr', a=self.nonce)) log.info('Verification email:\n%s', text) allura.tasks.mail_tasks.sendmail.post( destinations=[self._id], fromaddr=self._id, reply_to='', subject='Email address verification', message_id=h.gen_message_id(), text=text)
class ReactableArtifact(MappedClass): """Reaction support for the Artifact. Use as a mixin.""" react_counts = FieldProperty({str: None}, if_missing=dict()) # dict to store reaction counts react_users = FieldProperty({str: None}, if_missing=dict()) # dict to store reactions vs usernames def post_reaction(self, r, user): current_reaction = self.user_reacted(user) if current_reaction is None: # no prev reactions. simply append if r in self.react_users: self.react_users[r].append(user.username) else: self.react_users[r] = [user.username] self.update_react_count(r) elif current_reaction == r: # prev=current so remove self.react_users[r].remove(user.username) self.update_react_count(r, add=False) if len(self.react_users[r]) == 0: self.react_users.pop(r) else: # prev!=currnet so remove prev then append self.react_users[current_reaction].remove(user.username) if r in self.react_users: self.react_users[r].append(user.username) else: self.react_users[r] = [user.username] self.update_react_count(current_reaction, add=False) self.update_react_count(r) if len(self.react_users[current_reaction]) == 0: self.react_users.pop(current_reaction) def user_reacted(self, user): for i in self.react_users: if user.username in self.react_users[i]: return i return def update_react_count(self, r, add=True): i = 1 if not add: i = -1 if r in self.react_counts: self.react_counts[r] += i if self.react_counts[r] == 0: self.react_counts.pop(r) else: self.react_counts[r] = 1
class Group(SproxTestClass): """An ultra-simple group definition. (Relational-style) """ class __mongometa__: name = 'tg_group_rs' unique_indexes = [('group_name', )] _id = FieldProperty(S.ObjectId) group_name = FieldProperty(str) # unique display_name = FieldProperty(str) created = FieldProperty(datetime, if_missing=datetime.now) users = RelationProperty('User')
class TroveCategory(MappedClass): class __mongometa__: session = main_orm_session name = 'trove_category' indexes = ['trove_cat_id', 'trove_parent_id', 'shortname'] _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='') fullname = FieldProperty(str, if_missing='') fullpath = FieldProperty(str, if_missing='') parent_only = FieldProperty(bool, if_missing=False) show_as_skill = FieldProperty(bool, if_missing=True) @property def parent_category(self): return self.query.get(trove_cat_id=self.trove_parent_id) @property def subcategories(self): return self.query.find( dict(trove_parent_id=self.trove_cat_id)).sort('fullname').all() @property def children(self): result = [] children = self.query.find( dict(trove_parent_id=self.trove_cat_id)).all() for child in children: result.append(child) result.extend(child.children) result.sort(key=lambda x: x.fullpath) return result @property def type(self): trove = self while trove.trove_parent_id != 0: trove = trove.parent_category return trove.shortname @LazyProperty def ancestors(self): ancestors = [] trove = self while trove: ancestors.append(trove) trove = trove.parent_category return ancestors @LazyProperty def breadcrumbs(self): url = '/directory/' crumbs = [] for trove in reversed(self.ancestors[:-1]): url += trove.shortname + '/' crumbs.append((trove.fullname, url)) return crumbs
class TGMMUser(SproxTestClass): class __mongometa__: name = 'tg_mm_users' _id = FieldProperty(S.ObjectId) user_name = FieldProperty(S.String) _groups = FieldProperty(S.Array(str)) def _get_groups(self): return Group.query.find(dict(group_name={'$in': self._groups})).all() def _set_groups(self, groups): self._groups = [group.group_name for group in groups] groups = ProgrammaticRelationProperty(Group, _get_groups, _set_groups)
class Repository(M.Repository): tool_name = 'SVN' repo_id = 'svn' type_s = 'SVN Repository' class __mongometa__: name = 'svn-repository' branches = FieldProperty([dict(name=str, object_id=str)]) _refresh_precompute = False @LazyProperty def _impl(self): return SVNImplementation(self) def latest(self, branch=None): if self._impl is None: return None return self._impl.commit('HEAD') def tarball_filename(self, revision, path=None): fn = super(Repository, self).tarball_filename(revision, path) path = self._impl._path_to_root(path, revision) fn += ('-' + '-'.join(path.split('/'))) if path else '' return fn def rev_to_commit_id(self, rev): return self._impl.rev_parse(rev)
class DocumentCategoryReference(SproxTestClass): class __mongometa__: name = 'document_category_reference_rs' _id = FieldProperty(S.ObjectId) document_category_id = ForeignIdProperty(DocumentCategory) category = RelationProperty(DocumentCategory)
class Attachment(M.BaseAttachment): ArtifactClass = BlogPost class __mongometa__: polymorphic_identity = 'BlogAttachment' attachment_type = FieldProperty(str, if_missing='BlogAttachment')
def testTextArea(self): c = FieldProperty(S.String) c.sprox_meta = {"narrative": True} self._testSelect(c, TextArea)
def testPasswordField(self): c = FieldProperty(S.String) c.sprox_meta = {"password": True} self._testSelect(c, PasswordField)