def ytdla(bot, trigger): """Uses youtube-dl to download audio from a video and post it to chat.""" url = trigger.group(3) from_id = False # If no url, check memory for a stored YouTube ID if not url: try: url = bot.memory["youtube_ids"][trigger.sender] from_id = True except KeyError: bot.reply( "You've given me nothing to work with...what the Hell do you want?!" ) return # Check if "url" is a valid YouTube ID if re.search(r"^[^&=%\?]{11}$", url): from_id = True if re.search(VALID_YT_LINK, url) or from_id: pass else: return bot.reply("YouTube links or IDs only.") try: with youtube_dl.YoutubeDL(ytdla_opts) as ytdl: bot.say(italic("Processing...")) meta = ytdl.extract_info(url, download=False) id = meta["id"] ext = meta["audio_ext"] dur = meta["duration"] if not dur: bot.reply( "This video has no duration (livestream?) and won't be downloaded." ) return if dur > 600: bot.reply( "This video is longer than 10 minutes and won't be downloaded." ) return else: bot.say(italic("Downloading...")) ytdl.download([url]) bot.say("https://actionsack.com/tmp/{}.{}".format(id, ext)) return except youtube_dl.utils.DownloadError: bot.reply("Please submit a valid link.") except KeyError: bot.reply( "This video has no duration (livestream?) and won't be downloaded." ) return
def next4_mcu(bot, trigger): """Info on the next MCU release.""" url = "https://whenisthenextmcufilm.com/api" try: # 1st Request r1 = requests.get(url) # 1st Next Item days_until_1 = str(r1.json()["days_until"]) media_title_1 = r1.json()["title"] media_type_1 = r1.json()["type"] # 2nd Next Item days_until_2 = str(r1.json()["following_production"]["days_until"]) media_title_2 = r1.json()["following_production"]["title"] media_type_2 = r1.json()["following_production"]["type"] release_date_2 = r1.json()["following_production"]["release_date"] # 2nd Request date_for_r2 = {"date": release_date_2} r2 = requests.get(url, params=date_for_r2) # 3rd Next Item days_until_3 = str(r2.json()["days_until"]) media_title_3 = r2.json()["title"] media_type_3 = r2.json()["type"] # 4th Next Item days_until_4 = str(r2.json()["following_production"]["days_until"]) media_title_4 = r2.json()["following_production"]["title"] media_type_4 = r2.json()["following_production"]["type"] bot.say("Here are the next 4 upcoming MCU items:") bot.say( "Immediately up next is the {} '{}'. It will be out in {} days.". format(media_type_1, formatting.italic(media_title_1), formatting.bold(days_until_1))) bot.say("After that will be the {} '{}'. It will be out in {} days.". format(media_type_2, formatting.italic(media_title_2), formatting.bold(days_until_2))) bot.say("After that will be the {} '{}'. It will be out in {} days.". format(media_type_3, formatting.italic(media_title_3), formatting.bold(days_until_3))) bot.say( "Finally, after that is the {} '{}'. It will be out in {} days.". format(media_type_4, formatting.italic(media_title_4), formatting.bold(days_until_4))) except BaseException: bot.reply("Error reaching API, probably.")
def sif_song(bot, trigger): """Look up LLSIF live show information. Special keywords: song attribute (Smile, Pure, Cool), and whether the song was an event song (event, !event, or non-event). """ try: song = _get_song(trigger.group(2)) except APIError: bot.say("Sorry, something went wrong with the song API.") return except NoResultError: bot.reply("No song found!") return except InvalidQueryError as err: bot.reply("You have an error in your query: {}".format(err)) return title = formatting.hex_color(song['name'], ATTRIBUTE_COLORS[song['attribute'].lower()]) romaji_title = song['romaji_name'] english_title = song['translated_name'] main_unit = format_unit(song['main_unit']) attribute = format_attribute(song['attribute']) rotation = song[ 'daily_rotation'] or 'A' # API gives null if not B-sides, for some reason duration = song['time'] if duration is None: duration = '?:??' else: duration = "{}:{:0>2}".format(duration // 60, duration % 60) difficulties = [ '{}: {}🟊, {} notes, {} kizuna'.format( level.title(), info['stars'], info['notes'], _bond_points(info['notes']), ) for level, info in _get_song_level_info(song).items() ] bot.say("{}{} [{}] | {}, in {} {} — {}".format( title, ' ({})'.format(formatting.italic(romaji_title)) if romaji_title else '', duration, attribute, main_unit, 'Hits' if rotation == 'A' else 'B-sides', ' | '.join(difficulties), ))
def next_mcu(bot, trigger): """Info on the next MCU release.""" url = "https://whenisthenextmcufilm.com/api" try: r = requests.get(url) days_until = str(r.json()["days_until"]) media_title = r.json()["title"] media_type = r.json()["type"] bot.say( "Up next in the MCU is the {} '{}'. It will be out in {} days.". format(media_type, formatting.italic(media_title), formatting.bold(days_until))) except BaseException: bot.reply("Error reaching API, probably.")
def ytdl(bot, trigger): """Uses youtube-dl to download a video and post it to chat.""" url = trigger.group(3) if not url: try: url = bot.memory["youtube_ids"][trigger.sender] except KeyError: bot.reply( "You've given me nothing to work with...what the Hell do you want?!" ) return try: # https://github.com/yt-dlp/yt-dlp/issues/2396#issuecomment-1021210484 if re.search("tiktok", url): youtube_dl.utils.std_headers[ "User-Agent"] = "facebookexternalhit/1.1" with youtube_dl.YoutubeDL(ytdl_opts) as ytdl: bot.say(italic("Processing...")) meta = ytdl.extract_info(url, download=False) id = meta["id"] ext = meta["ext"] dur = meta["duration"] if not dur: bot.reply( "This video has no duration (livestream?) and won't be downloaded." ) return if dur > 600: bot.reply( "This video is longer than 10 minutes and won't be downloaded." ) return else: bot.say(italic("Downloading...")) ytdl.download([url]) bot.say("https://actionsack.com/tmp/{}.{}".format(id, ext)) return except youtube_dl.utils.DownloadError: bot.reply("Please submit a valid link.") except KeyError: if re.search(r"v\.redd\.it\/", url): bot.say(italic("Downloading...")) ytdl.download([url]) bot.say("https://actionsack.com/tmp/{}.{}".format(id, ext)) return if re.search(r"video\.twimg\.com\/", url): bot.say(italic("Downloading...")) ytdl.download([url]) bot.say("https://actionsack.com/tmp/{}.{}".format(id, ext)) return if re.search(r"cdn\.discordapp\.com\/", url): bot.say(italic("Downloading...")) ytdl.download([url]) bot.say("https://actionsack.com/tmp/{}.{}".format(id, ext)) return if re.search(r"vm\.tiktok\.com\/", url): bot.say(italic("Downloading...")) ytdl.download([url]) bot.say("https://actionsack.com/tmp/{}.{}".format(id, ext)) return else: bot.reply( "This video has no duration (livestream?) and won't be downloaded." ) return
def test_italic(): text = 'Hello World' assert italic(text) == '\x1d' + text + '\x1d'
nodes { id title { romaji english native } type } } } } """, } NO_DESCRIPTION = formatting.italic('[no description available]') class AniListAPIError(Exception): pass def al_query(query, variables={}): """Send a GraphQL query to AniList. :param str query: the query to send :param variables: any variables needed for the query to run :type variables: :class:`dict` :return: Decoded JSON result :rtype: :class:`dict` :raise AniListAPIError: when the API request fails for any reason
def gamble_wheel(bot, trigger): """Spin the Wheel of Fortune!""" try: data = gambling_checks(bot, trigger) except Exception as msg: return bot.reply(msg) bet = data["bet"] msg = data["msg"] gambler = trigger.nick if not bet: return bot.reply(msg) # Check if user has enough money to make the gamble... bet_check = bot.db.get_nick_value(gambler, "currency_amount") if bet_check is None: return bot.reply( "You can't gamble yet! Please run the `.iwantmoney` command.") if bet > bet_check: return bot.reply( "You don't have enough money to make this bet. Try a smaller bet.") # Take the user's money before continuing spend_on_bet = bet_check - bet bot.db.set_nick_value(gambler, "currency_amount", spend_on_bet) # Configure Wheel Spin Directions wheel_direction = ["֎", "֍"] pointer_direction = { "↗": 7, "→": 6, "↘": 5, "↓": 4, "↙": 3, "←": 2, "↖": 1, "↑": 0 } # Get the result first wheel_result = random.choices(list(pointer_direction.keys()), weights=[ 0.1, 0.4, 0.5, 1, 3, 25, 30, 40], k=1)[0] multiplier = pointer_direction[wheel_result] # Calculate winnings and award the user winnings = bet * multiplier new_balance = spend_on_bet + winnings bot.db.set_nick_value(gambler, "currency_amount", new_balance) balance = "${:,}".format(new_balance) # Conditionals if multiplier == 0: msg = "The arrow is facing [{}]. {}x multiplier. You lost. New balance: {}.".format( wheel_result, multiplier, bold(balance)) elif multiplier == 1: msg = "The arrow is facing [{}]. {}x multiplier. Same balance: {}.".format( wheel_result, multiplier, bold(balance)) else: msg = "The arrow is facing [{}]. You won: {}x your money! (${:,}). Your new balance is: {}.".format( wheel_result, multiplier, winnings, bold(balance)) # Stress user with delay bot.action( "spins the wheel...{0}{0}{0}".format( secrets.choice(wheel_direction))) time.sleep(4) bot.say(italic("The wheel slows to a stop...")) time.sleep(2) bot.reply(msg)
def gamble_betroll(bot, trigger): """Bet your money on a random roll from 0-100. Roll payouts: 0-66: 0x // 67-90: 2x // 91-99: 4x // 100: 10x""" try: data = gambling_checks(bot, trigger) except Exception as msg: return bot.reply(msg) bet = data["bet"] msg = data["msg"] gambler = trigger.nick if not bet: return bot.reply(msg) # Check if user has enough money to make the gamble... bet_check = bot.db.get_nick_value(gambler, "currency_amount") if bet_check is None: return bot.reply( "You can't gamble yet! Please run the `.iwantmoney` command.") if bet > bet_check: return bot.reply( "You don't have enough money to make this bet. Try a smaller bet.") # Take the user's money before continuing spend_on_bet = bet_check - bet bot.db.set_nick_value(gambler, "currency_amount", spend_on_bet) # Roll a number 0-100 roll = secrets.randbelow(101) # Determine multiplier if 0 <= roll <= 66: multiplier = 0 elif 67 <= roll <= 90: multiplier = 2 elif 91 <= roll <= 99: multiplier = 4 elif roll == 100: multiplier = 10 # Process winnings winnings = bet * multiplier new_balance = spend_on_bet + winnings bot.db.set_nick_value(gambler, "currency_amount", new_balance) balance = "${:,}".format(new_balance) # Conditionals if multiplier == 0: msg = "You rolled {}. You lost. {}x multiplier. New balance: {}.".format( roll, multiplier, bold(balance)) elif multiplier in (2, 4): msg = "You rolled {}. You win! {}x multiplier. New balance: {}.".format( roll, multiplier, bold(balance)) elif multiplier == 10: msg = "🎊 Holy shit! You rolled a {} which means {}x multiplier! New balance: {}. 🎊".format( roll, multiplier, bold(balance)) # Stress user with delay bot.say(italic("Rolling a number...")) time.sleep(1.5) bot.reply(msg)
def test_plain_italic(): text = 'some text' assert plain(italic(text)) == text