def get_channel_tz(bot, trigger): """ Gets the channel's preferred timezone; returns the current channel's if no channel name is given. """ channel = trigger.group(2) if not channel: channel = trigger.sender channel = channel.strip() zone = get_channel_timezone(bot.db, channel) if zone: bot.say('%s\'s timezone: %s' % (channel, zone)) else: bot.say('%s has no preferred timezone' % channel)
def spacex(bot, trigger): """Fetches next scheduled SpaceX rocket launch.""" args = trigger.group(2) if args: args = args.split() zone = None if args: tmp_args = args for idx, arg in enumerate(tmp_args): if arg.strip().lower() == "--utc": zone = "UTC" args.pop(idx) channel_or_nick = tools.Identifier(trigger.nick) zone = zone or get_nick_timezone(bot.db, channel_or_nick) if not zone: channel_or_nick = tools.Identifier(trigger.sender) zone = get_channel_timezone(bot.db, channel_or_nick) b_url = "https://spacelaunchnow.me/api/3.3.0/launch/upcoming/?format=json&limit=3&search=spacex" try: data = requests.get(b_url).json() except: return bot.reply("I couldn't fetch data from the API") if not data.get("results"): return bot.reply("No results returned from the API") if args: tmp_args = " ".join(args) try: parsed_data = _parse_results(data, "SpaceX", idx=int(tmp_args.strip()) - 1, tz=zone) except: parsed_data = _parse_results(data, "SpaceX", tz=zone) else: parsed_data = _parse_results(data, "SpaceX", tz=zone) for line in parsed_data: bot.say(line, max_messages=2)
def f_time(bot, trigger): """Return the current time. The command takes an optional parameter: it will try to guess if it's a nick, a channel, or a timezone (in that order). If it's a known nick or channel but there is no configured timezone, then it will complain. If nothing can be found, it'll complain that the argument is not a valid timezone. .. seealso:: Function :func:`~sopel.tools.time.format_time` is used to format the current datetime according to the timezone (if found). """ argument = trigger.group(2) if not argument: # get default timezone from nick, or sender, or bot, or UTC zone = get_timezone(bot.db, bot.config, None, trigger.nick, trigger.sender) else: # guess if the argument is a nick, a channel, or a timezone zone = None argument = argument.strip() channel_or_nick = tools.Identifier(argument) # first, try to get nick or channel's timezone help_prefix = bot.config.core.help_prefix if channel_or_nick.is_nick(): zone = get_nick_timezone(bot.db, channel_or_nick) if zone is None and channel_or_nick in bot.users: # zone not found for a known nick: error case set_command = '%ssettz <zone>' % help_prefix if channel_or_nick != trigger.nick: bot.say('Could not find a timezone for this nick. ' '%s can set a timezone with `%s`' % (argument, set_command)) else: bot.say('Could not find a timezone for you. ' 'You can set your timezone with `%s`' % set_command) return else: zone = get_channel_timezone(bot.db, channel_or_nick) if zone is None and channel_or_nick in bot.channels: # zone not found for an existing channel: error case set_command = '%ssetctz <zone>' % help_prefix bot.say('Could not find timezone for channel %s. ' 'It can be set with `.setctz <zone>`. ' '(requires OP privileges)' % argument) return # then, fallback on timezone detection if zone is None: # argument not found as nick or channel timezone try: zone = validate_timezone(argument) except ValueError: bot.say('Could not find timezone "%s".' % argument) return time = format_time(bot.db, bot.config, zone, trigger.nick, trigger.sender) bot.say(time)
def fight(bot, trigger): """Fetches UFC/MMA fight event information By default, with no parameters, will fetch the next or in-progress event. Use --search text/"text to search" to find a specific event. Use --prelim to fetch the preliminary card if there is one. Use --prev to find the previous completed event. Use --schedule/sched to fetch the next 5 events. Use --date YYYYMMDD to fetch events on a specific date. """ options = parseargs(trigger.group(2)) try: schedule = requests.get(schedule_url + "&league=ufc" if 'ufc' in trigger.group(1).lower() else schedule_url) schedule = schedule.json() except: return bot.say("I couldn't fetch the schedule") pv_fight = options.get('--prev') or False if any(key.startswith('--prelim') for key in options): card_type = options.get('--prelim') or options.get('--prelims') elif any(key.startswith('--fullcard') for key in options): card_type = 'all' else: card_type = 'main' if card_type == 'early': card_type = 'prelims2' elif card_type == True: card_type = 'prelims1' search = True if options.get('--search') else False search_string = options.get('--search') date_search = options.get('--date', '') if options.get('--utc'): zone = "UTC" else: zone = options.get('--tz') or None if zone == True: zone = "US/Eastern" channel_or_nick = tools.Identifier(trigger.nick) zone = zone or get_nick_timezone(bot.db, channel_or_nick) if not zone: channel_or_nick = tools.Identifier(trigger.sender) zone = get_channel_timezone(bot.db, channel_or_nick) if not zone: zone = "US/Eastern" event_blacklist = [ "401210113", "401223006", "401210554", "401223027", "401223444", "600002600", "600004344", "600004560", ] now = pendulum.now() inp_fut = [] previous = [] date_event = [] for date, event in schedule['events'].items(): for ev in event: if not ev['completed'] and ev['status']['detail'] not in [ 'Canceled', 'Postponed' ]: if 'Bellator 238' in ev['name'] or ev['id'] in event_blacklist: continue inp_fut.append(ev) if ev['completed'] and ev['status']['detail'] not in [ 'Canceled', 'Postponed' ]: previous.append(ev) if date == date_search: for ev in event: date_event.append(ev) if date_event: events = {"curr": date_event, "prev": []} else: events = { "curr": inp_fut, "prev": previous[::-1], } if options.get('--sched') or options.get('--schedule'): schd = [] for sched_event in inp_fut[:5]: venue = "" if sched_event.get('venue'): venue = " - {}".format(sched_event['venue']['fullName']) if sched_event['venue']['address'].get('state'): venue += " - {}, {}".format( sched_event['venue']['address']['city'], sched_event['venue']['address']['state'], ) else: venue += " - {}, {}".format( sched_event['venue']['address']['city'], sched_event['venue']['address']['country'], ) schd.append("{} - {}{}".format( bold(sched_event['name']), pendulum.parse(sched_event['date']).in_tz(zone).format( 'MMM Do h:mm A zz'), "{}".format(venue))) for line in schd: bot.say(line) return if not events['curr']: if not events['prev']: return bot.say( "I couldn't find any past, current, or future events!") else: event_id = [events['prev'][0]['id']] else: if len(events['curr']) > 1: event_id = [events['curr'][0]['id']] date1 = pendulum.parse(events['curr'][0]['date'], strict=False) for ev in events['curr'][1:]: tmp_date = pendulum.parse(ev['date'], strict=False) if date1.is_same_day(tmp_date): event_id.append(ev['id']) else: event_id = [events['curr'][0]['id']] if pv_fight: event_id = [events['prev'][0]['id']] if search: all_events = previous + inp_fut for event in all_events: tmp_name = event['name'].lower().replace(" ", "") if search_string.lower().replace(" ", "") in tmp_name: event_id = [event['id']] break for id_ in event_id: try: data = requests.get(event_url.format(event_id=id_)) data = data.json() except: return bot.say("I couldn't fetch current event JSON") event_name = data['event']['name'] event_time = pendulum.parse(data['event']['date']).in_tz(zone) event_loc = " - {}".format(data['venue']['displayNameLocation']) if \ data.get('venue') else "" strings = [] strings.append( f"\x02{event_name}\x02 - {event_time.format('MMM Do h:mm A zz')}{event_loc}" ) card_names = { 'main': "-- Main Card --", 'prelims1': "-- Prelims --", 'prelims2': "-- Early Prelims --" } if data.get('cards'): if card_type == 'all': cards = ['prelims2', 'prelims1', 'main'] else: cards = [card_type] for card in cards: if not data['cards'].get(card): continue decisions = [] divisions = [] left_strings = [] right_strings = [] strings.append(card_names.get(card, "-- Unknown --")) if pv_fight or data['cards'][card]['competitions'][0][ 'status']['type']['completed']: # fight over fights = data['cards'][card]['competitions'][::-1] for fight in fights: left_fighter = {} right_fighter = {} flg_code = None for fighter in fight['competitors']: if fighter['order'] == 1: left_fighter['name'] = bold( fighter['athlete']['displayName'] ) if fighter['winner'] else fighter['athlete'][ 'displayName'] left_fighter['winner_or_loser'] = color( "W", 'green') if fighter['winner'] else color( "L", 'red') flg_code = None if "TBA" not in left_fighter['name']: try: if len(fighter['athlete']['flag'] ['alt']) > 3: for country in countries: if fighter['athlete']['flag'][ 'alt'] == country[ 'name']: flg_code = country[ 'alpha-2'] break else: flg_code = fighter['athlete'][ 'flag']['alt'][:2] if not flg_code: flg_code = fighter['athlete'][ 'flag']['alt'][:2] try: if flg_code.lower() == "en": left_fighter[ 'flag'] = "\x02ЪЈ┤заЂДзаЂбзаЂЦзаЂ«заЂДзаЂ┐\x02" else: left_fighter[ 'flag'] = "{}".format( flag.flag(flg_code)) except: if flg_code.lower() == "en": left_fighter[ 'flag'] = "\x02ЪЈ┤заЂДзаЂбзаЂЦзаЂ«заЂДзаЂ┐\x02" else: left_fighter['flag'] = fighter[ 'athlete']['flag']['alt'] except: left_fighter['flag'] = "" else: left_fighter['flag'] = "ЪЈ│№ИЈ" left_fighter['record'] = fighter.get( 'displayRecord', "-") else: right_fighter['name'] = bold( fighter['athlete']['displayName'] ) if fighter['winner'] else fighter['athlete'][ 'displayName'] right_fighter['winner_or_loser'] = color( "W", 'green') if fighter['winner'] else color( "L", 'red') flg_code = None if "TBA" not in right_fighter['name']: try: if len(fighter['athlete']['flag'] ['alt']) > 3: for country in countries: if fighter['athlete']['flag'][ 'alt'] == country[ 'name']: flg_code = country[ 'alpha-2'] break else: flg_code = fighter['athlete'][ 'flag']['alt'][:2] if not flg_code: flg_code = fighter['athlete'][ 'flag']['alt'][:2] try: if flg_code.lower() == "en": right_fighter[ 'flag'] = "\x02ЪЈ┤заЂДзаЂбзаЂЦзаЂ«заЂДзаЂ┐\x02" else: right_fighter[ 'flag'] = "{}".format( flag.flag(flg_code)) except: if flg_code.lower() == "en": right_fighter[ 'flag'] = "\x02ЪЈ┤заЂДзаЂбзаЂЦзаЂ«заЂДзаЂ┐\x02" else: right_fighter['flag'] = fighter[ 'athlete']['flag']['alt'] except: right_fighter['flag'] = "" else: right_fighter['flag'] = "ЪЈ│№ИЈ" right_fighter['record'] = fighter.get( 'displayRecord', "-") left_string = "[{}] {} {} ({})".format( left_fighter['winner_or_loser'], left_fighter['name'], left_fighter['flag'], left_fighter['record'], ) right_string = "[{}] {} {} ({})".format( right_fighter['winner_or_loser'], right_fighter['name'], right_fighter['flag'], right_fighter['record'], ) left_strings.append(left_string) right_strings.append(right_string) try: decisions.append( " | {} - {} ({}) [R{}, {}]".format( fight['status']['type']['shortDetail'], fight['status']['result'] ['shortDisplayName'], fight['judgesScores'] if fight.get('judgesScores') else fight['status']['result']['description'], fight['status']['period'], fight['status']['displayClock'])) except: pass divisions.append(" | {}".format(fight['note']) if fight.get('note') else "") else: # fight not over fights = data['cards'][card]['competitions'][::-1] for fight in fights: left_fighter = {} right_fighter = {} flg_code = None round_status = None for fighter in fight['competitors']: if fighter['order'] == 1: left_fighter['name'] = bold( fighter['athlete']['displayName'] ) if fighter['winner'] else fighter['athlete'][ 'displayName'] if fight['status']['type']['completed']: left_fighter['winner_or_loser'] = color( "W", 'green' ) if fighter['winner'] else color( "L", 'red') else: left_fighter['winner_or_loser'] = "" if fight.get('status', {}).get('type', {}).get( 'state', '') != "pre": round_status = fight.get('status', {}).get( 'type', {}).get('shortDetail', '') flg_code = None if "TBA" not in left_fighter['name']: try: if len(fighter['athlete']['flag'] ['alt']) > 3: for country in countries: if fighter['athlete']['flag'][ 'alt'] == country[ 'name']: flg_code = country[ 'alpha-2'] break else: flg_code = fighter['athlete'][ 'flag']['alt'][:2] if not flg_code: flg_code = fighter['athlete'][ 'flag']['alt'][:2] try: if flg_code.lower() == "en": left_fighter[ 'flag'] = "\x02ЪЈ┤заЂДзаЂбзаЂЦзаЂ«заЂДзаЂ┐\x02" else: left_fighter[ 'flag'] = "{}".format( flag.flag(flg_code)) except: if flg_code.lower() == "en": left_fighter[ 'flag'] = "\x02ЪЈ┤заЂДзаЂбзаЂЦзаЂ«заЂДзаЂ┐\x02" else: left_fighter['flag'] = fighter[ 'athlete']['flag']['alt'] except: left_fighter['flag'] = "" else: left_fighter['flag'] = "ЪЈ│№ИЈ" left_fighter['record'] = fighter.get( 'displayRecord', "-") else: right_fighter['name'] = bold( fighter['athlete']['displayName'] ) if fighter['winner'] else fighter['athlete'][ 'displayName'] if fight['status']['type']['completed']: right_fighter['winner_or_loser'] = color( "W", 'green' ) if fighter['winner'] else color( "L", 'red') else: right_fighter['winner_or_loser'] = "" if fight.get('status', {}).get('type', {}).get( 'state', '') != "pre": round_status = fight.get('status', {}).get( 'type', {}).get('shortDetail', '') flg_code = None if "TBA" not in right_fighter['name']: try: if len(fighter['athlete']['flag'] ['alt']) > 3: for country in countries: if fighter['athlete']['flag'][ 'alt'] == country[ 'name']: flg_code = country[ 'alpha-2'] break else: flg_code = fighter['athlete'][ 'flag']['alt'][:2] if not flg_code: flg_code = fighter['athlete'][ 'flag']['alt'][:2] try: if flg_code.lower() == "en": right_fighter[ 'flag'] = "\x02ЪЈ┤заЂДзаЂбзаЂЦзаЂ«заЂДзаЂ┐\x02" else: right_fighter[ 'flag'] = "{}".format( flag.flag(flg_code)) except: if flg_code.lower() == "en": right_fighter[ 'flag'] = "\x02ЪЈ┤заЂДзаЂбзаЂЦзаЂ«заЂДзаЂ┐\x02" else: right_fighter['flag'] = fighter[ 'athlete']['flag']['alt'] except: right_fighter['flag'] = "" else: right_fighter['flag'] = "ЪЈ│№ИЈ" right_fighter['record'] = fighter.get( 'displayRecord', "-") left_string = "{}{} {} ({})".format( "{}".format('[' + left_fighter['winner_or_loser'] + '] ' if left_fighter['winner_or_loser'] else ''), left_fighter['name'], left_fighter['flag'], left_fighter['record'], ) right_string = "{}{} {} ({})".format( "{}".format( '[' + right_fighter['winner_or_loser'] + '] ' if right_fighter['winner_or_loser'] else ''), right_fighter['name'], right_fighter['flag'], right_fighter['record'], ) left_strings.append(left_string) right_strings.append(right_string) try: decisions.append( " | {} - {} ({}) [R{}, {}]".format( fight['status']['type']['shortDetail'], fight['status']['result'] ['shortDisplayName'], fight['judgesScores'] if fight.get('judgesScores') else fight['status']['result']['description'], fight['status']['period'], fight['status']['displayClock'])) except: if round_status: decisions.append(" | {} {}".format( bold(color("LIVE", colors.GREEN)), round_status)) else: pass divisions.append(" | {}".format(fight['note']) if fight.get('note') else "") replies = [] l_padding = 0 r_padding = 0 for string in left_strings: if len(_stripFormatting(string)) >= l_padding: l_padding = len(string) for string in right_strings: if len(_stripFormatting(string)) >= r_padding: r_padding = len(string) l_padding += 6 r_padding += 6 for idx, string in enumerate(left_strings): if "[" not in string: ppad = 6 else: ppad = 2 try: dec = decisions[idx] except: dec = "" strings.append( "{:{l_padding}} vs {:{r_padding}}{}{}".format( left_strings[idx], right_strings[idx], dec, divisions[idx] if divisions else "", l_padding=l_padding if "\x02" in left_strings[idx] else l_padding - ppad, r_padding=r_padding if "\x02" in right_strings[idx] else r_padding - ppad)) for string in strings: bot.write(['PRIVMSG', trigger.sender], string) return