Esempio n. 1
0
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'
Esempio n. 2
0
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'
Esempio n. 3
0
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)
Esempio n. 4
0
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)
Esempio n. 5
0
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()
Esempio n. 6
0
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
""")
Esempio n. 7
0
    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
Esempio n. 8
0
                              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:
Esempio n. 9
0
    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)]
Esempio n. 10
0
                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)