summaryrefslogtreecommitdiff
path: root/cogs/Info.py
blob: deb0e741bda7ba9485783cd62bc551242950d6ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
from discord.ext import commands, tasks
import datetime
import discord
import importlib
import utils
importlib.reload(utils)


class DiscordInfo(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        # https://discordpy.readthedocs.io/en/latest/ext/tasks/
        global cached_guild_invites
        cached_guild_invites = {}
        self.initial_setup.start()
        global extension_name

    @tasks.loop(count=1)
    async def initial_setup(self):
        global cached_guild_invites
        for guild in self.bot.guilds:
            try:
                if guild.me.guild_permissions.manage_guild:
                    cached_guild_invites[guild.id] = await self.bot.get_guild(guild.id).invites()

            except discord.Forbidden as e:
                print(f"[Info Forbidden Error] Guild: {guild.name} | ID: {guild.id} | {e}")

            except discord.HTTPException as e:
                print(f"HTTPException error during initial invite info: {e}")

    @commands.group(invoke_without_command=True)
    async def info(self, ctx):
        """Get information about users or the Discord server."""
        prefix = await self.bot.get_prefix(ctx.message)
        emb = await utils.embed(ctx, f"Commands for {prefix[2]}info", "info you can get information about a user or server.")
        emb = await utils.field(emb, f"{prefix[2]}info server", "Provides information about the Discord server.")
        emb = await utils.field(emb, f"{prefix[2]}info user [username]", "Provides information about the given user.")
        await ctx.send(embed=emb)

    @info.command(aliases=[], application_command_meta=commands.ApplicationCommandMeta(options=[]))
    async def user(self, ctx, *, member: discord.Member):
        """Tells you some info about the member."""
        emb = await utils.embed(ctx, "", "", thumbnail=member.avatar.url)
        emb = await utils.author(emb, member.name)
        emb = await utils.field(emb, "Roles:", value=str(len(member.roles)-1))
        emb = await utils.field(emb, "Created At:", value=member.created_at.strftime("%d %B %Y - %H:%M:%S"))
        emb = await utils.field(emb, "Joined:", value=member.joined_at.strftime("%d %B %Y - %H:%M:%S"))
        emb = await utils.field(emb, "Top Role:", value=member.top_role)
        emb = await utils.field(emb, "Bot:", value=member.bot)
        # emb = await utils.thumb(emb, member.avatar_url)
        await ctx.send(embed=emb)

    @info.command(aliases=[], application_command_meta=commands.ApplicationCommandMeta(options=[]))
    async def server(self, ctx):
        """Tells you some info about the guild."""

        emb = await utils.embed(ctx, "", "")
        emb = await utils.field(emb, "Owner:", ctx.guild.owner)
        emb = await utils.field(emb, "Created:", ctx.guild.created_at.strftime("%d %B %Y"))
        emb = await utils.field(emb, "Stats:", value=f"{len(ctx.guild.categories)} categories\n"
                                                     f"{len(ctx.guild.text_channels)} text channels\n"
                                                     f"{len(ctx.guild.voice_channels)} voice channels.\n"
                                                     f"{ctx.guild.member_count} members.\n"
                                                     f"{len(ctx.guild.roles)} roles.\n"
                                                     f"{len(ctx.guild.emojis)} emojis.\n")
        await ctx.send(embed=emb)

    @info.command(aliases=[], application_command_meta=commands.ApplicationCommandMeta(options=[]))
    async def bot(self, ctx):
        """Tells you some info about the bot."""

        emb = await utils.embed(ctx, "Synthy Info - bot", f"Currently serving {len(self.bot.guilds)} guilds.")
        await ctx.send(embed=emb)
        print(self.bot.guilds)

    @commands.Cog.listener()
    async def on_member_join(self, member):
        global cached_guild_invites
        current_guild_invites = []

        print('Member Join Event Start')

        # Obtain the current invites
        try:
            if member.guild.me.guild_permissions.manage_guild:
                guild_invites = await self.bot.get_guild(member.guild.id).invites()
            else:
                return
        except discord.Forbidden as e:
            print(f"Failed to get initial invite info: {e}")
            return
        except discord.HTTPException as e:
            print(f"HTTPException error during initial invite info: {e}")
            return

        for invite in guild_invites:
            current_guild_invites.append(invite)

        # Determine the difference
        for cachedInvite, invite in [(cachedInvite, invite) for cachedInvite in cached_guild_invites[member.guild.id] for invite in current_guild_invites]:
            print(f"Comparing {invite.code}/{invite.uses} to {cachedInvite.code}/{cachedInvite.uses}")
            if invite.code == cachedInvite.code and invite.uses > cachedInvite.uses:
                str_invite_used = str(invite.code)
                str_invite_owner = str(invite.inviter.name)
                str_invite_uses = str(invite.uses)
                break

        channel_id = await utils.sql('SELECT channel_id FROM "database1".synthy.invitedetails WHERE guild_id = %s', (member.guild.id,))
        print(f"channel_id {channel_id}")
        if not channel_id:
            print(f"channel_id []")
            return
        else:
            print(f"channel_id B {channel_id}")
            obj_channel = self.bot.get_channel(channel_id[0]["channel_id"])

            user_joined = f"**User Joined:** {member.display_name} ({member.mention})"
            invite_used = f"**Invite Used:** {str_invite_used}"
            invite_owner = f"**Invite Owner:** {str_invite_owner}"
            invite_uses = f"**Total times used:** {str_invite_uses}"
            joined_details = f"\n{user_joined}\n{invite_used}\n{invite_owner}\n{invite_uses}"

            emb = await utils.notice("New User Joined!", joined_details)
            await obj_channel.send(embed=emb)

        cached_guild_invites[member.guild.id] = current_guild_invites

    @commands.Cog.listener()
    async def on_member_remove(self, member):
        channel_id = await utils.sql('SELECT channel_id FROM "database1".synthy.invitedetails WHERE guild_id = %s', (member.guild.id,))
        if channel_id == ():
            return

        obj_channel = self.bot.get_channel(channel_id[0]["channel_id"])

        # print(obj_channel)
        # print(member.display_name)

        if channel_id is not None:
            emb = await utils.notice("User has left!", f"The user {member.name} has left the server.")
            await obj_channel.send(embed=emb)

    @commands.Cog.listener()
    async def on_guild_join(self):
        global cached_guild_invites
        cached_guild_invites = {}
        for guild in self.bot.guilds:
            try:
                cached_guild_invites[guild.id] = await self.bot.get_guild(guild.id).invites()
            except Exception as e:
                print(f"[INFO]on_guild_join:{guild.id}: {e}")

    @commands.Cog.listener()
    async def on_guild_remove(self):
        global cached_guild_invites
        cached_guild_invites = {}
        for guild in self.bot.guilds:
            try:
                cached_guild_invites[guild.id] = await self.bot.get_guild(guild.id).invites()
            except Exception as e:
                print(f"[INFO]on_guild_remove:{guild.id}: {e}")

    @commands.group(invoke_without_command=True)
    async def details(self, ctx):
        """Configure join/quit notices."""
        # Get guilds prefix
        prefix = await self.bot.get_prefix(ctx.message)
        chan_id = await utils.sql('SELECT channel_id FROM "database1".synthy.invitedetails WHERE guild_id = %s;', (ctx.guild.id,))

        if chan_id:
            obj_channel = self.bot.get_channel(chan_id[0]["channel_id"])
            cur_channel = f"\nThe channel I am using is #{obj_channel.name}."
        else:
            cur_channel = ""

        # Create message
        emb = await utils.embed(ctx, f"Help for `{prefix[2]}details`",
                                     "The details feature allows me to post extra info when a user joins to a " +
                                     "channel, like who joined, what invite was used and who owns that invite.")
        emb = await utils.field(emb, f"{prefix[2]}details set",
                                     f"Use this command in the channel you want me to post in.{cur_channel}")
        emb = await utils.field(emb, f"{prefix[2]}details clear",
                                     "Use this command to stop me posting join and leave messages.")
        await ctx.send(embed=emb)

    @details.command(aliases=[], application_command_meta=commands.ApplicationCommandMeta(options=[]))
    async def set(self, ctx):
        await utils.sql('INSERT INTO "database1".synthy.invitedetails (guild_id, channel_id) VALUES (%s, %s) ON CONFLICT (guild_id) DO UPDATE SET channel_id = %s;', (ctx.guild.id, ctx.channel.id, ctx.channel.id,))
        await ctx.send(f"I will put extra details into #{ctx.channel.name}.")

    @details.command(aliases=[], application_command_meta=commands.ApplicationCommandMeta(options=[]))
    async def clear(self, ctx):
        await utils.sql('DELETE FROM "database1".synthy.invitedetails WHERE guild_id = %s;', (ctx.guild.id,))
        await ctx.send(f"Channel has been cleared.")


def setup(bot):
    print("INFO: Loading [Info]... ", end="")
    bot.add_cog(DiscordInfo(bot))
    print("Done!")


def teardown():
    print("INFO: Unloading [Info]")