-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
202 lines (192 loc) · 9.92 KB
/
main.py
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
from discord import SelectOption, Option, Intents, SlashCommandGroup, User
import logging, argparse, discord, os, traceback, typing
from data import Data as _Data
from discord.ui import Select, View
from discord.ext import commands, bridge
from lib import _getGuildId, Send
#parse argv
argparser = argparse.ArgumentParser("VC Assistant Bot", description="The Bot that assistant VC.")
argparser.add_argument("-log_level", action="store", type=int, dest="log_level", default=20 ,help="set Log level.(0-50)")
argparser.add_argument("token", action="store", type=str, help="discord bot token")
argparser.add_argument("-path", action="store", type=str, dest="path", required=False ,help="data path", default="")
argparser.add_argument("-spot", action="store", type=str, dest="spot", required=False ,help="Spotify Client ID", default="")
argparser.add_argument("-spot_secret", action="store", type=str, dest="spotse", required=False ,help="Spotify Client Secret", default="")
argparser.add_argument("-logfile", action="store", type=str, dest="logfile", required=False ,help="Log file path", default=None)
##argparser.add_argument("--daemon", dest="daemon", help="Start in daemon mode.", action="store_true")
argv=argparser.parse_args()
#setting logging
logger_options={}
if argv.logfile is not None: logger_options["filename"]=argv.logfile
logging.basicConfig(level=argv.log_level, **logger_options)
logger = logging.getLogger("Main")
#intents
intents=Intents.default()
intents.typing=False
intents.members=True
intents.message_content=True
##bot init
#prefix_setter
def prefix_setter(bot, message):
if message.guild is None:
return "!"
else:
return bot.data.getGuildData(_getGuildId(message)).getProperty("prefix")
bot = bridge.Bot(command_prefix=prefix_setter, intents=intents)
bot.auto_sync_commands=True
#database
bot.data=_Data(data_dir=argv.path)
bot.argv=argv
import lib
lib.Data=bot.data
#add global check
def check_permission(ctx):
perms=bot.data.getGuildData(_getGuildId(ctx)).data["perms"]
if not ctx.command.name in bot.data.command_perms: return True
if not hasattr(ctx.author, "guild_permissions"): return True
if ctx.author.guild_permissions.administrator: return True
if "user-"+str(ctx.author.id) in perms:
if bot.data.command_perms[ctx.command.name] in perms["user-"+str(ctx.author.id)]: return True
for role in ctx.author.roles:
if "role-"+str(role.id) in perms:
if bot.data.command_perms[ctx.command.name] in perms["role-"+str(role.id)]: return True
return False
bot.add_check(check_permission)
#load modules
for ext in ["matcher", "music"]:
bot.load_extension(f'modules.{ext}')
class Core(commands.Cog):
def __init__(self, bot):
self.bot=bot
self.data=bot.data
##event
#on_ready
@commands.Cog.listener()
async def on_ready(self):
logger.info("Login")
await bot.sync_commands()
logger.info([f'{i.name}' for i in bot.commands])
#on_message
@commands.Cog.listener()
async def on_message(self, message):
if message.author.bot: return
if self.bot.user in message.mentions:
prefix=prefix_setter(bot, message)
await message.reply(f'Oh, It\'s me..!! My Command prefix is "{prefix}"\n If you want to see all commandlist, please type {prefix}help')
#on_error
@commands.Cog.listener()
async def on_command_error(self, ctx, error):
if isinstance(error, commands.CommandNotFound): return
logger.error(f'Error:\n{"".join(list(traceback.TracebackException.from_exception(error).format()))}')
await Send(ctx, "Sorry... Error was huppened...")
##commands
#ping
@bridge.bridge_command(name="ping", description="Ping! Pong!")
async def ping(self, ctx):
options={}
if isinstance(bridge.BridgeApplicationContext, ctx): options.update(ephemeral=True)
await ctx.respond("Pong!!", **options)
#va
@commands.group(name="va", description="Core command of VC-Assistant")#text command group
async def va(self, ctx):
if ctx.invoked_subcommand is None:
await ctx.send('This command must have subcommands.\n (chprefix, feature)')
#chprefix
@bridge.bridge_command(name="chprefix", description="Changing Prefix")
async def chprefix(self, ctx, prefix: str):
self.data.getGuildData(_getGuildId(ctx)).setProperty(property_name="prefix",value=prefix)
await ctx.respond("Prefix was successfully changed.")
#feature
features={"matcher":"Matcher","tts":"TTS","music":"Music"}
@va.group(name="feature", description="Setting Feather")#text command group
async def feature(self, ctx):
if ctx.invoked_subcommand is None:
await Send(ctx, 'This command must have subcommands.\n (enable, disable, list, apikey)')
feature_sl=SlashCommandGroup("feature", "Setting Feather")#slash command group
#feature - enable
@feature.command(name="enable", description="Enable Feather")
async def enable(self, ctx, feature: str):
if feature in self.features:
self.data.getGuildData(_getGuildId(ctx)).setProperty("en"+self.features[feature],True)
await Send(ctx, self.features[feature]+" is now enabled!!")
else:
await Send(ctx, f'Oh no...Can\'t find such as feature..\nSupported features: {",".join(list(self.features.keys()))}')
@feature_sl.command(name="enable", description="Enable Feather")
async def enable_sl(self, ctx, feature:Option(str, "Feature name", choices=list(features.keys()), required=True)):
await self.enable(ctx, feature)
#feature - disable
@feature.command(name="disable", description="Disable Feather")
async def disable(self, ctx, feature: str):
if feature in self.features:
self.data.getGuildData(_getGuildId(ctx)).setProperty("en"+self.features[feature],False)
await Send(ctx, self.features[feature]+" is now disabled!!")
else:
await Send(ctx, f'Oh no...Can\'t find such as feature..\nSupported features: {",".join(list(self.features.keys()))}')
@feature_sl.command(name="disable", description="Disable Feather")
async def disable_sl(self, ctx, feature:Option(str, "Feature name", choices=list(features.keys()), required=True)):
await self.disable(ctx, feature)
#feature - apikey
@feature.command(name="apikey", description="Set API key using in Feather")
async def apikey(self, ctx, kind:str, key:str):
self.data.getGuildData(_getGuildId(ctx)).setProperty("key"+kind,key)
await Send(ctx, "Key was seted.")
@feature_sl.command(name="apikey", description="Set API key using in Feather")
async def apikey_sl(self, ctx, kind:Option(str, "Keyname", required=True), key:Option(str, "Key", required=True)):
await self.apikey(ctx, kind, key)
#feature - config
@feature.command(name="config", description="Set API key using in Feather")
async def config(self, ctx, key:str, value:str=None):
if value is None:
await Send(ctx, f"{key}: {self.data.getGuildData(_getGuildId(ctx)).getProperty(key)}")
else:
self.data.getGuildData(_getGuildId(ctx)).setProperty(key, value)
await Send(ctx, "Config was seted.")
@feature_sl.command(name="config", description="Disable Feather")
async def config_sl(self, ctx, key:Option(str, "key", required=True), value:Option(str, "value", required=False, default=None)):
await self.config(ctx, key, value)
#Perm
@va.command(name="permission", description="Set Permission to User", aliases=["perm"])
async def perm(self, ctx, user:typing.Optional[discord.Member]=None, role:typing.Optional[discord.Role]=None):
view=View(timeout=0)
if not user is None:
permlist=[]
try:
guild_data=self.data.getGuildData(_getGuildId(ctx)).data["perms"]["user-"+str(user.id)]
except KeyError:
guild_data={}
for perm in self.data.perms:
permlist.append(SelectOption(label=perm, value=perm, description=self.data.perms[perm]["desc"], default=((perm in guild_data) if perm in guild_data else self.data.perms[perm]["def"])))
view.add_item(PermSelction(self.data, "perm", user, permlist, ctx.author, "user"))
await Send(ctx, f"Select Permission to grant {user.mention}.", view=view, ephemeral=True)
if not role is None:
permlist=[]
try:
guild_data=self.data.getGuildData(_getGuildId(ctx)).data["perms"]["role-"+str(role.id)]
except KeyError:
guild_data={}
for perm in self.data.perms:
permlist.append(SelectOption(label=perm, value=perm, description=self.data.perms[perm]["desc"], default=((perm in guild_data) if perm in guild_data else self.data.perms[perm]["def"])))
view.add_item(PermSelction(self.data, "perm", role, permlist, ctx.author, "role"))
await Send(ctx, f"Select Permission to grant {role.mention}.", view=view, ephemeral=True)
class PermSelction(Select):
def __init__(self, data, custom_id:str, user, permlist:list, author, user_type:typing.Literal["user","role"]):
self.permlist=permlist
self.target_user=user
self.author_user=author
self.target_user_type=user_type
self.data=data
super().__init__(custom_id=custom_id, options=self.permlist, max_values=len(self.permlist), placeholder="Select Permission.")
async def callback(self, interaction):
if self.author_user.id != interaction.user.id:
return
guild_data=self.data.getGuildData(_getGuildId(interaction))
guild_data.data["perms"][f'{self.target_user_type}-{self.target_user.id}']=self.values
guild_data._syncData()
await interaction.response.send_message(content=f'Granted.', ephemeral=True)
bot.add_cog(Core(bot))
##Run
if argv.token == "env":
bot.run(os.environ["BOT_TOKEN"])
else:
bot.run(argv.token)
for i in bot.data.playlists:
i.stop(save=True)