Пример #1
0
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)
Пример #2
0
    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.")
Пример #3
0
    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()
Пример #4
0
 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,
             },
         )
Пример #5
0
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)
Пример #6
0
    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,
                    },
                )
Пример #7
0
    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}))
Пример #8
0
    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.")
Пример #9
0
    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.")
Пример #10
0
    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}.")
Пример #11
0
    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.")
Пример #12
0
 async def on_ready():
     logger.info(f"\nLogged in as:\n{bot.user} (ID: {bot.user.id})")