def main(): logger.info("Starting Bot...") description = ''' Rewrite of the original Hellshade-bot and Hellshade-bot 2 ''' # Intents for experience tracking etc. intents = discord.Intents.all() bot = commands.Bot(command_prefix=commands.when_mentioned_or('!', '/'), description=description, owner_id=settings.BOT_OWNER, intents=intents) bot.add_cog(Core(bot)) bot.add_cog(Utility(bot, settings.ADMINS)) bot.add_cog(Games(bot)) bot.add_cog(Roles(bot)) @bot.event async def on_ready(): logger.info(f"\nLogged in as:\n{bot.user} (ID: {bot.user.id})") def handle_sigterm(sig, frame): raise KeyboardInterrupt signal.signal(signal.SIGTERM, handle_sigterm) bot.run(settings.BOT_TOKEN)
async def update_heroes(self): await self.__bot.wait_until_ready() logger.info("Fetching Dota 2 heroes...") r = requests.get( "https://www.dota2.com/datafeed/herolist?language=english" ) data = r.json() if 'result' not in data or \ 'data' not in data['result'] or \ 'heroes' not in data['result']['data']: logger.warning("Could not fetch heroes :/") return heroes = data['result']['data']['heroes'] self.__heroes = [] for hero in heroes: self.__heroes.append({ "name": hero['name_loc'], "link": f"https://cdn.cloudflare.steamstatic.com/apps/dota2/images/dota_react/heroes/{hero['name'].removeprefix('npc_dota_hero_')}.png" }) logger.info("Done fetching heroes.")
async def on_ready(): logger.info("\nLogged in as:\n{0} (ID: {0.id})".format(bot.user)) app = Application() app.add_routes(routes) # Pass bot to webserver app["bot"] = bot runner = AppRunner(app) await runner.setup() site = TCPSite(runner, "0.0.0.0", 9080) await site.start()
def set_up(self): try: shop_url = "https://%s:%s@%s.myshopify.com/admin/api/%s" % ( self.store_token, self.password, self.store_name, self.API_VERSION, ) shopify.ShopifyResource.set_site(shop_url) logger.info("successful setup for {}".format(self.company_id)) return True except Exception as e: logger.error( e, extra={ "store_name": self.store_name, "client_id": self.company_id, }, )
def main(): logger.info("Starting bot...") description = """PartyFiller-bot, I will fill your parties!""" intents = discord.Intents.default() bot = commands.Bot( command_prefix=commands.when_mentioned_or("!"), description=description, # TODO make dynamic owner_id=128914478178762753, intents=intents, ) @bot.event async def on_ready(): logger.info("\nLogged in as:\n{0} (ID: {0.id})".format(bot.user)) app = Application() app.add_routes(routes) # Pass bot to webserver app["bot"] = bot runner = AppRunner(app) await runner.setup() site = TCPSite(runner, "0.0.0.0", 9080) await site.start() def handle_sigterm(sig, frame): raise KeyboardInterrupt signal.signal(signal.SIGTERM, handle_sigterm) bot.run(settings.TOKEN)
def extract(self): logger.info("starting extraction for {} ---->".format(self.company_id)) for dates in self.custom_dates: time.sleep(1) logger.info( f"Downloading data from {dates['from']} to {dates['to']}") created_to = dates["to"] created_from = dates["from"] list_orders = [] next_page = True payload = { "source_name": self.platform, "data": { "orders": list_orders }, "client_id": self.company_id, "store_name": self.store_name, } if self.connector_id is not None: payload.update({"internal_id": self.connector_id}) try: orders = shopify.Order.find( created_at_min=created_from, created_at_max=created_to, status="any", limit=250, ) while next_page is not False: formatted_orders = list( map(lambda order: order.to_dict(), orders)) list_orders += formatted_orders if not list_orders: payload["data"] = "" all_ok = self.send(payload) if all_ok: logger.info("successfully extracted {} orders".format( len(list_orders))) next_page = orders.has_next_page() orders = orders.next_page() if next_page else None list_orders.clear() time.sleep(3) time.sleep(2) except Exception as e: logger.error( e, extra={ "store_name": self.store_name, "client_id": self.company_id, }, )
async def heartbeat(self): await self.__bot.wait_until_ready() logger.info("Heartbeat.") async with session_lock: with Session() as session: for guild in self.__bot.guilds: server = get_create(session, crud_server, obj_in=CreateServer( **{ "discord_id": guild.id, "name": guild.name, "server_exp": 0, "channel": None })) # Update last seen now = datetime.now() crud_server.update( session, db_obj=server, obj_in=UpdateServer(**{"last_seen": now}))
async def patch_notes(self): await self.__bot.wait_until_ready() logger.info("Fetching Dota 2 patch notes...") r = requests.get( "https://www.dota2.com/datafeed/patchnoteslist?language=english" ) data = r.json() if 'patches' not in data: logger.warning("Could not fetch patch notes :/") return latest = data['patches'][-1]['patch_name'] patch_file = Path('/files/last_title') if patch_file.exists(): with open('/files/last_title', 'r') as pfr: last_title = pfr.read() else: last_title = "" if latest > last_title: logger.info("New patch notes found!") with open('/files/last_title', 'w') as pfw: pfw.write(latest) embed = discord.Embed() embed.set_author(name="Dota2.com", icon_url="https://1000logos.net/wp-content/uploads/2019/03/Dota-2-Logo.png") embed.title = f"New patch **{latest}** found!" embed.url = f"https://www.dota2.com/patches/{latest}" # Send messages to configured channel # TODO make dynamic channel = self.__bot.get_channel(367057131750293514) await channel.send(embed=embed) logger.info("Done fetching Dota 2 patch notes.")
async def get_steam_news(self): await self.__bot.wait_until_ready() logger.info("Fetching Steam news...") async with session_lock: with Session() as session: subs = crud_subscription.get_multi(session) all_new_posts = [] async with ClientSession() as client: for s in subs: logger.info( f"Fetching news: {s.channel_id=} {s.app_id=}" ) async with client.get(f"https://api.steampowered.com/ISteamNews/GetNewsForApp/v0002/?appid={s.app_id}&count=100&maxlength=1500&format=json") as r: if r.status >= 400: logger.warning( f"Could not find news for app {s.app_id}!" ) continue data = await r.json() if 'appnews' not in data or 'newsitems' not in data['appnews']: logger.warning( f"Could not find news for app {s.app_id}!" ) continue new_posts = [] for p in data['appnews']['newsitems']: if p['feed_type'] != 1: continue db_post = crud_post.get_by_gid(session, p['gid']) if db_post is not None: continue new_posts.append(p) for p in new_posts: all_new_posts.append(p) embed = discord.Embed() embed.set_author( name=f"Steam News - {p['author']}", icon_url="https://logos-world.net/wp-content/uploads/2020/10/Steam-Logo.png" ) embed.title = p['title'] embed.url = p['url'] desc = re.sub(r"\{\S*\}\/\S*", "\n", p['contents']) embed.description = desc channel = self.__bot.get_channel( int(s.channel_id) ) await channel.send(embed=embed) await asyncio.sleep(0.5) # Add all new posts to database so they wont be sent again for p in all_new_posts: old_p = crud_post.get_by_gid(session, p['gid']) # Skip if already added if old_p is not None: continue crud_post.create(session, obj_in=CreatePost(**{ 'steam_gid': p['gid'], 'title': p['title'], 'content': p['contents'] })) logger.info("Done fetching Steam news.")
async def role_update(self): """ Update roles stored every 30 minutes :return: """ await self.__bot.wait_until_ready() logger.info("Updating role messages...") async with session_lock: with Session() as session: # Go through all visible guilds for guild in self.__bot.guilds: server = server_crud.get_by_discord(session, guild.id) # Skip if server is not found if server is None: continue # Get all roles for server roles = role_crud.get_multi_by_server_uuid( session, server.uuid ) temp_roles = {} for r in roles: temp_roles[r.discord_id] = r # Go through all roles of a guild for r in guild.roles: # Skip roles that are default or premium if r.is_default or r.is_premium_subscriber: continue # Check that role is registered, otherwise skip if r.id not in temp_roles: continue # If the name is the same, then skip if r.name == temp_roles[r.id].name: continue role_update = UpdateRole(**{ "name": r.name }) # Update role role_crud.update( session, temp_roles[r.id], role_update ) # Update role message if it exists if server.role_message is not None and \ server.role_channel is not None: channel = self.__bot.get_channel( int(server.role_channel) ) # Continue if channel wasn't found if channel is None: logger.info(f"No channel found for {server.name}.") continue # Channel must not be bloated with messages message = utils.find( lambda m: (m.id == int(server.role_message)), await channel.history(limit=10).flatten() ) # Continue if message wasn't found if message is None: logger.info(f"No message found for {server.name}.") continue # Get context ctx = await self.__bot.get_context(message) embed = Embed() embed.title = f"Assignable roles for " \ f"**{message.guild.name}**" embed.description = "Use reactions inorder to get " \ "roles assigned to you, or use " \ "`!role add roleName`" converter = commands.EmojiConverter() pconverter = commands.PartialEmojiConverter() # Get all roles of a server roles = role_crud.get_multi_by_server_uuid( session, server.uuid ) # Gather all used emojis for future reactions emojis = [] for ro in roles: emoji = emoji_crud.get_by_role(session, ro.uuid) try: # Convert into actual emoji e = await converter.convert( ctx, emoji.identifier ) except commands.EmojiNotFound: # Try partial emoji instead try: e = await pconverter.convert( ctx, emoji.identifier ) except commands.PartialEmojiConversionFailure: # Assume that it is an unicode emoji e = emoji.identifier # Add to message embed.add_field( name=f"{str(e)} == {ro.name}", value=ro.description, inline=False ) emojis.append(e) await message.edit(embed=embed) # Check old reactions old_emojis = [] for r in message.reactions: old_emojis.append(r.emoji) # Add new reactions to message for e in emojis: if isinstance(e, discord.partial_emoji.PartialEmoji): logger.error(f"Emoji not cannot be used! Emoji: {e}") elif e not in old_emojis: await message.add_reaction(e) logger.info(f"Message updated for {server.name}.")
async def online_experience(self): await self.__bot.wait_until_ready() async with session_lock: with Session() as session: leveled_up = {} for member in filter(gets_exp, self.__bot.get_all_members()): player_obj = get_create(session, crud_player, obj_in=CreatePlayer( **{ "discord_id": member.id, "name": member.name, "hidden": True })) server_obj = get_create( session, crud_server, obj_in=CreateServer( **{ "discord_id": member.guild.id, "name": member.guild.name, "server_exp": 0, "channel": None })) member_obj = get_create( session, crud_member, obj_in=CreateMember( **{ "exp": 0, "player_uuid": player_obj.uuid, "server_uuid": server_obj.uuid, "level_uuid": None })) base_exp = 5 special_multi = 1 now = datetime.datetime.utcnow() # Weekend double voice experience # Between Friday 15:00 -> Sunday 23:59 (UTC) if now.weekday() > 4 or \ (now.weekday() == 4 and now.hour > 15): special_multi = 2 exp = math.ceil( special_multi * (len(member.voice.channel.members) / 4 * base_exp)) if member_obj.level is not None: next_level = crud_level.get_by_value( session, member_obj.level.value + 1) else: next_level = crud_level.get_by_value(session, 1) if next_level is None and member_obj.level is not None: member_dict = { "exp": level_exp(member_obj.level.value + 1), "value": member_obj.level.value + 1 } next_level = crud_level.create( CreateMember(**member_dict)) if member_obj.exp + exp < next_level.exp: crud_member.update( session, db_obj=member_obj, obj_in={"exp": member_obj.exp + exp}) else: member_obj = crud_member.update( session, db_obj=member_obj, obj_in={ "exp": member_obj.exp + exp - next_level.exp, "level_uuid": next_level.uuid }) if server_obj.channel is not None: if server_obj.channel in leveled_up: leveled_up[server_obj.channel]. \ append(member_obj) else: leveled_up[server_obj.channel] \ = [member_obj] crud_server.update(session, db_obj=server_obj, obj_in={ "name": member.guild.name, "server_exp": server_obj.server_exp + exp }) for channel in leveled_up: embed = discord.Embed() embed.set_author(name=self.__bot.user.name, url=settings.URL, icon_url=self.__bot.user.avatar_url) if len(leveled_up) > 1: embed.title = f"{len(leveled_up)} players leveled up!" embed.description = f"{len(leveled_up)} players " \ f"leveled up by being active on " \ f"a voice channel." else: embed.title = f"1 player leveled up!" embed.description = f"1 player leveled up by being " \ f"active on a voice channel." embed.colour = 9442302 for member in leveled_up[channel]: embed.add_field(name=member.player.name, value=f"Leveled up to " f"**Level {member.level.value}**", inline=False) await self.__bot.get_channel(int(channel)).send(embed=embed ) logger.info("Experience calculated.")
async def on_ready(): logger.info(f"\nLogged in as:\n{bot.user} (ID: {bot.user.id})")