Skip to content

Commit

Permalink
Incorporates attendee_tournaments data model into uber plugin for bac…
Browse files Browse the repository at this point in the history
…kwards compatibility with legacy servers
  • Loading branch information
RobRuana committed Feb 5, 2018
1 parent 30f1781 commit 9b0fedf
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 9 deletions.
53 changes: 53 additions & 0 deletions alembic/versions/73b22ccbe472_initial_migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""Initial migration
Revision ID: 73b22ccbe472
Revises: 1ed43776064f
Create Date: 2017-04-24 09:08:30.923731
"""


# revision identifiers, used by Alembic.
revision = '73b22ccbe472'
down_revision = '1ed43776064f'
branch_labels = ('attendee_tournaments',)
depends_on = None

from alembic import op
import sqlalchemy as sa
import sideboard.lib.sa


try:
is_sqlite = op.get_context().dialect.name == 'sqlite'
except:
is_sqlite = False

if is_sqlite:
op.get_context().connection.execute('PRAGMA foreign_keys=ON;')
utcnow_server_default = "(datetime('now', 'utc'))"
else:
utcnow_server_default = "timezone('utc', current_timestamp)"


def upgrade():
op.create_table('attendee_tournament',
sa.Column('id', sideboard.lib.sa.UUID(), nullable=False),
sa.Column('first_name', sa.Unicode(), server_default='', nullable=False),
sa.Column('last_name', sa.Unicode(), server_default='', nullable=False),
sa.Column('email', sa.Unicode(), server_default='', nullable=False),
sa.Column('cellphone', sa.Unicode(), server_default='', nullable=False),
sa.Column('game', sa.Unicode(), server_default='', nullable=False),
sa.Column('availability', sa.Unicode(), server_default='', nullable=False),
sa.Column('format', sa.Unicode(), server_default='', nullable=False),
sa.Column('experience', sa.Unicode(), server_default='', nullable=False),
sa.Column('needs', sa.Unicode(), server_default='', nullable=False),
sa.Column('why', sa.Unicode(), server_default='', nullable=False),
sa.Column('volunteering', sa.Boolean(), server_default='False', nullable=False),
sa.Column('status', sa.Integer(), server_default='239694250', nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_attendee_tournament'))
)


def downgrade():
op.drop_table('attendee_tournament')
40 changes: 31 additions & 9 deletions uber/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -843,8 +843,19 @@ def _is_intstr(s):
c.EVENT_QR_ID = c.EVENT_QR_ID or c.EVENT_NAME_AND_YEAR.replace(' ', '_').lower()


try:
_items = sorted([int(step), url] for step, url in _config['volunteer_checklist'].items() if url)
except ValueError:
log.error('[volunteer_checklist] config options must have integer option names')
raise
else:
c.VOLUNTEER_CHECKLIST = [url for step, url in _items]

stripe.api_key = c.STRIPE_SECRET_KEY


# =============================
# Hotel
# hotel
# =============================

c.NIGHT_NAMES = [name.lower() for name in c.NIGHT_VARS]
Expand All @@ -870,15 +881,26 @@ def _is_intstr(s):
setattr(c, _attr + '_NAMES', [c.NIGHTS[night] for night in getattr(c, _attr + 'S')])


try:
_items = sorted([int(step), url] for step, url in _config['volunteer_checklist'].items() if url)
except ValueError:
log.error('[volunteer_checklist] config options must have integer option names')
raise
else:
c.VOLUNTEER_CHECKLIST = [url for step, url in _items]
# =============================
# attendee_tournaments
#
# NO LONGER USED.
#
# The attendee_tournaments module is no longer used, but has been
# included for backward compatibility with legacy servers.
# =============================

c.TOURNAMENT_AVAILABILITY_OPTS = []
_val = 0
for _day in range((c.ESCHATON - c.EPOCH).days):
for _when in ['Morning (8am-12pm)', 'Afternoon (12pm-6pm)', 'Evening (6pm-10pm)', 'Night (10pm-2am)']:
c.TOURNAMENT_AVAILABILITY_OPTS.append([
_val,
_when + ' of ' + (c.EPOCH + timedelta(days=_day)).strftime('%A %B %d')
])
_val += 1
c.TOURNAMENT_AVAILABILITY_OPTS.append([_val, 'Morning (8am-12pm) of ' + c.ESCHATON.strftime('%A %B %d')])

stripe.api_key = c.STRIPE_SECRET_KEY

# plugins can use this to append paths which will be included as <script> tags, e.g. if a plugin
# appends '../static/foo.js' to this list, that adds <script src="../static/foo.js"></script> to
Expand Down
21 changes: 21 additions & 0 deletions uber/configspec.ini
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,16 @@ barcode_salt = integer(default=0)
barcode_event_id = integer(default=0)


# NO LONGER USED.
#
# The attendee_tournaments module is no longer used, but has been
# included for backward compatibility with legacy servers.
#
# Side note: I'm on the fence about using "art" as an abbreviation for Attendee-Run Tournament.
art_email = string(default="MAGFest Console Department <consoles@magfest.org>")
art_email_signature = string(default="- The MAGFest Console Department")


[dates]
# Dates controlling when different site features and emails are turned on and off. Features
# can be turned off by setting these values to the empty string. For example, you can turn
Expand Down Expand Up @@ -846,6 +856,17 @@ teardown = string(default="Teardown")
other = string(default="Other (Please Specify)")
__many__ = string


# NO LONGER USED.
#
# The attendee_tournaments module is no longer used, but has been
# included for backward compatibility with legacy servers.
[[tournament_status]]
new = string(default="New")
accepted = string(default="Accepted")
declined = string(default="Declined")


# These sections need to exist but can stay empty for events which are not using
# the features they represent.
[[sale]]
Expand Down
1 change: 1 addition & 0 deletions uber/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ def minutestr(dt):
from uber.models.types import * # noqa: F401,E402,F403
from uber.models.api import * # noqa: F401,E402,F403
from uber.models.hotel import * # noqa: F401,E402,F403
from uber.models.attendee_tournaments import * # noqa: F401,E402,F403

# Explicitly import models used by the Session class to quiet flake8
from uber.models.admin import AdminAccount, WatchList # noqa: E402
Expand Down
8 changes: 8 additions & 0 deletions uber/models/attendee.py
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,14 @@ def amount_unpaid(self):
personal_cost = self.total_cost
return max(0, personal_cost - self.amount_paid)

@property
def paid_for_badge(self):
return bool(
self.paid == c.HAS_PAID
or self.group_id
and self.group
and self.group.amount_paid)

@property
def is_unpaid(self):
return self.paid == c.NOT_PAID
Expand Down
77 changes: 77 additions & 0 deletions uber/models/attendee_tournaments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""
NO LONGER USED.
The attendee_tournaments module is no longer used, but has been
included for backward compatibility with legacy servers.
"""

import re

from sideboard.lib.sa import CoerceUTF8 as UnicodeText
from sqlalchemy import func
from sqlalchemy.types import Boolean

from uber.config import c
from uber.decorators import validation
from uber.models import MagModel, Attendee
from uber.models.types import Choice, DefaultColumn as Column, MultiChoice


__all__ = ['AttendeeTournament']


class AttendeeTournament(MagModel):
first_name = Column(UnicodeText)
last_name = Column(UnicodeText)
email = Column(UnicodeText)
cellphone = Column(UnicodeText)
game = Column(UnicodeText)
availability = Column(MultiChoice(c.TOURNAMENT_AVAILABILITY_OPTS))
format = Column(UnicodeText)
experience = Column(UnicodeText)
needs = Column(UnicodeText)
why = Column(UnicodeText)
volunteering = Column(Boolean, default=False)

status = Column(
Choice(c.TOURNAMENT_STATUS_OPTS), default=c.NEW, admin_only=True)

email_model_name = 'app'

@property
def full_name(self):
return self.first_name + ' ' + self.last_name

@property
def matching_attendee(self):
return self.session.query(Attendee).filter(
Attendee.first_name == self.first_name.title(),
Attendee.last_name == self.last_name.title(),
func.lower(Attendee.email) == self.email.lower()
).first()


AttendeeTournament.required = [
('first_name', 'First Name'),
('last_name', 'Last Name'),
('email', 'Email Address'),
('game', 'Game Title'),
('availability', 'Your Availability'),
('format', 'Tournament Format'),
('experience', 'Past Experience'),
('needs', 'Your Needs'),
('why', '"Why?"'),
]


@validation.AttendeeTournament
def email(app):
if not re.match(c.EMAIL_RE, app.email):
return 'You did not enter a valid email address'


@validation.AttendeeTournament
def cellphone(app):
from uber.model_checks import _invalid_phone_number
if app.cellphone and _invalid_phone_number(app.cellphone):
return 'You did not enter a valid cellphone number'

0 comments on commit 9b0fedf

Please sign in to comment.