Exemple #1
0
    def _Handle(self, channel: channel_pb2.Channel, user: user_pb2.User,
                query: Text) -> hype_types.CommandResponse:
        if not query:
            return message_pb2.Card(
                header=message_pb2.Card.Header(
                    title='usage: %spopulation [region_id]' %
                    self.command_prefix),
                fields=[
                    message_pb2.Card.Field(text=(
                        'Population data is provided by The World Bank, the US '
                        'Census Bureau, and viewers like you.'))
                ])

        region_name = self._core.population.GetNameForRegion(query)
        if not region_name:
            return 'I don\'t know where that is, so I\'ll say {:,} or so.'.format(
                random.randint(1,
                               self._core.population.GetPopulation('world')))

        provider = 'US Census Bureau' if self._core.population.IsUSState(
            query) else 'The World Bank'
        return message_pb2.Card(fields=[
            message_pb2.Card.Field(text='{} has a population of {:,}'.format(
                region_name, self._core.population.GetPopulation(query)),
                                   title='Source: %s' % provider)
        ])
  def _SummonerDataToMessage(self, summoner_data, team_data):
    # Build a custom text response since the default card -> text is a bit
    # verbose.
    text_response = summoner_data['summoner']
    if summoner_data['username']:
      text_response = summoner_data['username'] + ' = ' + text_response
    if 'rank' in summoner_data:
      text_response += ', %s %s' % (
          summoner_data['region'].upper(), summoner_data['rank'])
    card = message_pb2.Card(
        header=message_pb2.Card.Header(
            title=summoner_data['summoner'],
            subtitle='%s %s, %s' %
            (summoner_data['region'].upper(),
             summoner_data.get('rank', 'Unranked'),
             summoner_data.get('username', 'HypeBot Pleb')),
            image={
                'url':
                    self._core.game.GetImageUrl(
                        'profileicon', '%d.png' %
                        summoner_data.get('profile_icon_id', 0))
            }))

    last_game_info = []
    win = '?'
    when = '?'
    # Checking is not None because "False" == a loss
    if summoner_data['last_game'].get('win') is not None:
      win = 'W' if summoner_data['last_game']['win'] else 'L'
    if summoner_data['last_game'].get('time'):
      when = util_lib.TimeDeltaToHumanDuration(
          arrow.now(self._core.timezone) - summoner_data['last_game']['time'])
    if summoner_data.get('penta'):
      last_game_info.append('PENTAKILL')
    if 'champion' in summoner_data['last_game']:
      last_game_info.append('%s: %s' % (summoner_data['last_game'].get(
          'type', 'Unknown'), summoner_data['last_game']['champion']))
    if 'fantasy_points' in summoner_data['last_game']:
      last_game_info.append('%.1fpts (%s ago, %s)' % (
          summoner_data['last_game']['fantasy_points'], when, win))
    if last_game_info:
      text_response += ' [%s]' % ', '.join(last_game_info)
      card.fields.add(title='Last Game', text=', '.join(last_game_info))

    if team_data:
      league = self._core.esports.leagues[team_data.team.league_id]
      team_text = '%s: %d%s' % (
          team_data.team.name, team_data.rank,
          inflect_lib.Ordinalize(team_data.rank))
      card.fields.add(title=league.name, text=team_text)
      text_response += ' [(%s) %s]' % (league.name, team_text)
    if not card.fields:
      card.fields.add(text='A very dedicated player.')

    card.fields.add(
        buttons=[{
            'text': 'u.gg',
            'action_url': _U_GG.format(**summoner_data),
        }])
    return message_pb2.Message(text=[text_response], card=card)
Exemple #3
0
    def _Handle(self, channel: channel_pb2.Channel, user: user_pb2.User,
                unit: Text, location: Text):
        unit = unit or self._core.user_prefs.Get(user, 'temperature_unit')
        unit = unit.upper()
        location = location or self._core.user_prefs.Get(user, 'location')

        weather = self._core.weather.GetForecast(location)
        if not weather:
            return 'Unknown location.'

        card = message_pb2.Card(header=message_pb2.Card.Header(
            title=weather.location,
            subtitle='%s and %s' %
            (self._FormatTemp(weather.current.temp_f, unit),
             weather.current.condition),
            image={
                'url': self._ICON_URL % weather.current.icon,
                'alt_text': weather.current.icon,
            }))

        for index, day in enumerate(
                weather.forecast[:len(self._params.forecast_days)]):
            card.fields.add(
                icon_url=self._ICON_URL % day.icon,
                text='%s: %s - %s %s' %
                (self._params.forecast_days[index],
                 self._FormatTemp(day.min_temp_f, unit),
                 self._FormatTemp(day.max_temp_f, unit), day.condition))

        return card
Exemple #4
0
 def _Handle(self,
             channel: channel_pb2.Channel,
             user: user_pb2.User,
             target_user: Optional[user_pb2.User] = None):
     if not target_user:
         target_user = user
     coffee_data = self._core.coffee.GetCoffeeData(target_user)
     card = message_pb2.Card(header=message_pb2.Card.Header(
         title='%s\'s Coffee Stash:' % target_user.display_name,
         subtitle='%d energy | %s | %s' %
         (coffee_data.energy,
          inflect_lib.Plural(len(coffee_data.beans or []), 'bean'),
          inflect_lib.Plural(len(coffee_data.badges or []), 'badge'))),
                             visible_fields_count=5)
     if not coffee_data.beans:
         card.fields.add(text='A %s flies out of your empty stash.' %
                         random.choice(('moth', 'fly', 'hypebug', 'bee')))
         return card
     beans = sorted(coffee_data.beans,
                    key=self._core.coffee.GetOccurrenceChance)
     c = 1
     for i, bean in enumerate(beans):
         if i < (len(beans) - 1) and bean == beans[i + 1]:
             c += 1
         else:
             card.fields.add(text=FormatBean(bean, uppercase=True, count=c))
             c = 1
     return card
Exemple #5
0
 def _Handle(self,
             channel: channel_pb2.Channel,
             user: user_pb2.User,
             target_user: Optional[user_pb2.User] = None):
     if not target_user:
         target_user = user
     coffee_data = self._core.coffee.GetCoffeeData(target_user)
     if not coffee_data.badges:
         return message_pb2.Card(fields=[
             message_pb2.Card.Field(text=NO_BADGES_MESSAGE %
                                    target_user.display_name)
         ])
     card = message_pb2.Card(header=message_pb2.Card.Header(
         title='%s\'s Coffee Badges' % target_user.display_name,
         subtitle=inflect_lib.Plural(len(coffee_data.badges), 'badge')),
                             visible_fields_count=5)
     # Reverse list so newest badges are shown first
     for b_id in coffee_data.badges[::-1]:
         badge = self._core.coffee.badges[b_id]
         card.fields.add(icon_url=badge.image_url,
                         text='%s: %s' % (badge.name, badge.description))
     return card
Exemple #6
0
  def _ComputeChampPassiveCard(self, champ):
    passive = champ.passive

    # Make passives more dank.
    tooltip = util_lib.Dankify(self._Sanitize(passive.description))

    return message_pb2.Card(
        header={
            'title': util_lib.Dankify(passive.name),
            'subtitle': '{} Passive'.format(champ.name),
            'image': {
                'url': self.GetImageUrl('passive', passive.image.full),
            },
        },
        fields=[{
            'text': tooltip
        }])
Exemple #7
0
  def _ComputeChampSkillCard(self, champ, skill_button):
    """Computes given skill for a given champion."""
    skill_button = skill_button.upper()

    skill = self.GetChampSkill(champ, skill_button)
    if skill is None:
      return 'Invalid skill name.'

    # Make skills more dank.
    skill_name = util_lib.Dankify(skill.name)
    tooltip = util_lib.Dankify(self._Sanitize(skill.tooltip))

    skill_strs = []
    skill_strs.append('{} {}: {}'.format(champ.name, skill_button, skill_name))
    card = message_pb2.Card(
        header={
            'title': skill_name,
            'subtitle': '{} {}'.format(champ.name, skill_button),
            'image': {
                'url': self.GetImageUrl('spell', skill.image.full),
            },
        })

    skill_range = skill.range_burn
    if skill_range != 'self':
      skill_strs.append('Range: {}'.format(skill_range))
      card.fields.add(title='Range', text='{}'.format(skill_range))

    resource = skill.resource
    if resource:
      cost = self._FillinSkillDescription(resource, skill)
      skill_strs.append('Cost: {}'.format(cost))
      card.fields.add(title='Cost', text=cost)

    skill_strs.append('CD: {}'.format(skill.cooldown_burn))
    card.fields.add(title='Cooldown', text='{}'.format(skill.cooldown_burn))

    skill_text = self._FillinSkillDescription(tooltip, skill)
    card.fields.add(text=skill_text)

    skill_info = [u'; '.join(skill_strs)]
    # this description is sometimes too long.
    # split it into multiple lines if necessary.
    skill_info += self._CleanChampionWrap(skill_text)
    return message_pb2.Message(text=skill_info, card=card)
Exemple #8
0
    def _Handle(self, channel: channel_pb2.Channel, user: user_pb2.User,
                energy: Optional[Text]):
        # Ensure users can't !coffee find 0 for infinite coffee
        energy = max(1, int(energy or 1))
        result = self._core.coffee.FindBeans(user, energy)
        if result == StatusCode.RESOURCE_EXHAUSTED:
            return OUT_OF_ENERGY_MESSAGE % energy
        if result == StatusCode.NOT_FOUND:
            return FOUND_NO_BEANS_MESSAGE
        if result == StatusCode.OUT_OF_RANGE:
            return BEAN_STASH_FULL_MESSAGE

        return message_pb2.Card(fields=[
            message_pb2.Card.Field(
                text='You found some {} ({:.2%} chance)!'.format(
                    FormatBean(result),
                    self._core.coffee.GetOccurrenceChance(result)))
        ])
Exemple #9
0
    def _Handle(self, channel, user, query):
        # Avoid spoilers in spoiler-free channels.
        if channel.id in FLAGS.spoiler_free_channels:
            return 'pls no spoilerino'
        query = query.split()
        league = query[0] if query else self._params.default_region
        bracket = ' '.join(query[1:]) if len(query) > 1 else 'regular'

        standings = self._core.esports.GetStandings(league, bracket)

        cards = []
        for standing in standings:
            has_ties = any([team.ties for team in standing['teams']])
            format_str = '{0.wins}-{0.losses}'
            if has_ties:
                format_str += '-{0.ties}, {0.points}'
            card = message_pb2.Card(
                header={
                    'title':
                    standing['league'].name,
                    'subtitle':
                    '%s (%s)' % (standing['bracket'].name,
                                 'W-L-D, Pts' if has_ties else 'W-L'),
                },
                # We will place the top-n teams into the first field separated by
                # newlines so that we don't have extra whitespace.
                visible_fields_count=1)
            team_strs = [('*{0.rank}:* {0.team.abbreviation} (%s)' %
                          format_str).format(team)
                         for team in standing['teams']]
            # If there are a lot of teams in the bracket, only display the top few.
            # 6 is chosen since many group stages and Grumble consist of 6 team
            # brackets.
            if len(team_strs) > 6:
                # The number placed into the visible field is n-1 so that we don't only
                # show a single team in the collapsed section.
                card.fields.add(text='\n'.join(team_strs[:5]))
                card.fields.add(text='\n'.join(team_strs[5:]))
            else:
                card.fields.add(text='\n'.join(team_strs))
            cards.append(card)
        return cards
Exemple #10
0
    def _Handle(self, channel: channel_pb2.Channel, user: user_pb2.User,
                location: Optional[Text]):
        location = location or self._core.user_prefs.Get(user, 'location')

        aqi = self._core.weather.GetAQI(location)
        if not aqi:
            return f'Cannot fetch AQI for {location}'

        card = message_pb2.Card(header=message_pb2.Card.Header(
            title=location,
            subtitle='%s %s %s%s' %
            (aqi[0]['ReportingArea'], aqi[0]['DateObserved'],
             aqi[0]['HourObserved'], aqi[0]['LocalTimeZone'])))

        for observation in aqi:
            card.fields.add(
                title=observation['ParameterName'],
                text='%s: %s' %
                (observation['AQI'], observation['Category']['Name']))

        return card
Exemple #11
0
    def _BuildHeadlineCard(self, header_text, raw_results):
        card = message_pb2.Card(header=message_pb2.Card.Header(
            title=header_text, image=self._core.news.icon),
                                visible_fields_count=6)

        sorted_results = sorted(raw_results,
                                key=lambda x: x.get('pub_date', arrow.get(0)),
                                reverse=True)
        for article in sorted_results:
            field = message_pb2.Card.Field(text=article['title'])
            if article.get('pub_date'):
                field.title = 'Published %s ago' % util_lib.TimeDeltaToHumanDuration(
                    arrow.utcnow() - arrow.get(article['pub_date']))
            source = article.get('source')
            if source and source != self._core.news.source:
                field.bottom_text = source
            card.fields.append(field)
            card.fields.append(
                message_pb2.Card.Field(buttons=[
                    message_pb2.Card.Field.Button(text='Read article',
                                                  action_url=article['url'])
                ]))

        return card
Exemple #12
0
    def _Handle(self, unused_channel, unused_user, detailed, region):
        endpoint = 'us'
        if region:
            region = region.upper()
            endpoint = 'states'
        region = region or 'USA'
        raw_results = self._core.proxy.FetchJson(self._API_URL + endpoint)
        logging.info('CovidAPI raw_result: %s', raw_results)
        if not raw_results:
            return 'Unknown region, maybe everyone should move there.'

        state_data = {}
        if len(raw_results) == 1:
            state_data = raw_results[0]
        else:
            state_data = [
                state for state in raw_results if state.get('state') == region
            ][0]

        if not state_data:
            return 'Unknown region, maybe everyone should move there.'

        # Raw data
        cases, new_cases = self._ParseResult(state_data, 'positive')
        tests, new_tests = self._ParseResult(state_data, 'totalTestResults')
        hospitalized, new_hospitalizations = self._ParseResult(
            state_data, 'hospitalizedCurrently')
        ventilators, _ = self._ParseResult(state_data, 'onVentilatorCurrently')
        icu_patients, _ = self._ParseResult(state_data, 'inIcuCurrently')
        deaths, new_deaths = self._ParseResult(state_data, 'death')
        population = self._core.population.GetPopulation(region)

        if detailed:
            fields = []
            info_field_fn = functools.partial(self._InfoField,
                                              population=population)
            if cases:
                fields.append(
                    info_field_fn('Confirmed cases', cases, new_cases))
            if tests:
                fields.append(
                    info_field_fn('Tests administered',
                                  tests,
                                  new_tests,
                                  up_is_good=True))
            if hospitalized:
                fields.append(
                    info_field_fn(
                        'Hospitalized',
                        hospitalized,
                        new_hospitalizations,
                    ))
            if icu_patients:
                fields.append(info_field_fn('ICU patients', icu_patients))
            if ventilators:
                fields.append(info_field_fn('Ventilators in use', ventilators))
            if deaths:
                fields.append(info_field_fn('Deaths', deaths, new_deaths))

            update_time = state_data.get('dateChecked') or state_data.get(
                'lastModified')
            update_time_str = 'some time'
            if update_time:
                update_timedelta = arrow.utcnow() - arrow.get(update_time)
                update_time_str = util_lib.TimeDeltaToHumanDuration(
                    update_timedelta)

            fields.append(
                message_pb2.Card.Field(buttons=[
                    message_pb2.Card.Field.Button(
                        text='Source', action_url='https://covidtracking.com/')
                ]))
            return message_pb2.Card(header=message_pb2.Card.Header(
                title='%s COVID-19 Statistics' %
                self._core.population.GetNameForRegion(region),
                subtitle='Updated %s ago' % update_time_str),
                                    fields=fields,
                                    visible_fields_count=4)

        deaths, descriptor = inflect_lib.Plural(deaths, 'death').split()
        death_str = '{:,} {}'.format(int(deaths), descriptor)

        cases, descriptor = inflect_lib.Plural(
            cases, 'confirmed cases').split(maxsplit=1)
        case_str = '{:,} {}'.format(int(cases), descriptor)

        tests, descriptor = inflect_lib.Plural(tests, 'test').split()
        percent_tested = float(tests) / population
        test_str = '{:,} [{:.1%} of the population] {}'.format(
            int(tests), percent_tested, descriptor)

        return '%s has %s (%s) with %s administered.' % (
            region or 'The US', case_str, death_str, test_str)