class ParticipantList(ContentMixin, Node): __tablename__ = 'participant_list' source = db.Column(db.Unicode(80), nullable=False, default=u'') sourceid = db.Column(db.Unicode(80), nullable=False, default=u'') api_key = db.Column(db.Unicode(80), nullable=False, default=u'') participant_template = db.Column(db.Unicode(80), nullable=False, default=u'') def purge(self): """ Discard all participants. """ self.participants = [] def has_user(self, user): return Participant.query.filter_by(participant_list=self).filter_by( user=user).first() is not None def url_for(self, action='view'): if action in ['sync', 'list']: return url_for('node_action', website=self.folder.website.name, folder=self.folder.name, node=self.name, action=action) else: return super(ParticipantList, self).url_for(action)
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)
class MapItem(BaseScopedNameMixin, db.Model): __tablename__ = 'map_item' map_id = db.Column(None, db.ForeignKey('map.id'), nullable=False) parent = db.synonym('map') url = db.Column(db.Unicode(250), nullable=True) latitude = db.Column(db.Numeric(7, 4), nullable=False) longitude = db.Column(db.Numeric(7, 4), nullable=False) zoomlevel = db.Column(db.Integer, nullable=True) marker = db.Column(db.Unicode(80), nullable=True) seq = db.Column(db.Integer, nullable=False) __table_args__ = (db.UniqueConstraint('map_id', 'name'),) @classmethod def get_or_new(cls, map, name=None): item = cls.query.filter_by(map=map, name=name).first() if item is None: item = cls(map=map, name=name) db.session.add(item) return item
class Redirect(NodeMixin, Node): __tablename__ = 'redirect' redirect_url = db.Column(db.Unicode(250), nullable=False) def as_json(self): result = super(Redirect, self).as_json() result.update({'redirect_url': self.redirect_url}) return result def import_from(self, data): super(Redirect, self).import_from(data) self.redirect_url = data['redirect_url']
class FunnelLink(ContentMixin, Node): __tablename__ = 'funnel_link' funnel_name = db.Column(db.Unicode(80), nullable=False) def as_json(self): result = super(FunnelLink, self).as_json() result.update({'funnel_name': self.funnel_name}) return result def import_from(self, data): super(FunnelLink, self).import_from(data) self.funnel_name = data['funnel_name'] def _data(self): if not hasattr(self, '_data_cached'): # Get JSON and cache locally try: r = requests.get('http://funnel.hasgeek.com/%s/json' % self.funnel_name) data = r.json() if callable(r.json) else r.json sectionmap = dict([(s['title'], s['name']) for s in data['sections']]) for proposal in data['proposals']: proposal['submitted'] = parse_isoformat( proposal['submitted']) proposal['section_name'] = sectionmap.get( proposal['section']) v = proposal['votes'] proposal['votes'] = '+%d' % v if v > 0 else '%d' % v self._data_cached = data except ConnectionError: self._data_cached = { 'proposals': [], 'sections': [], 'space': {}, } return self._data_cached def proposals_mapping(self): if not hasattr(self, '_dict_cached'): self._dict_cached = dict([(p['id'], p) for p in self.proposals()]) return self._dict_cached def sections(self): # Get data from Funnel and cache locally return self._data()['sections'] def proposals(self): return self._data()['proposals'] def confirmed(self): return [p for p in self._data()['proposals'] if p['confirmed']]
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
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')