class Event(db.Model, SerializableObject, TextRendererMixin): __tablename__ = 'event_event' __mapper_args__ = {'extension': db.SlugGenerator('slug', 'title')} # To order all queries by default, something like # __mapper_args__ = {'order_by':Event.start_date.asc() # has to be added to this class. No idea how to do that, now query = db.session.query_property(EventQuery) # serializer properties object_type = 'event.event' public_fields = ('id', 'title', 'slug', 'text', 'author', 'start', 'end', 'tags', 'discussion_question_id', 'info_question_id') #: Model columns id = db.Column(db.Integer, primary_key=True) title = db.Column(db.Unicode(100), nullable=False) slug = db.Column(db.Unicode(100), unique=True, index=True) text = db.Column(db.Text, nullable=False) author_id = db.Column(db.ForeignKey(User.id), nullable=False) start_date = db.Column(db.DateTime, nullable=False) end_date = db.Column(db.DateTime, nullable=False) tags = db.relationship(Tag, secondary=event_tag, backref=db.backref('events', lazy='dynamic'), lazy='joined', extension=TagCounterExtension()) discussion_question_id = db.Column(db.ForeignKey(Question.id), nullable=True) info_question_id = db.Column(db.ForeignKey(Question.id), nullable=True) author = db.relationship(User, lazy='joined') discussion_question = db.relationship( Question, primaryjoin=Question.id == discussion_question_id, backref=db.backref('eventd')) info_question = db.relationship( Question, primaryjoin=Question.id == info_question_id, backref=db.backref('eventi')) def get_url_values(self, action='view'): values = { 'view': 'event/view', 'browse': 'event/browse', 'calendar': 'event/calendar', 'edit': 'admin/event/edit', } return values[action], {'id': self.id} def __unicode__(self): return self.title
class Question(ForumEntry): """A :class:`Question` is an :class:`ForumEntry` with a title, a slug and several tags.""" __tablename__ = 'forum_question' __mapper_args__ = { 'extension': (db.SlugGenerator('slug', 'title'), SearchIndexMapperExtension('portal', 'question')), 'polymorphic_identity': u'question' } query = db.session.query_property(QuestionQuery) #: Serializer attributes object_type = 'forum.question' public_fields = ('entry_id', 'discriminator', 'author', 'date_created', 'date_active', 'score', 'text', 'votes', 'tags', 'id', 'title', 'slug') id = db.Column(db.Integer, db.ForeignKey(ForumEntry.entry_id), primary_key=True) title = db.Column(db.Unicode(160), nullable=False) slug = db.Column(db.Unicode(160), nullable=False, index=True) answer_count = db.Column(db.Integer, default=0) tags = db.relationship(Tag, secondary=question_tag, lazy='subquery', backref=db.backref('questions', lazy='dynamic'), extension=TagCounterExtension()) def get_url_values(self, **kwargs): """Generates an URL for this question.""" action = kwargs.get('action') if action == 'vote-up': return 'forum/vote', {'entry_id': self.id, 'action': 'up'} elif action == 'vote-down': return 'forum/vote', {'entry_id': self.id, 'action': 'down'} kwargs.update({'slug': self.slug}) return 'forum/question', kwargs def __unicode__(self): return self.title
class Forum(db.Model, SerializableObject): __tablename__ = 'forum_forum' __mapper_args__ = {'extension': db.SlugGenerator('slug', 'name')} query = db.session.query_property(ForumQuery) #: serializer attributes object_type = 'forum.forum' public_fields = ('id', 'name', 'slug', 'description', 'tags' 'position', 'subforums') id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Unicode(80), nullable=False) slug = db.Column(db.Unicode(80), unique=True, index=True) description = db.Column(db.Unicode(200), nullable=False, default=u'') parent_id = db.Column(db.Integer, db.ForeignKey(id), nullable=True, index=True) position = db.Column(db.Integer, nullable=False, default=0, index=True) subforums = db.relationship('Forum', backref=db.backref('parent', remote_side=id), lazy='joined') tags = db.relationship(Tag, secondary=forum_tag, lazy='dynamic', backref=db.backref('forums', lazy='dynamic'), extension=TagCounterExtension()) @cached_property def all_tags(self): """Return all tags for this forum, including those of the subforums.""" tags = list(self.tags) for subforum in self.subforums: tags.extend(subforum.tags) return tags def get_url_values(self, **kwargs): kwargs.update({'forum': self.slug}) return 'forum/questions', kwargs
class ForumEntry(db.Model, SerializableObject, TextRendererMixin): """The base class of a :class:`Question` or :class:`Answer`, which contains some general information about the author and the creation date, as well as the actual text and the votings.""" __tablename__ = 'forum_entry' query = db.session.query_property(ForumEntryQuery) #: Serializer attributes object_type = 'forum.entry' public_fields = ('entry_id', 'discriminator', 'author', 'date_created', 'date_active', 'score', 'text', 'votes') entry_id = db.Column(db.Integer, primary_key=True) discriminator = db.Column('type', db.Unicode(12)) author_id = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False) date_created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) date_active = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) score = db.Column(db.Integer, nullable=False, default=0) text = db.Column(db.Text, nullable=False) view_count = db.Column(db.Integer, default=0, nullable=False) author = db.relationship(User, lazy='joined', innerjoin=True) votes = db.relationship('Vote', backref='entry', extension=ForumEntryVotesExtension()) __mapper_args__ = {'polymorphic_on': discriminator} def touch(self): db.atomic_add(self, 'view_count', 1) def get_vote(self, user): return Vote.query.filter_by(user=user, entry=self).first()
class PasteEntry(db.Model, SerializableObject): __tablename__ = 'paste_entry' # serializer properties object_type = 'paste.entry' public_fields = ('id', 'text', 'title', 'author', 'pub_date', 'language', 'hidden') #: Model columns id = db.Column(db.Integer, primary_key=True) text = db.Column(db.Text, nullable=False) title = db.Column(db.Unicode(50), nullable=True) language = db.Column(db.Unicode(30)) author_id = db.Column(db.ForeignKey(User.id), nullable=False) pub_date = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) hidden = db.Column(db.Boolean, default=False) author = db.relationship(User, lazy='joined') # revision model implementation parent_id = db.Column(db.Integer, db.ForeignKey(id), nullable=True) children = db.relationship('PasteEntry', cascade='all', primaryjoin=parent_id == id, backref=db.backref('parent', remote_side=id)) def get_url_values(self, action='view'): if action == 'reply': return 'paste/index', {'reply_to': self.id} values = { 'view': 'paste/view', 'raw': 'paste/raw', 'show_tree': 'paste/show_tree', 'edit': 'paste/edit', } return values[action], {'id': self.id} @property def display_title(self): if self.title: return self.title return _(u'Paste #%d') % self.id @property def highlighted_text(self): return highlight_text(self.text, self.language) @property def has_tree(self): return bool(self.children) or bool(self.parent_id) def compare_to(self, other, column, context_lines=4, template=False): """Compare the model with another revision. Special version to enable highlighting between files. :param other: The other model instance to compare with. :param column: A string what column to compare. :param context_lines: How many additional lines to show on the udiff. :param template: Either or not to prepare the udiff for templates use. """ differ = generate_highlighted_udiff if template else generate_udiff generator = partial(differ, old=getattr(self, column, u''), new=getattr(other, column, u''), old_title=unicode(self), new_title=unicode(other), context_lines=context_lines) if template: udiff = generator(old_lang=self.language, new_lang=other.language) else: udiff = generator() if template: diff = prepare_udiff(udiff, True) return diff and diff[0] or None return udiff @classmethod def resolve_root(cls, identifier): """Find the root for a tree. :param identifier: The identifier a model should queried for. We use ``cls.query.get`` to query the identifier. :returns: The very root object with no additional parent_id set. """ obj = cls.query.get(identifier) if obj is None: return while obj.parent_id is not None: obj = obj.parent return obj def __unicode__(self): return self.display_title def __repr__(self): if self.title: s = repr(self.title) else: s = '#%s' % self.id if self.id else '[no id]' u = self.author.username return '<PasteEntry %s by %s>' % (s, u)
class Article(db.Model, TextRendererMixin): __tablename__ = 'news_article' __mapper_args__ = { 'extension': (db.SlugGenerator('slug', 'title'), SearchIndexMapperExtension('portal', 'news'), db.GuidGenerator('news/article')) } query = db.session.query_property(ArticleQuery) id = db.Column(db.Integer, primary_key=True) pub_date = db.Column(db.DateTime, default=datetime.utcnow) updated = db.Column(db.DateTime, default=datetime.utcnow) title = db.Column(db.Unicode(200)) slug = db.Column(db.Unicode(100), unique=True) intro = db.Column(db.Text) text = db.Column(db.Text) public = db.Column(db.Boolean, default=False, nullable=False) view_count = db.Column(db.Integer, default=0, nullable=False) comment_count = db.Column(db.Integer, default=0, nullable=False) comments_enabled = db.Column(db.Boolean, default=True, nullable=False) guid = db.Column(db.Unicode(80), unique=True) tags = db.relationship(Tag, secondary=article_tag, backref=db.backref('articles', lazy='dynamic'), lazy='joined', extension=TagCounterExtension()) author_id = db.Column(db.ForeignKey(User.id), nullable=False) author = db.relationship(User, backref=db.backref('articles', lazy='dynamic')) comments = db.relationship(Comment, backref=db.backref('article', lazy='joined'), primaryjoin=id == Comment.article_id, order_by=[db.asc(Comment.pub_date)], lazy='dynamic', cascade='all, delete, delete-orphan', extension=CommentCounterExtension()) @property def hidden(self): """ This returns a boolean whether this article is not visible for normal users. Article that are not published or whose pub_date is in the future aren't shown for a normal user. """ return not self.public or self.pub_date > datetime.utcnow() @property def was_updated(self): return self.updated.replace(microsecond=0) > \ self.pub_date.replace(microsecond=0) def touch(self): db.atomic_add(self, 'view_count', 1) def get_url_values(self, **kwargs): action = kwargs.pop('action', 'view') if action in ('subscribe', 'unsubscribe'): return 'news/subscribe_comments', { 'slug': self.slug, 'action': action, } values = { 'view': 'news/detail', 'edit': 'news/article_edit', 'delete': 'news/article_delete', } kwargs.update({'slug': self.slug}) return values[action], kwargs def __unicode__(self): return self.title