Пример #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)
    twitter_handle = db.Column(db.String(15))
    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)
Пример #2
0
class Presentation(db.Model):
    """Presentation of a talk."""

    __tablename__ = 'presentations'

    id = db.Column(db.Integer, primary_key=True)

    slot_id = db.Column(db.Integer, db.ForeignKey('slots.id'), nullable=False)
    slot = db.relationship('Slot',
                           backref=db.backref('presentation', uselist=False))

    talk_id = db.Column(db.Integer, db.ForeignKey('talks.id'), nullable=False)
    talk = db.relationship('Talk',
                           backref=db.backref('presentation', uselist=False))

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

    def is_in_all_rooms(self):
        """Return whether the instance is in all rooms."""
        return self.slot.number_of_rooms == 4

    @cached_property
    def number_of_rooms(self):
        """Return the number of rooms for the instance."""
        return len(self.slot.rooms)
Пример #3
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()
Пример #4
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)
Пример #5
0
class Volunteer(db.Model):
    """Volunteer."""

    __tablename__ = 'volunteers'
    query_class = EventQuery

    id = db.Column(db.Integer, primary_key=True)

    event_id = db.Column(db.ForeignKey('events.id'))
    event = db.relationship('Event', backref='volunteers')

    user_id = db.Column(db.ForeignKey('users.id'))
    user = db.relationship('User', uselist=False)

    def __str__(self):
        """Return a printable representation."""
        return self.user.name
Пример #6
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)
Пример #7
0
class Slot(db.Model):
    """Time slot."""

    __tablename__ = 'slots'

    id = db.Column(db.Integer, primary_key=True)
    kind = db.Column(
        db.Enum('break',
                'meal',
                'keynote',
                'talk',
                'tutorial',
                name='slotkind'),
        nullable=False,
    )
    content_override = db.Column(db.Text)
    start = db.Column(db.Time, nullable=False)
    end = db.Column(db.Time, nullable=False)

    day_id = db.Column(db.Integer, db.ForeignKey('days.id'), nullable=False)
    day = db.relationship('Day', backref=db.backref('slots', lazy='dynamic'))

    rooms = db.relationship(
        'Room',
        secondary=rooms_slots,
        backref=db.backref('slots', lazy='dynamic'),
        order_by=Room.order,
    )

    def __str__(self):
        """Return a printable representation."""
        start = self.start.strftime('%I:%M %p')
        end = self.end.strftime('%I:%M %p')
        rooms = ', '.join(map(str, self.rooms))
        return '{} - {} on {}, {}'.format(start, end, self.day, rooms)

    @cached_property
    def duration(self):
        """Return the duration as a :class:`~datetime.timedelta`."""
        return self.end - self.start
Пример #8
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
Пример #9
0
import string

from cached_property import cached_property
from flask import g
from flask_security import RoleMixin, UserMixin, recoverable
from sqlalchemy import event

from pygotham.core import db
from pygotham.events.models import Volunteer
from pygotham.talks.models import Talk

__all__ = ('Role', 'User')

roles_users = db.Table(
    'roles_users',
    db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
    db.Column('role_id', db.Integer, db.ForeignKey('roles.id')),
)


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."""
Пример #10
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)
Пример #11
0
class Day(db.Model):
    """Day of talks."""

    __tablename__ = 'days'

    id = db.Column(db.Integer, primary_key=True)
    date = db.Column(db.Date)
    event_id = db.Column(db.Integer,
                         db.ForeignKey('events.id'),
                         nullable=False)
    event = db.relationship('Event',
                            backref=db.backref('days', lazy='dynamic'))

    def __str__(self):
        """Return a printable representation."""
        return self.date.strftime('%B %d, %Y')

    @cached_property
    def rooms(self):
        """Return the rooms for the day."""
        return Room.query.join(rooms_slots,
                               Slot).filter(Slot.day == self).order_by(
                                   Room.order).all()

    def __iter__(self):
        """Iterate over the schedule for the day."""
        if not self.rooms:
            raise StopIteration

        def rowspan(start, end):
            """Find the rowspan for an entry in the schedule table.

            This uses a binary search for the given end time from a
            sorted list of start times in order to find the index of the
            first start time that occurs after the given end time. This
            method is used to prevent issues that can occur with
            overlapping start and end times being included in the same
            list.
            """
            return bisect_left(times, end) - times.index(start)

        times = sorted({slot.start for slot in self.slots})
        # While we typically only care about the start times here, the
        # list is iterated over two items at a time. Without adding a
        # final element, the last time slot would be omitted. Any value
        # could be used here as bisect_left only assumes the list is
        # sorted, but using a meaningful value feels better.
        times.append(self.slots[-1].end)

        slots = db.session.query(
            Slot.id,
            Slot.content_override,
            Slot.kind,
            Slot.start,
            Slot.end,
            func.count(rooms_slots.c.slot_id).label('room_count'),
            func.min(Room.order).label('order'),
        ).join(rooms_slots, Room).filter(Slot.day == self).order_by(
            func.count(rooms_slots.c.slot_id),
            func.min(Room.order)).group_by(Slot.id, Slot.content_override,
                                           Slot.kind, Slot.start,
                                           Slot.end).all()

        for time, next_time in pairwise(times):
            row = {'time': time, 'slots': []}
            for slot in slots:
                if slot.start == time:
                    slot.rowspan = rowspan(slot.start, slot.end)
                    slot.colspan = slot.room_count
                    if not slot.content_override:
                        slot.presentation = Presentation.query.filter(
                            Presentation.slot_id == slot.id).first()
                    row['slots'].append(slot)
            if row['slots'] or next_time is None:
                yield row
Пример #12
0

def pairwise(iterable):
    """Return values from ``iterable`` two at a time.

    Recipe from
    https://docs.python.org/3/library/itertools.html#itertools-recipes.
    """
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)


rooms_slots = db.Table(
    'rooms_slots',
    db.Column('slot_id', db.Integer, db.ForeignKey('slots.id')),
    db.Column('room_id', db.Integer, db.ForeignKey('rooms.id')),
)


class Day(db.Model):
    """Day of talks."""

    __tablename__ = 'days'

    id = db.Column(db.Integer, primary_key=True)
    date = db.Column(db.Date)
    event_id = db.Column(db.Integer,
                         db.ForeignKey('events.id'),
                         nullable=False)
    event = db.relationship('Event',