Skip to content

Commit 43b6bcb

Browse files
committed
Sync with backend updates
Updates the magprime plugin with changes for the new file service and other major updates
1 parent d3a0388 commit 43b6bcb

28 files changed

Lines changed: 175 additions & 185 deletions

alembic/versions/3b1f31ec9f24_add_external_sync_created_and_last_.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from alembic import op
1717
import sqlalchemy as sa
1818
from sqlalchemy.dialects import postgresql
19-
import residue
2019

2120

2221
try:
@@ -53,12 +52,12 @@ def sqlite_column_reflect_listener(inspector, table, column_info):
5352

5453

5554
def upgrade():
56-
op.add_column('prev_season_supporter', sa.Column('created', residue.UTCDateTime(), server_default=sa.text("timezone('utc', current_timestamp)"), nullable=False))
57-
op.add_column('prev_season_supporter', sa.Column('last_updated', residue.UTCDateTime(), server_default=sa.text("timezone('utc', current_timestamp)"), nullable=False))
55+
op.add_column('prev_season_supporter', sa.Column('created', sa.DateTime(timezone=True), server_default=sa.text("timezone('utc', current_timestamp)"), nullable=False))
56+
op.add_column('prev_season_supporter', sa.Column('last_updated', sa.DateTime(timezone=True), server_default=sa.text("timezone('utc', current_timestamp)"), nullable=False))
5857
op.add_column('prev_season_supporter', sa.Column('external_id', postgresql.JSONB(astext_type=sa.Text()), server_default='{}', nullable=False))
5958
op.add_column('prev_season_supporter', sa.Column('last_synced', postgresql.JSONB(astext_type=sa.Text()), server_default='{}', nullable=False))
60-
op.add_column('season_pass_ticket', sa.Column('created', residue.UTCDateTime(), server_default=sa.text("timezone('utc', current_timestamp)"), nullable=False))
61-
op.add_column('season_pass_ticket', sa.Column('last_updated', residue.UTCDateTime(), server_default=sa.text("timezone('utc', current_timestamp)"), nullable=False))
59+
op.add_column('season_pass_ticket', sa.Column('created', sa.DateTime(timezone=True), server_default=sa.text("timezone('utc', current_timestamp)"), nullable=False))
60+
op.add_column('season_pass_ticket', sa.Column('last_updated', sa.DateTime(timezone=True), server_default=sa.text("timezone('utc', current_timestamp)"), nullable=False))
6261
op.add_column('season_pass_ticket', sa.Column('external_id', postgresql.JSONB(astext_type=sa.Text()), server_default='{}', nullable=False))
6362
op.add_column('season_pass_ticket', sa.Column('last_synced', postgresql.JSONB(astext_type=sa.Text()), server_default='{}', nullable=False))
6463

alembic/versions/e68ef1dc43fc_initial_migration.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
from alembic import op
1717
import sqlalchemy as sa
18-
import residue
1918

2019

2120
try:
@@ -32,15 +31,15 @@
3231

3332
def upgrade():
3433
op.create_table('prev_season_supporter',
35-
sa.Column('id', residue.UUID(), nullable=False),
34+
sa.Column('id', sa.Uuid(as_uuid=False), nullable=False),
3635
sa.Column('first_name', sa.Unicode(), server_default='', nullable=False),
3736
sa.Column('last_name', sa.Unicode(), server_default='', nullable=False),
3837
sa.Column('email', sa.Unicode(), server_default='', nullable=False),
3938
sa.PrimaryKeyConstraint('id', name=op.f('pk_prev_season_supporter'))
4039
)
4140
op.create_table('season_pass_ticket',
42-
sa.Column('id', residue.UUID(), nullable=False),
43-
sa.Column('fk_id', residue.UUID(), nullable=False),
41+
sa.Column('id', sa.Uuid(as_uuid=False), nullable=False),
42+
sa.Column('fk_id', sa.Uuid(as_uuid=False), nullable=False),
4443
sa.Column('slug', sa.Unicode(), server_default='', nullable=False),
4544
sa.PrimaryKeyConstraint('id', name=op.f('pk_season_pass_ticket'))
4645
)

magprime/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
@Session.model_mixin
2626
class SessionMixin:
2727
def season_pass(self, id):
28-
pss = self.query(PrevSeasonSupporter).filter_by(id=id).all()
28+
pss = self.get(PrevSeasonSupporter, id).all()
2929
if pss:
3030
return pss[0]
3131
else:

magprime/automated_emails.py

Lines changed: 11 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def __init__(self, event):
5757
subject='Claim your {} badges with your MAGFest Season Pass'.format(event.name),
5858
ident='magprime_season_supporter_{}_invite'.format(event.slug),
5959
template='season_supporter_event_invite.txt',
60-
when=before(event.deadline),
60+
when=[before(event.deadline)],
6161
extra_data={'event': event})
6262

6363
for _event in SeasonEvent.instances.values():
@@ -68,15 +68,15 @@ def __init__(self, event):
6868
Attendee, 'MAGFest schedule, map, and other FAQs', 'precon_faqs.html',
6969
filter=lambda a: not a.cannot_check_in_reason,
7070
ident='magprime_precon_faqs',
71-
when=days_before(7, c.EPOCH),
71+
when=[days_before(7, c.EPOCH)],
7272
sender='MAGFest <contact@magfest.org>')
7373

7474
AutomatedEmailFixture(
7575
Attendee, 'Thank you for your Super MAGFest Superstars Donation!',
7676
'superstar_intro.html',
7777
filter=lambda a: a.extra_donation >= c.SUPERSTAR_MINIMUM and a.active_receipt and not a.amount_unpaid,
7878
ident='superstar_intro',
79-
when=before(c.SUPERSTAR_DEADLINE),
79+
when=[before(c.SUPERSTAR_DEADLINE)],
8080
sender='MAGFest Superstar Program <superstars@magfest.org>'
8181
)
8282

@@ -96,14 +96,14 @@ def __init__(self, event):
9696
Attendee, 'Department Heads', 'food/department_heads.txt',
9797
lambda a: a.is_dept_head,
9898
ident='magprime_department_water_and_food_info',
99-
# when=days_before(7, c.UBER_TAKEDOWN),
99+
#when=[days_before(7, c.UBER_TAKEDOWN)],
100100
sender='MAGFest Staff Suite <chefs@magfest.org>')
101101

102102
AutomatedEmailFixture(
103103
Attendee, 'MAGFest Volunteer Food', 'volunteer_food_info.txt',
104104
lambda a: a.staffing,
105105
ident='magprime_volunteer_food_info',
106-
when=days_before(7, c.UBER_TAKEDOWN),
106+
when=[days_before(7, c.UBER_TAKEDOWN)],
107107
sender='MAGFest Staff Suite <chefs@magfest.org>')
108108

109109
AutomatedEmailFixture(
@@ -119,67 +119,14 @@ def __init__(self, event):
119119
needs_approval=True,
120120
sender='MAGFest LAN <lan@magfest.org>')
121121

122-
MarketplaceEmailFixture(
123-
'Your {} {} has been waitlisted'.format(c.EVENT_NAME, c.DEALER_APP_TERM.capitalize()),
124-
'dealers/waitlisted.txt',
125-
lambda g: g.status == c.WAITLISTED,
126-
# query=Group.status == c.WAITLISTED,
127-
needs_approval=True,
128-
ident='dealer_reg_waitlisted')
129-
130-
MarketplaceEmailFixture(
131-
'Your {} {} has been declined'.format(c.EVENT_NAME, c.DEALER_APP_TERM.capitalize()),
132-
'dealers/declined.txt',
133-
lambda g: g.status == c.DECLINED,
134-
# query=Group.status == c.DECLINED,
135-
needs_approval=True,
136-
ident='dealer_reg_declined')
137-
138-
"""
139-
AutomatedEmailFixture(
140-
Attendee, 'MAGFest Tech Ops volunteering', 'techops.txt',
141-
lambda a: a.staffing and a.assigned_to(c.TECH_OPS),
142-
ident='magprime_techops_volunteer',
143-
sender='MAGFest TechOps <techops@magfest.org>')
144-
145-
AutomatedEmailFixture(
146-
Attendee, 'MAGFest Chipspace volunteering', 'chipspace.txt',
147-
lambda a: a.staffing and a.assigned_to(c.CHIPSPACE),
148-
ident='magprime_chipspace_volunteer',
149-
sender='MAGFest ChipSpace <chipspace@magfest.org>')
150-
151-
AutomatedEmailFixture(
152-
Attendee, 'MAGFest Chipspace shifts', 'chipspace_trusted.txt',
153-
lambda a: a.staffing and a.has_shifts_in(c.CHIPSPACE) and a.trusted_in(c.CHIPSPACE),
154-
ident='magprime_chipspace_trusted_volunteer',
155-
sender='MAGFest ChipSpace <chipspace@magfest.org>')
156-
157-
AutomatedEmailFixture(
158-
Attendee, 'MAGFest Chipspace', 'chipspace_untrusted.txt',
159-
lambda a: a.staffing and a.has_shifts_in(c.CHIPSPACE) and not a.trusted_in(c.CHIPSPACE),
160-
ident='magprime_chipspace_untrusted_volunteer',
161-
sender='MAGFest ChipSpace <chipspace@magfest.org>')
162-
163-
AutomatedEmailFixture(
164-
Attendee, 'Want to help run MAGFest poker tournaments?', 'poker.txt',
165-
lambda a: a.has_shifts_in(c.TABLETOP),
166-
ident='magprime_tabletop_volunteer_poker_inquiry',
167-
sender='MAGFest Tabletop <tabletop@magfest.org>')
168-
169122
StopsEmailFixture(
170-
'MAGFest Staff Support', 'staff_support.txt',
171-
lambda a: a.assigned_to(c.STAFF_SUPPORT) and not a.trusted_in(c.STAFF_SUPPORT),
172-
ident='magprime_staff_support_volunteer')
173-
"""
174-
175-
StopsEmailFixture(
176-
'{EVENT_NAME} ({EVENT_DATE}) shifts are live tomorrow!',
123+
f'{c.EVENT_NAME} ({c.EPOCH.strftime('%b %Y')}) shifts are live tomorrow!',
177124
'shifts/shifts_created.txt',
178125
lambda a: (
179126
a.badge_type != c.CONTRACTOR_BADGE
180127
and a.takes_shifts
181128
and a.registered_local <= c.SHIFTS_CREATED),
182-
when=before(c.PREREG_TAKEDOWN),
129+
when=[before(c.PREREG_TAKEDOWN)],
183130
ident='volunteer_shift_signup_notification')
184131

185132
StopsEmailFixture(
@@ -192,11 +139,11 @@ def __init__(self, event):
192139
StopsEmailFixture(
193140
'Last Chance to enter your MAGFest staff shirt preferences', 'second_shirt.html',
194141
lambda a: a.gets_staff_shirt and not a.shirt_info_marked,
195-
when=days_before(21, c.SHIRT_DEADLINE),
142+
when=[days_before(21, c.SHIRT_DEADLINE)],
196143
ident='magprime_second_shirt')
197144

198145
AutomatedEmailFixture(
199-
Attendee, 'Last Chance for MAGFest ' + c.EVENT_YEAR + ' bonus swag!', 'attendee_swag_promo.html',
146+
Attendee, f'Last Chance for MAGFest {c.EVENT_YEAR} bonus swag!', 'attendee_swag_promo.html',
200147
lambda a: (
201148
a.can_spam
202149
and (a.paid == c.HAS_PAID or a.paid == c.NEED_NOT_PAY or (a.group and a.group.amount_paid))
@@ -208,9 +155,8 @@ def __init__(self, event):
208155
# who kicked in at the shirt level or above). Should not be sent after the t-shirt
209156
# size deadline.
210157
AutomatedEmailFixture(
211-
Attendee, 'MAGFest ' + c.EVENT_YEAR + ' t-shirt size confirmation', 'confirm_shirt_size.html',
158+
Attendee, f'MAGFest {c.EVENT_YEAR} t-shirt size confirmation', 'confirm_shirt_size.html',
212159
lambda a: days_after(3, a.registered)() and a.gets_any_kind_of_shirt,
213-
when=before(c.SHIRT_DEADLINE),
160+
when=[before(c.SHIRT_DEADLINE)],
214161
sender='MAGFest Merch Team <merch@magfest.org>',
215162
ident='magprime_shirt_size_confirmation')
216-

magprime/forms.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1+
import logging
2+
13
from markupsafe import Markup
24
from wtforms import (BooleanField, DecimalField, EmailField, Form, FormField,
35
HiddenField, SelectField, SelectMultipleField, IntegerField,
46
StringField, TelField, validators, TextAreaField)
57
from wtforms.validators import ValidationError, StopValidation
68
from wtforms.widgets import html_params
7-
from pockets.autolog import log
89

910
from uber.config import c
1011
from uber.forms import AddressForm, NumberInputGroup, MagForm, IntSelect, SwitchInput, HiddenIntField
1112
from uber.custom_tags import popup_link, format_currency, pluralize, table_prices, email_to_link
1213

1314

15+
log = logging.getLogger(__name__)
16+
17+
1418
class NumberInputGroupChoices(NumberInputGroup):
1519
def __init__(self, choices=None, **kwargs):
1620
self.choices = choices

magprime/models.py

Lines changed: 32 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1-
from pockets import classproperty
2-
from pockets.autolog import log
3-
from residue import CoerceUTF8 as UnicodeText, UUID
1+
import logging
2+
3+
from sqlalchemy import String, Uuid
44
from markupsafe import Markup
5+
from typing import ClassVar
56

67
from uber.config import c
78
from uber.custom_tags import readable_join, format_image_size, email_only, email_to_link
89
from uber.decorators import presave_adjustment, render
9-
from uber.models import Boolean, MagModel, Choice, DefaultColumn as Column, Session, GuestImage
10+
from uber.models import Boolean, MagModel, Choice, DefaultColumn as Column, Session
1011
from uber.tasks.email import send_email
12+
from uber.models.types import DefaultField as Field
1113
from uber.utils import add_opt, check, localized_now, remove_opt, GuidebookUtils
1214

1315

16+
log = logging.getLogger(__name__)
17+
18+
1419
@Session.model_mixin
1520
class LotteryApplication:
1621
@property
@@ -33,9 +38,9 @@ def staff_award_status_str(self):
3338

3439
@Session.model_mixin
3540
class PanelApplication:
36-
magscouts_opt_in = Column(Choice(c.PANEL_MAGSCOUTS_OPTS), default=c.NO_CHOICE)
37-
broadcast_title = Column(UnicodeText)
38-
broadcast_subtitle = Column(UnicodeText)
41+
magscouts_opt_in: int = Field(sa_column=Column(Choice(c.PANEL_MAGSCOUTS_OPTS), default=c.NO_CHOICE))
42+
broadcast_title: str = Field(sa_type=String, default='')
43+
broadcast_subtitle: str = Field(sa_type=String, default='')
3944

4045
@presave_adjustment
4146
def no_magscouts_mature_panel(self):
@@ -59,69 +64,23 @@ def email_when_dept_changes(self):
5964
log.error('unable to send panel dept changed email', exc_info=True)
6065

6166

62-
@Session.model_mixin
63-
class GuestGroup:
64-
def handle_images_from_params(self, session, **params):
65-
header_image = params.get('header_image')
66-
thumbnail_image = params.get('thumbnail_image')
67-
bio_image = params.get('bio_pic')
68-
header_pic, thumbnail_pic, bio_pic = None, None, None
69-
message = ''
70-
71-
if bio_image and bio_image.filename:
72-
bio_pic = GuestImage.upload_image(bio_image, guest_id=self.id)
73-
if bio_pic.extension not in c.ALLOWED_BIO_PIC_EXTENSIONS:
74-
message = 'Bio pic must be one of ' + ', '.join(c.ALLOWED_BIO_PIC_EXTENSIONS)
75-
76-
if not message:
77-
if header_image and header_image.filename:
78-
message = GuidebookUtils.check_guidebook_image_filetype(header_image)
79-
if not message:
80-
header_pic = GuestImage.upload_image(header_image, guest_id=self.id,
81-
is_header=True)
82-
if not header_pic.check_image_size():
83-
message = f"Your header image must be {format_image_size(c.GUIDEBOOK_HEADER_SIZE)}."
84-
elif not self.guidebook_header:
85-
message = f"You must upload a {format_image_size(c.GUIDEBOOK_HEADER_SIZE)} header image."
86-
87-
if not message:
88-
if thumbnail_image and thumbnail_image.filename:
89-
message = GuidebookUtils.check_guidebook_image_filetype(thumbnail_image)
90-
if not message:
91-
thumbnail_pic = GuestImage.upload_image(thumbnail_image, guest_id=self.id,
92-
is_thumbnail=True)
93-
if not thumbnail_pic.check_image_size():
94-
message = f"Your thumbnail image must be {format_image_size(c.GUIDEBOOK_THUMBNAIL_SIZE)}."
95-
elif not self.guidebook_thumbnail:
96-
message = f"You must upload a {format_image_size(c.GUIDEBOOK_THUMBNAIL_SIZE)} thumbnail image."
97-
98-
if not message:
99-
if bio_pic:
100-
if self.bio_pic:
101-
session.delete(self.bio_pic)
102-
session.add(bio_pic)
103-
if header_pic:
104-
if self.guidebook_header:
105-
session.delete(self.guidebook_header)
106-
session.add(header_pic)
107-
if thumbnail_pic:
108-
if self.guidebook_thumbnail:
109-
session.delete(self.guidebook_thumbnail)
110-
session.add(thumbnail_pic)
111-
112-
return message
113-
114-
11567
@Session.model_mixin
11668
class Group:
117-
prior_name = Column(UnicodeText)
118-
has_permit = Column(Boolean, default=False)
119-
license = Column(UnicodeText)
69+
prior_name: str = Field(sa_type=String, default='')
70+
has_permit: bool = Field(sa_type=Boolean, default=False)
71+
license: str = Field(sa_type=String, default='')
12072

12173
@Session.model_mixin
12274
class Attendee:
123-
special_merch = Column(Choice(c.SPECIAL_MERCH_OPTS), default=c.NO_MERCH)
124-
donate_badge_cost = Column(Boolean, default=False)
75+
special_merch: int = Field(sa_column=Column(Choice(c.SPECIAL_MERCH_OPTS)), default=c.NO_MERCH)
76+
donate_badge_cost: bool = Field(sa_type=Boolean, default=False)
77+
78+
@presave_adjustment
79+
def defaults(self):
80+
if not self.special_merch:
81+
self.special_merch = c.NO_MERCH
82+
if not self.donate_badge_cost:
83+
self.donate_badge_cost = False
12584

12685
@presave_adjustment
12786
def indie_ribbon(self):
@@ -296,20 +255,20 @@ def is_not_ready_to_checkin(self):
296255
return message
297256

298257

299-
class SeasonPassTicket(MagModel):
300-
fk_id = Column(UUID)
301-
slug = Column(UnicodeText)
258+
class SeasonPassTicket(MagModel, table=True):
259+
fk_id: str = Field(sa_type=Uuid(as_uuid=False))
260+
slug: str = Field(sa_type=String, default='')
302261

303262
@property
304263
def fk(self):
305264
return self.session.season_pass(self.fk_id)
306265

307266

308-
class PrevSeasonSupporter(MagModel):
309-
first_name = Column(UnicodeText)
310-
last_name = Column(UnicodeText)
311-
email = Column(UnicodeText)
267+
class PrevSeasonSupporter(MagModel, table=True):
268+
first_name: str = Field(sa_type=String, default='')
269+
last_name: str = Field(sa_type=String, default='')
270+
email: str = Field(sa_type=String, default='')
312271

313-
email_model_name = 'attendee' # used by AutomatedEmailFixture code
272+
email_model_name: ClassVar = 'attendee' # used by AutomatedEmailFixture code
314273

315274
_repr_attr_names = ['first_name', 'last_name', 'email']

0 commit comments

Comments
 (0)