Skip to content
This repository has been archived by the owner on Mar 20, 2024. It is now read-only.

Commit

Permalink
update to release-260819
Browse files Browse the repository at this point in the history
  • Loading branch information
infinitepower18 committed Aug 27, 2019
1 parent 4d60604 commit 4bfb2a6
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 21 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ Just a quick note: ***This is not in any way official***. This is just a guide o

**As this bot is modified from the original version, do not expect any support for it on their official Discord server. They will NOT help you. You may open an issue here if you think it's a Heroku related issue and we can try to help but please try updating the dependencies first using the instructions given near the end of this readme to see if it fixes your problem.**

The original MusicBot (previously known as RhinoBot) is available [here](https://github.com/Just-Some-Bots/MusicBot).
The original MusicBot is available [here](https://github.com/Just-Some-Bots/MusicBot).

This is to host the Discord music bot onto your own free Heroku cloud account.

This branch is based on MusicBot release-120519. Previous releases of the bot can be found in the [releases page](https://github.com/helionmusic/rhinobot_heroku/releases).
This branch is based on MusicBot release-260819. Previous releases of the bot can be found in the [releases page](https://github.com/helionmusic/rhinobot_heroku/releases).

### Instructions to get this up and working:
**Your bot will be shut down by Heroku on the last week of each month. If you're ok with this, you can follow the tutorial below. Otherwise you will need to add a credit card to have enough hours for a whole month (provided you don't have any other applications on your Heroku account)**
Expand Down Expand Up @@ -116,9 +116,9 @@ This bot relies on several components listed in the [requirements.txt](https://g
The important ones are [discord.py](https://github.com/Rapptz/discord.py/releases) and [youtube-dl](https://github.com/ytdl-org/youtube-dl/releases). You would want to check the latest release of these two dependencies and include these latest versions in your requirements.txt in the following format:

```
discord.py[voice]==1.2.2
discord.py[voice]==1.2.3
pip
youtube_dl==2019.06.21
youtube_dl==2019.08.13
colorlog
cffi --only-binary all;
aiohttp ~= 3.5.4
Expand All @@ -127,7 +127,7 @@ chardet
opuslib
pynacl==1.2.1
```
Here's an example format given above. They're using the current versions at the time of this writing (discord.py 1.2.2 and youtube-dl 2019.06.21), simply replace these versions with the latest ones found in the releases section of these two dependencies.
Here's an example format given above. They're using the current versions at the time of this writing (discord.py 1.2.3 and youtube-dl 2019.08.13), simply replace these versions with the latest ones found in the releases section of these two dependencies.

Also, check the [requirements.txt file of discord.py](https://github.com/Rapptz/discord.py/blob/master/requirements.txt) and if they've updated the aiohttp and websockets requirements, copy and paste them into the Heroku MusicBot's requirements.txt file.

Expand Down
2 changes: 1 addition & 1 deletion config/aliases.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"play": ["p"],
"skip": ["s"],
"queue": ["q"]
}
}
5 changes: 5 additions & 0 deletions config/example_options.ini
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ OwnerID = auto
# are familiar with Python code.
DevIDs =

# This option determines if the bot should respond to other any other bots
# put bot ID's here seperated with spaces
# Any id you put here the bot WILL respond to.
BotExceptionIDs =

[Chat]
# Determines the prefix that must be used before commands in the Discord chat.
# e.g if you set this to *, the play command would be triggered using *play.
Expand Down
5 changes: 5 additions & 0 deletions config/options.ini
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ OwnerID = auto
# are familiar with Python code.
DevIDs =

# This option determines if the bot should respond to other any other bots
# put bot ID's here seperated with spaces
# Any id you put here the bot WILL respond to.
BotExceptionIDs =

[Chat]
# Determines the prefix that must be used before commands in the Discord chat.
# e.g if you set this to *, the play command would be triggered using *play.
Expand Down
78 changes: 67 additions & 11 deletions musicbot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
from .constants import VERSION as BOTVERSION
from .constants import DISCORD_MSG_CHAR_LIMIT, AUDIO_CACHE_PATH


load_opus_lib()

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -241,6 +240,9 @@ def check(member):
if excluding_deaf and any([member.deaf, member.self_deaf]):
return False

if member.bot:
return False

return True

return not sum(1 for m in vchannel.members if check(m))
Expand Down Expand Up @@ -1404,8 +1406,15 @@ async def cmd_play(self, message, player, channel, author, permissions, leftover
while True:
try:
info = await self.downloader.extract_info(player.playlist.loop, song_url, download=False, process=False)
info_process = await self.downloader.extract_info(player.playlist.loop, song_url, download=False)
# If there is an exception arise when processing we go on and let extract_info down the line report it
# because info might be a playlist and thing that's broke it might be individual entry
try:
info_process = await self.downloader.extract_info(player.playlist.loop, song_url, download=False)
except:
info_process = None

log.debug(info)

if info_process and info and info_process.get('_type', None) == 'playlist' and 'entries' not in info and not info.get('url', '').startswith('ytsearch'):
use_url = info_process.get('webpage_url', None) or info_process.get('url', None)
if use_url == song_url:
Expand Down Expand Up @@ -2412,24 +2421,37 @@ async def cmd_listids(self, guild, author, leftover_args, cat='all'):
return Response("Sent a message with a list of IDs.", delete_after=20)


async def cmd_perms(self, author, user_mentions, channel, guild, permissions):
async def cmd_perms(self, author, user_mentions, channel, guild, message, permissions, target=None):
"""
Usage:
{command_prefix}perms [@user]
Sends the user a list of their permissions, or the permissions of the user specified.
"""

lines = ['Command permissions in %s\n' % guild.name, '```', '```']

if user_mentions:
user = user_mentions[0]
permissions = self.permissions.for_user(user)

if not user_mentions and not target:
user = author

if not user_mentions and target:
user = guild.get_member_named(target)
if user == None:
try:
user = await self.fetch_user(target)
except discord.NotFound:
return Response("Invalid user ID or server nickname, please double check all typing and try again.", reply=False, delete_after=30)

permissions = self.permissions.for_user(user)

if user == author:
lines = ['Command permissions in %s\n' % guild.name, '```', '```']
else:
lines = ['Command permissions for {} in {}\n'.format(user.name, guild.name), '```', '```']

for perm in permissions.__dict__:
if perm in ['user_list'] or permissions.__dict__[perm] == set():
continue

lines.insert(len(lines) - 1, "%s: %s" % (perm, permissions.__dict__[perm]))

await self.safe_send_message(author, '\n'.join(lines))
Expand Down Expand Up @@ -2644,6 +2666,10 @@ async def on_message(self, message):
log.warning("Ignoring command from myself ({})".format(message.content))
return

if message.author.bot and message.author.id not in self.config.bot_exception_ids:
log.warning("Ignoring command from other bot ({})".format(message.content))
return

if (not isinstance(message.channel, discord.abc.GuildChannel)) and (not isinstance(message.channel, discord.abc.PrivateChannel)):
return

Expand Down Expand Up @@ -2889,7 +2915,16 @@ async def on_voice_state_update(self, member, before, after):
except exceptions.CommandError:
return

if not member == self.user: # if the user is not the bot
def is_active(member):
if not member.voice:
return False

if any([member.voice.deaf, member.voice.self_deaf, member.bot]):
return False

return True

if not member == self.user and is_active(member): # if the user is not inactive
if player.voice_client.channel != before.channel and player.voice_client.channel == after.channel: # if the person joined
if auto_paused and player.is_paused:
log.info(autopause_msg.format(
Expand All @@ -2901,7 +2936,7 @@ async def on_voice_state_update(self, member, before, after):
self.server_specific_data[player.voice_client.guild]['auto_paused'] = False
player.resume()
elif player.voice_client.channel == before.channel and player.voice_client.channel != after.channel:
if len(player.voice_client.channel.members) == 1:
if not any(is_active(m) for m in player.voice_client.channel.members): # channel is empty
if not auto_paused and player.is_playing:
log.info(autopause_msg.format(
state = "Pausing",
Expand All @@ -2911,8 +2946,18 @@ async def on_voice_state_update(self, member, before, after):

self.server_specific_data[player.voice_client.guild]['auto_paused'] = True
player.pause()
elif player.voice_client.channel == before.channel and player.voice_client.channel == after.channel: # if the person undeafen
if auto_paused and player.is_paused:
log.info(autopause_msg.format(
state = "Unpausing",
channel = player.voice_client.channel,
reason = "(member undeafen)"
).strip())

self.server_specific_data[player.voice_client.guild]['auto_paused'] = False
player.resume()
else:
if len(player.voice_client.channel.members) > 0: # channel is not empty
if any(is_active(m) for m in player.voice_client.channel.members): # channel is not empty
if auto_paused and player.is_paused:
log.info(autopause_msg.format(
state = "Unpausing",
Expand All @@ -2923,6 +2968,17 @@ async def on_voice_state_update(self, member, before, after):
self.server_specific_data[player.voice_client.guild]['auto_paused'] = False
player.resume()

else:
if not auto_paused and player.is_playing:
log.info(autopause_msg.format(
state = "Pausing",
channel = player.voice_client.channel,
reason = "(empty channel or member deafened)"
).strip())

self.server_specific_data[player.voice_client.guild]['auto_paused'] = True
player.pause()

async def on_guild_update(self, before:discord.Guild, after:discord.Guild):
if before.region != after.region:
log.warning("Guild \"%s\" changed regions: %s -> %s" % (after.name, before.region, after.region))
Expand Down
9 changes: 9 additions & 0 deletions musicbot/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def __init__(self, config_file):

self.owner_id = config.get('Permissions', 'OwnerID', fallback=ConfigDefaults.owner_id)
self.dev_ids = config.get('Permissions', 'DevIDs', fallback=ConfigDefaults.dev_ids)
self.bot_exception_ids = config.get("Permissions", "BotExceptionIDs", fallback=ConfigDefaults.bot_exception_ids)

self.command_prefix = config.get('Chat', 'CommandPrefix', fallback=ConfigDefaults.command_prefix)
self.bound_channels = config.get('Chat', 'BindToChannels', fallback=ConfigDefaults.bound_channels)
Expand Down Expand Up @@ -169,6 +170,13 @@ def run_checks(self):
preface=self._confpreface
)

if self.bot_exception_ids:
try:
self.bot_exception_ids = set(int(x) for x in self.bot_exception_ids.replace(',', ' ').split())
except:
log.warning("BotExceptionIDs data is invalid, will ignore all bots")
self.bot_exception_ids = set()

if self.bound_channels:
try:
self.bound_channels = set(x for x in self.bound_channels.replace(',', ' ').split() if x)
Expand Down Expand Up @@ -318,6 +326,7 @@ class ConfigDefaults:

token = None
dev_ids = set()
bot_exception_ids = set()

spotify_clientid = None
spotify_clientsecret = None
Expand Down
4 changes: 2 additions & 2 deletions musicbot/constants.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import os.path

MAIN_VERSION = 'release-120519'
MAIN_VERSION = 'release-260819'
SUB_VERSION = ''
VERSION = MAIN_VERSION + SUB_VERSION

AUDIO_CACHE_PATH = os.path.join(os.getcwd(), 'audio_cache')
DISCORD_MSG_CHAR_LIMIT = 2000
DISCORD_MSG_CHAR_LIMIT = 2000
5 changes: 4 additions & 1 deletion musicbot/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ def read(self):
def get_progress(self):
return self.progress * 0.02

def cleanup(self):
self._source.cleanup()


class MusicPlayer(EventEmitter, Serializable):
def __init__(self, bot, voice_client, playlist):
Expand Down Expand Up @@ -223,7 +226,7 @@ def _playback_finished(self, error=None):
break
except PermissionError as e:
if e.winerror == 32: # File is in use
log.error('Can\'t delete file, it is currently in use: {0}').format(filename)
log.error('Can\'t delete file, it is currently in use: {0}'.format(filename))
except FileNotFoundError:
log.debug('Could not find delete {} as it was not found. Skipping.'.format(filename), exc_info=True)
break
Expand Down
2 changes: 1 addition & 1 deletion update.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def update_deps():
print("Attempting to update dependencies...")

try:
subprocess.check_call('"{}" -m pip install -U -r requirements.txt'.format(sys.executable), shell=True)
subprocess.check_call('"{}" -m pip install --no-warn-script-location --user -U -r requirements.txt'.format(sys.executable), shell=True)
except subprocess.CalledProcessError:
raise OSError("Could not update dependencies. You will need to run '\"{0}\" -m pip install -U -r requirements.txt' yourself.".format(sys.executable))

Expand Down

0 comments on commit 4bfb2a6

Please sign in to comment.