Example #1
0
 async def cog_overrides(self, ctx):
     """cog_overrides_help"""
     if ctx.invoked_subcommand is self.cog_overrides:
         overrides = Configuration.get_var(ctx.guild.id, "PERM_OVERRIDES")
         desc = ""
         for k, v in overrides.items():
             lvl = v["required"]
             if lvl >= 0:
                 desc += f"{k}: {lvl} ({Translator.translate(f'perm_lvl_{lvl}', ctx)})\n"
         if desc == "":
             desc = Translator.translate('no_overrides', ctx)
         embed = discord.Embed(color=6008770, title=Translator.translate('cog_overrides', ctx), description=desc)
         await ctx.send(embed=embed)
Example #2
0
    async def dismiss_raid(self, channel, raid_info):
        """Dismiss raid as false alarm, will also remove the mute role from all of them again"""
        await channel.send("Dismissing raid")
        targets = [m for m in raid_info["TODO"]]
        failures = []
        # terminate raid
        if channel.guild.id in self.under_raid:
            await self._terminate_raid(channel.guild, dismised=True)
        message = await channel.send("Unmuting people...")
        # remove mute role from people who have been detected
        for target in targets:
            member = channel.guild.get_member(target)
            if member is not None:
                role = member.guild.get_role(
                    Configuration.get_var(member.guild.id, "MUTE_ROLE"))
                if role is not None:
                    try:
                        await member.remove_roles(
                            role, reason="Raid alarm dismissed")
                        raid_info['RAIDERS'][str(
                            target)]["state"] = "Dismissed"
                    except discord.HTTPException:
                        failures.append(str(target))
        await channel.send(f"{len(targets) - len(failures)} have been unmuted")
        if len(failures) > 0:
            people = '\n'.join(failures)
            out = f"Failed to unmute the following people:\n{people}"
            for page in Utils.paginate(out):
                await channel.send(page)

        # notify it was just a false alarm so they can stand down
        for other_guild in self.bot.guilds:
            if other_guild != channel.guild:
                new_channel = self.bot.get_channel(
                    Configuration.get_var(other_guild.id, f"MOD_CHANNEL"))
                if new_channel is not None:
                    await new_channel.send(
                        f"Raid over at {channel.guild} turned out to not be an actual raid and has been dismissed."
                    )
Example #3
0
 async def cat(self, ctx):
     """cat_help"""
     await ctx.trigger_typing()
     future_fact = self.get_json("https://animal.gearbot.rocks/cat/fact")
     key = Configuration.get_master_var("CAT_KEY", "")
     future_cat = self.get_json(
         "https://api.thecatapi.com/v1/images/search?limit=1&size=full",
         {'x-api-key': key})
     fact_json, cat_json = await asyncio.gather(future_fact, future_cat)
     embed = discord.Embed(description=fact_json["content"])
     if key != "":
         embed.set_image(url=cat_json[0]["url"])
     await ctx.send(embed=embed)
Example #4
0
async def on_guild_update(before, after):
    if after.owner is not None and after.owner.id in Configuration.get_persistent_var(
            "user_blacklist", []):
        GearbotLogging.info(
            f"Someone transferred {after.name} ({after.id}) to ({after.owner} ({after.owner.id})) but they are blacklisted"
        )
        try:
            await after.owner.send(
                f"Someone transferred {after.name} (``{after.id}``) to you, but you have been blacklisted due to bot abuse, so i left"
            )
        except Exception:
            pass
        await after.leave()
Example #5
0
def check_permission(ctx: commands.Context):
    if ctx.guild is None:
        return 0 >= get_required(ctx, ctx.cog.permissions)
    else:
        overrides = Configuration.get_var(ctx.guild.id, "PERM_OVERRIDES")
        cog_name = type(ctx.cog).__name__
        required = -1
        if cog_name in overrides:
            required = get_required(ctx, overrides[cog_name])
        if required == -1:
            required = get_required(ctx, ctx.cog.permissions)
        return get_user_lvl(ctx) >= (ctx.cog.permissions["required"]
                                     if required == -1 else required)
Example #6
0
 async def on_raw_bulk_message_delete(
         self, event: discord.RawBulkMessageDeleteEvent):
     channel_id = Configuration.getConfigVar(event.guild_id, "MINOR_LOGS")
     if channel_id is not 0:
         message_list = dict()
         for mid in event.message_ids:
             message = LoggedMessage.get_or_none(
                 LoggedMessage.messageid == mid)
             if message is not None:
                 message_list[mid] = message
         await Archive.archive(
             self.bot, event.guild_id,
             collections.OrderedDict(sorted(message_list.items())))
Example #7
0
    async def on_message(self, message: discord.Message):
        if message.author.bot or message.webhook_id is not None:
            return
        if not hasattr(message.channel, "guild") or message.channel.guild is None:
            return

        me = message.guild.me
        if me is None:
            me = Utils.get_member(self.bot, message.guild, self.bot.user.id)
        permissions = message.channel.permissions_for(me)
        if me is None:
            return
        if not (permissions.read_messages and permissions.send_messages and permissions.embed_links):
            return

        role_list = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "ROLES")
        role_required = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "ROLE_REQUIRED")
        channel_list = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "CHANNELS")
        channels_ignored = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "CHANNELS_IGNORED")
        mod_bypass = Configuration.get_var(message.guild.id, "CUSTOM_COMMANDS", "MOD_BYPASS")

        is_mod = message.author is not None and Permissioncheckers.is_mod(message.author)

        if (message.channel.id in channel_list) is channels_ignored and not (is_mod and mod_bypass):
            return

        has_role = False
        if message.author is not None and hasattr(message.author, "roles"):
            for role in message.author.roles:
                if role.id in role_list:
                    has_role = True
                    break

        if has_role is not role_required and not (is_mod and mod_bypass):
            return

        prefix = Configuration.get_var(message.guild.id, "GENERAL", "PREFIX")
        if message.content.startswith(prefix, 0) and message.guild.id in self.commands:
            for trigger in self.commands[message.guild.id]:
                if message.content.lower() == prefix + trigger or (
                        message.content.lower().startswith(trigger, len(prefix)) and message.content.lower()[len(prefix + trigger)] == " "):
                    info = self.commands[message.guild.id][trigger]
                    images = IMAGE_MATCHER.findall(info.content)
                    image = None
                    if len(images) == 1:
                        image = images[0]
                        description = info.content.replace(image, "")
                    else:
                        description = info.content
                    embed = Embed(description=description)
                    if info.created_by is not None:
                        creator = await Utils.get_user(info.created_by)
                        embed.set_footer(text=f"Created by {str(creator)} ({info.created_by})",
                                         icon_url=creator.avatar_url)
                    if image is not None:
                        embed.set_image(url=image)
                    await message.channel.send(embed=embed)
                    self.bot.custom_command_count += 1
Example #8
0
async def pack_messages(messages, guild_id):
    out = ""
    for message in messages:
        name = await Utils.username(message.author, clean=False)
        reply = ""
        if message.reply_to is not None:
            reply = f" | In reply to https://discord.com/channels/{message.server}/{message.channel}/{message.reply_to}"
        timestamp = datetime.datetime.strftime(
            discord.Object(message.messageid).created_at.astimezone(
                pytz.timezone(
                    Configuration.get_var(guild_id, 'GENERAL', 'TIMEZONE'))),
            '%H:%M:%S')
        out += f"{timestamp} {message.server} - {message.channel} - {message.messageid} | {name} ({message.author}) | {message.content}{reply} | {(', '.join(Utils.assemble_attachment(message.channel, attachment.id, attachment.name) for attachment in message.attachments))}\r\n"
    return out
Example #9
0
 async def dog(self, ctx):
     """dog_help"""
     await ctx.trigger_typing()
     future_fact = self.get_json(
         "https://dog-api.kinduff.com/api/facts?number=1")
     key = Configuration.get_master_var("DOG_KEY", "")
     future_dog = self.get_json(
         "https://api.thedogapi.com/v1/images/search?limit=1&size=full",
         {'x-api-key': key}, key != "")
     fact_json, dog_json = await asyncio.gather(future_fact, future_dog)
     embed = discord.Embed(description=fact_json["facts"][0])
     if key != "":
         embed.set_image(url=dog_json[0]["url"])
     await ctx.send(embed=embed)
Example #10
0
    async def init(self):
        try:
            self.redis_link = await aioredis.create_redis_pool(
                (Configuration.get_master_var('REDIS_HOST', "localhost"),
                 Configuration.get_master_var('REDIS_PORT', 6379)),
                encoding="utf-8",
                db=0,
                maxsize=2)  # size 2: one send, one receive
            self.bot.loop.create_task(self._receiver())

            if Configuration.get_master_var("DASH_OUTAGE")["outage_detection"]:
                self.bot.loop.create_task(self.dash_monitor())

            await self.redis_link.subscribe(
                self.receiver.channel("dash-bot-messages"))
            await self.redis_link.publish_json(
                "bot-dash-messages", {
                    'type': 'cache_info',
                    'message': await self.cache_info()
                })

        except OSError:
            await GearbotLogging.bot_log("Failed to connect to the dash!")
Example #11
0
async def update():
    message = await GearbotLogging.bot_log(
        f"{Emoji.get_chat_emoji('REFRESH')} Updating translations")
    crowdin_data = Configuration.get_master_var("CROWDIN")
    session: aiohttp.ClientSession = BOT.aiosession
    async with session.get(
            f"https://api.crowdin.com/api/project/Gearbot/export?login={crowdin_data['login']}&account-key={crowdin_data['key']}&json",
    ) as reply:
        if reply.status is not 200:
            await GearbotLogging.bot_log(
                f"{Emoji.get_chat_emoji('WARNING')} Crowdin api error, got response code {reply.status}"
            )
        else:
            response = await reply.json()
            if response["success"][
                    "status"] == "built":  # only update translations if we actually got a new build, should be every time though unless this runs 2x within 30 mins for some reason
                async with session.get(
                        f"https://api.crowdin.com/api/project/Gearbot/download/all.zip?login={crowdin_data['login']}&account-key={crowdin_data['key']}"
                ) as reply:
                    data = await reply.read()
                    with open("zip.zip", "wb") as file:
                        file.write(data)
                    with zipfile.ZipFile("zip.zip", "r") as archive:
                        tempdir = os.path.abspath("temp")
                        if os.path.isdir(tempdir):
                            shutil.rmtree(tempdir, ignore_errors=True)
                        os.mkdir(tempdir)
                        archive.extractall("temp")
                        for entry in archive.filelist:
                            if not entry.filename.endswith(".json"):
                                continue
                            filename = entry.filename[-10:]
                            if os.path.isfile(
                                    os.path.abspath(f"lang/{filename}")):
                                os.remove(os.path.abspath(f"lang/{filename}"))
                            archive.extract(entry, tempdir)
                            os.rename(
                                os.path.abspath(f"temp/{entry.filename}"),
                                os.path.abspath(f"lang/{filename}"))
                            shutil.rmtree("temp", ignore_errors=True)
                    load_translations()
                    await message.edit(
                        content=
                        f"{Emoji.get_chat_emoji('YES')} Translations have been updated"
                    )
            else:
                await message.edit(
                    content=
                    f"{Emoji.get_chat_emoji('WARNING')} Crowdin build status was `{response['success']['status']}`, no translation update required"
                )
Example #12
0
 async def on_message(self, message: discord.Message):
     if message.guild is not None or len(
             message.content
     ) > 1800 or message.author.id == self.bot.user.id:
         return
     if not message.content.startswith("!"):
         channel = self.bot.get_channel(
             Configuration.get_master_var("inbox", 0))
         if channel is not None:
             await channel.send(
                 f"[`{message.created_at.strftime('%c')}`] {message.author} (`{message.author.id}`) said: {message.clean_content}"
             )
         for attachement in message.attachments:
             await channel.send(attachement.url)
Example #13
0
 async def mute_role(self, ctx:commands.Context, role:discord.Role):
     """configure_mute_help"""
     if role == ctx.guild.default_role:
         return await ctx.send(
             f"{Emoji.get_chat_emoji('NO')} {Translator.translate(f'default_role_forbidden', ctx)}")
     guild:discord.Guild = ctx.guild
     perms = guild.me.guild_permissions
     if not perms.manage_roles:
         await ctx.send(f"{Emoji.get_chat_emoji('NO')} {Translator.translate('mute_missing_perm', ctx)}")
         return
     if not guild.me.top_role > role:
         await ctx.send(f"{Emoji.get_chat_emoji('NO')} {Translator.translate('mute_missing_perm', ctx, role=role.mention)}")
         return
     Configuration.set_var(ctx.guild.id, "MUTE_ROLE", int(role.id))
     await ctx.send(f"{Emoji.get_chat_emoji('YES')} {Translator.translate('mute_role_confirmation', ctx, role=role.mention)}")
     failed = []
     for channel in guild.text_channels:
         try:
             await channel.set_permissions(role, reason=Translator.translate('mute_setup', ctx), send_messages=False, add_reactions=False)
         except discord.Forbidden as ex:
             failed.append(channel.mention)
     for channel in guild.voice_channels:
         try:
             await channel.set_permissions(role, reason=Translator.translate('mute_setup', ctx), speak=False, connect=False)
         except discord.Forbidden as ex:
             failed.append(Translator.translate('voice_channel', ctx, channel=channel.name))
     if len(failed) > 0:
         message = f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate('mute_setup_failures', ctx, role=role.mention)}\n"
         for fail in failed:
             if len(message) + len(fail) > 2048:
                 await ctx.send(message)
                 message = ""
             message = message + fail
         if len(message) > 0:
             await ctx.send(message)
     else:
         await ctx.send(f"{Emoji.get_chat_emoji('YES')} {Translator.translate('mute_setup_complete', ctx)}")
Example #14
0
    async def on_raw_message_delete(self, data: RawMessageDeleteEvent):
        if data.message_id in self.bot.data["message_deletes"]:
            self.bot.data["message_deletes"].remove(data.message_id)
            return
        message = LoggedMessage.get_or_none(messageid=data.message_id)
        if message is not None and Features.is_logged(message.server, "EDIT_LOGS"):
            guild = self.bot.get_guild(message.server)
            user: discord.User = self.bot.get_user(message.author)
            hasUser = user is not None
            if not hasUser or user.id in Configuration.get_var(guild.id, "IGNORED_USERS") or user.id == guild.me.id:
                return
            attachments = LoggedAttachment.select().where(LoggedAttachment.messageid == data.message_id)
            channel = self.bot.get_channel(message.channel)
            name = Utils.clean_user(user) if hasUser else str(message.author)
            GearbotLogging.log_to(guild.id, "EDIT_LOGS",
                                  f":wastebasket: {Translator.translate('message_removed', guild.id, name=name, user_id=user.id if hasUser else 'WEBHOOK', channel=channel.mention)}")
            if Configuration.get_var(channel.guild.id, "EMBED_EDIT_LOGS"):

                embed = discord.Embed(timestamp=datetime.datetime.utcfromtimestamp(time.time()),
                                      description=message.content)
                embed.set_author(name=user.name if hasUser else message.author,
                                 icon_url=user.avatar_url if hasUser else EmptyEmbed)

                embed.set_footer(text=f"Sent in #{channel.name}")
                if len(attachments) > 0:
                    embed.add_field(name=Translator.translate('attachment_link', guild),
                                    value="\n".join(attachment.url for attachment in attachments))
                GearbotLogging.log_to(guild.id, "EDIT_LOGS", embed=embed)
            else:
                cleaned_content = await Utils.clean(message.content, channel.guild)
                GearbotLogging.log_to(guild.id, "EDIT_LOGS", f"**Content:** {cleaned_content}", can_stamp=False)
                count = 1
                for attachment in attachments:
                    GearbotLogging.log_to(guild.id, "EDIT_LOGS",
                                          f"**Attachment{f' {count}' if len(attachments) > 1 else ''}:** <{attachment.url}>",
                                          can_stamp=False)
                    count += 1
Example #15
0
 async def temp_ban_punishment(self, v: Violation):
     reason = self.assemble_reason(v)
     duration = v.bucket["PUNISHMENT"]["DURATION"]
     until = time.time() + duration
     await self.bot.redis_pool.psetex(f"forced_exits:{v.guild.id}-{v.member.id}", 8000, 1)
     await v.guild.ban(v.member, reason=reason, delete_message_days=0)
     i = await InfractionUtils.add_infraction(v.guild.id, v.member.id, self.bot.user.id, 'Tempban', reason,
                                        end=until)
     if Configuration.get_var(v.guild.id, "INFRACTIONS", "DM_ON_TEMPBAN"):
         dur = Utils.to_pretty_time(duration, None)
         asyncio.create_task(Utils.send_infraction(self.bot, v.member, v.guild, 'BAN', 'tempban', "Spam", duration=dur))
     GearbotLogging.log_key(v.guild.id, 'tempban_log', user=Utils.clean_user(v.member),
                            user_id=v.member.id, moderator=Utils.clean_user(v.guild.me),
                            moderator_id=v.guild.me.id, reason=reason,
                            until=datetime.datetime.utcfromtimestamp(until), inf=i.id)
Example #16
0
 async def on_message(self, message: discord.Message):
     if message.guild is None or message.webhook_id is not None or message.channel is None or isinstance(
             message.channel, DMChannel) or not Configuration.get_var(
                 message.channel.guild.id, "CENSORING",
                 "ENABLED") or self.bot.user.id == message.author.id:
         return
     member = message.guild.get_member(message.author.id)  #d.py is weird
     if member is None:
         return
     if message.reference is not None and message.reference.channel_id == message.channel.id:
         reply = message.reference.message_id
     else:
         reply = None
     await self.check_message(member, message.content, message.channel,
                              message.id, False, reply, message.attachments)
async def init():
    await Tortoise.init(
        config={
            'connections': {
                'default': {
                    'engine': 'tortoise.backends.mysql',
                    'credentials': {
                        'host': Configuration.get_master_var('DATABASE_HOST'),
                        'port': Configuration.get_master_var('DATABASE_PORT'),
                        'user': Configuration.get_master_var('DATABASE_USER'),
                        'password': Configuration.get_master_var(
                            'DATABASE_PASS'),
                        'database': Configuration.get_master_var(
                            'DATABASE_NAME')
                    }
                }
            },
            'apps': {
                'models': {
                    'models': ['database.DatabaseConnector']
                }
            }
        })
    await Tortoise.generate_schemas()
Example #18
0
 def __init__(self, bot):
     super().__init__(bot, {
         "min": 0,
         "max": 6,
         "required": 0,
         "commands": {}
     })
     to_remove = {
         "CAT_KEY": "cat",
         "DOG_KEY": "dog",
         "APEX_KEY": "apexstats"
     }
     for k, v in to_remove.items():
         if Configuration.get_master_var(k, "0") == "0":
             bot.remove_command(v)
Example #19
0
def log_raw(guild_id, key, message=None, embed=None, file=None):
    # logging category, emoji and
    info = LOG_TYPES[key]

    # determine where it should be logged so we don't need to bother assembling everything when it's just gona be voided anyways
    targets = []
    channels = Configuration.get_var(guild_id, "LOG_CHANNELS")
    for cid, settings in channels.items():
        if info.category in settings["CATEGORIES"] and info.config_key not in settings["DISABLED_KEYS"]:
            targets.append(cid)

    # no targets? no logging
    if len(targets) is 0:
        return
    log_to(guild_id, targets, Utils.trim_message(message, 2000) if message is not None else None, embed, file, None)
Example #20
0
    async def voice_spam_detector(self):
        while self.running:
            try:
                member = None
                before = None
                after = None
                (member, before, after) = await self.bot.wait_for("voice_state_update")
                # make sure our cog is still running so we don't handle it twice
                if not self.running:
                    return

                # make sure anti-spam is enabled
                cfg = Configuration.get_var(member.guild.id, "ANTI_SPAM")
                if after.channel is None or before.channel == after.channel or member is None or not cfg.get("ENABLED", False) or self.is_exempt(member.guild.id, member):
                    continue
                buckets = Configuration.get_var(member.guild.id, "ANTI_SPAM", "BUCKETS", [])
                count = 0
                for b in buckets:
                    t = b["TYPE"]
                    if t == "voice_joins":
                        now = int(datetime.datetime.utcnow().timestamp())
                        bucket = self.get_bucket(member.guild.id, f"voice_channel_join", b, member.id)
                        if bucket is not None and await bucket.check(member.id, now, message=now, amount=1):
                            count = await bucket.count(member.id, now, expire=False)
                            period = await bucket.size(member.id, now, expire=False)
                            self.bot.loop.create_task(
                                self.violate(Violation("max_voice_joins", member.guild, f"{Translator.translate('spam_max_voice_join', member.guild)} ({count}/{period}s)",
                                                       member,
                                                       None,
                                                       set(),
                                                       b, count)))

            except CancelledError:
                pass
            except Exception as e:
                await TheRealGearBot.handle_exception("voice spam join detector", self.bot, e)
Example #21
0
 async def command_overrides(self, ctx):
     """command_overrides_help"""
     if ctx.invoked_subcommand is self.command_overrides:
         overrides = Configuration.get_var(ctx.guild.id, "PERM_OVERRIDES")
         embed = discord.Embed(color=6008770, title=Translator.translate('command_overrides', ctx))
         has_overrides = False
         for cog in self.bot.cogs:
             if cog in overrides:
                 out = gen_override_strings(ctx, overrides[cog])
                 if out != "":
                     has_overrides = True
                     embed.add_field(name=cog, value=out)
         if not has_overrides:
             embed.description = Translator.translate('no_overrides', ctx)
         await ctx.send(embed=embed)
Example #22
0
 async def on_member_join(self, member: discord.Member):
     if Features.is_logged(member.guild.id, "TRAVEL_LOGS"):
         dif = (datetime.datetime.utcfromtimestamp(time.time()) - member.created_at)
         new_user_threshold = Configuration.get_var(member.guild.id, "GENERAL", "NEW_USER_THRESHOLD")
         minutes, seconds = divmod(dif.days * 86400 + dif.seconds, 60)
         hours, minutes = divmod(minutes, 60)
         age = (Translator.translate('days', member.guild.id,
                                     amount=dif.days)) if dif.days > 0 else Translator.translate('hours',
                                                                                               member.guild.id,
                                                                                               hours=hours,
                                                                                               minutes=minutes)
         if new_user_threshold > dif.total_seconds():
             GearbotLogging.log_key(member.guild.id, 'join_logging_new', user=Utils.clean_user(member), user_id=member.id, age=age)
         else:
             GearbotLogging.log_key(member.guild.id, 'join_logging', user=Utils.clean_user(member), user_id=member.id, age=age)
Example #23
0
 async def on_member_join(self, member: discord.Member):
     channelid = Configuration.getConfigVar(member.guild.id, "JOIN_LOGS")
     if channelid is not 0:
         logChannel: discord.TextChannel = self.bot.get_channel(channelid)
         if logChannel is not None:
             dif = (datetime.datetime.utcnow() - member.created_at)
             minutes, seconds = divmod(dif.days * 86400 + dif.seconds, 60)
             hours, minutes = divmod(minutes, 60)
             age = (Translator.translate(
                 'days', member.guild.id,
                 days=dif.days)) if dif.days > 0 else Translator.translate(
                     'hours', member.guild.id, hours=hours, minutes=minutes)
             await logChannel.send(
                 f"{Emoji.get_chat_emoji('JOIN')} {Translator.translate('join_logging', member.guild.id, user=Utils.clean_user(member), user_id=member.id, age=age)}"
             )
Example #24
0
 async def on_raw_bulk_message_delete(self, event: discord.RawBulkMessageDeleteEvent):
     if Features.is_logged(event.guild_id, "MESSAGE_LOGS"):
         if event.channel_id in Configuration.get_var(event.guild_id, "MESSAGE_LOGS", "IGNORED_CHANNELS_OTHER"):
             return
         if event.channel_id in self.bot.being_cleaned:
             for mid in event.message_ids:
                 self.bot.being_cleaned[event.channel_id].add(mid)
             return
         message_list = dict()
         for mid in event.message_ids:
             message = await MessageUtils.get_message_data(self.bot, mid)
             if message is not None:
                 message_list[mid] = message
         if len(message_list) > 0:
             await Archive.archive_purge(self.bot, event.guild_id,
                                         collections.OrderedDict(sorted(message_list.items())))
Example #25
0
 async def _warn(ctx, target, *, reason, message=True, dm_action=True):
     i = await InfractionUtils.add_infraction(ctx.guild.id, target.id, ctx.author.id, "Warn", reason)
     name = Utils.clean_user(target)
     if message:
         await MessageUtils.send_to(ctx, 'YES', 'warning_added', user=name, inf=i.id)
     aname = Utils.clean_user(ctx.author)
     GearbotLogging.log_key(ctx.guild.id, 'warning_added_modlog', user=name, moderator=aname, reason=reason,
                            user_id=target.id, moderator_id=ctx.author.id, inf=i.id)
     if Configuration.get_var(ctx.guild.id, "INFRACTIONS", "DM_ON_WARN") and dm_action:
         try:
             dm_channel = await target.create_dm()
             await dm_channel.send(
                 f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate('warning_dm', ctx.guild.id, server=ctx.guild.name)}```{reason}```")
         except discord.Forbidden:
             GearbotLogging.log_key(ctx.guild.id, 'warning_could_not_dm', user=name,
                                    userid=target.id)
Example #26
0
 async def on_message(self, message: discord.Message):
     if message.author.bot:
         return
     if not hasattr(message.channel,
                    "guild") or message.channel.guild is None:
         return
     prefix = Configuration.getConfigVar(message.guild.id, "PREFIX")
     if message.content.startswith(prefix, 0):
         for trigger in self.commands[message.guild.id]:
             if message.content.lower() == prefix + trigger or (
                     message.content.lower().startswith(
                         trigger, len(prefix)) and
                     message.content.lower()[len(prefix + trigger)] == " "):
                 await message.channel.send(
                     self.commands[message.guild.id][trigger])
                 self.bot.commandCount = self.bot.commandCount + 1
Example #27
0
    async def user_info_request(self, message):
        user_id = message["user_id"]
        user_info = await self.bot.fetch_user(user_id)
        return_info = {
            "username":
            user_info.name,
            "discrim":
            user_info.discriminator,
            "avatar_url":
            str(user_info.avatar_url_as(size=256)),
            "bot_admin_status":
            await self.bot.is_owner(user_info)
            or user_id in Configuration.get_master_var("BOT_ADMINS", [])
        }

        return return_info
Example #28
0
 async def on_raw_message_edit(self, event: discord.RawMessageUpdateEvent):
     channel = self.bot.get_channel(int(event.data["channel_id"]))
     if channel is None or isinstance(
             channel, DMChannel) or not Configuration.get_var(
                 channel.guild.id, "CENSORING", "ENABLED"):
         return
     permissions = channel.permissions_for(channel.guild.me)
     if permissions.read_messages and permissions.read_message_history:
         try:
             message = await channel.fetch_message(event.message_id)
         except (discord.NotFound, discord.Forbidden
                 ):  # we should never get forbidden, be we do, somehow
             pass
         else:
             if self.bot.user.id != message.author.id:
                 await self.check_message(message)
Example #29
0
async def on_ready():
    global STARTED
    if not STARTED:
        await Logging.onReady(bot,
                              Configuration.get_master_var("BOT_LOG_CHANNEL"))
        await Configuration.on_ready(bot)

        for e in ["Maintenance", "Moderation", "BadNames"]:
            try:
                bot.load_extension("Cogs." + e)
            except Exception as ex:
                Logging.error(f"Failed to load cog {e}")
                await handle_exception(f"Loading cog {e}", ex)
        Logging.info("Cogs loaded")
        await Logging.bot_log("Outboard engine running at full speed!")
        STARTED = True
Example #30
0
async def on_command_error(bot, ctx: commands.Context, error):
    if isinstance(error, NotCachedException):
        if bot.loading_task is not None:
            if bot.initial_fill_complete:
                await send(ctx, f"{Emoji.get_chat_emoji('CLOCK')} Due to a earlier connection failure the cached data for this guild is no longer up to date and is being rebuild. Please try again in a few minutes.")
            else:
                await send(ctx, f"{Emoji.get_chat_emoji('CLOCK')} GearBot is in the process of starting up and has not received the member info for this guild. Please try again in a few minutes.")
        else:
            await send(ctx, f"{Emoji.get_chat_emoji('CLOCK')} GearBot only just joined this guild and is still receiving the initial member info for this guild, please try again in a few seconds")
    if isinstance(error, commands.BotMissingPermissions):
        GearbotLogging.error(f"Encountered a permission error while executing {ctx.command}: {error}")
        await send(ctx, error)
    elif isinstance(error, commands.CheckFailure):
        if ctx.command.qualified_name != "latest" and ctx.guild is not None and Configuration.get_var(ctx.guild.id, "GENERAL", "PERM_DENIED_MESSAGE"):
            await MessageUtils.send_to(ctx, 'LOCK', 'permission_denied')
    elif isinstance(error, commands.CommandOnCooldown):
        await send(ctx, error)
    elif isinstance(error, commands.MissingRequiredArgument):
        param = list(ctx.command.params.values())[min(len(ctx.args) + len(ctx.kwargs), len(ctx.command.params))]
        bot.help_command.context = ctx
        await send(ctx,
            f"{Emoji.get_chat_emoji('NO')} {Translator.translate('missing_arg', ctx, arg=param._name, error=Utils.replace_lookalikes(str(error)))}\n{Emoji.get_chat_emoji('WRENCH')} {Translator.translate('command_usage', ctx, usage=bot.help_command.get_command_signature(ctx.command))}")
    elif isinstance(error, PostParseError):
        bot.help_command.context = ctx
        await send(ctx, f"{Emoji.get_chat_emoji('NO')} {Translator.translate('bad_argument', ctx, type=error.type, error=Utils.replace_lookalikes(str(error.error)))}\n{Emoji.get_chat_emoji('WRENCH')} {Translator.translate('command_usage', ctx, usage=bot.help_command.get_command_signature(ctx.command))}")
    elif isinstance(error, commands.BadArgument):
        param = list(ctx.command.params.values())[min(len(ctx.args) + len(ctx.kwargs), len(ctx.command.params))]
        bot.help_command.context = ctx
        await send(ctx, f"{Emoji.get_chat_emoji('NO')} {Translator.translate('bad_argument', ctx, type=param._name, error=Utils.replace_lookalikes(str(error)))}\n{Emoji.get_chat_emoji('WRENCH')} {Translator.translate('command_usage', ctx, usage=bot.help_command.get_command_signature(ctx.command))}")
    elif isinstance(error, commands.CommandNotFound):
        return
    elif isinstance(error, NotFound):
        e = Emoji.get_chat_emoji('BUG')
        await send(ctx, f"{e} Command failed because the discord api responded with \"not found\" If you didn't delete anything manually and this keeps happening please report it on support server (DM me ``!about`` or check the website for an invite) {e}")
    elif isinstance(error, Forbidden):
        e = Emoji.get_chat_emoji('BUG')
        await ctx.send(f"{e} Command failed because the discord api responded with \"forbidden\" reply. Please make sure the bot has the permissions and roles required to perform this command {e}")
    elif isinstance(error, UnexpectedQuoteError) or isinstance(error, InvalidEndOfQuotedStringError):
        e = Emoji.get_chat_emoji('BUG')
        await ctx.send(f"{e} Command parsing failed, unexpected or unclosed quote encountered {e}")

    else:
        await handle_exception("Command execution failed", bot, error.original if hasattr(error, "original") else error, ctx=ctx)
        # notify caller
        e = Emoji.get_chat_emoji('BUG')
        if ctx.channel.permissions_for(ctx.me).send_messages:
            await ctx.send(f"{e} Something went wrong while executing that command {e}")