Exemplo n.º 1
0
class Sponsor(db.Model):

    """Sponsor."""

    __tablename__ = 'sponsors'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False)
    description = db.Column(db.Text)
    url = db.Column(db.String(255))
    logo = db.Column(db.String(255))
    contact_name = db.Column(db.String(255))
    contact_email = db.Column(db.String(255))
    accepted = db.Column(db.Boolean)
    payment_received = db.Column(db.Boolean)
    level_id = db.Column(
        db.Integer, db.ForeignKey('sponsor_levels.id'), nullable=False,
    )
    level = db.relationship(
        'Level', backref=db.backref('sponsors', lazy='dynamic'),
    )

    applicant_id = db.Column(
        db.Integer, db.ForeignKey('users.id'), nullable=False,
    )
    applicant = db.relationship('User')

    def __str__(self):
        """Return a printable representation."""
        return self.name

    @cached_property
    def slug(self):
        """Return the slug for the sponsor."""
        return slugify(self.name)
Exemplo n.º 2
0
class Announcement(db.Model):
    """News announcement."""

    __tablename__ = 'announcements'
    query_class = EventQuery

    id = db.Column(db.Integer, primary_key=True)
    slug = db.Column(db.String(255), nullable=False)
    title = db.Column(db.String(255), nullable=False)
    content = db.Column(db.Text, nullable=False)

    active = db.Column(db.Boolean, nullable=False)
    published = db.Column(ArrowType)

    event_id = db.Column(db.Integer,
                         db.ForeignKey('events.id'),
                         nullable=False)
    event = db.relationship('Event',
                            backref=db.backref('announcements',
                                               lazy='dynamic'))

    def __str__(self):
        """Return a printable representation."""
        return self.title

    @observes('title')
    def _create_slug(self, title):
        """Create a slug from the title of the announcement."""
        self.slug = slugify(self.title)
Exemplo n.º 3
0
class AboutPage(db.Model):
    """About page."""

    __tablename__ = 'about_pages'
    query_class = EventQuery

    id = db.Column(db.Integer, primary_key=True)
    # TODO: validate that the navbar_section / slug combination do not conflict
    # with an existing generated blueprint view route

    # The navbar_path dictates the location of this menu item in the
    # navbar hierarchy.
    navbar_path = db.Column(postgresql.ARRAY(db.String), nullable=False)
    # A slug may be empty. If it is, the item will be placed at the
    # root of the navbar hierarchy.
    slug = db.Column(db.String(255), default='', nullable=False)
    title = db.Column(db.String(255), nullable=False)
    content = db.Column(db.Text, nullable=False)
    active = db.Column(db.Boolean, nullable=False)

    event_id = db.Column(
        db.Integer, db.ForeignKey('events.id'), nullable=False,
    )
    event = db.relationship(
        'Event', backref=db.backref('about_pages', lazy='dynamic'),
    )

    __table_args__ = (
        db.UniqueConstraint(
            'navbar_path', 'slug', 'event_id',
            name='ix_about_pages_navbar_path_slug_event_id',
        ),
    )

    def __str__(self):
        """Return a printable representation."""
        return self.title

    @observes('title')
    def _create_slug(self, title):
        """Create the slug for the page."""
        if not self.slug:
            self.slug = slugify(self.title)

    @property
    def rst_document(self):
        """Return the full reST document, including the title.

        The page's title was be used as the document heading, causing
        any headings defined in the page's content to be used as
        subheadings. To cut down on potential collisions, ``#`` symbols
        will be placed on the lines before and after the title.
        """
        lines = ('{divider}', '{page.title}', '{divider}', '{page.content}')
        return '\n'.join(lines).format(
            divider='#' * len(self.title), page=self)
Exemplo n.º 4
0
class Category(db.Model):
    """Talk category."""

    __tablename__ = 'categories'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False)
    slug = db.Column(db.String(75), unique=True, nullable=False)

    def __str__(self):
        """Return a printable representation."""
        return self.name
Exemplo n.º 5
0
class Level(db.Model):
    """Sponsorship level."""

    __tablename__ = 'sponsor_levels'
    query_class = EventQuery

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False)
    description = db.Column(db.Text)
    order = db.Column(db.Integer, default=0)
    cost = db.Column(db.String, default=0)  # This isn't always money.
    limit = db.Column(db.Integer, default=0)

    event_id = db.Column(
        db.Integer, db.ForeignKey('events.id'), nullable=False)
    event = db.relationship(
        'Event', backref=db.backref('sponsor_levels', lazy='dynamic'))

    def __str__(self):
        """Return a printable representation."""
        return self.name

    @cached_property
    def accepted_sponsors(self):
        """Return the accepted sponsors for the level."""
        return self.sponsors.filter(Sponsor.accepted == True)  # NOQA

    @cached_property
    def is_sold_out(self):
        """Return whether the level is sold out."""
        return 0 < self.limit <= self.accepted_sponsors.count()
Exemplo n.º 6
0
class Role(db.Model, RoleMixin):
    """User role."""

    __tablename__ = 'roles'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), unique=True)
    description = db.Column(db.String(255))

    def __str__(self):
        """Return a printable representation."""
        return self.name

    def __eq__(self, other):
        return self.name == other or self.name == getattr(other, 'name', None)

    def __hash__(self):
        return id(self)

    def __ne__(self, other):
        return self.name != other and self.name != getattr(other, 'name', None)
Exemplo n.º 7
0
class Room(db.Model):
    """Room of talks."""

    __tablename__ = 'rooms'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False)
    order = db.Column(db.Integer, nullable=False)

    def __str__(self):
        """Return a printable representation."""
        return self.name
Exemplo n.º 8
0
class Duration(db.Model):
    """Talk duration."""

    __tablename__ = 'durations'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False)
    duration = db.Column(db.Integer, nullable=False)
    inactive = db.Column(db.Boolean, default=False)

    __mapper_args__ = {
        'order_by': (inactive, duration),
    }

    def __str__(self):
        """Return a printable representation."""
        return self.name
Exemplo n.º 9
0
class CallToAction(db.Model):
    """Call to action."""

    __tablename__ = 'calls_to_action'
    query_class = EventQuery

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255), nullable=False)
    url = db.Column(URLType)

    active = db.Column(db.Boolean, nullable=False)
    begins = db.Column(ArrowType)
    ends = db.Column(ArrowType)

    event_id = db.Column(
        db.Integer, db.ForeignKey('events.id'), nullable=False)
    event = db.relationship(
        'Event', backref=db.backref('calls_to_action', lazy='dynamic'))

    def __str__(self):
        """Return a printable representation."""
        return self.title
Exemplo n.º 10
0
class Event(db.Model):
    """Event."""

    __tablename__ = 'events'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), unique=True, nullable=False)
    slug = db.Column(db.String(75), unique=True, nullable=True)

    # Event dates
    begins = db.Column(db.Date)
    ends = db.Column(db.Date)

    # Fields to control when the event is active
    active = db.Column(db.Boolean, nullable=False)
    activity_begins = db.Column(ArrowType)
    activity_ends = db.Column(ArrowType)

    # Proposal window
    proposals_begin = db.Column(ArrowType)
    proposals_end = db.Column(ArrowType)

    # When to publish the talks
    talk_list_begins = db.Column(ArrowType)
    # When to publish the schedule
    talk_schedule_begins = db.Column(ArrowType)

    # Registration information
    registration_closed = db.Column(
        db.Boolean,
        server_default='false',
        nullable=False,
    )
    registration_url = db.Column(db.String(255))
    registration_begins = db.Column(ArrowType)
    registration_ends = db.Column(ArrowType)

    def __str__(self):
        """Return a printable representation."""
        return self.name

    @cached_property
    def accepted_talks(self):
        """Return the accepted :class:`~pygotham.models.Talk` list."""
        return self.talks.filter(Talk.status == 'accepted').order_by(Talk.name)

    @observes('name')
    def _create_slug(self, title):
        """Create a slug from the name of the event."""
        if not self.slug:
            self.slug = slugify(self.name)

    @property
    def dates(self):
        """Return the date(s) for the event."""
        dates = ['{:%B %d}'.format(self.begins)]
        if self.begins != self.ends:
            if self.begins.month == self.ends.month:
                format = '{:%d}'
            else:
                format = '{:%B %d}'
            dates.append(format.format(self.ends))
        return ' - '.join(dates)

    @property
    def is_call_for_proposals_active(self):
        """Return whether the call for proposals for an event is active.

        The CFP is active when the current :class:`~datetime.datetime`
        is greater than or equal to
        :attribute:`~pygotham.events.models.Event.proposals_begin` and
        less than
        :attribute:`~pygotham.events.models.Event.proposals_end`.
        """
        now = arrow.utcnow().to(current_app.config['TIME_ZONE']).naive
        if not self.proposals_begin or now < self.proposals_begin.naive:
            return False
        if self.proposals_end and self.proposals_end.naive < now:
            return False

        return True

    @property
    def is_call_for_proposals_expired(self):
        """Return whether the call for proposals has expired."""
        now = arrow.utcnow().to(current_app.config['TIME_ZONE']).naive
        return self.proposals_end and self.proposals_end.naive < now

    @property
    def is_registration_active(self):
        """Return whether registration for an event is active.

        There are several pieces to the logic of whether or not an
        event's registration is active:

        - :attribute:`~pygotham.events.models.Event.registration_closed`
          must be ``False``.
        - :attribute:`~pygotham.events.models.Event.registration_url`
          must be set.
        - :attribute:`~pygotham.events.models.Event.registration_begins`
          must be earlier than the current date and time.
        - :attribute:`~pygotham.events.models.Event.registration_ends`
          must be ``None`` or later than the current date and time.

        """
        if self.registration_closed:
            return False

        if not self.registration_url:
            return False

        now = arrow.utcnow().to(current_app.config['TIME_ZONE']).naive
        begins = self.registration_begins
        if not begins or now < begins.naive:
            return False
        ends = self.registration_ends
        if ends and ends.naive < now:
            return False

        return True

    @property
    def schedule_is_published(self):
        """Return whether the schedule for an event is published."""
        now = arrow.utcnow().to(current_app.config['TIME_ZONE']).naive
        talk_schedule_begins = self.talk_schedule_begins
        if not talk_schedule_begins or talk_schedule_begins.naive > now:
            return False
        return True

    @property
    def talks_are_published(self):
        """Return whether the talk list for an event is published."""
        now = arrow.utcnow().to(current_app.config['TIME_ZONE']).naive
        if not self.talk_list_begins or self.talk_list_begins.naive > now:
            return False
        return True
Exemplo n.º 11
0
class User(db.Model, UserMixin):
    """User."""

    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), info={'label': 'Name'})
    email = db.Column(db.String(255), unique=True, nullable=False)
    password = db.Column(db.String(130))
    active = db.Column(db.Boolean)
    confirmed_at = db.Column(db.DateTime)
    last_login_at = db.Column(db.DateTime)
    current_login_at = db.Column(db.DateTime)
    last_login_ip = db.Column(db.String(100))
    current_login_ip = db.Column(db.String(100))
    login_count = db.Column(db.Integer)
    registered_at = db.Column(db.DateTime)

    bio = db.Column(db.Text)

    twitter_handle = db.Column(db.String(15))

    roles = db.relationship(
        'Role',
        secondary=roles_users,
        backref=db.backref('users', lazy='dynamic'),
    )

    def __str__(self):
        """Return a printable representation."""
        return self.name or self.email

    def __eq__(self, other):
        return self.id == getattr(other, 'id', None)

    def __hash__(self):
        return id(self)

    def __ne__(self, other):
        return self.id != getattr(other, 'id', None)

    @cached_property
    def accepted_talks(self):
        """Return the user's accepted talks."""
        return Talk.query.current.filter(Talk.status == 'accepted',
                                         Talk.user == self).order_by(Talk.name)

    @cached_property
    def has_accepted_talks(self):
        """Return whether the user has accepted talks."""
        return self.accepted_talks.count() > 0

    @cached_property
    def is_volunteer(self):
        """Return whether the user has signed up to volunteer."""
        volunteers = Volunteer.query.filter(
            Volunteer.event_id == g.current_event.id,
            Volunteer.user_id == self.id,
        )

        return db.session.query(volunteers.exists()).scalar()
Exemplo n.º 12
0
class Talk(db.Model):
    """Talk."""

    __tablename__ = 'talks'
    query_class = EventQuery

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False)
    description = db.Column(db.Text, nullable=False)
    status = db.Column(
        db.Enum('draft', 'submitted', 'accepted', 'rejected', name='status'),
        default='draft',
        nullable=False,
    )
    level = db.Column(
        db.Enum('novice', 'intermediate', 'advanced', name='level'),
        nullable=False,
    )
    type = db.Column(
        db.Enum('talk', 'tutorial', name='type'),
        nullable=False,
    )
    duration_id = db.Column(db.ForeignKey('durations.id'), nullable=False)
    duration = db.relationship('Duration')
    recording_release = db.Column(db.Boolean, nullable=True)

    abstract = db.Column(db.Text)
    additional_requirements = db.Column(db.Text)
    objectives = db.Column(db.Text)
    outline = db.Column(db.Text)
    target_audience = db.Column(db.Text)

    event_id = db.Column(
        db.Integer,
        db.ForeignKey('events.id'),
        nullable=False,
    )
    event = db.relationship(
        'Event',
        backref=db.backref('talks', lazy='dynamic'),
    )

    category_id = db.Column(db.Integer,
                            db.ForeignKey('categories.id'),
                            nullable=True)
    category = db.relationship(
        'Category',
        backref=db.backref('talks', lazy='dynamic'),
    )

    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    user = db.relationship('User', backref=db.backref('talks', lazy='dynamic'))

    video_url = db.Column(db.String(255))

    def __str__(self):
        """Return a printable representation."""
        return self.name

    @property
    def is_accepted(self):
        """Return whether the instance is accepted."""
        return self.status == 'accepted'

    @property
    def slug(self):
        """Return a slug for the instance."""
        return slugify(self.name, max_length=25)