Пример #1
0
class Revisions(BaseMixin, db.Model):
    """
    Collection of revisions of content.
    """
    __tablename__ = 'revisions'
    #: All revisions of the content
    history = db.relationship(
        ContentRevision,
        primaryjoin='ContentRevision.parent_id == Revisions.id',
        order_by=ContentRevision.id.desc,
        backref=db.backref('parent', cascade='all'))
    #: Latest published revision
    published_id = db.Column(db.Integer,
                             db.ForeignKey('content_revision.id'),
                             nullable=True)
    published = db.relationship(ContentRevision,
                                post_update=True,
                                primaryjoin=published_id == ContentRevision.id)
    #: Latest draft revision
    draft_id = db.Column(db.Integer,
                         db.ForeignKey('content_revision.id'),
                         nullable=True)
    draft = db.relationship(ContentRevision,
                            post_update=True,
                            primaryjoin=draft_id == ContentRevision.id)
Пример #2
0
class ContentRevision(BaseMixin, db.Model):
    """
    A single revision of any piece of content.
    """
    __tablename__ = 'content_revision'
    parent_id = db.Column(db.Integer,
                          db.ForeignKey('revisions.id',
                                        use_alter=True,
                                        name='fk_content_revision_parent_id'),
                          nullable=False)
    #: Previous revision
    previous_id = db.Column(db.Integer,
                            db.ForeignKey('content_revision.id'),
                            nullable=True)
    previous = db.relationship('ContentRevision',
                               remote_side='ContentRevision.id',
                               uselist=False)
    #: User who made this content revision
    user_id = db.Column(db.Integer,
                        db.ForeignKey('user.id'),
                        nullable=False,
                        default=default_user_id)
    user = db.relationship(User)
    #: Title of the current revision
    title = db.Column(db.Unicode(250), nullable=False)
    #: Abstract that is shown in summaries. Plain text.
    description = db.Column(db.UnicodeText, nullable=False, default=u'')
    #: Page content. Rich text.
    _content = db.Column('content',
                         db.UnicodeText,
                         nullable=False,
                         default=u'')
    #: Template with which this page will be rendered
    template = db.Column(db.Unicode(80), nullable=False, default=u'')

    def __init__(self, **kwargs):
        super(ContentRevision, self).__init__(**kwargs)
        if self.previous:
            # Copy over content from the previous revision
            if not self.user:
                self.user = self.previous.user
            if not self.title:
                self.title = self.previous.title
            if not self.description:
                self.description = self.previous.description
            if not self._content:
                self._content = self.previous._content
            if not self.template:
                self.template = self.previous.template

    @property
    def content(self):
        return Markup(self._content)

    @content.setter
    def content(self, value):
        self._content = value

    content = db.synonym('_content', descriptor=content)
Пример #3
0
class Participant(BaseMixin, db.Model):
    __tablename__ = 'participant'

    #: List that this participant is in
    participant_list_id = db.Column(None,
                                    db.ForeignKey('participant_list.id'),
                                    nullable=False)
    #: Datetime when this participant's record was created upstream
    datetime = db.Column(db.DateTime, nullable=True)
    #: Ticket no, the reference key
    ticket = db.Column(db.Unicode(80), nullable=True, unique=True)
    #: Participant's name
    fullname = db.Column(db.Unicode(80), nullable=True)
    #: Unvalidated email address
    email = db.Column(db.Unicode(80), nullable=True)
    #: Unvalidated phone number
    phone = db.Column(db.Unicode(80), nullable=True)
    #: Unvalidated Twitter id
    twitter = db.Column(db.Unicode(80), nullable=True)
    #: Ticket type, if the registration system had multiple tickets
    ticket_type = db.Column(db.Unicode(80), nullable=True)
    #: Job title
    jobtitle = db.Column(db.Unicode(80), nullable=True)
    #: Company
    company = db.Column(db.Unicode(80), nullable=True)
    #: Participant's city
    city = db.Column(db.Unicode(80), nullable=True)
    #: T-shirt size
    tshirt_size = db.Column(db.Unicode(4), nullable=True)
    #: Link to the user record
    user_id = db.Column(None, db.ForeignKey('user.id'), nullable=True)
    user = db.relationship(User)
    #: Access key for connecting to the user record (nulled when linked)
    access_key = db.Column(db.Unicode(44),
                           nullable=True,
                           default=newsecret,
                           unique=True)
    #: Is listed in the public directory
    is_listed = db.Column(db.Boolean, default=False, nullable=False)
    #: Data fields the participant has chosen to reveal in public
    fields_directory = db.Column(db.Unicode(250),
                                 nullable=False,
                                 default=u'fullname company')
    #: Data fields the participant has chosen to reveal via ContactPoint
    fields_contactpoint = db.Column(
        db.Unicode(250),
        nullable=False,
        default=u'fullname email phone twitter jobtitle company city')

    participant_list = db.relationship(ParticipantList,
                                       backref=db.backref(
                                           'participants',
                                           order_by=fullname,
                                           cascade='all, delete-orphan'))

    parent = db.synonym('participant_list')
Пример #4
0
class Map(NodeMixin, Node):
    __tablename__ = 'map'
    items = db.relationship(MapItem,
        order_by=[MapItem.seq],
        collection_class=ordering_list('seq'),
        backref='map',
        cascade='all, delete-orphan')

    def as_json(self):
        result = super(NodeMixin, self).as_json()
        result['items'] = [{'name': item.name,
                            'title': item.title,
                            'url': item.url,
                            'latitude': item.latitude,
                            'longitude': item.longitude,
                            'zoomlevel': item.zoomlevel,
                            'marker': item.marker}
            for item in self.items]
        return result

    def populate_map(self, items):
        newitems = []
        for itemdata in items:
            mitem = MapItem.get_or_new(self, name=itemdata['name'])
            for key in itemdata:
                setattr(mitem, key, itemdata[key])
            newitems.append(mitem)

        self.items = newitems
        self.items.reorder()
        # Since self.items is a relationship, it won't update self.updated_at
        self.updated_at = datetime.utcnow()

    def import_from(self, data):
        super(NodeMixin, self).import_from(data)
        self.populate_map(data['items'])

    def get_by_name(self, name):
        if name is not None:
            for i in self.items:
                if i.name == name:
                    return i

    def prev_to(self, item, items=None):
        items = items or self.items

        candidate = None
        for i in items:
            if i is item:
                return candidate
            else:
                candidate = i
        # The given item is not in this list
        return None

    def next_to(self, item):
        # Reverse the list and search with prev_to
        return self.prev_to(item, items=self.items[::-1])
Пример #5
0
class ListItem(BaseMixin, db.Model):
    __tablename__ = 'list_item'
    list_id = db.Column(None, db.ForeignKey('list.id'), nullable=False)
    name = db.Column(db.Unicode(80), nullable=True)
    title = db.Column(db.Unicode(250), nullable=True)
    url = db.Column(db.Unicode(250), nullable=True)
    node_id = db.Column(None, db.ForeignKey('node.id'), nullable=True)
    node = db.relationship(Node,
                           backref=db.backref('lists',
                                              cascade='all, delete-orphan'))
    seq = db.Column(db.Integer, nullable=False)

    __table_args__ = (
        db.UniqueConstraint(
            'list_id',
            'name'),  # name, if present, must be unique in this list
        db.UniqueConstraint('list_id',
                            'node_id')  # A node can only be in a list once
    )

    @classmethod
    def get_or_new(cls, list, name=None, node=None):
        if name is None and node is None:
            return
        query = cls.query.filter_by(list=list)
        if name:
            query = query.filter_by(name=name)
        if node:
            query = query.filter_by(node=node)
        item = query.first()
        if item:
            return item
        else:
            item = cls(list=list, name=name, node=node)
            db.session.add(item)
        return item
Пример #6
0
 def revisions(cls):
     return db.relationship(Revisions, uselist=False)
Пример #7
0
class List(NodeMixin, Node):
    __tablename__ = 'list'
    items = db.relationship(ListItem,
                            order_by=[ListItem.seq],
                            collection_class=ordering_list('seq'),
                            backref='list',
                            cascade='all, delete-orphan')

    def as_json(self):
        result = super(NodeMixin, self).as_json()
        result['items'] = [[
            item.name, item.title, item.url,
            '%s/%s' %
            (item.node.folder.name, item.node.name) if item.node else ''
        ] for item in self.items]
        return result

    def populate_list(self, items):
        newitems = []
        for name, title, url, path in items:
            name = name or None  # Convert blank strings into None
            litem = None
            if path:
                try:
                    foldername, nodename = path.split('/', 1)
                except ValueError:
                    # No folder specified? Try loading nodes from the current folder
                    lfolder = self.folder
                    nodename = path
                else:
                    if self.folder.name == foldername:
                        lfolder = self.folder
                    else:
                        lfolder = Folder.query.filter_by(
                            website=self.folder.website,
                            name=foldername).first()

                if lfolder:
                    lnode = Node.query.filter_by(folder=lfolder,
                                                 name=nodename).first()
                    if lnode:
                        litem = ListItem.get_or_new(self, node=lnode)
                        # If this item has a name, ensure the name is unique
                        if name is not None:
                            for existing in self.items:
                                if existing is not litem and existing.name == name:
                                    existing.name = None
                        litem.name = name
                        litem.title = title
                        litem.url = url
            if name and litem is None:
                litem = ListItem.get_or_new(self, name=name)
                litem.title = title
                litem.url = url
                litem.node = None
            if litem is None:
                litem = ListItem(name=name, title=title, node=None, url=url)
            newitems.append(litem)

        self.items = newitems
        self.items.reorder()
        # Since self.items is a relationship, it won't update self.updated_at
        self.updated_at = datetime.utcnow()

    def import_from(self, data):
        super(NodeMixin, self).import_from(data)

    def import_from_internal(self, data):
        super(NodeMixin, self).import_from_internal(data)
        self.populate_list(data['items'])

    def get_by_node(self, node):
        if node is not None:
            for i in self.items:
                if i.node == node:
                    return i

    def prev_to(self, item, items=None):
        items = items or self.items

        candidate = None
        for i in items:
            if i == item:
                return candidate
            else:
                candidate = i
        # The given node is not in this list
        return None

    def next_to(self, item):
        # Reverse the list and search with prev_to
        return self.prev_to(item, items=self.items[::-1])

    def prev_to_node(self, node, items=None):
        items = items or self.items

        candidate = None
        for i in items:
            if i.node == node:
                return candidate
            else:
                candidate = i
        # The given node is not in this list
        return None

    def next_to_node(self, node):
        # Reverse the list and search with prev_to
        return self.prev_to_node(node, items=self.items[::-1])
Пример #8
0
 def revisions(cls):
     return db.relationship(Revisions, uselist=False)