def play(self, ctx, voice_channel: discord.Channel=None):
"""Play Radio Haru"""
server = ctx.message.server
author = ctx.message.author
if voice_channel == None:
voice_channel = author.voice_channel
if self.voice_connected(server):
await self.bot.say("Already connected to a voice channel, use `{}radioharu stop` to change radio.".format(ctx.prefix))
else:
try:
voice = await self.bot.join_voice_channel(voice_channel)
Channel = ctx.message.channel
await self.bot.send_typing(Channel)
player = voice.create_ffmpeg_player('https://cdn.discordapp.com/attachments/336598653923753987/360413654224601089/Radio-Haru.ogg', use_avconv=self.use_avconv)
player.start()
await asyncio.sleep(7)
player.stop()
player = voice.create_ffmpeg_player('https://stream.radioharu.pw/radioharu', use_avconv=self.use_avconv)
player.start()
await self.bot.say(":green_heart: **Playing Radio Haru!**")
except InvalidArgument:
await self.bot.say("You either didn't enter a voice channel to connect to, or weren't in one!")
python类Channel()的实例源码
def setchatchannel(self, ctx, *, channel : discord.Channel = None):
"""Sets the channel for bot chatter."""
isAdmin = ctx.message.author.permissions_in(ctx.message.channel).administrator
# Only allow admins to change server stats
if not isAdmin:
await self.bot.send_message(ctx.message.channel, 'You do not have sufficient privileges to access this command.')
return
if channel == None:
self.settings.setServerStat(ctx.message.server, "ChatChannel", "")
msg = 'Chat channel removed - must use the `{}chat [message]` command to chat.'.format(ctx.prefix)
await self.bot.send_message(ctx.message.channel, msg)
return
# If we made it this far - then we can add it
self.settings.setServerStat(ctx.message.server, "ChatChannel", channel.id)
msg = 'Chat channel set to **{}**.'.format(channel.name)
await self.bot.send_message(ctx.message.channel, msg)
def new_channel(self, channel, guild=None):
"""Creates a new Dwarf ?Guild? object and connects it to the database.
Parameters
----------
channel
Can be a Discord ?Channel? object or a channel ID.
guild : Optional
Can be a Discord ?Server? object or a guild ID.
Is not an optional parameter if ?channel? is not a Discord ?Channel? object.
"""
if isinstance(channel, discord.Channel):
return Channel(id=channel.id, guild=channel.server.id)
else:
if guild is None:
raise ValueError("Either a Channel object or both channel ID "
"and guild ID must be given as argument(s).")
return Channel(id=channel, guild=guild)
def __init__(self, channel, title, description,
modulename="Modis", colour=0xAAFF00, thumbnail=None, image=None, datapacks=()):
"""Initialises variables and builds GUI
Args:
channel (discord.Channel): Channel to lock UI to
title (str): GUI title, in bold
description (str): GUI description
modulename (str): Name of your module, default "Modis"
colour (int): Colour of line on left, default 0xAAFF00
thumbnail (str): URL to picture shown in top right corner, default None
datapacks (list): Contains tuples of (title str, data str, inline bool)
"""
self.channel = channel
self.title = title
self.description = description
self.modulename = modulename
self.colour = colour
self.thumbnail = thumbnail
self.image = image
self.datapacks = datapacks
self.built_embed = self.build()
self.sent_embed = None
def movehere(self, channel):
"""
Moves the embed message to a new channel; can also be used to move the musicplayer to the front
Args:
channel (discord.Channel): The channel to move to
"""
self.logger.debug("movehere command")
# Delete the old message
await self.embed.delete()
# Set the channel to this channel
self.embed.channel = channel
# Send a new embed to the channel
await self.embed.send()
# Re-add the reactions
await self.add_reactions()
self.statuslog.info("Moved to front")
def msetup(self, text_channel):
"""Creates the gui
Args:
text_channel (discord.Channel): The channel for the embed ui to run in
"""
if self.mready:
logger.warning("Attempt to init music when already initialised")
return
if self.state != 'starting':
logger.error("Attempt to init from wrong state ('{}'), must be 'starting'.".format(self.state))
return
self.logger.debug("Setting up gui")
# Create gui
self.mchannel = text_channel
self.new_embed_ui()
await self.embed.send()
await self.embed.usend()
await self.add_reactions()
self.mready = True
def modify_module(channel, module_name, module_state):
"""
Creates an embed UI containing the module modified message
Args:
channel (discord.Channel): The Discord channel to bind the embed to
module_name (str): The name of the module that was updated
module_state (bool): The current state of the module
Returns:
embed: The created embed
"""
# Create embed UI object
gui = ui_embed.UI(
channel,
"{} updated".format(module_name),
"{} is now {}".format(module_name, "activated" if module_state else "deactivated"),
modulename=modulename
)
return gui
def warning_max_changed(channel, max_warnings):
"""
Creates an embed UI containing an error message
Args:
channel (discord.Channel): The Discord channel to bind the embed to
max_warnings (int): The new maximum warnings
Returns:
ui (ui_embed.UI): The embed UI object
"""
# Create embed UI object
gui = ui_embed.UI(
channel,
"Maximum Warnings Changed",
"Users must now have {} warnings to be banned "
"(this won't ban existing users with warnings)".format(max_warnings),
modulename=modulename
)
return gui
def error(channel, title, description):
"""
Creates an embed UI containing an error message
Args:
channel (discord.Channel): The Discord channel to bind the embed to
title (str): The title of the embed
description (str): The description for the error
Returns:
ui (ui_embed.UI): The embed UI object
"""
# Create embed UI object
gui = ui_embed.UI(
channel,
title,
description,
modulename=modulename
)
return gui
def join(self, *, channel: discord.Channel):
"""Joins a voice channel."""
try:
await self.bot.create_voice_client(channel)
except discord.InvalidArgument:
out = await self.bot.say('This is not a voice channel...')
await asyncio.sleep(5)
try:
await self.bot.delete_messages([ctx.message, out])
except:
pass
except discord.ClientException:
out = await self.bot.say('Already in a voice channel...')
await asyncio.sleep(5)
try:
await self.bot.delete_messages([ctx.message, out])
except:
pass
else:
out = await self.bot.say('Ready to play audio in ' + channel.name)
await asyncio.sleep(5)
try:
await self.bot.delete_messages([ctx.message, out])
except:
pass
def get_interface(self, channel: discord.Channel, generate=True):
""" Retrieves a channel interface. If none found for the channel, a new
one is created with its default values (if generate is True).
:param channel: The channel the interface belongs to.
:type channel: discord.Channel
:param generate: Whether the interface should be auto-generated if none
is found or not.
:type generate: bool
:return: The interface belonging to the channel, new or old.
"""
if channel not in self._interfaces:
if not generate:
return None
self._interfaces[channel] = ChannelTimerInterface(channel)
return self._interfaces[channel]
def spoof(self, member: discord.Member, channel: discord.Channel):
""" Spoofs a channel ID if there's a set channel to spoof from
the one where the command was executed. Also checks for the
author's permissions to see if they can spoof commands.
:param member: The member trying to spoof the command.
:type member: discord.Member
:param channel: The channel from which the command to spoof was sent.
:type channel: discord.Channel
:return: If there's a registered ID to spoof and the author has elevated
permissions, returns the spoofed ID. If not, returns the same ID
as channel_id
"""
if self.has_permission(member) and self.get_interface(channel).spoofed\
is not None:
return self._interfaces[channel].spoofed
return channel
def _generate_messages(self, channel: discord.Channel):
""" Generates and pins the messages for the given channel.
:param channel: The channel in which the messages will be
generated and pinned.
:type channel: discord.Channel
:raises: discord.errors.Forbidden: if the client doesn't have
permissions to pin messages.
"""
interface = self.get_interface(channel)
if interface.timer is None:
return
interface.time_message = await self.send_message(
channel, "Generating status...")
interface.list_message = await self.send_message(
channel, interface.timer.list_periods())
# The last message pinned ends up in the top
await self.pin_message(interface.time_message)
await self.pin_message(interface.list_message)
def mark_active(self, channel: discord.Channel, author: discord.Member,
time: datetime):
""" Marks a user as active within a channel, giving them a
last-active-at timestamp.
:param channel: The channel in which to mark the user as active at.
:type channel: discord.Channel
:param author: The user to mark as active.
:type author: discord.Member
:param time: The last-active-at time.
:type time: datetime
"""
interface = self.get_interface(channel, generate=False)
if interface is not None and author in interface.subbed:
interface.subbed[author]['last'] = time
def channel_cmd(self, ctx, *, channel : discord.Channel = None):
"""Ignores a specific channel from being processed.
If no channel is specified, the current channel is ignored.
If a channel is ignored then the bot does not process commands in that
channel until it is unignored.
"""
if channel is None:
channel = ctx.message.channel
ignored = self.config.get('ignored', [])
if channel.id in ignored:
await self.bot.responses.failure(message='That channel is already ignored.')
return
ignored.append(channel.id)
await self.config.put('ignored', ignored)
await self.bot.responses.success(message='Channel <#{}> will be ignored.'.format(channel.id))
def _list(self, ctx, channel: discord.Channel=None):
"""Lists regexes used to filter messages.
Channel listing includes global patterns."""
server = ctx.message.server
self.regexen = dataIO.load_json(JSON_PATH)
if not self._re_present(server):
await self.bot.say('There are no filter patterns set for this server.')
return
table = ' | '.join(['mode', 'pattern']) + '\n' # header
for c in self.regexen[server.id]:
if c == ALL_CHANNELS and self._re_present(server):
table += '\nServer-wide:\n'
elif (channel and channel.id == c) or not channel:
if channel:
ch_obj = channel
else:
ch_obj = self.bot.get_channel(c)
if ch_obj is None:
table += '\n' + 'Channel ID %s (deleted):' % c + '\n'
if self._re_present(ch_obj):
table += '\n#' + ch_obj.name + '\n'
for regex, mode in self.regexen[server.id][c].items():
table += ' | '.join([mode, regex]) + '\n'
await self.bot.say('```py\n' + table + '```')
def fetch_channel(self, ctx, subfolder: str, channel: discord.Channel = None, attachments: bool = None):
"Fetch complete logs for a channel. Defaults to the current one."
msg = await self.bot.say('Dispatching fetch task...')
start = datetime.now()
cookie = FetchCookie(ctx, start, msg)
if channel is None:
channel = ctx.message.channel
callback = partial(self.fetch_callback, cookie)
task = self.fetch_task([channel], subfolder, attachments=attachments,
status_cb=callback)
self.fetch_handle = self.bot.loop.create_task(task)
def set_channel(self, ctx, on_off: bool, channel: discord.Channel = None):
"""Sets channel logging on or off. Optional channel parameter.
To enable or disable all channels at once, use `logset server`."""
if channel is None:
channel = ctx.message.channel
server = channel.server
if server.id not in self.settings:
self.settings[server.id] = {}
self.settings[server.id][channel.id] = on_off
if on_off:
await self.bot.say('Logging enabled for %s' % channel.mention)
else:
await self.bot.say('Logging disabled for %s' % channel.mention)
self.save_json()
def on_channel_update(self, before, after):
if type(before) is discord.PrivateChannel:
return
entries = []
if before.name != after.name:
entries.append('Channel rename: %s renamed to %s' %
(before, after))
if before.topic != after.topic:
entries.append('Channel topic: %s topic was set to "%s"' %
(before, after.topic))
if before.position != after.position:
entries.append('Channel position: {0.name} moved from {0.position} '
'to {1.position}'.format(before, after))
# TODO: channel permissions overrides
for e in entries:
await self.log(before.server, e)
def on_channel_update(before: discord.Channel, after: discord.Channel):
""" Update the changelog when a channel changes name. """
if after.is_private:
return
changelog_channel = get_changelog_channel(after.server)
if not changelog_channel:
return
# We only want to update when a name change is performed
if before.name == after.name:
return
# Differ between voice channels and text channels
if after.type == discord.ChannelType.text:
await client.send_message(
changelog_channel, "Channel **#{0.name}** changed name to {1.mention}, **{1.name}**.".format(before, after))
else:
await client.send_message(
changelog_channel, "Voice channel **{0.name}** changed name to **{1.name}**.".format(before, after))
def can_use_command(cmd: Command, author, channel: discord.Channel=None):
""" Return True if the member who sent the message can use this command. """
if cmd.owner and not is_owner(author):
return False
if channel is not None and not has_permissions(cmd, author, channel):
return False
if not has_roles(cmd, author):
return False
# Handle server specific commands for both server and PM commands
if type(author) is discord.User and cmd.servers:
return False
if type(author) is discord.Member and not is_valid_server(cmd, author.server):
return False
return True
def run_coro(self, event):
channel = self.bot.get_channel(event.channel)
try:
server = channel.server
prefix = self.bot.settings.get_prefixes(server)[0]
except AttributeError:
log.debug("Channel no longer found, not running scheduled event.")
return
data = {}
data['timestamp'] = time.strftime("%Y-%m-%dT%H:%M:%S%z", time.gmtime())
data['id'] = randint(10**(17), (10**18) - 1)
data['content'] = prefix + event.command
data['channel'] = self.bot.get_channel(event.channel)
data['author'] = {'id': event.author}
data['nonce'] = randint(-2**32, (2**32) - 1)
data['channel_id'] = event.channel
data['reactions'] = []
fake_message = discord.Message(**data)
# coro = self.bot.process_commands(fake_message)
log.info("Running '{}' in {}".format(event.name, event.server))
# self.bot.loop.create_task(coro)
self.bot.dispatch('message', fake_message)
def channel_allow(self, ctx, command, channel: discord.Channel=None):
"""Explicitly allows [command/cog] to be used in [channel].
Not really useful because role perm overrides channel perm"""
server = ctx.message.server
try:
command_obj = self._get_command(command)
except BadCommand as e:
try:
self.bot.cogs[command]
command_obj = command
except KeyError:
raise e
if channel is None:
channel = ctx.message.channel
await self._set_permission(command_obj, server, channel=channel)
await self.bot.say("Channel {} allowed use of {}.".format(
channel.mention, command))
def channel_deny(self, ctx, command, channel: discord.Channel=None):
"""Explicitly denies [command/cog] usage in [channel]
Overridden by role based permissions"""
server = ctx.message.server
try:
command_obj = self._get_command(command)
except BadCommand as e:
try:
self.bot.cogs[command]
command_obj = command
except KeyError:
raise e
if channel is None:
channel = ctx.message.channel
await self._set_permission(command_obj, server, channel=channel,
allow=False)
await self.bot.say("Channel {} denied use of {}.".format(
channel.mention, command))
def modlog(self, ctx, channel : discord.Channel=None):
"""Sets a channel as mod log
Leaving the channel parameter empty will deactivate it"""
server = ctx.message.server
if channel:
self.settings[server.id]["mod-log"] = channel.id
await self.bot.say("Mod events will be sent to {}"
"".format(channel.mention))
else:
if self.settings[server.id]["mod-log"] is None:
await send_cmd_help(ctx)
return
self.settings[server.id]["mod-log"] = None
await self.bot.say("Mod log deactivated.")
dataIO.save_json("data/mod/settings.json", self.settings)
def ignore_channel(self, ctx, channel: discord.Channel=None):
"""Ignores channel
Defaults to current one"""
current_ch = ctx.message.channel
if not channel:
if current_ch.id not in self.ignore_list["CHANNELS"]:
self.ignore_list["CHANNELS"].append(current_ch.id)
dataIO.save_json("data/mod/ignorelist.json", self.ignore_list)
await self.bot.say("Channel added to ignore list.")
else:
await self.bot.say("Channel already in ignore list.")
else:
if channel.id not in self.ignore_list["CHANNELS"]:
self.ignore_list["CHANNELS"].append(channel.id)
dataIO.save_json("data/mod/ignorelist.json", self.ignore_list)
await self.bot.say("Channel added to ignore list.")
else:
await self.bot.say("Channel already in ignore list.")
def unignore_channel(self, ctx, channel: discord.Channel=None):
"""Removes channel from ignore list
Defaults to current one"""
current_ch = ctx.message.channel
if not channel:
if current_ch.id in self.ignore_list["CHANNELS"]:
self.ignore_list["CHANNELS"].remove(current_ch.id)
dataIO.save_json("data/mod/ignorelist.json", self.ignore_list)
await self.bot.say("This channel has been removed from the ignore list.")
else:
await self.bot.say("This channel is not in the ignore list.")
else:
if channel.id in self.ignore_list["CHANNELS"]:
self.ignore_list["CHANNELS"].remove(channel.id)
dataIO.save_json("data/mod/ignorelist.json", self.ignore_list)
await self.bot.say("Channel removed from ignore list.")
else:
await self.bot.say("That channel is not in the ignore list.")
def status(self, ctx):
"""Shows the servers settings for welcomer."""
db = fileIO(self.load, "load")
if ctx.message.server.id not in db:
await self.bot.say(":x: **Welcomer has not been configured for this server, use `welcomer channel` first**")
return
server = ctx.message.server
color = ''.join([choice('0123456789ABCDEF') for x in range(6)])
color = int(color, 16)
e = discord.Embed(colour=discord.Colour(value=color), description="\n\a")
role = discord.utils.get(ctx.message.server.roles, id=db[server.id]["botrole"])
e.set_author(name="Settings for " + server.name, icon_url=server.icon_url)
e.add_field(name="Welcomer Channel:", value="#" + self.bot.get_channel(db[server.id]["Channel"]).name if self.bot.get_channel(db[server.id]["Channel"]) else None, inline=True)
e.add_field(name="Join Toggle:", value=db[server.id]["join"], inline=True)
e.add_field(name="Leave Toggle:", value=db[server.id]["leave"], inline=True)
e.add_field(name="Bot Role:", value=role.name if role else None)
e.add_field(name="Bot Role Toggle:", value=db[server.id]["botroletoggle"])
e.add_field(name="Embed", value=db[server.id]["Embed"], inline=True)
e.add_field(name="Leave Message:", value=db[server.id]["leavemessage"], inline=False)
e.add_field(name="Join Message:", value=db[server.id]["joinmessage"], inline=False)
try:
await self.bot.say(embed=e)
except Exception as e:
await self.bot.say(e)
def channel(self, ctx, *, channel : discord.Channel=None):
"""Sets the welcomer channel settings."""
if channel is None:
channel = ctx.message.channel
server = ctx.message.server
db = fileIO(self.load, "load")
if server.id in db:
db[server.id]['Channel'] = channel.id
fileIO(self.load, "save", db)
await self.bot.say("Channel changed.")
return
if not ctx.message.server.me.permissions_in(channel).manage_channels:
await self.bot.say("I dont have the `manage_channels` permission.")
return
if ctx.message.server.me.permissions_in(channel).send_messages:
if not server.id in db:
db[server.id] = settings
db[server.id]['Channel'] = channel.id
invs = await self.bot.invites_from(server)
for i in invs:
db[server.id]["Invites"][i.url] = i.uses
fileIO(self.load, "save", db)
await self.bot.say("Channel set.")
def on_member_remove(self, member):
server = member.server
db = fileIO(self.load, "load")
if not server.id in db:
return
if db[server.id]['leave'] is False:
return
message = db[server.id]['leavemessage']
channel = db[server.id]["Channel"]
if db[server.id]["Embed"]:
color = ''.join([choice('0123456789ABCDEF') for x in range(6)])
color = int(color, 16)
data = discord.Embed(title="Member Left!".format(member.id),
description=message.format(member, server),
colour=discord.Colour(value=color))
data.set_thumbnail(url=member.avatar_url)
await self.bot.send_message(server.get_channel(channel), embed=data)
else:
await self.bot.send_message(server.get_channel(channel), message.format(member, server))