def bulk_dept_import( self, session, target_server='', api_token='', message='', **kwargs): service, message, target_url = get_api_service_from_server(target_server, api_token) uri = '{}/jsonrpc/'.format(target_url) if not message and service and cherrypy.request.method == 'POST': from_departments = [(id, name) for id, name in sorted(service.dept.list().items(), key=lambda d: d[1])] for id, name in from_departments: from_department = service.dept.jobs(department_id=id) to_department = session.query(Department).filter_by(name=from_department['name']).first() if not to_department: to_department = _create_copy_department(from_department) session.add(to_department) _copy_department_roles(to_department, from_department) message = 'Successfully imported all departments and roles from {}'.format(uri) raise HTTPRedirect('import_shifts?target_server={}&api_token={}&message={}', target_server, api_token, message)
def cancel_dealer(self, session, id): group = session.group(id) _decline_and_convert_dealer_group(session, group, c.CANCELLED) message = "Sorry you couldn't make it! Group members have been emailed confirmations for individual badges." raise HTTPRedirect('../preregistration/group_members?id={}&message={}', group.id, message)
def reset(self, session, message='', email=None): if email is not None: try: account = session.get_account_by_email(email) except NoResultFound: message = 'No account exists for email address {!r}'.format(email) else: password = genpasswd() if account.password_reset: session.delete(account.password_reset) session.commit() session.add(PasswordReset(admin_account=account, hashed=bcrypt.hashpw(password, bcrypt.gensalt()))) body = render('emails/accounts/password_reset.txt', { 'name': account.attendee.full_name, 'password': password}, encoding=None) send_email.delay( c.ADMIN_EMAIL, account.attendee.email, c.EVENT_NAME + ' Admin Password Reset', body, model=account.attendee.to_dict('id')) raise HTTPRedirect('login?message={}', 'Your new password has been emailed to you') return { 'email': email, 'message': message }
def mailing_address(self, session, message='', **params): app = session.art_show_application(params) if 'copy_address' in params: app.address1 = app.attendee.address1 app.address2 = app.attendee.address2 app.city = app.attendee.city app.region = app.attendee.region app.zip_code = app.attendee.zip_code app.country = app.attendee.country from uber.model_checks import _invalid_zip_code if not app.address1: message = 'Please enter a street address.' if not app.city: message = 'Please enter a city.' if not app.region and app.country in ['United States', 'Canada']: message = 'Please enter a state, province, or region.' if not app.country: message = 'Please enter a country.' if app.country == 'United States': if _invalid_zip_code(app.zip_code): message = 'Enter a valid zip code' if message: session.rollback() else: message = 'Mailing address added.' raise HTTPRedirect('edit?id={}&message={}', app.id, message)
def problems(self, session, game_id): game = session.indie_game(game_id) if not game.has_issues: raise HTTPRedirect('index?message={}{}', game.title, ' has no outstanding issues') else: return {'game': game}
def kiosk(self): """ Landing page for kiosk laptops, this should redirect to whichever page we want at-the-door laptop kiosks to land on. The reason this is a redirect is that at-the-door laptops might be imaged and hard to change their default landing page. If sysadmins want to change the landing page, they can do it here. """ raise HTTPRedirect(c.KIOSK_REDIRECT_URL)
def with_check(self, *args, **kwargs): if c.UBER_SHUT_DOWN or c.AT_THE_CON: raise HTTPRedirect( 'index?message={}', 'The page you requested is only available pre-event.') else: return func(self, *args, **kwargs)
def checkin(self, session, message='', **params): id = params.get('id') if not id: raise HTTPRedirect('index') try: uuid.UUID(id) filters = [Attraction.id == id] except Exception: filters = [Attraction.slug.startswith(sluggify(id))] attraction = session.query(Attraction).filter(*filters).first() if not attraction: raise HTTPRedirect('index') return {'attraction': attraction, 'message': message}
def assign(self, session, game_id, judge_id, return_to): return_to = return_to + '&message={}' for gid in listify(game_id): for jid in listify(judge_id): if not session.query(IndieGameReview).filter_by(game_id=gid, judge_id=jid).first(): session.add(IndieGameReview(game_id=gid, judge_id=jid)) raise HTTPRedirect(return_to, 'Assignment successful')
def emails_by_kickin_csv(self, out, session, **params): """ Generate a list of attendee emails by what kick-in level they've donated at. We also select attendees with kick-in levels above the selected level. """ if 'amount_extra' not in params: raise HTTPRedirect('emails_by_kickin?message={}', 'You must select a kick-in level') amount_extra = params['amount_extra'] base_filter = Attendee.badge_status.in_( [c.NEW_STATUS, c.COMPLETED_STATUS]) email_filter = [Attendee.can_spam == True ] if 'only_can_spam' in params else [] # noqa: E712 attendee_filter = Attendee.amount_extra >= amount_extra if 'include_staff' in params: attendee_filter = or_(attendee_filter, Attendee.badge_type == c.STAFF_BADGE) attendees = session.query(Attendee).filter(base_filter, attendee_filter, *email_filter).all() out.writerow(["fullname", "email", "zipcode"]) for a in attendees: out.writerow([a.full_name, a.email, a.zip_code])
def update_dates(self, session, ident, **params): email = session.query(AutomatedEmail).filter_by(ident=ident).first() email.apply(params, restricted=False) session.add(email) session.commit() raise HTTPRedirect('pending_examples?ident={}&message={}', ident, 'Email send dates updated')
def new(self, session, show_all='', message='', checked_in=''): if 'reg_station' not in cherrypy.session: raise HTTPRedirect('index?message={}', 'You must set your reg station number') if show_all: restrict_to = [ Attendee.paid == c.NOT_PAID, Attendee.placeholder == False ] # noqa: E711 else: restrict_to = [ Attendee.paid != c.NEED_NOT_PAY, Attendee.registered > datetime.now(UTC) - timedelta(minutes=90) ] return { 'message': message, 'show_all': show_all, 'checked_in': checked_in, 'recent': session.query(Attendee).filter( Attendee.checked_in == None, Attendee.first_name != '', Attendee.badge_status.in_([c.NEW_STATUS, c.COMPLETED_STATUS]), *restrict_to).order_by(Attendee.registered.desc()).all(), 'Charge': Charge } # noqa: E711
def features(self, session, id=None, slug=None, **params): filters = [Attraction.is_public == True] # noqa: E712 options = subqueryload(Attraction.public_features) \ .subqueryload(AttractionFeature.events).subqueryload(AttractionEvent.attendees) if slug: attraction = session.query(Attraction) \ .filter(Attraction.slug.startswith(slug), *filters) \ .options(options).first() else: attraction = _model_for_id(session, Attraction, id, options, filters) if not attraction: raise HTTPRedirect('index') no_events = datetime.max.replace( tzinfo=UTC) # features with no events should sort to the end features = attraction.public_features return { 'attraction': attraction, 'features': sorted(features, key=lambda f: f.events[0].start_time if f.events else no_events), 'show_all': params.get('show_all') }
def take_payment(self, session, payment_id, stripeToken): charge = Charge.get(payment_id) [attendee] = charge.attendees message = charge.charge_cc(session, stripeToken) if message: raise HTTPRedirect('pay?id={}&message={}', attendee.id, message) else: db_attendee = session.query(Attendee).filter_by( id=attendee.id).first() if db_attendee: attendee = db_attendee attendee.paid = c.HAS_PAID session.add_receipt_items_by_model(charge, attendee) attendee.amount_paid_override = attendee.total_cost session.add(attendee) raise HTTPRedirect('register?message={}', c.AT_DOOR_PREPAID_MSG)
def show_info(self, session, id, message='', promo_image=None, **params): game = session.indie_game(id=id) if cherrypy.request.method == 'POST': game.apply( params, bools=[ 'tournament_at_event', 'has_multiplayer', 'leaderboard_challenge' ], restricted=False ) # Setting restricted to false lets us define custom bools and checkgroups game.studio.name = params.get('studio_name', '') if promo_image: image = session.indie_game_image(params) image.game = game image.content_type = promo_image.content_type.value image.extension = promo_image.filename.split('.')[-1].lower() image.is_screenshot = False message = check(image) if not message: with open(image.filepath, 'wb') as f: shutil.copyfileobj(promo_image.file, f) message = check(game) or check(game.studio) if not message: if game.tournament_at_event and not game.promo_image and not promo_image: message = 'Please upload a high resolution image of cover art or the game logo.' else: session.add(game) raise HTTPRedirect('index?message={}', 'Game information uploaded') return {'message': message, 'game': game}
def delete(self, session, id, return_to='index?'): attendee = session.attendee(id, allow_invalid=True) if attendee.group: if attendee.group.leader_id == attendee.id: message = 'You cannot delete the leader of a group; ' \ 'you must make someone else the leader first, or just delete the entire group' elif attendee.is_unassigned: session.delete_from_group(attendee, attendee.group) message = 'Unassigned badge removed.' else: replacement_attendee = Attendee(**{attr: getattr(attendee, attr) for attr in [ 'group', 'registered', 'badge_type', 'badge_num', 'paid', 'amount_paid', 'amount_extra' ]}) if replacement_attendee.group and replacement_attendee.group.is_dealer: replacement_attendee.ribbon = add_opt(replacement_attendee.ribbon_ints, c.DEALER_RIBBON) session.add(replacement_attendee) attendee._skip_badge_shift_on_delete = True session.delete_from_group(attendee, attendee.group) message = 'Attendee deleted, but this badge is still ' \ 'available to be assigned to someone else in the same group' else: session.delete(attendee) message = 'Attendee deleted' raise HTTPRedirect(return_to + ('' if return_to[-1] == '?' else '&') + 'message={}', message)
def process_free_prereg(self, session): charge = Charge(listify(Charge.unpaid_preregs.values())) if charge.total_cost <= 0: for attendee in charge.attendees: session.add(attendee) for group in charge.groups: session.add(group) Charge.unpaid_preregs.clear() Charge.paid_preregs.extend(charge.targets) raise HTTPRedirect('paid_preregistrations?payment_received={}', charge.dollar_amount) else: message = "These badges aren't free! Please pay for them." raise HTTPRedirect('index?message={}', message)
def take_payment(self, session, payment_id, stripeToken): charge = Charge.get(payment_id) [attendee] = charge.attendees message = charge.charge_cc(session, stripeToken) if message: raise HTTPRedirect('pay?id={}&message={}', attendee.id, message) else: db_attendee = session.query(Attendee).filter_by(id=attendee.id).first() if db_attendee: attendee = db_attendee attendee.paid = c.HAS_PAID attendee.amount_paid = attendee.total_cost session.add(attendee) raise HTTPRedirect( 'register?message={}', 'Your payment has been accepted, please proceed to the Preregistration desk to pick up your badge')
def unset_group_member(self, session, id): attendee = session.attendee(id) try: send_email.delay( c.REGDESK_EMAIL, attendee.email, '{} group registration dropped'.format(c.EVENT_NAME), render('emails/reg_workflow/group_member_dropped.txt', {'attendee': attendee}, encoding=None), model=attendee.to_dict('id')) except Exception: log.error('unable to send group unset email', exc_info=True) session.assign_badges(attendee.group, attendee.group.badges + 1, new_badge_type=attendee.badge_type, new_ribbon_type=attendee.ribbon, registered=attendee.registered, paid=attendee.paid) session.delete_from_group(attendee, attendee.group) raise HTTPRedirect( 'group_members?id={}&message={}', attendee.group_id, 'Attendee unset; you may now assign their badge to someone else')
def undo_delete(self, session, id, message='', page='1', who='', what='', action=''): if cherrypy.request.method == "POST": model_class = None tracked_delete = session.query(Tracking).get(id) if tracked_delete.action != c.DELETED: message = 'Only a delete can be undone' else: model_class = Session.resolve_model(tracked_delete.model) if model_class: params = json.loads(tracked_delete.snapshot) model_id = params.get('id').strip() if model_id: existing_model = session.query(model_class).filter( model_class.id == model_id).first() if existing_model: message = '{} has already been undeleted'.format(tracked_delete.which) else: model = model_class(id=model_id).apply(params, restricted=False) else: model = model_class().apply(params, restricted=False) if not message: session.add(model) message = 'Successfully undeleted {}'.format(tracked_delete.which) else: message = 'Could not resolve {}'.format(tracked_delete.model) raise HTTPRedirect('feed?page={}&who={}&what={}&action={}&message={}', page, who, what, action, message)
def check_id_for_model(model, **params): message = None session = params['session'] model_id = params.get('id') if not model_id: message = "No ID provided. Try using a different link or going back." elif model_id == 'None': # Some pages use the string 'None' is indicate that a new model should be created, so this is a valid ID pass else: try: if not isinstance(model_id, uuid.UUID): uuid.UUID(model_id) except ValueError: message = "That ID is not a valid format. Did you enter or edit it manually or paste it incorrectly?" else: if not session.query(model).filter(model.id == model_id).first(): message = "The ID provided was not found in our database." if message: log.error("check_id {} error: {}: id={}", model.__name__, message, model_id) raise HTTPRedirect('../preregistration/not_found?id={}&message={}', model_id, message)
def set_status(self, session, id, status=None, confirmed=False, csrf_token=None, return_to='index', message=''): team = session.mits_team(id) matching = [ t for t in session.mits_teams() if t.name == team.name and t.id != team.id ] if confirmed or (status and not matching and team.status == c.PENDING and team.completion_percentage == 100): check_csrf(csrf_token) team.status = int(status) separator = '&' if '?' in return_to else '?' raise HTTPRedirect(return_to + separator + 'message={}{}{}', team.name, ' marked as ', team.status_label) return { 'team': team, 'message': message, 'matching': matching, 'return_to': return_to }
def new_agent(self, session, **params): app = session.art_show_application(params['id']) promo_code = session.promo_code(code=app.agent_code) message = 'Agent code updated' page = "edit" if 'admin' not in params else "../art_show_admin/form" app.agent_code = app.new_agent_code() session.delete(promo_code) if app.agent: message = 'Agent removed and code updated' send_email.delay(c.ART_SHOW_EMAIL, [app.agent.email, app.attendee.email], '{} Art Show Agent Removed'.format(c.EVENT_NAME), render('emails/art_show/agent_removed.html', {'app': app}, encoding=None), 'html', model=app.to_dict('id')) app.agent_id = None send_email.delay( c.ART_SHOW_EMAIL, app.attendee.email, 'New Agent Code for the {} Art Show'.format(c.EVENT_NAME), render('emails/art_show/agent_code.html', {'app': app}, encoding=None), 'html', model=app.to_dict('id')) raise HTTPRedirect('{}?id={}&message={}', page, app.id, message)
def delete_team(self, session, id, duplicate_of=None, csrf_token=None, message=''): team = session.mits_team(id) if cherrypy.request.method == 'POST': check_csrf(csrf_token) team.deleted = True team.duplicate_of = duplicate_of or None raise HTTPRedirect('index?message={}{}{}', team.name, ' marked as deleted', ' and as a duplicate' if duplicate_of else '') other = [t for t in session.mits_teams() if t.id != id] return { 'team': team, 'message': message, 'match_count': len([t for t in other if t.name == team.name]), 'other_teams': sorted(other, key=lambda t: (t.name != team.name, t.name)) }
def reset_problems(self, session, game_id): game = session.indie_game(game_id) for review in game.reviews: if review.has_video_issues: body = render('emails/mivs/video_fixed.txt', {'review': review}, encoding=None) send_email.delay(c.MIVS_EMAIL, review.judge.email_to_address, 'MIVS: Video Problems Resolved for {}'.format( review.game.title), body, model=review.judge.to_dict('id')) review.video_status = c.PENDING if review.has_game_issues: body = render('emails/mivs/game_fixed.txt', {'review': review}, encoding=None) send_email.delay(c.MIVS_EMAIL, review.judge.email_to_address, 'MIVS: Game Problems Resolved for {}'.format( review.game.title), body, model=review.judge.to_dict('id')) review.game_status = c.PENDING raise HTTPRedirect( 'index?message={}{}', review.game.title, ' has been marked as having its judging issues fixed')
def edit(self, session, message='', **params): app = session.art_show_application(params, restricted=True, ignore_csrf=True) return_to = params['return_to'] \ if 'return_to' in params else '/art_show_applications/edit' if 'id' not in params: message = 'Invalid art show application ID. ' \ 'Please try going back in your browser.' if cherrypy.request.method == 'POST': message = check(app, prereg=True) if not message: session.add(app) session.commit() # Make sure we update the DB or the email will be wrong! send_email.delay( c.ART_SHOW_EMAIL, app.email, 'Art Show Application Updated', render('emails/art_show/appchange_notification.html', {'app': app}, encoding=None), 'html', model=app.to_dict('id')) raise HTTPRedirect('..{}?id={}&message={}', return_to, app.id, 'Your application has been updated') else: session.rollback() return { 'message': message, 'app': app, 'return_to': 'edit', }
def delete_role(self, session, id): dept_role = session.query(DeptRole).get(id) department_id = dept_role.department_id message = '' if cherrypy.request.method == 'POST': message = check_dept_admin(session, department_id) if not message: session.delete(dept_role) raise HTTPRedirect( 'form?id={}&message={}', department_id, 'The {} role was deleted'.format(dept_role.name)) if not message: raise HTTPRedirect('form?id={}', department_id) else: raise HTTPRedirect('form?id={}&message={}', department_id, message)
def unmark_screenshot(self, session, id): screenshot = session.indie_game_image(id, applicant=True) screenshot.use_in_promo = False session.add(screenshot) raise HTTPRedirect( 'show_info?id={}&message={}', screenshot.game.id, 'Screenshot unmarked as one of your "best" screenshots')
def mark(self, session, status, **params): app = session.panel_application(params) app.status = int(status) if not app.poc: app.poc_id = session.admin_attendee().id raise HTTPRedirect('index?message={}{}{}', app.name, ' was marked as ', app.status_label)
def hotel(self, session, message='', id=None, edit_id=None, requested_hotel_info=False): id = edit_id or id if not id: raise HTTPRedirect('form') if not c.PREREG_REQUEST_HOTEL_INFO_OPEN: if cherrypy.request.method == 'POST': raise HTTPRedirect( 'index?message={}', 'Requests for hotel booking info have already been closed') else: raise HTTPRedirect('form?edit_id={}', id) attendee, group = self._get_unsaved( id, if_not_found=HTTPRedirect( 'form?message={}', 'Could not find the given preregistration')) is_group_leader = not attendee.is_unassigned and len( group.attendees) > 0 if cherrypy.request.method == 'POST': attendee.requested_hotel_info = requested_hotel_info target = group if group.badges else attendee track_type = c.EDITED_PREREG if target.id in Charge.unpaid_preregs else c.UNPAID_PREREG Charge.unpaid_preregs[target.id] = to_sessionized(attendee, group) Tracking.track(track_type, attendee) if group.badges: Tracking.track(track_type, group) raise HTTPRedirect('index') return { 'message': message, 'id': id, 'edit_id': edit_id, 'is_group_leader': is_group_leader, 'requested_hotel_info': attendee.requested_hotel_info if edit_id else True }