mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 03:08:55 -05:00
* More changes
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixed auto play defaulting to playlist
Signed-off-by: Guy <guyreis96@gmail.com>
* Localtrack fix
Signed-off-by: Guy <guyreis96@gmail.com>
* Updated deps .. since for some reason aiosqlite is not being auto installed for everyone
Signed-off-by: Guy <guyreis96@gmail.com>
* Yupo
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixed a crash in [p]now
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixed crash on playlist save
Signed-off-by: Guy <guyreis96@gmail.com>
* Debugging Commit
Signed-off-by: Guy <guyreis96@gmail.com>
* Yet more prints
Signed-off-by: Guy <guyreis96@gmail.com>
* Even more spammy debug
Signed-off-by: Guy <guyreis96@gmail.com>
* Debugging commit + NEw Dispatches
Signed-off-by: Guy <guyreis96@gmail.com>
* Debugging commit + NEw Dispatches
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixed localpath checks
Signed-off-by: Guy <guyreis96@gmail.com>
* more fixes for Localpaths
Signed-off-by: Guy <guyreis96@gmail.com>
* Spelling mistake on method
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixed Crash on event handler
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixed Crash on local search
Signed-off-by: Guy <guyreis96@gmail.com>
* Reduced fuzzy match percentage threshold for local tracks to account for nested folders
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixed a crash on queue end
Signed-off-by: Guy <guyreis96@gmail.com>
* Sigh ... Removed a duplicate dispatch
Signed-off-by: Guy <guyreis96@gmail.com>
* Sigh i removed this before ...
Signed-off-by: Guy <guyreis96@gmail.com>
* Reorder dispatch signatures so all 3 new dispatch have matching signature
Signed-off-by: Guy <guyreis96@gmail.com>
* Formatting
Signed-off-by: Guy <guyreis96@gmail.com>
* Edited Error Event to support localtracks
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix a Crash on track crash :awesome:
Signed-off-by: Guy <guyreis96@gmail.com>
* Yikes soo much spam
Signed-off-by: Guy <guyreis96@gmail.com>
* Remove spam and improve existance check
Signed-off-by: Guy <guyreis96@gmail.com>
* Repeat and Auto-play are mutually exclusive now
Signed-off-by: Guy <guyreis96@gmail.com>
* DEBUGS for Preda
Signed-off-by: Guy <guyreis96@gmail.com>
* Vimeo tracks can be from both these domains "vimeo.com", "beam.pro"
Signed-off-by: Guy <guyreis96@gmail.com>
* I mean Mixer can be from those 2 domains ....
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixed `search sc` command
Signed-off-by: Guy <guyreis96@gmail.com>
* Run everything though lints.
rename localtracks module to dataclasses
Clear lock on errors
Signed-off-by: Draper <guyreis96@gmail.com>
* Try to speed up long playlist loading
Signed-off-by: Draper <guyreis96@gmail.com>
* Im an idiot
Signed-off-by: Draper <guyreis96@gmail.com>
* Im an idiot
Signed-off-by: Draper <guyreis96@gmail.com>
* Added logging for writes
Signed-off-by: Draper <guyreis96@gmail.com>
* Fix crash on cog reload
Signed-off-by: Draper <guyreis96@gmail.com>
* Fix for runtimewarning ?
Signed-off-by: Draper <guyreis96@gmail.com>
* Fix for Local Track cache
Signed-off-by: Draper <guyreis96@gmail.com>
* Remove broken tracks from queue on exception
Theoretically do not auto play if track stop reason is Stopped or cleanup
Signed-off-by: Draper <guyreis96@gmail.com>
* Previous commit was a fluke ... ignore it
Signed-off-by: Draper <guyreis96@gmail.com>
* Change from cleanup to Replaced
Signed-off-by: Draper <guyreis96@gmail.com>
* Fixed AttributeError: 'Track' object has no attribute 'info'.
[p]skip will only work for autoplay is there a track being played.
Fixed Console spam if query saving failed in the background while reloading bot.
Autoplay now respect [p]stop command
Signed-off-by: Guy <guyreis96@gmail.com>
* Black formatting
Fix Issue with auto play working when there is songs in the queue
Stop notifying queue ended if autoplay is on
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixed a crash on track load timeout
Signed-off-by: Guy <guyreis96@gmail.com>
* [p]playlist start will now show the playlist name in embed body
Improved Logic for handling broken tracks when repeat is on.
Signed-off-by: Draper <guyreis96@gmail.com>
* Enqueue tracks as soon as we have the youtube URL ....
This basically changes how spotify urls are handled
Need to test saving spotify playlist
Need to test loading a spotify playlist from file
Need to test enqueuing a spotify playlist
Signed-off-by: Draper <guyreis96@gmail.com>
* Updated a track whrn enqueuing spotify playlist
Signed-off-by: Draper <guyreis96@gmail.com>
* Debug
Signed-off-by: Draper <guyreis96@gmail.com>
* Debug
Signed-off-by: Draper <guyreis96@gmail.com>
* Debug
Signed-off-by: Draper <guyreis96@gmail.com>
* Debug
Signed-off-by: Draper <guyreis96@gmail.com>
* Debug
Signed-off-by: Draper <guyreis96@gmail.com>
* Debug
Signed-off-by: Draper <guyreis96@gmail.com>
* Debug
Signed-off-by: Draper <guyreis96@gmail.com>
* Debug
Signed-off-by: Draper <guyreis96@gmail.com>
* Debug
Signed-off-by: Draper <guyreis96@gmail.com>
* Debug
Signed-off-by: Draper <guyreis96@gmail.com>
* Revert spotify_enqueue changes
Signed-off-by: Draper <guyreis96@gmail.com>
* Revert spotify_enqueue changes
Signed-off-by: Draper <guyreis96@gmail.com>
* Allow to set Lavalink jar version from Environment vars
Signed-off-by: Draper <guyreis96@gmail.com>
* Allow to set Lavalink jar version from Environment vars
Signed-off-by: Draper <guyreis96@gmail.com>
* Fix for a crash on Equalizer, Merge Spotify_enqueue changes and revert manager changes
Signed-off-by: Draper <guyreis96@gmail.com>
* Break playlist enqueue after 10 consecutive failures
Signed-off-by: Draper <guyreis96@gmail.com>
* Auto DC, is not compatible with Auto Play
Signed-off-by: Draper <guyreis96@gmail.com>
* Make notifier aware of guild its being called for
Signed-off-by: Draper <guyreis96@gmail.com>
* Type checking
Signed-off-by: Draper <guyreis96@gmail.com>
* Remove lock from 2 exits that i didn't before
Signed-off-by: Draper <guyreis96@gmail.com>
* Fixed TypeError: spotify_enqueue() got an unexpected keyword argument 'notify'
Signed-off-by: Guy <guyreis96@gmail.com>
* Reorder toggles to alphabetical order
Signed-off-by: Guy <guyreis96@gmail.com>
* Update Query to handle spotify URIs
Signed-off-by: Guy <guyreis96@gmail.com>
* update database
Signed-off-by: Guy <guyreis96@gmail.com>
* Dont say tracks enqued on invalid link
Make autop lay a mod only setting
Signed-off-by: Draper <guyreis96@gmail.com>
* Dont say tracks enqued on invalid spotify link
Signed-off-by: Draper <guyreis96@gmail.com>
* Set default age to 365 days
Signed-off-by: Draper <guyreis96@gmail.com>
* Allow Audio mods to set auto play playlists.
Save playlists songs to cache when migrating
Signed-off-by: Guy <guyreis96@gmail.com>
* Black formatting
Signed-off-by: Guy <guyreis96@gmail.com>
* [p]eq cooldown is not triggered is player check fails (i.e if nothing is currently playing)
Adding and removing reaction is no longer a blocking action
Signed-off-by: Guy <guyreis96@gmail.com>
* changelog for non blocking reaction handles
Signed-off-by: Guy <guyreis96@gmail.com>
* Show auto dc and auto play settings by default
Signed-off-by: Guy <guyreis96@gmail.com>
* lint is being a bitch
Signed-off-by: Guy <guyreis96@gmail.com>
* lint changes
Signed-off-by: Draper <guyreis96@gmail.com>
* stop caching local tracks
Signed-off-by: Draper <guyreis96@gmail.com>
* List of Lavalink.Tracks natively added to Playlist Objects
Signed-off-by: Draper <guyreis96@gmail.com>
* Fix UX changes and should fix autoplay
Signed-off-by: Draper <guyreis96@gmail.com>
* Fixed Skip x number of tracks
Signed-off-by: Draper <guyreis96@gmail.com>
* Lint changes
Signed-off-by: Draper <guyreis96@gmail.com>
* Remvoe dead code
Signed-off-by: Draper <guyreis96@gmail.com>
* Update playlist embed formatting to reflect Preda's suggestions
Signed-off-by: Draper <guyreis96@gmail.com>
* Update change logs
Signed-off-by: Draper <guyreis96@gmail.com>
* Add `async with ctx.typing():` to queue and to local folder
Signed-off-by: Draper <guyreis96@gmail.com>
* Stop queuing now when queue is empty with [p]queue
Signed-off-by: Draper <guyreis96@gmail.com>
* fix ctx.typing()
Signed-off-by: Draper <guyreis96@gmail.com>
* fix ctx.typing()
Signed-off-by: Draper <guyreis96@gmail.com>
* Part 1
Signed-off-by: Draper <guyreis96@gmail.com>
* Dont check local track author and name if title is Unknown
Signed-off-by: Guy <guyreis96@gmail.com>
* Makes auto play more random
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixes local play
Fixed missing format
Signed-off-by: Guy <guyreis96@gmail.com>
* Query.process_input accept lavalink.Track objects
Signed-off-by: Draper <guyreis96@gmail.com>
* docstrings
Signed-off-by: Draper <guyreis96@gmail.com>
* Add TODO for timestamp support
Signed-off-by: Draper <guyreis96@gmail.com>
* Improve autoplay from cache logic (possibly slightly slower but more efficient overall)
Signed-off-by: Draper <guyreis96@gmail.com>
* Add My Lavalink PR as a dependency
Remember to remove this .... The PR will bump it to 0.3.2
Signed-off-by: Draper <guyreis96@gmail.com>
* Add My Lavalink PR as a dependency
Remember to remove this .... The PR will bump it to 0.3.2
Signed-off-by: Draper <guyreis96@gmail.com>
* Add My Lavalink PR as a dependency
Remember to remove this .... The PR will bump it to 0.3.2
Signed-off-by: Draper <guyreis96@gmail.com>
* Compile all regex at runtime
Signed-off-by: Draper <guyreis96@gmail.com>
* Fixes local play
Fixed missing format
Signed-off-by: Guy <guyreis96@gmail.com>
* Revert Dep error
Signed-off-by: Guy <guyreis96@gmail.com>
* black
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixed attribute error
Signed-off-by: Guy <guyreis96@gmail.com>
* add `self.bot.dispatch("audio_disconnect", ctx.guild)` dispatch when the player is disconnected
Signed-off-by: Guy <guyreis96@gmail.com>
* Removed shuffle lock on skip
Signed-off-by: Guy <guyreis96@gmail.com>
* Better logic for auto seek (timestamps)
Signed-off-by: Guy <guyreis96@gmail.com>
* Better logic for auto seek (timestamps)
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixes timestamps on spotify tracks
Signed-off-by: Guy <guyreis96@gmail.com>
* Add ctx typing to playlist enqueue
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix Deps
Signed-off-by: Guy <guyreis96@gmail.com>
* Black formatting + Using new lavalink methods for shuffling
Signed-off-by: Guy <guyreis96@gmail.com>
* remove ctx.typing from playlist start
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixes typerror when enqueuing spotify playlists
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix keyerror
Signed-off-by: Guy <guyreis96@gmail.com>
* black formatting, + embed for [p]audioset cache as I forgot it before
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix Error on playlist upload
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix Text help for bump
Signed-off-by: Guy <guyreis96@gmail.com>
* Allow track bumping while shuffle is on
Signed-off-by: Guy <guyreis96@gmail.com>
* Edit bump embed to be consistent with other embed
Hyperlink tracks and removed dynamic title
Signed-off-by: Guy <guyreis96@gmail.com>
* Black
Signed-off-by: Guy <guyreis96@gmail.com>
* Errors not printing fix?
Signed-off-by: Guy <guyreis96@gmail.com>
* Errors not printing fix?
Signed-off-by: Guy <guyreis96@gmail.com>
* Track enqueued footer now shows correct track position when shuffle is on
Signed-off-by: Guy <guyreis96@gmail.com>
* Update changelogs
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix is_owner check in audioset settings
Signed-off-by: Guy <guyreis96@gmail.com>
* Changelogs
Signed-off-by: Guy <guyreis96@gmail.com>
* Dont store searches with no results in cache, fix malformated playlist to cache upon settings migration
Signed-off-by: Guy <guyreis96@gmail.com>
* _clear_lock_on_error > Needs to be reviewed to see if it has been done correctly
Signed-off-by: Guy <guyreis96@gmail.com>
* _clear_lock_on_error > Needs to be reviewed to see if it has been done correctly
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix Query search so that it works with absolute paths for localtracks
Signed-off-by: Guy <guyreis96@gmail.com>
* Extra error if lavalink is set to external and the query is a localtrack and nothing is found
Signed-off-by: Guy <guyreis96@gmail.com>
* Black
Signed-off-by: Guy <guyreis96@gmail.com>
* More detailed error message
Signed-off-by: Guy <guyreis96@gmail.com>
* [p]seek and [p]skip can be used by user if they are the song requester while DJ mode is enabled, if votes are disabled. , [p]queue shuffle can be used to shuffle the queue manually. and [p]queue clean self can be used to remove all songs you requested from the queue.
Signed-off-by: Guy <guyreis96@gmail.com>
* black
Signed-off-by: Guy <guyreis96@gmail.com>
* All the fixes + a `should_auto_play` dispatch for the tech savy peeps
Signed-off-by: Guy <guyreis96@gmail.com>
* Spellchecker + Pythonic changes
Signed-off-by: Guy <guyreis96@gmail.com>
* NO spam for logs
Signed-off-by: Guy <guyreis96@gmail.com>
* Pass Current voice channel to `red_audio_should_auto_play` dispatch
Signed-off-by: Guy <guyreis96@gmail.com>
* Black
Signed-off-by: Guy <guyreis96@gmail.com>
* playlist upload also updates cache in the background
Signed-off-by: Guy <guyreis96@gmail.com>
* playlist upload also updates cache in the background
Signed-off-by: Guy <guyreis96@gmail.com>
* Add scope to playlist picker
Signed-off-by: Guy <guyreis96@gmail.com>
* Delete Playlist picker message once something is selected
Signed-off-by: Guy <guyreis96@gmail.com>
* OCD Fix
Signed-off-by: Guy <guyreis96@gmail.com>
* Facepalm
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix a Potential crash
Signed-off-by: Guy <guyreis96@gmail.com>
* Update my stupidity
Signed-off-by: Guy <guyreis96@gmail.com>
* Auto Pause + Skip tracks already in playlist upon playlist append + a command to remove duplicated tracks from playlist
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix DJ mode when Role is deleted - Credits go to Neuro Assassin#4779
Fix an issue where auto play MAY not trigger
Signed-off-by: Guy <guyreis96@gmail.com>
* Change log to Neuro Assassin#4779 fix
Signed-off-by: Guy <guyreis96@gmail.com>
* Black
Signed-off-by: Guy <guyreis96@gmail.com>
* Dont auto pause manual pauses
Signed-off-by: Guy <guyreis96@gmail.com>
* Adds `[p]autoplay` that can be run by mods or higher
Signed-off-by: Guy <guyreis96@gmail.com>
* 🤦
Signed-off-by: Guy <guyreis96@gmail.com>
* 2x 🤦
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixed wrong import
Signed-off-by: Guy <guyreis96@gmail.com>
* Added Autoplay notify
Signed-off-by: Guy <guyreis96@gmail.com>
* Added Autoplay notify
Signed-off-by: Guy <guyreis96@gmail.com>
* Black
Signed-off-by: Guy <guyreis96@gmail.com>
* Store Track object as prev song instead of URI
Signed-off-by: Guy <guyreis96@gmail.com>
* Black why do u hate me
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix command name
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix Autoplay notify
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix missing await and TypeError, Thanks Flame
Signed-off-by: Guy <guyreis96@gmail.com>
* Add a list of tracks to show as a menu
Signed-off-by: Guy <guyreis96@gmail.com>
* adds the `[p]genre` command which uses the Spotify and Youtube API
Signed-off-by: Guy <guyreis96@gmail.com>
* Enqueue Playlists from genre command
Signed-off-by: Guy <guyreis96@gmail.com>
* Pretify `[p]genre`
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix a Typo and correct jukebox charge order
Signed-off-by: Guy <guyreis96@gmail.com>
* Add genre command to error handling
Signed-off-by: Guy <guyreis96@gmail.com>
* Type checking
Signed-off-by: Guy <guyreis96@gmail.com>
* Update naming scheme for `[p]genre`
Signed-off-by: Guy <guyreis96@gmail.com>
* Black why do you hate me
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixed `[p]local start`
Playlist picker auto selects if theres just 1 playlist found
`[p]queue cleanself` added
Signed-off-by: Guy <guyreis96@gmail.com>
* *sigh* back compatibility with old localtrack paths
Signed-off-by: Guy <guyreis96@gmail.com>
* *sigh* back compatibility with old localtrack paths, even more
Signed-off-by: Guy <guyreis96@gmail.com>
* *sigh* back compatibility with old localtrack paths Even more
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixes localtracks in playlist info command
Signed-off-by: Guy <guyreis96@gmail.com>
* Debug Local Strings
Signed-off-by: Guy <guyreis96@gmail.com>
* Debug Local Strings
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixes `[p]playlist info` for local tracks + fixed error in `[p]remove`
Signed-off-by: Guy <guyreis96@gmail.com>
* Black
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixes formatting in `[p]playlist info`
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix an issue with User Scope playlists were not being deleted
Signed-off-by: Guy <guyreis96@gmail.com>
* Typechecking
Signed-off-by: Guy <guyreis96@gmail.com>
* Black
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix the logic of `delegate_autoplay`
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix a Crash on Load due to type hinting
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix a Crash on Load due to type hintingBlack + fix order of `red_audio_should_auto_play`
Signed-off-by: Guy <guyreis96@gmail.com>
* Add `red_audio_initialized` dispatch so that ownership of auto play can be maintained after a reload
Signed-off-by: Guy <guyreis96@gmail.com>
* Check if the current owner is loaded before raising an error
Signed-off-by: Guy <guyreis96@gmail.com>
* Fixes the Existence Check in `delegate_autoplay`
Signed-off-by: Guy <guyreis96@gmail.com>
* Turns `own_autoplay` in a property of Audio and improves `delegate_autoplay` Thanks Sinbad!
Signed-off-by: Guy <guyreis96@gmail.com>
* Fix for Localtracks playlists
Signed-off-by: Guy <guyreis96@gmail.com>
* When disconnecting send `Disconnecting...`
Fix Stop after a skip
Fix UX discrepancy on Playlist IDs
Fixed Exception when theres a track error
Signed-off-by: Guy <guyreis96@gmail.com>
* add `on_red_audio_unload` dispatch
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Fix a crash on track start where `player.current` can be none?
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Missing new line
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Allow `--author` for playlist to be used to filter playlist for an specific author.
Plus a few bugfixes for UX
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Rename `remdupe` to `dedupe`
Make global scope always be referenced as Global
add missing backwards quotes around the Playlist ID for 1 string
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Towncrier entries for dep changes
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Remove track index when shuffle is on
Fix Progress bar for livestreams
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Trigger autoplay on `QUEUE_END` event instead of `TRACK_END`
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Can't reproduce Ians bug but here a safeguard agaisnt it just in case
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Fixes 2 Messages that had the wrong formatting
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* standerdize playlist naming scheme
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Fix `[p]autoplay` message when Notify is enabled
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* y u h8 me black
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Fix an issue with `[p]audioset localpath` where the localtracks folder was incorrect
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Pythonic formatting
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Ugh
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Fix a typo
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Silently try to delete messages + fixes error Ian found with `[p]genre`
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* sigh black
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Add humanize_number usage correctly
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Bump RLL to 0.4.0
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Update changelog entries
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Change `bot.db` to new API's added by #2967
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Additional reformatting
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Remove PyCharm noise + Fixes a few Pycharm warnings
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Rework `index` parsing for youtube urls
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Addess Aika's review
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Fix a potential crash, saves guild ID to playlists to avoid an scheme change in the future
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Add handling for Python installs without sqlite3.
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Address Flame's review
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Fix ma stupidity
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Address Aika's latest review.
1. Update docstring for `[p]playlist rename`.
2. Fix punctuation for playlist matching.
3. `[p]playlist update` now respect playlist management perms
4. Playlist management errors now shows playlist name, id and scope where possible
5. Remove duplicated code and dead code.
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
* Pluralize string
Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
346 lines
13 KiB
Python
346 lines
13 KiB
Python
import contextlib
|
|
import sys
|
|
import codecs
|
|
import datetime
|
|
import logging
|
|
import traceback
|
|
import asyncio
|
|
from datetime import timedelta
|
|
|
|
import aiohttp
|
|
import discord
|
|
import pkg_resources
|
|
from colorama import Fore, Style, init
|
|
from pkg_resources import DistributionNotFound
|
|
|
|
from redbot.core.commands import RedHelpFormatter
|
|
from .. import __version__ as red_version, version_info as red_version_info, VersionInfo
|
|
from . import commands
|
|
from .config import get_latest_confs
|
|
from .data_manager import storage_type
|
|
from .utils.chat_formatting import inline, bordered, format_perms_list, humanize_timedelta
|
|
from .utils import fuzzy_command_search, format_fuzzy_results
|
|
|
|
log = logging.getLogger("red")
|
|
init()
|
|
|
|
INTRO = """
|
|
______ _ ______ _ _ ______ _
|
|
| ___ \ | | | _ (_) | | | ___ \ | |
|
|
| |_/ /___ __| | ______ | | | |_ ___ ___ ___ _ __ __| | | |_/ / ___ | |_
|
|
| // _ \/ _` | |______| | | | | / __|/ __/ _ \| '__/ _` | | ___ \/ _ \| __|
|
|
| |\ \ __/ (_| | | |/ /| \__ \ (_| (_) | | | (_| | | |_/ / (_) | |_
|
|
\_| \_\___|\__,_| |___/ |_|___/\___\___/|_| \__,_| \____/ \___/ \__|
|
|
"""
|
|
|
|
|
|
def init_events(bot, cli_flags):
|
|
@bot.event
|
|
async def on_connect():
|
|
if bot._uptime is None:
|
|
print("Connected to Discord. Getting ready...")
|
|
|
|
@bot.event
|
|
async def on_ready():
|
|
if bot._uptime is not None:
|
|
return
|
|
|
|
bot._uptime = datetime.datetime.utcnow()
|
|
packages = []
|
|
|
|
if cli_flags.no_cogs is False:
|
|
packages.extend(await bot._config.packages())
|
|
|
|
if cli_flags.load_cogs:
|
|
packages.extend(cli_flags.load_cogs)
|
|
|
|
if packages:
|
|
# Load permissions first, for security reasons
|
|
try:
|
|
packages.remove("permissions")
|
|
except ValueError:
|
|
pass
|
|
else:
|
|
packages.insert(0, "permissions")
|
|
|
|
to_remove = []
|
|
print("Loading packages...")
|
|
for package in packages:
|
|
try:
|
|
spec = await bot._cog_mgr.find_cog(package)
|
|
await bot.load_extension(spec)
|
|
except Exception as e:
|
|
log.exception("Failed to load package {}".format(package), exc_info=e)
|
|
await bot.remove_loaded_package(package)
|
|
to_remove.append(package)
|
|
for package in to_remove:
|
|
packages.remove(package)
|
|
if packages:
|
|
print("Loaded packages: " + ", ".join(packages))
|
|
|
|
if bot.rpc_enabled:
|
|
await bot.rpc.initialize()
|
|
|
|
guilds = len(bot.guilds)
|
|
users = len(set([m for m in bot.get_all_members()]))
|
|
|
|
try:
|
|
data = await bot.application_info()
|
|
invite_url = discord.utils.oauth_url(data.id)
|
|
except:
|
|
invite_url = "Could not fetch invite url"
|
|
|
|
prefixes = cli_flags.prefix or (await bot._config.prefix())
|
|
lang = await bot._config.locale()
|
|
red_pkg = pkg_resources.get_distribution("Red-DiscordBot")
|
|
dpy_version = discord.__version__
|
|
|
|
INFO = [
|
|
str(bot.user),
|
|
"Prefixes: {}".format(", ".join(prefixes)),
|
|
"Language: {}".format(lang),
|
|
"Red Bot Version: {}".format(red_version),
|
|
"Discord.py Version: {}".format(dpy_version),
|
|
"Shards: {}".format(bot.shard_count),
|
|
]
|
|
|
|
if guilds:
|
|
INFO.extend(("Servers: {}".format(guilds), "Users: {}".format(users)))
|
|
else:
|
|
print("Ready. I'm not in any server yet!")
|
|
|
|
INFO.append("{} cogs with {} commands".format(len(bot.cogs), len(bot.commands)))
|
|
|
|
with contextlib.suppress(aiohttp.ClientError, discord.HTTPException):
|
|
async with aiohttp.ClientSession() as session:
|
|
async with session.get("https://pypi.python.org/pypi/red-discordbot/json") as r:
|
|
data = await r.json()
|
|
if VersionInfo.from_str(data["info"]["version"]) > red_version_info:
|
|
INFO.append(
|
|
"Outdated version! {} is available "
|
|
"but you're using {}".format(data["info"]["version"], red_version)
|
|
)
|
|
|
|
await bot.send_to_owners(
|
|
"Your Red instance is out of date! {} is the current "
|
|
"version, however you are using {}!".format(
|
|
data["info"]["version"], red_version
|
|
)
|
|
)
|
|
INFO2 = []
|
|
|
|
mongo_enabled = storage_type() != "JSON"
|
|
reqs_installed = {"docs": None, "test": None}
|
|
for key in reqs_installed.keys():
|
|
reqs = [x.name for x in red_pkg._dep_map[key]]
|
|
try:
|
|
pkg_resources.require(reqs)
|
|
except DistributionNotFound:
|
|
reqs_installed[key] = False
|
|
else:
|
|
reqs_installed[key] = True
|
|
|
|
options = (
|
|
("MongoDB", mongo_enabled),
|
|
("Voice", True),
|
|
("Docs", reqs_installed["docs"]),
|
|
("Tests", reqs_installed["test"]),
|
|
)
|
|
|
|
on_symbol, off_symbol, ascii_border = _get_startup_screen_specs()
|
|
|
|
for option, enabled in options:
|
|
enabled = on_symbol if enabled else off_symbol
|
|
INFO2.append("{} {}".format(enabled, option))
|
|
|
|
print(Fore.RED + INTRO)
|
|
print(Style.RESET_ALL)
|
|
print(bordered(INFO, INFO2, ascii_border=ascii_border))
|
|
|
|
if invite_url:
|
|
print("\nInvite URL: {}\n".format(invite_url))
|
|
|
|
bot._color = discord.Colour(await bot._config.color())
|
|
|
|
@bot.event
|
|
async def on_command_error(ctx, error, unhandled_by_cog=False):
|
|
|
|
if not unhandled_by_cog:
|
|
if hasattr(ctx.command, "on_error"):
|
|
return
|
|
|
|
if ctx.cog:
|
|
if commands.Cog._get_overridden_method(ctx.cog.cog_command_error) is not None:
|
|
return
|
|
|
|
if isinstance(error, commands.MissingRequiredArgument):
|
|
await ctx.send_help()
|
|
elif isinstance(error, commands.ArgParserFailure):
|
|
msg = f"`{error.user_input}` is not a valid value for `{error.cmd}`"
|
|
if error.custom_help_msg:
|
|
msg += f"\n{error.custom_help_msg}"
|
|
await ctx.send(msg)
|
|
if error.send_cmd_help:
|
|
await ctx.send_help()
|
|
elif isinstance(error, commands.ConversionFailure):
|
|
if error.args:
|
|
await ctx.send(error.args[0])
|
|
else:
|
|
await ctx.send_help()
|
|
elif isinstance(error, commands.UserInputError):
|
|
await ctx.send_help()
|
|
elif isinstance(error, commands.DisabledCommand):
|
|
disabled_message = await bot._config.disabled_command_msg()
|
|
if disabled_message:
|
|
await ctx.send(disabled_message.replace("{command}", ctx.invoked_with))
|
|
elif isinstance(error, commands.CommandInvokeError):
|
|
log.exception(
|
|
"Exception in command '{}'".format(ctx.command.qualified_name),
|
|
exc_info=error.original,
|
|
)
|
|
|
|
message = "Error in command '{}'. Check your console or logs for details.".format(
|
|
ctx.command.qualified_name
|
|
)
|
|
exception_log = "Exception in command '{}'\n" "".format(ctx.command.qualified_name)
|
|
exception_log += "".join(
|
|
traceback.format_exception(type(error), error, error.__traceback__)
|
|
)
|
|
bot._last_exception = exception_log
|
|
await ctx.send(inline(message))
|
|
elif isinstance(error, commands.CommandNotFound):
|
|
fuzzy_commands = await fuzzy_command_search(
|
|
ctx,
|
|
commands={
|
|
c async for c in RedHelpFormatter.help_filter_func(ctx, bot.walk_commands())
|
|
},
|
|
)
|
|
if not fuzzy_commands:
|
|
pass
|
|
elif await ctx.embed_requested():
|
|
await ctx.send(embed=await format_fuzzy_results(ctx, fuzzy_commands, embed=True))
|
|
else:
|
|
await ctx.send(await format_fuzzy_results(ctx, fuzzy_commands, embed=False))
|
|
elif isinstance(error, commands.BotMissingPermissions):
|
|
if bin(error.missing.value).count("1") == 1: # Only one perm missing
|
|
plural = ""
|
|
else:
|
|
plural = "s"
|
|
await ctx.send(
|
|
"I require the {perms} permission{plural} to execute that command.".format(
|
|
perms=format_perms_list(error.missing), plural=plural
|
|
)
|
|
)
|
|
elif isinstance(error, commands.UserFeedbackCheckFailure):
|
|
if error.message:
|
|
await ctx.send(error.message)
|
|
elif isinstance(error, commands.CheckFailure):
|
|
pass
|
|
elif isinstance(error, commands.NoPrivateMessage):
|
|
await ctx.send("That command is not available in DMs.")
|
|
elif isinstance(error, commands.CommandOnCooldown):
|
|
await ctx.send(
|
|
"This command is on cooldown. Try again in {}.".format(
|
|
humanize_timedelta(seconds=error.retry_after) or "1 second"
|
|
),
|
|
delete_after=error.retry_after,
|
|
)
|
|
else:
|
|
log.exception(type(error).__name__, exc_info=error)
|
|
|
|
@bot.event
|
|
async def on_message(message):
|
|
await bot.process_commands(message)
|
|
discord_now = message.created_at
|
|
if (
|
|
not bot._checked_time_accuracy
|
|
or (discord_now - timedelta(minutes=60)) > bot._checked_time_accuracy
|
|
):
|
|
system_now = datetime.datetime.utcnow()
|
|
diff = abs((discord_now - system_now).total_seconds())
|
|
if diff > 60:
|
|
log.warning(
|
|
"Detected significant difference (%d seconds) in system clock to discord's "
|
|
"clock. Any time sensitive code may fail.",
|
|
diff,
|
|
)
|
|
bot._checked_time_accuracy = discord_now
|
|
|
|
@bot.event
|
|
async def on_command_add(command: commands.Command):
|
|
disabled_commands = await bot._config.disabled_commands()
|
|
if command.qualified_name in disabled_commands:
|
|
command.enabled = False
|
|
for guild in bot.guilds:
|
|
disabled_commands = await bot._config.guild(guild).disabled_commands()
|
|
if command.qualified_name in disabled_commands:
|
|
command.disable_in(guild)
|
|
|
|
async def _guild_added(guild: discord.Guild):
|
|
disabled_commands = await bot._config.guild(guild).disabled_commands()
|
|
for command_name in disabled_commands:
|
|
command_obj = bot.get_command(command_name)
|
|
if command_obj is not None:
|
|
command_obj.disable_in(guild)
|
|
|
|
@bot.event
|
|
async def on_guild_join(guild: discord.Guild):
|
|
await _guild_added(guild)
|
|
|
|
@bot.event
|
|
async def on_guild_available(guild: discord.Guild):
|
|
# We need to check guild-disabled commands here since some cogs
|
|
# are loaded prior to `on_ready`.
|
|
await _guild_added(guild)
|
|
|
|
@bot.event
|
|
async def on_guild_leave(guild: discord.Guild):
|
|
# Clean up any unneeded checks
|
|
disabled_commands = await bot._config.guild(guild).disabled_commands()
|
|
for command_name in disabled_commands:
|
|
command_obj = bot.get_command(command_name)
|
|
if command_obj is not None:
|
|
command_obj.enable_in(guild)
|
|
|
|
@bot.event
|
|
async def on_cog_add(cog: commands.Cog):
|
|
confs = get_latest_confs()
|
|
for c in confs:
|
|
uuid = c.unique_identifier
|
|
group_data = c.custom_groups
|
|
await bot._config.custom("CUSTOM_GROUPS", c.cog_name, uuid).set(group_data)
|
|
|
|
|
|
def _get_startup_screen_specs():
|
|
"""Get specs for displaying the startup screen on stdout.
|
|
|
|
This is so we don't get encoding errors when trying to print unicode
|
|
emojis to stdout (particularly with Windows Command Prompt).
|
|
|
|
Returns
|
|
-------
|
|
`tuple`
|
|
Tuple in the form (`str`, `str`, `bool`) containing (in order) the
|
|
on symbol, off symbol and whether or not the border should be pure ascii.
|
|
|
|
"""
|
|
encoder = codecs.getencoder(sys.stdout.encoding)
|
|
check_mark = "\N{SQUARE ROOT}"
|
|
try:
|
|
encoder(check_mark)
|
|
except UnicodeEncodeError:
|
|
on_symbol = "[X]"
|
|
off_symbol = "[ ]"
|
|
else:
|
|
on_symbol = check_mark
|
|
off_symbol = "X"
|
|
|
|
try:
|
|
encoder("┌┐└┘─│") # border symbols
|
|
except UnicodeEncodeError:
|
|
ascii_border = True
|
|
else:
|
|
ascii_border = False
|
|
|
|
return on_symbol, off_symbol, ascii_border
|