def get_external_schedule_menu_name(): if getattr(c, 'ALT_SCHEDULE_URL', ''): try: url = urlparse(c.ALT_SCHEDULE_URL) return 'View External Public Schedule on {}'.format(url.netloc) except Exception: log.warning('Menu: Unable to parse ALT_SCHEDULE_URL: "{}"', c.ALT_SCHEDULE_URL) return 'View External Public Schedule' return 'View Public Schedule'
def get_external_schedule_menu_name(): if getattr(c, 'ALT_SCHEDULE_URL', ''): try: url = urlparse(c.ALT_SCHEDULE_URL) return 'View External Public Schedule on {}'.format(url.netloc) except Exception: log.warning('Menu: Unable to parse ALT_SCHEDULE_URL: "{}"', c.ALT_SCHEDULE_URL) return 'View External Public Schedule' return 'View Public Schedule'
def mivs_assign_game_codes_to_judges(): if not c.PRE_CON: return with Session() as session: for game in session.indie_games(): if game.code_type == c.NO_CODE or game.unlimited_code: continue for review in game.reviews: if not set(game.codes).intersection(review.judge.codes): for code in game.codes: if not code.judge_id: code.judge = review.judge session.commit() break else: log.warning( 'Unable to find free code for game {} to assign to judge {}', game.title, review.judge.full_name)
def mivs_assign_game_codes_to_judges(): if not c.PRE_CON: return with Session() as session: for game in session.indie_games(): if game.code_type == c.NO_CODE or game.unlimited_code: continue for review in game.reviews: if not set(game.codes).intersection(review.judge.codes): for code in game.codes: if not code.judge_id: code.judge = review.judge session.commit() break else: log.warning( 'Unable to find free code for game {} to assign to judge {}', game.title, review.judge.full_name)
def tabletop_check_notification_replies(): twilio_client = get_twilio_client(c.TABLETOP_TWILIO_SID, c.TABLETOP_TWILIO_TOKEN) if not twilio_client or not c.TABLETOP_TWILIO_NUMBER: log.warn('SMS notification replies disabled for tabletop') return with Session() as session: entrants = session.entrants_by_phone() existing_sids = {sid for [sid] in session.query(TabletopSmsReply.sid)} messages = [] # Pull all the messages down before attempting to act on them. The new # twilio client uses a streaming mode, so the stream might be timing # out while it waits for us to act on each message inside our loop. try: stream = twilio_client.messages.list(to=c.TABLETOP_TWILIO_NUMBER) messages = [message for message in stream] except ConnectionError as ex: if ex.errno == 'Connection aborted.' \ and isinstance(ex.strerror, BadStatusLine) \ and ex.strerror.line == "''": log.warning('Twilio connection closed unexpectedly') else: raise ex for message in messages: if message.sid in existing_sids: continue for entrant in entrants[message.from_]: if entrant.matches(message): session.add(TabletopSmsReply( entrant=entrant, sid=message.sid, text=message.body, when=message.date_sent.replace(tzinfo=UTC) )) entrant.confirmed = 'Y' in message.body.upper() session.commit()
def test_eager_formatting_adapter(log_stream): log = AutoLogger(EagerFormattingAdapter) log.log(0, 'suppressed') log.debug('a %(a)d b %(b)s', {'a': 1, 'b': 2}) log.trace('TEST NO INTERPOLATION') log.trace('TEST %s', 'MSG') log.debug('TEST %s', 'MSG') log.info('TEST %s%s%s', 'M', 'S', 'G') log.warn('TEST %s', 'MSG') log.warning('TEST %s', 'MSG') log.error('TEST %s', 'MSG') try: assert False except Exception: log.exception('TEST %s', 'MSG') log.critical('TEST %s', 'MSG') log.fatal('TEST %s', 'MSG') result = log_stream.getvalue() assert result.startswith("""\ [DEBUG] tests.test_logging: a 1 b 2 [TRACE] tests.test_logging: TEST NO INTERPOLATION [TRACE] tests.test_logging: TEST MSG [DEBUG] tests.test_logging: TEST MSG [INFO] tests.test_logging: TEST MSG [WARNING] tests.test_logging: TEST MSG [WARNING] tests.test_logging: TEST MSG [ERROR] tests.test_logging: TEST MSG [ERROR] tests.test_logging: TEST MSG Traceback (most recent call last): """) assert result.endswith("""\ AssertionError: assert False [CRITICAL] tests.test_logging: TEST MSG [CRITICAL] tests.test_logging: TEST MSG """)
def _create_or_fetch(cls, session, value, **backref_mapping): """ Fetch an existing or create a new instance of this class. Fetching uses the values from the value positional argument (the id if available, or if any keys that correspond to unique constraints are present). In both cases the instance will still need to be updated using whatever new values you want. Args: cls (class): The class object we're going to fetch or create session (Session): the session object value (any): the dictionary value to fetch with **backref_mapping: the backref key name and value of the "parent" object of the object you're fetching or about to create. If the backref value of a fetched instance is not the same as the value of what's passed in, we will instead create a new instance. This is because we want to prevent "stealing" an existing object in a one-to-one relationship unless an id is explicitly passed. Returns: A previously existing or newly created (and added to the session) model instance. """ assert len( backref_mapping ) <= 1, 'only one backref key is allowed at this time: {}'.format( backref_mapping) if backref_mapping: backref_name = list(backref_mapping.keys())[0] parent_id = backref_mapping[backref_name] else: backref_name, parent_id = None, None id = None if isinstance(value, Mapping): id = value.get('id', None) elif isinstance(value, six.string_types): id = value instance = None if id is not None: try: instance = session.query(cls).filter(cls.id == id).first() except Exception: log.error('Unable to fetch instance based on id value {!r}', value, exc_info=True) raise TypeError( 'Invalid instance ID type for relation: {0.__name__} (value: {1})' .format(cls, value)) elif isinstance(value, Mapping): # if there's no id, check to see if we're provided a dictionary # that includes all of the columns associated with a UniqueConstraint. for column_names in cls.unique_constraint_column_names: if all( (name in value and value[name]) for name in column_names): # all those column names are provided, # use that to query by chaining together all the necessary # filters to construct that query q = session.query(cls) filter_kwargs = { name: value[name] for name in column_names } try: instance = q.filter_by(**filter_kwargs).one() except NoResultFound: continue except MultipleResultsFound: log.error( 'multiple results found for {} unique constraint: {}', cls.__name__, column_names) raise else: break else: log.debug( 'unable to search using unique constraints: {} with {}', column_names, value) if instance and id is None and backref_mapping and getattr( instance, backref_name, None) != parent_id: log.warning( 'Attempting to change the owner of {} without an explicitly passed id; ' 'a new {} instance will be used instead', instance, cls.__name__) instance = None if not instance: log.debug('creating new: {} with id {}', cls.__name__, id) if id is None: instance = cls() else: instance = cls(id=id) session.add(instance) return instance
href='../schedule/edit'), ]), MenuItem(name='Statistics', access=c.STATS, submenu=[ MenuItem(name='Summary', href='../summary/'), MenuItem(name='Graphs', href='../graphs/'), ]), ]) if getattr(c, 'ALT_SCHEDULE_URL', ''): try: url = urlparse(c.ALT_SCHEDULE_URL) external_schedule_name = 'View Schedule on {}'.format(url.netloc) except Exception: log.warning('Unable to parse ALT_SCHEDULE_URL: "{}"', c.ALT_SCHEDULE_URL) external_schedule_name = 'View Schedule Externally' c.MENU['Schedule'].append_menu_item( MenuItem(name='View Schedule Internally', access=c.STUFF, href='../schedule/internal')) c.MENU['Schedule'].append_menu_item( MenuItem(name=external_schedule_name, href='../schedule/')) else: c.MENU['Schedule'].append_menu_item( MenuItem(name='View Schedule', access=c.STUFF, href='../schedule/internal')) if c.ATTRACTIONS_ENABLED:
for index, (location, description) in enumerate(rooms): for word in filter(lambda s: s, re.split(r'\W+', description)): current_dict = root current_dict['__rooms__'][location] = index for letter in word: current_dict = current_dict.setdefault(letter.lower(), nesteddefaultdict()) current_dict['__rooms__'][location] = index return root c.ROOM_TRIE = _make_room_trie(c.EVENT_LOCATION_OPTS) invalid_rooms = [room for room in (c.PANEL_ROOMS + c.MUSIC_ROOMS) if not getattr(c, room.upper(), None)] for room in invalid_rooms: log.warning('config: panels_room config problem: ' 'Ignoring {!r} because it was not also found in [[event_location]] section.'.format(room.upper())) c.PANEL_ROOMS = [getattr(c, room.upper()) for room in c.PANEL_ROOMS if room not in invalid_rooms] c.MUSIC_ROOMS = [getattr(c, room.upper()) for room in c.MUSIC_ROOMS if room not in invalid_rooms] # This can go away if/when we implement plugin enum merging c.ACCESS.update(c.PANEL_ACCESS_LEVELS) c.ACCESS_OPTS.extend(c.PANEL_ACCESS_LEVEL_OPTS) c.ACCESS_VARS.extend(c.PANEL_ACCESS_LEVEL_VARS) # ============================= # tabletop # ============================= invalid_tabletop_rooms = [room for room in c.TABLETOP_LOCATIONS if not getattr(c, room.upper(), None)]
current_dict = current_dict.setdefault(letter.lower(), nesteddefaultdict()) current_dict['__rooms__'][location] = index return root c.ROOM_TRIE = _make_room_trie(c.EVENT_LOCATION_OPTS) invalid_rooms = [ room for room in (c.PANEL_ROOMS + c.MUSIC_ROOMS) if not getattr(c, room.upper(), None) ] for room in invalid_rooms: log.warning( 'config: panels_room config problem: ' 'Ignoring {!r} because it was not also found in [[event_location]] section.' .format(room.upper())) c.PANEL_ROOMS = [ getattr(c, room.upper()) for room in c.PANEL_ROOMS if room not in invalid_rooms ] c.MUSIC_ROOMS = [ getattr(c, room.upper()) for room in c.MUSIC_ROOMS if room not in invalid_rooms ] # This can go away if/when we implement plugin enum merging c.ACCESS.update(c.PANEL_ACCESS_LEVELS) c.ACCESS_OPTS.extend(c.PANEL_ACCESS_LEVEL_OPTS) c.ACCESS_VARS.extend(c.PANEL_ACCESS_LEVEL_VARS)