class Event(BaseScopedNameMixin, db.Model): __tablename__ = 'event' profile_id = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=False) profile = db.relationship(Profile) parent = db.synonym('profile') venue_id = db.Column(db.Integer, db.ForeignKey('venue.id'), nullable=False) venue = db.relationship('Venue') blurb = db.Column(db.Unicode(250), default=u'', nullable=False) description = db.Column(db.UnicodeText, default=u'', nullable=False) start_datetime = db.Column(db.DateTime, nullable=False) end_datetime = db.Column(db.DateTime, nullable=False) maximum_participants = db.Column(db.Integer, default=0, nullable=False) website = db.Column(db.Unicode(250), default=u'', nullable=False) status = db.Column(db.Integer, nullable=False, default=EVENT_STATUS.DRAFT) ticket_price = db.Column(db.Unicode(250), nullable=False, default=u'') __table_args__ = (db.UniqueConstraint('name', 'profile_id'), ) def owner_is(self, user): """Check if a user is an owner of this event""" return user is not None and self.profile.userid in user.user_organizations_owned_ids( ) def participant_is(self, user): from hacknight.models.participant import Participant return Participant.get(user, self) is not None def confirmed_participant_is(self, user): from hacknight.models.participant import Participant, PARTICIPANT_STATUS p = Participant.get(user, self) return p and p.status == PARTICIPANT_STATUS.CONFIRMED
class Sponsor(BaseScopedNameMixin, db.Model): __tablename__ = 'sponsor' event_id = db.Column(db.Integer, db.ForeignKey('event.id'), nullable=False) event = db.relation(Event, backref=db.backref('sponsors', cascade='all, delete-orphan')) parent = db.synonym('event') website = db.Column(db.Unicode(250), nullable=True) image_url = db.Column(db.Unicode(250), nullable=False) description = db.Column(db.UnicodeText, nullable=False) __table_args__ = (db.UniqueConstraint('name', 'event_id'), )
class EventRedirect(BaseMixin, db.Model): __tablename__ = "event_redirect" profile_id = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=False) profile = db.relationship(Profile) name = db.Column(db.Unicode(250), nullable=False) event_id = db.Column(None, db.ForeignKey('event.id'), nullable=False) event = db.relationship(Event, backref=db.backref('redirects', cascade='all, delete-orphan')) __table_args__ = (db.UniqueConstraint(profile_id, name), )
class ProjectMember(BaseMixin, db.Model): __tablename__ = 'project_member' project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False) # project = db.relationship(Project, backref=db.backref('members', cascade='all, delete-orphan')) participant_id = db.Column(db.Integer, db.ForeignKey('participant.id'), nullable=False) participant = db.relationship( Participant, backref=db.backref('projects', cascade='all, delete-orphan')) status = db.Column(db.Integer, nullable=False, default=0) role = db.Column(db.Unicode(250), nullable=False, default=u'') __table_args__ = (db.UniqueConstraint('project_id', 'participant_id'), )
class Vote(BaseMixin, db.Model): __tablename__ = 'vote' user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) user = db.relationship(User, primaryjoin=user_id == User.id, backref=db.backref('votes', cascade="all, delete-orphan")) votespace_id = db.Column(db.Integer, db.ForeignKey('votespace.id'), nullable=False) votespace = db.relationship(VoteSpace, primaryjoin=votespace_id == VoteSpace.id, backref=db.backref( 'votes', cascade="all, delete-orphan")) votedown = db.Column(db.Boolean, default=False, nullable=False) __table_args__ = (db.UniqueConstraint("user_id", "votespace_id"), {})
class Sponsor(BaseScopedNameMixin, db.Model): __tablename__ = 'sponsor' event_id = db.Column(db.Integer, db.ForeignKey('event.id'), nullable=False) event = db.relation(Event, backref=db.backref('sponsors', cascade='all, delete-orphan')) parent = db.synonym('event') website = db.Column(db.Unicode(250), nullable=True) image_url = db.Column(db.Unicode(250), nullable=False) description = db.Column(db.UnicodeText, nullable=False) __table_args__ = (db.UniqueConstraint('name', 'event_id'), ) def url_for(self, action='view', _external=False): if action == 'view': return url_for('sponsor_view', profile=self.event.profile.name, event=self.event.name, sponsor=self.name)
class ProjectMember(BaseMixin, db.Model): __tablename__ = 'project_member' project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False) #: User who created this project user_id = db.Column(None, db.ForeignKey('user.id'), nullable=False) user = db.relationship(User, backref=db.backref('project_memberships', cascade='all, delete-orphan')) status = db.Column(db.Integer, nullable=False, default=0) role = db.Column(db.Unicode(250), nullable=False, default=u'') __table_args__ = (db.UniqueConstraint('project_id', 'user_id'), ) def permissions(self, user, inherited=None): perms = super(ProjectMember, self).permissions(user, inherited) if user is not None and user == self.project.user and self.user != user: perms.add('remove-member') return perms
class Project(BaseScopedIdNameMixin, db.Model): __tablename__ = 'project' event_id = db.Column(db.Integer, db.ForeignKey('event.id'), nullable=False) event = db.relation(Event, backref=db.backref('projects', cascade='all, delete-orphan')) parent = db.synonym('event') #: Participant who created this project participant_id = db.Column(None, db.ForeignKey('participant.id'), nullable=False) participant = db.relationship(Participant) blurb = db.Column(db.Unicode(250), nullable=False) description = db.Column(db.UnicodeText, nullable=False) maximum_size = db.Column(db.Integer, default=0, nullable=False) #: Is the project owner participating? participating = db.Column(db.Boolean, nullable=False, default=True) members = db.relationship('ProjectMember', backref='project', lazy='dynamic') votes_id = db.Column(db.Integer, db.ForeignKey('votespace.id'), nullable=False) votes = db.relationship(VoteSpace, uselist=False) comments_id = db.Column(db.Integer, db.ForeignKey('commentspace.id'), nullable=False) comments = db.relationship(CommentSpace, uselist=False) __table_args__ = (db.UniqueConstraint('url_id', 'event_id'), ) def __init__(self, **kwargs): super(Project, self).__init__(**kwargs) if not self.votes: self.votes = VoteSpace(type=0) if not self.comments: self.comments = CommentSpace() @property def user(self): return self.participant.user @property def participants(self): return set([self.participant] + [m.participant for m in self.members]) @property def users(self): return set([self.user] + [m.participant.user for m in self.members]) def owner_is(self, user): return self.user == user def getnext(self): return Project.query.filter(Project.event == self.event).filter( Project.id != self.id).filter( Project.created_at < self.created_at).order_by( db.desc('created_at')).first() def getprev(self): return Project.query.filter(Project.event == self.event).filter( Project.id != self.id).filter(Project.created_at > self.created_at ).order_by('created_at').first()
class Comment(BaseScopedIdMixin, db.Model): __tablename__ = 'comment' user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=True) user = db.relationship(User, primaryjoin=user_id == User.id, backref=db.backref('comments', cascade="all")) commentspace_id = db.Column(db.Integer, db.ForeignKey('commentspace.id'), nullable=False) commentspace = db.relationship( CommentSpace, primaryjoin=commentspace_id == CommentSpace.id, backref=db.backref('comments', cascade="all, delete-orphan")) reply_to_id = db.Column(db.Integer, db.ForeignKey('comment.id'), nullable=True) children = db.relationship("Comment", backref=db.backref("reply_to", remote_side="Comment.id")) message = db.Column(db.Text, nullable=False) message_html = db.Column(db.Text, nullable=False) status = db.Column(db.Integer, default=0, nullable=False) votes_id = db.Column(db.Integer, db.ForeignKey('votespace.id'), nullable=False) votes = db.relationship(VoteSpace, uselist=False) edited_at = db.Column(db.DateTime, nullable=True) parent = db.synonym('commentspace') __table_args__ = (db.UniqueConstraint('url_id', 'commentspace_id'), ) def __init__(self, **kwargs): super(Comment, self).__init__(**kwargs) self.votes = VoteSpace(type=SPACETYPE.COMMENT) def delete(self): """ Delete this comment. """ if len(self.children) > 0: self.status = COMMENTSTATUS.DELETED self.user = None self.message = '' self.message_html = '' else: if self.reply_to and self.reply_to.is_deleted: # If the parent comment is deleted, ask it to reconsider removing itself reply_to = self.reply_to reply_to.children.remove(self) db.session.delete(self) reply_to.delete() else: db.session.delete(self) @property def is_deleted(self): return self.status == COMMENTSTATUS.DELETED def sorted_children(self): return sorted(self.children, key=lambda child: child.votes.count)
class Event(BaseScopedNameMixin, db.Model): __tablename__ = 'event' profile_id = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=False) profile = db.relationship(Profile) parent = db.synonym('profile') venue_id = db.Column(db.Integer, db.ForeignKey('venue.id'), nullable=True) venue = db.relationship('Venue') blurb = db.Column(db.Unicode(250), default=u'', nullable=False) description = db.Column(db.UnicodeText, default=u'', nullable=False) apply_instructions = db.Column(db.UnicodeText, default=u'', nullable=False) start_datetime = db.Column(db.DateTime, nullable=False) end_datetime = db.Column(db.DateTime, nullable=False) maximum_participants = db.Column(db.Integer, default=0, nullable=False) website = db.Column(db.Unicode(250), default=u'', nullable=False) status = db.Column(db.Integer, nullable=False, default=EVENT_STATUS.DRAFT) ticket_price = db.Column(db.Unicode(250), nullable=False, default=u'') confirmation_message = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) confirmation_message_text = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) waitlisted_message = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) waitlisted_message_text = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) rejected_message = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) rejected_message_text = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) pending_message = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) pending_message_text = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) # Sync details sync_service = db.Column(db.Unicode(100), nullable=True) sync_credentials = db.Column(db.Unicode(100), nullable=True) sync_eventsid = db.Column(db.Unicode(100), nullable=True) __table_args__ = (db.UniqueConstraint('name', 'profile_id'), ) # List of statuses which are not allowed to be displayed in index page. NON_DISPLAYABLE_STATUSES = (EVENT_STATUS.DRAFT, EVENT_STATUS.CANCELLED, EVENT_STATUS.UNLISTED) @classmethod def upcoming_events(cls): return cls.query.filter( cls.end_datetime > datetime.utcnow(), not_(cls.status.in_(cls.NON_DISPLAYABLE_STATUSES))).order_by( cls.start_datetime.asc()).all() @classmethod def past_events(cls): return cls.query.filter( cls.end_datetime < datetime.utcnow(), not_(cls.status.in_(cls.NON_DISPLAYABLE_STATUSES))).order_by( cls.end_datetime.desc()).all() def owner_is(self, user): """Check if a user is an owner of this event""" return user is not None and self.profile.userid in user.user_organizations_owned_ids( ) def has_sync(self): return self.sync_service and self.sync_credentials and self.sync_eventsid def _fetch_and_sync(self, event_id, participants): """Fetch data from external service like doattend""" from hacknight import lastuser if self.sync_service == SYNC_SERVICE.DOATTEND: data_url = u"http://doattend.com/api/events/{event_id}/participants_list.json?api_key={credentials}".format( event_id=event_id, credentials=self.sync_credentials) try: r = requests.get(data_url) except requests.ConnectionError: raise SyncException(u"Unable to connect to internet") if r.status_code == 200: registered_participants = r.json() if callable( r.json) else r.json emails = set([ p.get('Email') for p in registered_participants['participants'] ]) for participant in participants: if participant.email in emails or emails.intersection( set(lastuser.user_emails(participant.user))): participant.confirm() yield u"{email} is confirmed.\n".format( email=participant.email) yield u"Synced all participants.\n" else: raise SyncException( u"Sync service failed with status code {code}".format( code=r.status_code)) def sync_participants(self, participants): final_msg = u"<a href=\"{url}\">Click here for hacknight page.</a>\n".format( url=self.url_for()) if self.has_sync(): for event_id in self.sync_eventsid.split(','): try: for msg in self._fetch_and_sync(event_id.strip(), participants): yield msg except SyncException, e: yield unicode(e) db.session.commit() yield Markup(final_msg) else:
class Event(BaseScopedNameMixin, db.Model): __tablename__ = 'event' profile_id = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=False) profile = db.relationship(Profile) parent = db.synonym('profile') venue_id = db.Column(db.Integer, db.ForeignKey('venue.id'), nullable=False) venue = db.relationship('Venue') blurb = db.Column(db.Unicode(250), default=u'', nullable=False) description = db.Column(db.UnicodeText, default=u'', nullable=False) apply_instructions = db.Column(db.UnicodeText, default=u'', nullable=False) start_datetime = db.Column(db.DateTime, nullable=False) end_datetime = db.Column(db.DateTime, nullable=False) maximum_participants = db.Column(db.Integer, default=0, nullable=False) website = db.Column(db.Unicode(250), default=u'', nullable=False) status = db.Column(db.Integer, nullable=False, default=EVENT_STATUS.DRAFT) ticket_price = db.Column(db.Unicode(250), nullable=False, default=u'') confirmation_message = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) confirmation_message_text = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) waitlisted_message = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) waitlisted_message_text = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) rejected_message = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) rejected_message_text = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) pending_message = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) pending_message_text = deferred( db.Column(db.UnicodeText, nullable=False, default=u'')) __table_args__ = (db.UniqueConstraint('name', 'profile_id'), ) def owner_is(self, user): """Check if a user is an owner of this event""" return user is not None and self.profile.userid in user.user_organizations_owned_ids( ) def participant_is(self, user): from hacknight.models.participant import Participant return Participant.get(user, self) is not None def confirmed_participant_is(self, user): from hacknight.models.participant import Participant, PARTICIPANT_STATUS p = Participant.get(user, self) return p and p.status == PARTICIPANT_STATUS.CONFIRMED def permissions(self, user, inherited=None): perms = super(Event, self).permissions(user, inherited) if user is not None and user.userid == self.profile.userid or self.status in [ EVENT_STATUS.PUBLISHED, EVENT_STATUS.ACTIVE, EVENT_STATUS.COMPLETED, EVENT_STATUS.CANCELLED, EVENT_STATUS.CLOSED ]: perms.add('view') if user is not None and self.profile.userid in user.user_organizations_owned_ids( ): perms.add('edit') perms.add('delete') perms.add('send-email') return perms def url_for(self, action='view', _external=False): if action == 'view': return url_for('event_view', profile=self.profile.name, event=self.name, _external=_external) elif action == 'edit': return url_for('event_edit', profile=self.profile.name, event=self.name, _external=_external) elif action == 'delete': return url_for('event_delete', profile=self.profile.name, event=self.name, _external=_external) elif action == 'new-project': return url_for('project_new', profile=self.profile.name, event=self.name, _external=_external) elif action == 'apply': return url_for('event_apply', profile=self.profile.name, event=self.name, _external=_external) elif action == 'withdraw': return url_for('event_withdraw', profile=self.profile.name, event=self.name, _external=_external) elif action == 'open': return url_for('event_open', profile=self.profile.name, event=self.name, _external=_external) elif action == 'export': return url_for('event_export', profile=self.profile.name, event=self.name, _external=_external) elif action == 'send_email': return url_for('event_send_email', profile=self.profile.name, event=self.name, _external=_external) elif action == 'email_template': return url_for('email_template_form', profile=self.profile.name, event=self.name, _external=_external)
class Project(BaseScopedIdNameMixin, db.Model): __tablename__ = 'project' event_id = db.Column(db.Integer, db.ForeignKey('event.id'), nullable=False) event = db.relation(Event, backref=db.backref('projects', order_by=db.desc('url_id'), cascade='all, delete-orphan')) parent = db.synonym('event') #: User who is part of this project user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) user = db.relationship(User, backref='projects') blurb = db.Column(db.Unicode(250), nullable=False) description = db.Column(db.UnicodeText, nullable=False) maximum_size = db.Column(db.Integer, default=0, nullable=False) #: Is the project owner participating? participating = db.Column(db.Boolean, nullable=False, default=True) members = db.relationship('ProjectMember', backref='project', uselist=True) votes_id = db.Column(db.Integer, db.ForeignKey('votespace.id'), nullable=False) votes = db.relationship(VoteSpace, uselist=False) comments_id = db.Column(db.Integer, db.ForeignKey('commentspace.id'), nullable=False) comments = db.relationship(CommentSpace, uselist=False) __table_args__ = (db.UniqueConstraint('url_id', 'event_id'), ) def __init__(self, **kwargs): super(Project, self).__init__(**kwargs) if not self.votes: self.votes = VoteSpace(type=0) if not self.comments: self.comments = CommentSpace() @property def users(self): return set([self.user] + [m.user for m in self.members]) participants = users def owner_is(self, user): return user is not None and self.user == user def getnext(self): return Project.query.filter(Project.event == self.event).filter( Project.id != self.id).filter( Project.created_at < self.created_at).order_by( db.desc('created_at')).first() def getprev(self): return Project.query.filter(Project.event == self.event).filter( Project.id != self.id).filter(Project.created_at > self.created_at ).order_by('created_at').first() def url_for(self, action='view', _external=False): if action == 'view': return url_for('project_view', profile=self.event.profile.name, event=self.event.name, project=self.url_name, _external=_external) elif action == 'edit': return url_for('project_edit', profile=self.event.profile.name, event=self.event.name, project=self.url_name, _external=_external) elif action == 'delete': return url_for('project_delete', profile=self.event.profile.name, event=self.event.name, project=self.url_name, _external=_external) elif action == 'voteup': return url_for('project_voteup', profile=self.event.profile.name, event=self.event.name, project=self.url_name, _external=_external) elif action == 'votedown': return url_for('project_votedown', profile=self.event.profile.name, event=self.event.name, project=self.url_name, _external=_external) elif action == 'cancelvote': return url_for('project_cancelvote', profile=self.event.profile.name, event=self.event.name, project=self.url_name, _external=_external) elif action == 'prev': return url_for('project_view', profile=self.event.profile.name, event=self.event.name, project=self.getprev().url_name, _external=_external) elif action == 'next': return url_for('project_view', profile=self.event.profile.name, event=self.event.name, project=self.getnext().url_name, _external=_external) elif action == 'join': return url_for('project_join', profile=self.event.profile.name, event=self.event.name, project=self.url_name, _external=_external)