Compare commits

...

2177 Commits

Author SHA1 Message Date
github-actions[bot]
2e902b067e Version bump to 3.5.18 (#6545)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-26 20:04:52 +01:00
Jakub Kuczys
61695daded Red 3.5.18 - Changelog (#6544) 2025-03-26 20:00:45 +01:00
Jakub Kuczys
10889642ce Bump dependencies (#6543) 2025-03-26 18:53:40 +00:00
Kreusada
a3b254fe8e [Audio] Bump YT source plugin version (#6542) 2025-03-26 19:52:00 +01:00
github-actions[bot]
71554c981d Version bump to 3.5.18.dev1 (#6535)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-08 20:45:09 +00:00
github-actions[bot]
e1225029b0 Version bump to 3.5.17 (#6533)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-08 21:37:30 +01:00
github-actions[bot]
85923d4c0f Automated Crowdin downstream (#6534)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-08 21:36:48 +01:00
Jakub Kuczys
19b34c63b2 Red 3.5.17 - Changelog (#6532)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2025-03-08 21:24:16 +01:00
Kowlin
60e819159f Bump d.py and Jinja2 (#6531) 2025-03-08 20:44:22 +01:00
Jakub Kuczys
0f4c7b0fe6 Bump deps (including d.py 2.5 bump) (#6529)
Co-authored-by: Kowlin <10947836+Kowlin@users.noreply.github.com>
2025-03-04 23:38:37 +01:00
aikaterna
3bf7c64d01 [Audio] Bump YT plugin version (#6530) 2025-03-04 22:57:52 +01:00
Karlo Prikratki
4558b72082 Fix YouTube upcoming stream's embed not being timezone-agnostic (#6527) 2025-02-15 23:33:15 +01:00
github-actions[bot]
73958d87f1 Version bump to 3.5.17.dev1 (#6522)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-06 02:44:41 +01:00
github-actions[bot]
d6054412f4 Version bump to 3.5.16 (#6520)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-06 02:36:23 +01:00
github-actions[bot]
5cf69bdc51 Automated Crowdin downstream (#6521)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-06 02:35:50 +01:00
Jakub Kuczys
2fd6ea88d9 Red 3.5.16 - Changelog (#6519) 2025-02-06 02:31:40 +01:00
Jakub Kuczys
50ad59a6c8 Catch TypeError when setting global locale (#6518) 2025-02-06 02:31:03 +01:00
Jakub Kuczys
dfc1e742f8 Handle invalid locale configuration graciously during startup (#6517) 2025-02-05 19:42:42 -05:00
github-actions[bot]
769c319ffd Version bump to 3.5.16.dev1 (#6516)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-03 02:13:08 +00:00
github-actions[bot]
3c1f2cddfd Version bump to 3.5.15 (#6514)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-03 02:43:09 +01:00
github-actions[bot]
1299db0f3a Automated Crowdin downstream (#6515)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-02-03 01:41:27 +00:00
Jakub Kuczys
c58d208ca2 Red 3.5.15 - Changelog (#6513) 2025-02-03 02:38:31 +01:00
Jakub Kuczys
c308ea0184 Bump dependencies and drop openSUSE Leap 15.5 (#6512) 2025-02-03 02:35:02 +01:00
Kowlin
8e0948d560 Truncate service names in [p]set api modal (#6502) 2025-02-01 18:36:37 -05:00
aikaterna
952a372652 [Audio] Bump YT plugin version (#6511) 2025-02-01 23:56:01 +01:00
Jakub Kuczys
a0c1713e78 Split public and private i18n APIs (#6022) 2025-01-26 19:33:06 -05:00
Jakub Kuczys
8b1daf1ad0 Move private things in modlog and redbot.core.errors (#6020) 2025-01-26 18:49:03 -05:00
Jakub Kuczys
dcdef9d798 Use build.jobs.install to avoid installing unnecessary deps (#6508) 2025-01-27 00:28:07 +01:00
Jakub Kuczys
f962aeb7b8 Split public and private config/driver APIs (#6024) 2025-01-26 18:25:53 -05:00
Jakub Kuczys
b13b1f8f16 Add explicit Sphinx config to .readthedocs.yml (#6507) 2025-01-27 00:10:10 +01:00
Jakub Kuczys
6bf2a88995 Single-source supported Java versions in Audio code (#6500) 2025-01-26 14:03:20 -08:00
Kowlin
22888f8014 Bump actions to V4 (#6504) 2025-01-07 20:41:17 +00:00
Jakub Kuczys
ba44370020 Add subnet masks in CIDR notation as answers to computers trivia (#6495) 2025-01-07 21:31:27 +01:00
Jakub Kuczys
cd0e8750c1 Allow usage of [p]audioset logs in DMs (#6499) 2024-12-28 16:48:24 -08:00
github-actions[bot]
679289fd1c Version bump to 3.5.15.dev1 (#6498)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-12-25 04:34:06 +00:00
github-actions[bot]
ce6489325e Version bump to 3.5.14 (#6496)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-12-25 05:25:15 +01:00
github-actions[bot]
d64cbdf83e Automated Crowdin downstream (#6497)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-12-25 04:24:55 +00:00
Jakub Kuczys
66d1c87b5a Red 3.5.14 - Changelog (#6493) 2024-12-25 05:20:47 +01:00
Jakub Kuczys
3888f09cfa Fix safety of `[p]repo list` (#6494) 2024-12-24 23:09:00 -05:00
Jakub Kuczys
8ad9c55d50 Bump dependencies and update OS matrix (#6492) 2024-12-24 19:54:56 +01:00
Glas
3aac07a4d7 Explain how to remove URL restrictions in the play error message (#6348)
Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-12-24 15:22:02 +01:00
Kowlin
bd26e7d5af Fix permissions fetching for User Installable Bots (#6457)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-12-24 14:16:03 +00:00
Karlo Prikratki
9392077434 Allow passing multiple cogs to slash enablecog and slash disablecog (#6001)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2024-12-23 22:49:19 -05:00
Chovin
1f48919005 Add a separate timeout for Lavalink download (#6461)
Co-authored-by: chovin <chovin@users.noreply.github.com>
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-12-24 04:08:49 +01:00
TrustyJAID
fdaa869130 [Help command] Utilize copy to clipboard (#6244)
Co-authored-by: Kreusada Ignad Amredes <67752638+Kreusada@users.noreply.github.com>
2024-12-24 03:23:26 +01:00
Michael Oliveira
18614b1604 Respect [p]bypasscooldowns in [p]slash sync (#6465) 2024-12-24 03:04:11 +01:00
Michael Oliveira
016684bcce Add methods for getting app command IDs/mentions from cache (#6278)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-12-24 03:02:16 +01:00
Kowlin
5cfb8edab8 ANSI formatting support (#5538)
Co-authored-by: Kowlin <Kowlin@users.noreply.github.com>
Co-authored-by: Vexed <vex@vexcodes.com>
Co-authored-by: Jack Tealey <67752638+Kreusada@users.noreply.github.com>
2024-12-24 01:20:42 +00:00
cdaman3141
150692538f Fixed [p]ban raising an unhandled error if an ID too large is provided (#6486)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-12-24 01:12:33 +00:00
TrustyJAID
f4ffc6bc80 Add support for SimpleMenu to use custom select options (#6480)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-12-24 02:00:41 +01:00
Kevin Wang
9419f2642a Allow enforcing reason to be filled in Mod cog commands (#6477)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-12-24 01:58:57 +01:00
Jakub Kuczys
f0a29e9815 Support [botname] substitutions in cog install messages too (#6491) 2024-12-23 19:18:36 -05:00
aikaterna
d29ae723c1 Bump YT plugin version (#6490) 2024-12-22 23:15:43 +01:00
Jakub Kuczys
9920628948 Bump YT plugin version and update LL server config (#6488) 2024-12-17 21:28:05 -08:00
Ascensionn
48b2fe77c0 [p]warn ask to ban when user not in server (#6481)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2024-12-08 13:42:22 -05:00
palmtree5
33e0eac741 Remove deprecated options from .pylintrc (#6462)
Co-authored-by: Kreusada <67752638+Kreusada@users.noreply.github.com>
2024-11-17 17:01:31 +00:00
Kyla
2871992772 Define view once inside menus.menu for button menus (#6472) 2024-11-17 16:24:30 +00:00
Seaswimmer
30058c0f73 Add links to the output of [p]repo list (#6284)
Co-authored-by: Seaswimmer <102361830+SeaswimmerTheFsh@users.noreply.github.com>
Co-authored-by: Kreusada <67752638+Kreusada@users.noreply.github.com>
2024-10-29 18:10:02 +00:00
Jakub Kuczys
4134881fae Optimize Trivia list loading (#6336)
Co-authored-by: Kreusada <67752638+Kreusada@users.noreply.github.com>
2024-10-29 17:58:28 +00:00
Lemon Rose
4396323205 [Trivia] Add non-punctuated alias (#5889)
Co-authored-by: Kreusada <67752638+Kreusada@users.noreply.github.com>
2024-10-29 17:46:58 +00:00
sravan
4e27059209 [Core] Add error handling when [p]load tries to load "locales" (#6466) 2024-10-20 16:20:29 -04:00
Jakub Kuczys
d3887b595f Fix release helper subcommands (#6451) 2024-09-15 02:49:04 +02:00
Jakub Kuczys
005b8af10a Update docs vars to work with RTD changes (#6410) 2024-09-11 05:32:36 +02:00
Kreusada Ignar Yadrak
d304da7a16 [Downloader] Support [botname] substitutions in cog install messages (#6443) 2024-09-11 05:32:18 +02:00
Kreusada
f3c89ad8bd Fix header utility docstring (#6444) 2024-09-02 00:51:14 +02:00
Kreusada
05cf9b7f39 Add header, hyperlink and subtext utilities (#6102)
Co-authored-by: Kowlin <10947836+Kowlin@users.noreply.github.com>
2024-09-01 21:40:12 +00:00
Jakub Kuczys
907a3f7561 Split out non-Python assets in Publish Release workflow (#6440) 2024-08-28 15:47:35 +02:00
Mellow
2595c9de10 [Trivia] Correct typos in World Cup trivia list for Golden Glove questions (#6441) 2024-08-27 18:02:53 +01:00
Jakub Kuczys
8be7b0850c Version bump to 3.5.14.dev1 2024-08-27 02:12:58 +02:00
Jakub Kuczys
61ec913789 Change Red 3.5.13 release date 2024-08-27 02:00:28 +02:00
Jakub Kuczys
88b11f2b9c Add missing perm to Publish Release workflow 2024-08-27 02:00:13 +02:00
Jakub Kuczys
9ca0ced2d8 Fix publish release workflow 2024-08-27 01:54:47 +02:00
github-actions[bot]
a5a178bfaf Version bump to 3.5.13 (#6438)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-27 01:22:52 +02:00
github-actions[bot]
eeb90aaa45 Automated Crowdin downstream (#6439)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-26 23:21:43 +00:00
Jakub Kuczys
b7a59b5e4c Red 3.5.13 - Changelog (#6437) 2024-08-27 01:12:13 +02:00
Jakub Kuczys
2769ea025f Bump dependencies (#6436) 2024-08-26 18:08:50 -04:00
aikaterna
818420a641 [Audio] Fix trying to send notify message with no channel object (#6429) 2024-08-26 19:53:30 +02:00
aikaterna
3c49a77e34 [Audio] Update Lavalink.jar and yt source build numbers (#6435)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-08-26 19:51:59 +02:00
Jakub Kuczys
90691ba2b9 Generate default LL server config and attach it to GH release (#6430) 2024-08-26 19:34:37 +02:00
Guyonsteroids
68f2806204 [Trivia] Correct Stephen to Steven (#6434)
Co-authored-by: Artemis6969 <82315185+Artemis6969@users.noreply.github.com>
2024-08-24 23:33:20 +02:00
github-actions[bot]
903992f48a Version bump to 3.5.13.dev1 (#6428)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-08 04:25:02 +02:00
github-actions[bot]
e4b75f5333 Version bump to 3.5.12 (#6426)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-08 04:11:33 +02:00
github-actions[bot]
254d5a91d6 Automated Crowdin downstream (#6427)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-08 02:11:20 +00:00
Jakub Kuczys
b979a7c4d1 Red 3.5.12 - Changelog (#6425) 2024-08-07 19:08:08 -07:00
aikaterna
54a29174ea [Audio] Update yt source version (#6424) 2024-08-07 22:38:46 +02:00
aikaterna
5bbced5b0d [Audio] Fix llset secured (#6423) 2024-08-07 22:36:27 +02:00
github-actions[bot]
5b21c89505 Version bump to 3.5.12.dev1 (#6421)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-04 22:07:27 +00:00
github-actions[bot]
04d856cfb0 Version bump to 3.5.11 (#6419)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-08-04 23:54:31 +02:00
github-actions[bot]
701339f8a1 Automated Crowdin downstream (#6420)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-04 23:51:49 +02:00
Jakub Kuczys
3d04d696c1 Red 3.5.11 - Changelog (#6418) 2024-08-04 23:47:44 +02:00
Jakub Kuczys
0b8bcef86c Bump dependencies (#6417) 2024-08-04 23:37:47 +02:00
Kowlin
2d47d75919 Fix unmuting when a mod isn't a mod anymore. (#6411)
Co-authored-by: TrustyJAID <TrustyJAID@gmail.com>
2024-08-04 23:01:34 +02:00
Jakub Kuczys
7eb26da647 Bump YT source plugin version to 1.5.1 and add custom plugin config (#6415) 2024-08-04 12:33:59 -07:00
Kowlin
699471f27a Forcefully shutdown RPC to prevent hangs (#6412) 2024-08-04 21:28:17 +02:00
Jakub Kuczys
2c2080df12 Set ProcessType in macOS auto-restart service to 'interactive' (#6416) 2024-08-04 12:19:28 -07:00
anopem
fa7236af63 Get viewer count from stream data instead of user profile data (#6413) 2024-07-21 13:08:22 -08:00
Ryan
601816abc0 Allow SimpleMenu to delete ephemeral responses (#6304) 2024-07-18 23:35:52 +02:00
Lemon Rose
bf8c0d03b5 [RedTree] add UserFeedbackCheckFailure for app_commands (#6397)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-07-12 13:30:22 -04:00
Jakub Kuczys
2e40ec4a1a Use PEP 508's req @ url syntax instead of deprecated egg fragments (#6408) 2024-07-12 18:08:43 +02:00
github-actions[bot]
9b9fdf555b Version bump to 3.5.11.dev1 (#6406)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-07-11 01:20:16 +02:00
Jakub Kuczys
7dee8d7963 Last-minute changelog fixes 2024-07-11 01:11:18 +02:00
github-actions[bot]
0281d6c93e Version bump to 3.5.10 (#6404)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-07-11 01:03:12 +02:00
github-actions[bot]
f4c8077268 Automated Crowdin downstream (#6405)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-07-11 01:02:52 +02:00
Jakub Kuczys
7b8acd7ef6 Red 3.5.10 - Changelog (#6403) 2024-07-11 00:42:52 +02:00
Jakub Kuczys
6ee976c341 Bump dependencies (#6402) 2024-07-10 17:47:46 -04:00
Michael Oliveira
0b0b23b971 Fix @commands.can_manage_channel always passing (#6398) 2024-07-10 20:41:24 +02:00
Jakub Kuczys
2b1e603124 Bump d.py version to 2.4.0 (#6401)
Co-authored-by: Ryan <yamikaitou@gmail.com>
2024-07-10 20:36:47 +02:00
Jakub Kuczys
dd61b669b0 Use YouTube source plugin over the deprecated built-in source (#6373)
Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
2024-07-10 07:13:23 -07:00
Michael Oliveira
57b76bc0d7 Fix info.json keys in approved CC guide (#6382) 2024-07-10 14:53:40 +02:00
Seaswimmer
573e5c2b40 Docs: remove Atom from the list of recommended editors (#6388) 2024-07-10 14:45:36 +02:00
Jakub Kuczys
ad1e1aa2ba OS support spring cleaning spree (#6386) 2024-06-30 21:11:02 +02:00
TrustyJAID
4242a7adf2 Fix an issue with autocomplete in ignored channels/servers (#6375) 2024-05-06 19:53:37 -04:00
Jakub Kuczys
e03f97d1cd Update macOS instructions to use default cask (#6368) 2024-05-04 14:18:31 -07:00
Jakub Kuczys
975c0007fe Add Ubuntu 24.04 instructions + support for Fedora 40 (#6364) 2024-04-29 01:22:56 -04:00
github-actions[bot]
bef3aa5f69 Version bump to 3.5.10.dev1 (#6363)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-21 02:12:28 +00:00
github-actions[bot]
cbf8247e6e Version bump to 3.5.9 (#6361)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-21 04:04:51 +02:00
github-actions[bot]
23c86d7850 Automated Crowdin downstream (#6362)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-21 04:04:35 +02:00
Jakub Kuczys
aa21091b84 Red 3.5.9 - Changelog (#6359) 2024-04-21 03:58:37 +02:00
Jakub Kuczys
72ec88aa3c Fix humanize_timedelta() docstring to account for negative values (#6360) 2024-04-20 21:55:33 -04:00
aikaterna
b1f331e51f [Audio] Update Lavalink.jar build (#6358) 2024-04-21 03:04:51 +02:00
TrustyJAID
0c9c210dbb Prevent OverflowError from very large timedeltas in Mutes (#6353) 2024-04-21 03:01:28 +02:00
Jakub Kuczys
47d4675f52 Fix error message edge case in parse_timedelta (#6357) 2024-04-21 00:27:40 +02:00
aikaterna
80d0bab29a Update Lavalink repo links to new lavalink-devs org owner (#6356) 2024-04-21 00:12:02 +02:00
Jakub Kuczys
e61327a65c Fix potential API compatibility issue in parse_timedelta() (#6355) 2024-04-20 23:42:20 +02:00
Zephyrkul
11ebd40dfa Fix TimedeltaConverter allowing negative values by default (#6354)
Co-authored-by: zephyrkul <zephyrkul@users.noreply.github.com>
2024-04-20 23:17:38 +02:00
Zephyrkul
00e41d38f9 Improve timedelta conversions (#6349)
Co-authored-by: zephyrkul <zephyrkul@users.noreply.github.com>
2024-04-14 12:58:00 -06:00
Zephyrkul
afb4f6079a humanize_timedelta improvements (#6350)
Co-authored-by: TrustyJAID <TrustyJAID@gmail.com>
Co-authored-by: zephyrkul <zephyrkul@users.noreply.github.com>
2024-04-14 12:56:42 -06:00
Louis Dominic
97b467939c Increase default timeout for ctx.send_interactive to 60 (#6352) 2024-04-11 21:18:40 -08:00
TrustyJAID
f54499eaba Increase default timeout for send_interactive to 60 (#6346) 2024-04-04 20:21:05 +02:00
gip
f8d6bbb0af Added discord timestamps (#6264)
Co-authored-by: palmtree5 <3577255+palmtree5@users.noreply.github.com>
2024-04-03 23:32:15 -08:00
github-actions[bot]
24afd61a85 Version bump to 3.5.9.dev1 (#6345)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-01 02:18:15 +00:00
github-actions[bot]
8e118733ea Version bump to 3.5.8 (#6343)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-01 04:05:22 +02:00
github-actions[bot]
f01c0ec675 Automated Crowdin downstream (#6344)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-01 02:04:48 +00:00
Jakub Kuczys
94d12cb45f Red 3.5.8 - Changelog (#6338) 2024-04-01 04:01:25 +02:00
Jakub Kuczys
e9ed52cf16 Fix placement of empty Trivia list check (#6335) 2024-03-31 21:11:00 -04:00
Jakub Kuczys
194dea545d Update Mutes docs with timeout changes (#6341) 2024-04-01 03:00:53 +02:00
aikaterna
59400204e8 [Trivia] Fix descriptions on Star Wars and Star Trek (#6342) 2024-04-01 02:45:34 +02:00
aikaterna
1c863c7b3b [Audio] Update Lavalink.jar build (#6340) 2024-04-01 02:11:11 +02:00
TrustyJAID
ad9e00d1d9 Menuify [p]activemutes command (#6266) 2024-04-01 02:06:38 +02:00
TrustyJAID
463f0c5e6d Add support for timeouts to Mutes cog (#5604)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2024-04-01 02:05:37 +02:00
Jakub Kuczys
e71312ede0 Update LL version stringification and make parsing stricter (#6334) 2024-03-31 14:26:36 -07:00
Kreusada
48d74712bc Implement [p]trivia info and add DESCRIPTION to trivia schema (#5897)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-03-31 03:11:17 +02:00
Jakub Kuczys
c3a493a500 Bump dependencies (#6333) 2024-03-30 17:56:11 -04:00
Jakub Kuczys
4034ddd452 Add Amazon Linux 2023 install guide (#6331) 2024-03-30 17:20:07 -04:00
Jakub Kuczys
2ae1eb9ec9 Ask for confirmation when path passed to addpath seems incorrect (#6330) 2024-03-27 00:57:47 -04:00
github-actions[bot]
0b390fe2f6 Version bump to 3.5.8.dev1 (#6328)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-03-24 01:07:22 +01:00
github-actions[bot]
b2e7458353 Version bump to 3.5.7 (#6326)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-03-24 00:33:29 +01:00
github-actions[bot]
6adb7e6de7 Automated Crowdin downstream (#6327)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-03-23 23:31:24 +00:00
Jakub Kuczys
1756593785 Red 3.5.7 - Changelog (#6325) 2024-03-23 19:27:42 -04:00
Karlo Prikratki
c3b96b7a9e Update image formats listed as supported by set bot avatar (#6323)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-03-24 00:21:30 +01:00
Jakub Kuczys
a26b9d6d3a Fix behavior of the menu() function calls without user param (#6324) 2024-03-23 16:16:44 -07:00
Jakub Kuczys
76c2c75f2c Fix release helper not considering workflow status (#6320) 2024-03-24 00:14:31 +01:00
github-actions[bot]
afabc4769d Version bump to 3.5.7.dev1 (#6319)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-03-22 01:06:06 +00:00
github-actions[bot]
b5e6231408 Version bump to 3.5.6 (#6317)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-03-22 01:58:11 +01:00
github-actions[bot]
de1141af98 Automated Crowdin downstream (#6318)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-03-22 01:56:41 +01:00
Jakub Kuczys
24cc3115fe Fix missing Crowdin CLI bump for Prepare Release workflow (#6316) 2024-03-22 01:42:49 +01:00
Jakub Kuczys
a3e371e0ab Red 3.5.6 - Changelog (#6314)
Co-authored-by: palmtree5 <3577255+palmtree5@users.noreply.github.com>
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2024-03-21 20:36:35 -04:00
Jakub Kuczys
bc76d53cd5 Update Crowdin CLI to v3 (#6313) 2024-03-21 23:14:46 +01:00
Jakub Kuczys
273ad147c8 Bump dependencies (#6312) 2024-03-21 19:28:21 +01:00
aikaterna
3a81e8327f [Audio] Update Lavalink.jar build (#6305) 2024-03-18 01:38:00 +01:00
Auguste Charpentier
8c2976504a Add user param to menu() (#4913)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-03-18 01:35:53 +01:00
Michael Oliveira
4c7a691ec9 Add note to refresh client after syncing slash commands (#6298) 2024-03-18 01:29:17 +01:00
Michael Oliveira
f5011a90e1 Fix editrole color (#6270) 2024-03-18 01:17:12 +01:00
Jakub Kuczys
0c83fcd495 Add explicit mention of word 'provisional' for version guarantee exclusions (#6311) 2024-03-17 20:15:17 -04:00
Jakub Kuczys
293d8065ec Remove traceback suppression from buttonized menu() (#6310) 2024-03-17 18:53:06 -04:00
Jakub Kuczys
a30f9ff7e6 Update install guides with new OS support matrix (#6309) 2024-03-17 18:13:43 -04:00
Blizzard the Wolf
edfb9ffe62 Update ModLog to include info about [p]modlogset (#6300) 2024-03-05 19:45:22 +00:00
Glas
f5f684bad5 [General] Update lmgtfy to our own fork of NatoBoram/lmgtfy (#6269) 2024-03-03 16:56:48 -05:00
Lemon Rose
9dc7462d0f Prohibit zero-length prefixes in [p]set [server]prefix (#6013)
Co-authored-by: Kreusada Ignad Amredes <67752638+Kreusada@users.noreply.github.com>
2024-02-27 15:18:33 +00:00
Jakub Kuczys
9345b691b3 Ask for confirmation before setting prefix on first-time setup (#6287)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2024-02-26 18:15:07 -05:00
Kreusada Ignad Amredes
185b607544 Fix markdown formatting in [p]streamalert list (#6292) 2024-02-26 18:09:36 -05:00
Michael Oliveira
ff09713aad Fix edge case where perm names are not validated in custom Red decos (#6291) 2024-02-11 10:42:25 +01:00
Dav
dbd71db6a8 [Help] Send menus to dm if maxpages is 0 (#5375)
Co-authored-by: Dav <dav@mail.stopdavabuse.de>
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2024-01-19 15:06:14 -05:00
yeetbruises
409ece427f Add a start_dm option to SimpleMenu (#6286)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-01-14 22:17:19 -05:00
goettner
569840e9e6 [Alias] Aliased commands retain newlines (#4656)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2024-01-08 19:34:48 -05:00
Michael Oliveira
a393a10ceb Fix spelling mistake in [p]slash sync error (#6285) 2024-01-08 01:31:35 +01:00
aikaterna
531b4fe357 Humanize number fix (#6283)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2024-01-03 19:13:26 -05:00
Kreusada Ramicario
47a267b38b [Help] Allow prefix formatting in taglines (#4972)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2024-01-01 23:25:02 -05:00
Michael Oliveira
d322d91a18 [Audio] Fix attachment suffix reading on playlist upload w/ urllib (#6280) 2023-12-29 13:11:27 -08:00
Zephyrkul
76abb7cab2 [modlog] Use new audit log event (#5970)
Co-authored-by: zephyrkul <zephyrkul@users.noreply.github.com>
2023-12-26 17:06:48 -05:00
Jan
ecccea6781 Detect git authentication failure (#5420)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2023-12-23 19:23:39 -05:00
michael-is-qcde
da8cabaf50 [Trivia] Add Doom trivia (#4803)
Co-authored-by: msaeo <no email available>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-12-23 19:01:30 -05:00
Kreusada Ramicario
3fd0afd87d Update FIFA World Cup trivia list with changes from 2022 tournament (#5931) 2023-11-12 16:23:24 -05:00
Jakub Kuczys
fef3fc19ca Fix AUTHOR field in startrek trivia (#6267) 2023-11-06 23:23:48 +01:00
Jakub Kuczys
8997bf6002 Prefer force_registration=true in Config documentation (#6259)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2023-11-06 17:06:36 -05:00
Jacob Bowen
eb3267e332 Add startrek Trivia list (#2946)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
Co-authored-by: Kowlin <10947836+Kowlin@users.noreply.github.com>
Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
2023-11-06 21:49:41 +00:00
Jakub Kuczys
ca84cc9c2a Fix broken "Edit on GitHub" URLs in docs (#6258) 2023-11-06 16:00:36 -05:00
Lydia
6c4a5e5407 [General] Update LMGTFY link (#6255) 2023-11-06 15:57:55 -05:00
github-actions[bot]
7dfe24397e Version bump to 3.5.6.dev1 (#6252)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-09-14 20:51:50 +00:00
Jakub Kuczys
63359ce831 Fix changelog date 2023-09-14 22:43:25 +02:00
github-actions[bot]
6b81d80588 Version bump to 3.5.5 (#6250)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-09-14 22:02:52 +02:00
github-actions[bot]
97377a9f8d Automated Crowdin downstream (#6251)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-09-14 20:02:01 +00:00
Jakub Kuczys
56377b0596 Red 3.5.5 - Changelog (#6249)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2023-09-14 21:50:17 +02:00
Jakub Kuczys
4d4cb14725 Bump dependencies (#6248) 2023-09-14 21:36:34 +02:00
Jakub Kuczys
1132498f6c Fix [p]diagnoseissues edge case for commands without a cog (#6237) 2023-09-13 22:04:21 -04:00
Kreusada
5069f464cc Sort cogs alphabetically inside [p]cog list (#6215) 2023-09-14 01:35:59 +02:00
Jakub Kuczys
2157ed4f9b Fix formatting of nested result lists in [p]diagnoseissues (#6238)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2023-09-13 20:24:50 +00:00
MAX
ef098c8d02 fix the discord format in ban, kick and tempban (#6245)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2023-09-13 20:22:22 +00:00
Karlo Prikratki
64deccff5f [Streams] Switch to Twitch's newer follower endpoint (#6247) 2023-09-06 10:41:35 -08:00
Jakub Kuczys
d844c6f1f8 Bump Python versions in pyenv instructions (#6241) 2023-08-27 23:31:21 +02:00
Jakub Kuczys
9ef4271afa Use more restrictive tag pattern in publish release workflow (#6242) 2023-08-26 21:02:49 +02:00
github-actions[bot]
bb2e3687fc Version bump to 3.5.5.dev1 (#6235)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-08-12 16:38:51 +02:00
github-actions[bot]
979a6aa9eb Version bump to 3.5.4 (#6233)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-08-12 16:26:04 +02:00
github-actions[bot]
0747b92653 Automated Crowdin downstream (#6234)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-08-12 14:25:40 +00:00
Jakub Kuczys
47cc879b80 Red 3.5.4 - Changelog (#6232) 2023-08-12 16:19:24 +02:00
Auguste Charpentier
b6471797cc Remove type-breaking annotation on cog_i18n decorator (#6231)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-08-12 14:13:24 +00:00
Jakub Kuczys
742339a990 Bump dependencies (#6225) 2023-08-12 16:11:03 +02:00
aikaterna
e8c89d4d08 [Audio] Update Lavalink.jar build (#6221) 2023-08-12 04:50:43 +02:00
ADudeCalledLeo
483682dfb5 Fix Picarto channel avatar in Streams cog (#6230) 2023-08-12 04:50:10 +02:00
Jakub Kuczys
100de11ce6 Fix http errors for interaction deferring and message changes (#6229) 2023-08-11 02:51:36 +02:00
Jakub Kuczys
dbb91dfce8 Fix poor fuzzy results due to changes in rapidfuzz 3.0 (#6224)
Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
2023-08-09 22:03:21 -07:00
Jakub Kuczys
3ac2512c14 Fix local search's issue with bad escapes causing non-local playback (#6223) 2023-08-09 20:50:44 -07:00
Predä
a06a704365 Make use of dpy commands.Range on set status commands (#6227) 2023-08-10 03:15:41 +02:00
Predä
9e23c3a5b8 Add custom status support (#6226)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-08-10 02:45:24 +02:00
Jakub Kuczys
1248927fb6 Update supported versions in the security policy (#6222) 2023-08-06 19:29:51 +02:00
github-actions[bot]
93b51acf31 Version bump to 3.5.4.dev1 (#6213)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-07-24 21:40:32 +02:00
github-actions[bot]
7e03756f06 Version bump to 3.5.3 (#6211)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-07-24 20:16:02 +02:00
github-actions[bot]
d04cc36bc6 Automated Crowdin downstream (#6212)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-07-24 20:15:23 +02:00
Jakub Kuczys
6fbcdfc74a Red 3.5.3 - Changelog (#6210)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2023-07-24 20:06:42 +02:00
Jakub Kuczys
7e05bec6a0 Include instance name in the instance not found error (#6206) 2023-07-24 14:00:23 -04:00
Jakub Kuczys
6f920daeed Improve unreleased Command.is_enabled() and document related methods (#6209)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2023-07-23 21:12:33 -04:00
Jakub Kuczys
df7bbe5b55 Add changelog to PyPI project URLs (#6207) 2023-07-24 00:41:23 +02:00
Jakub Kuczys
8e1b906012 Bump dependencies (#6185) 2023-07-23 23:14:36 +02:00
Jakub Kuczys
ba210bd08e Use action='extend' for all multi-argument cli flags (#6200) 2023-07-19 22:47:38 +02:00
Jakub Kuczys
d8e584b5e8 Fix CancelledError handling in done callbacks of cog init tasks (#6203) 2023-07-19 22:45:44 +02:00
Jakub Kuczys
bad23a4a93 Ensure bot doesn't indefinitely hang on an exception in on_ready (#6202) 2023-07-19 22:44:38 +02:00
Zephyrkul
48cfde7b8c Fix _ValueCtxManager.__await__ typehint (#6163)
Co-authored-by: zephyrkul <zephyrkul@users.noreply.github.com>
2023-07-19 22:13:54 +02:00
Kreusada
8ee3ac9352 [Cleanup] Fix [p]cleanup self inside DMs (#6197) 2023-06-29 06:06:44 +02:00
Jakub Kuczys
9c85917dad Handle exception chaining and groups in Dev's traceback handling (#6178) 2023-06-22 01:42:01 +02:00
Jakub Kuczys
fdcbe00143 Include command-line arguments in debuginfo (#6164)
Co-authored-by: TrustyJAID <TrustyJAID@gmail.com>
2023-06-22 01:15:40 +02:00
TrustyJAID
7dff136937 Add ConfirmView utility (#6176)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-06-21 10:47:47 -06:00
Jakub Kuczys
49bf103891 Update the Lavalink version parsing and add tests for it (#6093) 2023-06-21 15:52:00 +02:00
Om
41204ccf77 Pass timeout to SimpleMenu (#6173) 2023-06-20 23:18:58 +02:00
AAA3A
b1c3b37235 Clear the view in [p]set api after timeout (#6166) 2023-06-20 13:09:01 +02:00
Jakub Kuczys
4dc7efab29 Hide diffs for .po files by default (#6168) 2023-06-20 12:38:20 +02:00
aikaterna
85cf0f52d9 Update Audio terminology in LICENSE (#6193) 2023-06-20 12:00:01 +02:00
Jakub Kuczys
8acc1c3e02 Support and switch to Java 17 everywhere except CentOS 7 (#6190) 2023-06-20 11:29:50 +02:00
Jakub Kuczys
be5751a7ea Handle empty name case when splitting description field in help (#5941) 2023-06-19 14:15:34 +02:00
AAA3A
30dc128c39 Shorten max page size in [p]slash list to account for box size (#6167) 2023-06-19 14:02:33 +02:00
Jakub Kuczys
3b92c225ac Add a usage example to get_end_user_data_statement_or_raise() (#6171) 2023-06-19 14:00:55 +02:00
Draper
9d04f17cd2 Add an option to auto-use default HTTP(S) port for Lavalink (#5629)
Co-authored-by: Jakub Kuczys <me@jacken.men>
Co-authored-by: Kreusada <67752638+Kreusada@users.noreply.github.com>
2023-06-19 13:56:59 +02:00
Kreusada
31700a226e Fix NUMBER_EMOJIS breakages inside Audio (#6170)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-06-19 13:44:51 +02:00
Jakub Kuczys
dc94c96c9e Drop Fedora 36, RHEL 8.4, Ubuntu 18.04 + extras (#6189) 2023-06-18 02:06:47 +02:00
Jakub Kuczys
10e09d6abc d.py 2.3 / pomelo changes (#6130)
Co-authored-by: Michael Oliveira <34169552+Flame442@users.noreply.github.com>
2023-06-14 04:56:50 +02:00
Jakub Kuczys
3abf4cac05 Use backtracking resolver in pip-compile (#6184) 2023-06-12 19:08:27 +02:00
Michael Oliveira
9b7aa17564 Clarify requirements for delisting an approved cog (#6180)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-06-05 18:43:24 -04:00
Predä
f47d1dffb3 Use a SnowflakeList for Command disable instead of checks (#5552) 2023-05-17 21:33:04 +01:00
github-actions[bot]
edb3369169 Version bump to 3.5.3.dev1 (#6162)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-05-14 20:42:48 +00:00
github-actions[bot]
e8ce3d8682 Version bump to 3.5.2 (#6160)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-05-14 22:18:32 +02:00
github-actions[bot]
a59e73a605 Automated Crowdin downstream (#6161)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-05-14 22:17:45 +02:00
Jakub Kuczys
69cf604e0e Fix workflow completion watcher in release helper 2023-05-14 22:15:47 +02:00
Jakub Kuczys
1ec95beb56 Red 3.5.2 - Changelog (#6157) 2023-05-14 21:59:14 +02:00
Jakub Kuczys
1262921b17 Handle delete_after in interaction error handling for followup (#6159) 2023-05-14 21:55:10 +02:00
Michael Oliveira
8dfa5c2a86 Fix interaction docs example code (#6154)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-05-14 12:12:04 +02:00
Jakub Kuczys
327f2fed50 Bump dependencies (#6155) 2023-05-13 14:16:35 -04:00
Ryan Ramboer
6cd7a380f4 Update bad looking 'diff' code blocks with 'markdown' (#6152)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-05-13 19:21:27 +02:00
TrustyJAID
ecb60c0856 Fix menus passing PartialEmoji instead of str (#6143) 2023-05-13 18:14:42 +02:00
Jakub Kuczys
cbe50bf82e Use proper Parameter type in CustomCommands cog (#6149)
Co-authored-by: Jamie <31554168+flaree@users.noreply.github.com>
2023-05-13 16:55:10 +01:00
Jakub Kuczys
a2132ad0a5 Add global prefixes to debuginfo (#6153) 2023-05-13 16:45:25 +01:00
Vexed
2386b8363f Fix visual issues with Discord's new Markdown (#6101)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-05-13 12:39:57 +02:00
Jakub Kuczys
7f820dab0c Fix max heapsize calculation on 32-bit platforms (#6150) 2023-05-12 16:51:59 -07:00
Karlo Prikratki
5893d590a7 Fix NoneType error and channelmute saying user is already muted (#6144)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-05-12 21:54:10 +02:00
Karlo Prikratki
59216e2632 Fix set serverprefix docstring and update its docs (#6004)
Co-authored-by: Kreusada <67752638+Kreusada@users.noreply.github.com>
2023-05-12 21:33:34 +02:00
Jakub Kuczys
31b975eecc Address change in behavior of bool(Permissions()) on d.py 2.x (#6148) 2023-05-12 14:02:41 -04:00
Jakub Kuczys
2369017f6a Add data_manager.instance_name() public API (#6146) 2023-05-12 11:53:53 +01:00
Jakub Kuczys
91f19c7410 Make mentions of x86-64-v2 accurate for AMD (#6147) 2023-05-12 11:04:18 +01:00
Jakub Kuczys
70ca8ff1f4 Add snippet numbers to filenames in the Dev cog to fix exception formatting (#6135) 2023-05-11 18:27:19 -04:00
Jakub Kuczys
e7d7eba68f Fix the bot starting when using --debuginfo (#6131) 2023-05-11 16:55:13 -04:00
Jakub Kuczys
1d828c447c Update documentation with x86-64-v2 changes (#6141) 2023-05-11 00:33:47 -04:00
Ben Armstrong
66fe981ea8 Include vendored menus update for guild attribute (#6139) 2023-05-10 17:11:20 +02:00
github-actions[bot]
41d89c7b54 Version bump to 3.5.2.dev1 (#6128)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-05-04 08:45:55 +02:00
github-actions[bot]
30d452b311 Version bump to 3.5.1 (#6126)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-05-04 08:27:53 +02:00
github-actions[bot]
c52ef73097 Automated Crowdin downstream (#6127)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-05-04 08:22:59 +02:00
Jakub Kuczys
d3310f80fa Red 3.5.1 - Changelog (#6125)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-05-04 08:20:46 +02:00
Jakub Kuczys
d7455ff568 Include --no-cogs flag in Updating Red document (#6123) 2023-05-04 08:16:36 +02:00
Jakub Kuczys
b52f7ede46 Fix ValueError on bot startup when update is available (#6124) 2023-05-04 08:16:11 +02:00
github-actions[bot]
1d654c2edc Version bump to 3.5.1.dev1 (#6122)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-05-04 07:44:35 +02:00
github-actions[bot]
a04fb84ffd Version bump to 3.5.0 (#6118)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-05-04 06:26:43 +02:00
Jakub Kuczys
5f4b0e853e Fix issues with channel unmutes for mute data from 3.4.x (#6121) 2023-05-04 06:22:54 +02:00
Jakub Kuczys
c541425b57 Mention bank cog in Read before updating section for 3.5 (#6120)
Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
2023-05-04 05:40:03 +02:00
github-actions[bot]
7b80043d19 Automated Crowdin downstream (#6119)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-05-04 03:04:41 +02:00
Flame442
b3fd90ae4c Red 3.5.0 - Changelog (#6106)
Co-authored-by: Jakub Kuczys <me@jacken.men>
Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
2023-05-04 02:53:02 +02:00
Jakub Kuczys
525c3885cd Fix broken links to d.py's docs pages (#6117) 2023-05-03 16:32:25 -07:00
Jakub Kuczys
ba1bf23363 Remove unused ConversionFailure (#6113) 2023-05-03 23:49:12 +02:00
Jakub Kuczys
970f8a7a1e Bump dependencies (#6100) 2023-05-02 20:35:08 -04:00
Jakub Kuczys
8996aee7fb Fix shutdown handling failing when exit code is not ExitCodes instance (#6112) 2023-05-02 20:25:35 -04:00
Jakub Kuczys
af307377ad Update exit codes in the autostart doc for Windows (#6111) 2023-05-02 20:08:09 -04:00
Jakub Kuczys
0cc9bccb86 Drop Debian (not RPi OS) 10, add Fedora 38 and Ubuntu 23.04 (#6110) 2023-05-02 19:07:53 -04:00
Jakub Kuczys
2fe251ecf3 Port TiV changes applied to voice channels to stage channels (#6109) 2023-05-02 19:05:44 -04:00
Jakub Kuczys
f1439a37c8 Add Incompatible changes document (#5603)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-05-02 18:04:17 -04:00
Jakub Kuczys
b7c710ac04 Make it possible to set slowmode in stage/voice channels (#6108) 2023-05-02 16:05:51 -04:00
Jakub Kuczys
6a53d7dcd5 Add checks submodule to redbot.core.app_commands (#6107) 2023-05-02 10:50:55 -04:00
Jakub Kuczys
4edf975996 Merge pull request #6099 from Jackenmen/bump_black
Reformat with Black 2023 formatting changes
2023-05-02 00:55:19 +02:00
Jakub Kuczys
3de5b56216 Bump Black and its deps 2023-05-02 00:52:02 +02:00
Jakub Kuczys
226d8d734d Reformat with Black 2023 formatting changes 2023-05-02 00:51:29 +02:00
Flame442
6cef8408e8 Fix help breaking when removing a command without removing its cog (#6104) 2023-04-28 02:01:46 +02:00
Kowlin
2abafbcc10 Add guide for slash commands (#6008)
Co-authored-by: Jamie <31554168+flaree@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-04-27 18:51:11 -04:00
Vexed
db1892da65 Fix AttributeError from slash command tree (#6103) 2023-04-27 22:20:18 +02:00
Jakub Kuczys
5fecff0779 Bump platformdirs to 3.x and remove the migration code for 2.x (#6098) 2023-04-25 07:29:10 +02:00
Jakub Kuczys
d8d4b4f15a Improve consistency of shutdown message across Python versions (#6095) 2023-04-24 14:29:51 -04:00
Jakub Kuczys
c6551f4bcc Suppress importlib 3.12 warning about load_module (#6094) 2023-04-24 14:09:18 -04:00
Flame442
ab8f00ae7b [Trivia] Fix string interpolation in test errors (#5955)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-04-21 01:52:56 +02:00
Jakub Kuczys
e2737a08d2 Stop manually adding category to automated PRs (#6089) 2023-04-20 15:43:36 +02:00
Jakub Kuczys
588fa19594 Red 3.4.19 - Changelog (#6082)
Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-04-20 03:51:34 +02:00
Jakub Kuczys
1ed64949aa Add require_var_positional=True to [p]selfroleset add/remove (#6084) 2023-04-19 21:41:55 -04:00
aikaterna
0d284cabe9 Use the contributor list URL instead of the org in [p]info (#6079)
Co-authored-by: Kowlin <git@wyvern.blue>
2023-04-20 02:34:11 +02:00
aikaterna
e1f5d65d16 [Audio] Update Lavalink.jar build (#6033)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-04-19 21:32:56 +02:00
Jakub Kuczys
9681cac820 Bump Red-Lavalink to stable 0.11.0 (#6030) 2023-04-19 04:07:31 +02:00
Jakub Kuczys
f48f0bd1d1 Fix wrong extract location in Publish Release workflow (#6029) 2023-04-19 03:30:52 +02:00
aikaterna
f98db62b69 [Audio] Don't escape formatting on Playlist Enqueued message (#6025) 2023-04-17 18:39:10 -04:00
Jakub Kuczys
f051eae92d Privatize APIs by renaming or removing them from __all__ (#6021) 2023-04-17 17:44:33 -04:00
AAA3A
eafbb06756 Add public positive_int and finite_float converters (#5969)
Co-authored-by: Kreusada <67752638+Kreusada@users.noreply.github.com>
2023-04-17 22:33:44 +01:00
Samuel
fa305cb060 [Help] Optimisation on getting commands in Cog-help (#5354)
Co-authored-by: npc203 <npc203@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-04-16 17:17:10 -04:00
Jakub Kuczys
64c72e79b5 Switch the Publish Release workflow to use OpenID Connect (#6012) 2023-04-16 22:53:27 +02:00
Samuel
c2da29c93e Dispatch a cog unload event [on_cog_remove] (#5570)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-04-15 16:56:17 -04:00
Jakub Kuczys
67f4dd5201 Fix missing app_commands import (#6019) 2023-04-15 15:29:27 -04:00
Jakub Kuczys
2c4bd38ba1 Show source code in tracebacks sent by Dev cog commands (#5843)
Co-authored-by: Kreusada <67752638+Kreusada@users.noreply.github.com>
2023-04-15 10:30:19 +01:00
Flame442
aa51fd9ad1 Allow force enabling app commands using flag in extras (#6018) 2023-04-14 15:59:21 -06:00
Flame442
ccdd1ca892 Add global checks to app commands (#6015) 2023-04-14 15:58:02 -06:00
yuansheng1549
030607fb04 Add Traceback prompt (#5851)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-04-14 18:50:39 +02:00
Draper
896d5e9200 Remove deprecated checks in checks module (#6016) 2023-04-13 23:15:22 +02:00
Jakub Kuczys
d47c91cca8 Allow any Messageable in MessagePredicate's channel parameter (#5942)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-04-13 15:21:56 -04:00
Jakub Kuczys
145b2e43ce Allow any Messageable in MessagePredicate's channel parameter (#5942)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-04-13 15:21:36 -04:00
Jakub Kuczys
533f036ed2 Improve performance of pagify() (#5698)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2023-04-13 14:52:54 -04:00
Kreusada
79d11e947c Use the commands module instead of checks for permission decorators (#5463)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-04-13 14:16:12 -04:00
Jakub Kuczys
a70f444255 Add brew shellenv to shell profile in macOS install guide (#5993) 2023-04-13 12:48:47 -04:00
Jakub Kuczys
44e129bc66 Add redbot.core.app_commands namespace (#6006) 2023-03-27 20:49:59 -04:00
Kowlin
c79d0d723e Fix the handling of PartialMessageable channels (#6005)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-03-27 19:35:36 -04:00
Kowlin
0a5aa94cde Fix file endings (#6002) 2023-03-21 23:34:01 +01:00
Flame442
f06b734e15 Application Command Manager (#5992)
Co-authored-by: Danny <1695103+Rapptz@users.noreply.github.com>
2023-03-20 21:31:37 +01:00
Kowlin
b2e17775a0 Bump just Discord.py to 2.2.2 (#5998) 2023-03-20 17:59:06 +01:00
Kowlin
469b2de391 Drop the launcher (#5999)
Co-authored-by: palmtree5 <3577255+palmtree5@users.noreply.github.com>
2023-03-18 22:25:56 -04:00
Flame442
d597c35fff [Docs] Windows batch autostart docs (#5996) 2023-03-19 02:44:19 +01:00
Flame442
6774801649 Always allow licenseinfo to be run with a mention prefix (#5865)
Co-authored-by: Zephyrkul <23347632+Zephyrkul@users.noreply.github.com>
2023-03-18 22:32:52 +01:00
Dav
7c7e5edb19 [Modlog]Raise error instead of failing silently on invalid arguments (#5386)
Co-authored-by: Dav <dav@mail.stopdavabuse.de>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-03-18 17:31:28 -04:00
Vexed
2ab204438e Document setting overrides in Trivia list format (#5390)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-03-02 15:54:51 +01:00
Kreusada
8de6b97700 Add JSON Schema for Trivia Lists (#5565)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-03-02 15:43:55 +01:00
Tom Marcot
d9c46342d4 Fix typos issues (#5977)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-02-14 04:36:40 +00:00
Lioness100
a89a27cadf docs: fix typos (#5989)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2023-02-13 21:36:09 -05:00
Jakub Kuczys
9811e4e871 Fix labeler patterns for changelogs (#5987) 2023-02-13 00:17:51 +01:00
Jakub Kuczys
6c32ff58e4 Revamp of automatically applied PR labels (#5954)
Co-authored-by: Jakub Kuczys <6032823+jack1142@users.noreply.github.com>
2023-02-12 23:34:00 +01:00
aikaterna
7e7d5322b7 [Audio] Use more of the newer Managed/Unmanaged terminology (#5952)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-02-12 22:07:46 +01:00
Leet
e0c335eda2 [Trivia] Handle FileNotFoundError when adding a custom trivia list (#5950) 2023-02-03 13:52:43 -05:00
Jakub Kuczys
d0f22a7773 Fallback to asyncio's default exception handler when possible (#5813)
Co-authored-by: Jakub Kuczys <6032823+jack1142@users.noreply.github.com>
2023-01-31 11:02:49 -05:00
keqking
c390b89bd2 [Core] fix error in [p]ignore list (#5973) 2023-01-23 14:49:05 -05:00
Jakub Kuczys
2168585ee1 Improve changelog format (#5602)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2023-01-23 14:39:15 -05:00
Jakub Kuczys
794d486bc0 Bump OS version ranges - Fedora to <36, 37>, macOS to <11, 13> (#5974) 2023-01-19 11:54:37 +01:00
Jakub Kuczys
0358aabd1f Use newer RTD config syntax (#5774) 2023-01-15 17:01:13 +01:00
aikaterna
a13870b45f Remove llsetup alias for llset (#5953)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-01-14 15:33:03 +01:00
Lemon Rose
eda1288bea Add missing help descriptions for flags in redbot-setup (#5818)
Co-authored-by: Lemon Rose <japandotorg@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
Co-authored-by: Leet <36166244+leetfin@users.noreply.github.com>
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-01-14 14:18:01 +00:00
Jakub Kuczys
f13d910f66 Disallow NaN and Infinity in Trivia CONFIG schema (#5949) 2023-01-02 06:13:12 +01:00
Vexed
b493103dcb Improve validation in trivia (#5947)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2023-01-02 05:24:27 +01:00
Jakub Kuczys
7db635a05b Change 'Managed' to 'External' in [p]llset secured's output (#5944) 2022-12-31 16:35:06 -08:00
Kreusada
b98156c589 Use usage attr to remove appended underscore for from_ parameter in [p]reorderpath (#5946) 2022-12-30 17:28:44 -05:00
Ryan
82e92a8dc3 Update enqueued track message to distinguish album from playlist (#5569)
Co-authored-by: aleclol <50505980+aleclol@users.noreply.github.com>
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-12-30 04:48:44 +01:00
Predä
60a9d47003 Core - Add invoke error message customisation (#5894)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-12-30 04:43:37 +01:00
Jakub Kuczys
88a348210c Add support for sdists and git-archive to _get_version() (#5814)
Co-authored-by: Jakub Kuczys <6032823+jack1142@users.noreply.github.com>
2022-12-30 03:52:49 +01:00
Jakub Kuczys
fa6b2f8c10 Fix incorrect default argument value in [p]streamalert twitch (#5945) 2022-12-30 03:24:05 +01:00
Jakub Kuczys
519acedf46 Make some dependency changes, support Python 3.10 and 3.11 (#5611)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2022-12-30 03:21:57 +01:00
Karlo Prikratki
d3308af0e2 [Streams] Add toggleable button to stream alerts (#5856)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-12-29 20:18:26 +01:00
Karlo Prikratki
9b1171ea8c Use Discord's relative timestamps as command cooldown countdown (#5893)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-12-29 17:55:11 +01:00
Flame442
0e97c26b2d Test implicit subclass type conversion in config defaults/sets (#5874)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-12-29 06:50:18 +01:00
Honkertonken
19ebd02595 Change/Update casing in findcog command. (#5772)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-12-28 00:52:02 +01:00
Jakub Kuczys
99479342ea Fix ordering of 3.0.0.dev1 and 3.0.0a1.dev1 versions (#5932) 2022-12-27 17:22:56 -05:00
Kreusada
abb0101420 [CogManagerUI] Resolve core path under bot._cog_mgr.CORE_PATH (#5142)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-12-27 21:58:01 +01:00
Julien Mauroy
d9dd37b867 Remove multiple paths (#5859)
Co-authored-by: Kreusada <67752638+Kreusada@users.noreply.github.com>
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-12-27 21:51:13 +01:00
Draper
1ab303bce7 Fix managed LL subprocess's stdout overflowing and deadlocking (#5903)
Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-12-27 20:33:50 +01:00
Jakub Kuczys
43ab6e2ef5 Add missing empty line in error output of Trivia unit test (#5659)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2022-12-27 14:42:20 +01:00
Jakub Kuczys
14f142da2b Update installation URLs for Homebrew and Chocolatey (#5776)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2022-12-27 14:28:34 +01:00
Kowlin
f890f65c35 Updated excluded features (#5919)
Co-authored-by: Zephyrkul <23347632+Zephyrkul@users.noreply.github.com>
2022-12-27 11:29:05 +01:00
Predä
7af2ed13ec Update disable commands logic during cogs loading (#5550)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-12-26 19:29:54 -05:00
Jakub Kuczys
e88884edb6 Fix usage of file/folder names without suffix in Downloader (#5938) 2022-12-26 18:39:17 -05:00
sravan
f02491a092 Update intents screenshot (#5936) 2022-12-26 07:50:39 +01:00
Jakub Kuczys
e8c044a9bf Use different exit codes for critical errors vs configuration errors (#5674)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2022-12-25 16:27:07 -05:00
Kowlin
0e58897bfc Add SECURITY.md to the repo (#5929)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-12-25 14:40:35 +00:00
Flame442
9bfc3ecbce Fix tests badge in readme (#5934) 2022-12-25 15:25:40 +01:00
Kreusada
1c7178a10b Add automodule reference for the antispam module (#5641)
Co-authored-by: Jakub Kuczys <me@jacken.men>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-12-22 17:49:44 -05:00
Kowlin
3cb17116be Revert `mock and mockmsg` back to a guild_only state (#5926) 2022-12-22 17:41:52 -05:00
SnappyDragon64
eb613ea154 [Trivia] Who's that Pokemon? Generation VII and VIII trivia lists (#5890)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-12-19 00:44:01 -05:00
Dav
4dd496c67f [Modlog API] Stop modlog.get_case() from erroring if no modlog channel is set up (#5866)
Co-authored-by: Dav <dav@mail.stopdavabuse.de>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-12-18 19:23:57 -05:00
Lemon Rose
333e359bbb [Admin] add reasoning to addrole & removerole. (#5927)
Co-authored-by: Matt <psykzz@users.noreply.github.com>
2022-12-17 22:36:40 -05:00
MAX
fb3dc51fe2 [Docs] Update bot hosting list. (#5928) 2022-12-11 21:25:37 +01:00
Jakub Kuczys
f7c14b4321 Modernize packaging-related things in Red (#5924) 2022-12-09 18:50:37 +01:00
Kowlin
72172ff1cb Bump discord.py to version 2.1.0 (#5920) 2022-12-02 19:40:15 +01:00
AntonioNarra
b018a76b61 Core - #5891 Recovering Server Prefixes (#5918) 2022-12-01 18:58:11 -05:00
TrustyJAID
bbb15924b9 Allow send_interactive to upload a file containing all content (#5902)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-11-24 16:05:07 -05:00
Flame442
6c8b6eb71c [CustomCom] Fix [p]cc cooldown docstring & docs (#5914) 2022-11-23 01:37:20 +01:00
Kreusada
ed4f36a529 Add serverlock warning to [p]invite (#5898) 2022-11-17 18:11:56 -05:00
Ryan
1fbd6d854b [General] Fix [p]lmgtfy URL generation (#5909)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-11-17 17:22:44 -05:00
Jakub Kuczys
66f906c274 Update CODEOWNERS file with my new username (#5911) 2022-11-17 20:16:01 +01:00
Jakub Kuczys
4574f13ad5 Fix flaky CI caused by flake8's flakiness (GitHub migration) (#5910) 2022-11-17 19:58:24 +01:00
TrustyJAID
0580213cb6 Fix [p]helpset usemenus disable (#5907) 2022-11-15 23:56:56 -05:00
Jakub Kuczys
6023f9015c Restrict first/last character in instance name (#5680)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-11-13 22:50:02 +00:00
Visne
d5cdebcd76 Improve topography trivia (#5572)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-11-12 18:49:33 -05:00
Ankur Gupta
e864924acb Harrypotter questions (#5887)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
Co-authored-by: Lemon Rose <78662983+japandotorg@users.noreply.github.com>
2022-11-12 18:44:13 -05:00
Kowlin
86aed37769 Fix HTTPException in set api's send_modal (#5860)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-11-11 19:59:51 -05:00
Jakub Kuczys
51fa3f502e Remove bordered() utility function (#5692) 2022-11-11 15:37:49 +01:00
Jakub Kuczys
0f20f15c26 Stop using deprecated set-output GH Actions command (#5876) 2022-11-11 15:12:54 +01:00
Alex
3f749b840f fix usage/syntax info in command_audioset_autoplay_playlist docstring (#5592)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-11-01 12:33:21 -04:00
OofChair
6cda937ec2 [Modlog] Make modlogset cases docstring less vague (#5352)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
2022-10-30 21:06:32 -07:00
Jakub Kuczys
0c35c9686b Add Lavalink version parsing (#5872) 2022-10-30 19:20:45 -07:00
Kreusada
236a10c464 [Docs] Audio Cog Guide (#5871)
Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-10-30 18:43:19 -07:00
aikaterna
236d30f335 [Audio] Adjust docstrings (#5895) 2022-10-30 21:00:32 -04:00
AA
115083b18b Case-Insensitive SelfRole (#3865)
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-10-30 18:00:21 -04:00
Kreusada
85288c1d06 [Docs] Dev Cog Guide (#5869)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-10-25 18:57:32 -04:00
Kreusada
cc5c31999d Document new [p]set usebuttons command (#5885) 2022-10-23 00:36:41 +02:00
Mark Heath
16465c8d83 Fix typo in league of legends trivia list (#5888) 2022-10-22 18:00:46 +02:00
Kreusada
86aff952f0 Update [p]helpset usemenus documentation with converter changes (#5886)
Co-authored-by: Kowlin <10947836+Kowlin@users.noreply.github.com>
2022-10-21 21:03:56 +02:00
Vexed
3be22b683c [Mod] Account for roles in mention spam (#5388)
Co-authored-by: Kowlin <10947836+Kowlin@users.noreply.github.com>
2022-10-20 18:56:40 +02:00
Kreusada Lavranocoyaskalas
a90974d659 Exclude files_from_attatch member from Tunnel automodule (#5778) 2022-10-16 21:13:11 +02:00
Jakub Kuczys
86c6f199b3 Get rid of localized guild feature list in serverinfo (#5830) 2022-10-13 14:04:57 +02:00
Jakub Kuczys
a3de616e4d Properly handle missing schemas/tables in PostgreSQL driver (#5855) 2022-10-13 13:38:43 +02:00
Kreusada Lavranocoyaskalas
a82c08c9d3 Add core/_debuginfo.py to labeler configuration (#5797) 2022-10-13 13:36:42 +02:00
Leet
fcbe37b956 [Docs] Use gender neutral language in remaining places where it isn't (#5873) 2022-10-13 13:34:14 +02:00
keqking
1cb5836db4 [cleanup] fix error in [p]cleanup spam command (#5879) 2022-10-13 11:57:41 +02:00
Leet
64e6044aba [Cleanup] Pass reason for bulk message deletion to audit log (#5863)
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-10-12 23:02:37 +02:00
Kowlin
501c2b97dd Fix a lack of permission checks on usebuttons (#5878) 2022-10-12 20:40:49 +00:00
TrustyJAID
b0a3f00f41 Add global buttons to base menus (#5683)
Co-authored-by: Kowlin <10947836+Kowlin@users.noreply.github.com>
2022-10-12 22:13:33 +02:00
TrustyJAID
aaeb1b5daa Add buttons to help (#5634)
Co-authored-by: Zephyrkul <23347632+Zephyrkul@users.noreply.github.com>
Co-authored-by: Kowlin <10947836+Kowlin@users.noreply.github.com>
Co-authored-by: Jakub Kuczys <me@jacken.men>
2022-10-12 16:29:10 +02:00
Kreusada Lavranocoyaskalas
4158244117 Use bot embed colour in [p]dm command (#5868) 2022-10-11 23:01:47 +02:00
Flame442
76c0ee243e [Mod] Hide config migration commands (#5870) 2022-10-11 22:57:18 +02:00
TrustyJAID
f8b0cc6c6a Add support for Hybrid commands in Red (#5681)
Co-authored-by: Kowlin <10947836+Kowlin@users.noreply.github.com>
Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
Co-authored-by: Jakub Kuczys <6032823+jack1142@users.noreply.github.com>
Co-authored-by: Kreusada <67752638+Kreusada@users.noreply.github.com>
Co-authored-by: Candy <28566705+mina9999@users.noreply.github.com>
Co-authored-by: Matt Chandra <55866950+matcha19@users.noreply.github.com>
Co-authored-by: Lemon Rose <78662983+japandotorg@users.noreply.github.com>
Co-authored-by: Honkertonken <94032937+Honkertonken@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
Co-authored-by: River <18037011+RheingoldRiver@users.noreply.github.com>
Co-authored-by: AAA3A <89632044+AAA3A-AAA3A@users.noreply.github.com>
Co-authored-by: Lemon Rose <japandotorg@users.noreply.github.com>
Co-authored-by: Julien Mauroy <pro.julien.mauroy@gmail.com>
Co-authored-by: TheThomanski <15034759+TheThomanski@users.noreply.github.com>
2022-10-11 22:52:43 +02:00
Honkertonken
7ff89302b2 [Trivia] Various typo fixes. (#5867) 2022-10-07 11:32:58 -04:00
Jakub Kuczys
1241ea165c Fix unintended moving *between* VCs when channel muting (#5854) 2022-10-03 18:11:37 +02:00
Jakub Kuczys
f02528378f discord.py 2.0 update (3d914e08->2.0.1) (#5709) 2022-10-03 16:07:15 +02:00
AlexRatman
d7d6ab46f4 Add missing period which caused ignore list to fail (#5850) 2022-09-17 20:23:50 +02:00
Jakub Kuczys
9d820234bb Fix Tunnel.message_forwarder's handling of >2000 strings (#5844) 2022-09-12 19:34:34 -04:00
Kreusada Tagiazala
cadcffbae5 [Dev] Fix __repr__() errors in REPL when referencing an instance of a class & catch Exception (#5794)
* initial fix (test)

* Replace instances of bare excepts by catching Exception
2022-08-22 20:32:02 -04:00
TheThomanski
6f04698013 Renamed the country of Turkey to Türkiye (#5795)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-08-22 19:31:30 -04:00
Julien Mauroy
d07eb0f7b2 fix: use correct typehint in Config.user's docstring (#5791)
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-08-22 22:59:29 +00:00
Jakub Kuczys
008fb0f042 Red 3.4.18 - Changelog (#5829) 2022-08-15 12:55:08 +02:00
Jakub Kuczys
a32f10d758 Use the new ready line from LL dev build 1352+ (#5775)
* Revert "Wait for two 'Started Launcher' lines before connecting to managed LL (#5751)"

This reverts commit cf85a6470f.

* Use the new ready line from LL dev build 1352+
2022-08-14 12:03:48 -07:00
Jakub Kuczys
4daf81aa5b Bump Lavalink.jar version and update the default application.yml (#5823)
* Bump Lavalink.jar version

* Update the default Lavalink YAML file

* Let's add schema migration too...

* Fix migration (but still actually untested)
2022-08-14 19:57:15 +02:00
Jakub Kuczys
87a9c10369 Remove Temurin version pin on Windows (#5815) 2022-08-10 02:26:09 +02:00
Lemon Rose
4d1381d7c9 [General] show stage channels in [p]serverinfo 1 (#5785)
* [General] show stage channels in `[p]serverinfo 1`

* [General] Formatted with black

* fix black

* [General] Newline `\n` to match the current formatting.

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: Lemon Rose <japandotorg@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-08-08 19:55:43 -04:00
Kreusada Tagiazala
fb5f9b6498 Fix [p]set api docstring (#5807) 2022-07-26 20:54:09 +02:00
AAA3A
6ced7ba945 [Core] Add --unload-cogs cli flag. (#5802)
* [Core] Add `--unload-cogs` cli.

* Fixed error + Reformat.

* At @Jack1142's request, the `packages` local variable is no longer a list, but a dictionary with `None` values, to avoid duplication.

* Update redbot/core/bot.py

Co-authored-by: Jakub Kuczys <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/bot.py

Co-authored-by: Jakub Kuczys <6032823+jack1142@users.noreply.github.com>

* Update bot.py

* Update bot.py

Co-authored-by: Jakub Kuczys <6032823+jack1142@users.noreply.github.com>
2022-07-19 17:10:45 +02:00
Jakub Kuczys
7429b4ff89 Add remaining RHEL 9 derivatives EOL dates (#5803)
Rocky Linux 9 released today so it is time.
2022-07-14 23:34:51 +02:00
River
a0f72ed7dd Update documentation about messages intent (#5798)
* Update documentation about messages intents

* Remove note

* Update screenshot
2022-07-10 22:42:36 +02:00
Kreusada Tanfala
ae80e62a13 Prevent / being used in bot or server prefixes (#5693)
* Update `[p]set prefix`/`[p]set serverprefix`

* Update cli

* style

* update __main__

* style

* improve checks

* Raise in Red.set_prefixes, update responses

* uniform responses

* Fixes

* Keep generator variable names consistent across files
2022-06-28 19:19:20 -04:00
Flame442
febc503df1 Update workflow versions (#5789)
* Update auto_labeler_issues.yml

* Update auto_labeler_pr.yml

* Update codeql-analysis.yml

* Update crowdin_upload_strings.yml

* Update lint_python.yaml

* Update prepare_release.yml

* Update publish_release.yml

* Update tests.yml

* Update for breaking change in actions/github-script@v5

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2022-06-27 17:16:11 +02:00
Kreusada Tanfala
ccec53eef3 Exclude get_embed_color member from Bot framework (#5782) 2022-06-24 18:33:39 +02:00
Lemon Rose
9455ccabfa New Music Trivia List (#5687)
* new trivia category - music

* fix

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* ty aika

* fixed

"Mr. Custer" would be more appropriate than "please mister custer" in respect of the original title of the song.

* Out of context for a trivia list

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/music.yaml

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>

* Made changes as per Aika's change requests

* duplicate removed

* add alternative answers/remove duplicates

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
2022-06-23 09:19:13 -07:00
Jakub Kuczys
0cc964b87c Drop openSUSE Leap 15.2, add openSUSE Leap 15.4 (#5777)
* Add openSUSE Leap 15.4 to list in version guarantees

* Drop openSUSE Leap 15.2
2022-06-16 18:41:07 +02:00
Honkertonken
cc4ccd8414 Update Clash Royale Info in trivia. (#5771)
typo + changes
2022-06-13 16:55:30 -04:00
Jack Reusayda
68557336da Geography Trivia: Update most populous city in Africa (Kinshasa) (#5743)
Kinshasa -> Lagos
2022-06-11 23:50:02 -04:00
Lemon Rose
7a41becbde fixed outdated flags (#5684)
* fixed outdated flags

* made changes as per suggested
2022-06-11 20:02:13 -04:00
Jakub Kuczys
c00f8b3aab Red 3.4.17 - Changelog (#5763) 2022-06-07 04:44:33 +02:00
Kreusada
9c11e85bb4 Include commit hash for each cog inside [p]cog listpinned (#5563)
* Initial commit

* Necessary amendments/changes

* style changes (i knew id have to do this...)

* Use inline()

Co-authored-by: Jakub Kuczys <6032823+jack1142@users.noreply.github.com>
2022-06-05 19:27:36 +02:00
Matt Chandra
5522f909bd Allow sending the file in follow-up message in ACL upload commands (#5685)
Added follow up message when uploading acl file in permissions cog.
2022-06-05 17:51:02 +02:00
Kreusada
1fd9324171 Prepend emojis to better differentiate between [p]canrun responses (#5711)
* Add emojis to better differentiate between canrun responses

* Apply `success()`

Co-authored-by: Jakub Kuczys <6032823+jack1142@users.noreply.github.com>

* Apply `error()`

Co-authored-by: Jakub Kuczys <6032823+jack1142@users.noreply.github.com>

* add imports

Co-authored-by: Jakub Kuczys <6032823+jack1142@users.noreply.github.com>
2022-06-05 17:42:11 +02:00
Kowlin
4580a13e98 Minor bugfixes resolving around modlog UI (#5615)
Multiple bugfixes
 * Fixed unbound channel_value
 * Fixed lack of new lines for listcases
 * Fixed response text for case. It can only be used in the current server.
2022-06-05 17:38:46 +02:00
Candy
485e6837ca [Modlog] Check if guild is unavailable (#5647)
fix for  AttributeError: 'NoneType' object has no attribute 'guild_permissions'
2022-06-05 17:16:33 +02:00
Kreusada
cc3c1a6a95 Add use_spoilers property to TRIVIA_LIST_SCHEMA schema (#5566)
* Add `use_spoilers` to schema

* Update session.py

Co-authored-by: Jakub Kuczys <6032823+jack1142@users.noreply.github.com>
2022-06-05 17:07:41 +02:00
Kreusada
9d50a851eb Escape Discord's formatting in [p]servers command (#5744)
* Escape formatting in `[p]servers` command

* style...
2022-06-05 16:19:52 +02:00
Jakub Kuczys
ee69f6e17f Add RHEL 9 (+ derivatives) install guide (#5721)
* rhel->rhel8 rename of the include file for install guides

* Add RHEL 9

* Add Alma, Oracle, and Rocky Linux 9 pre-emptively

* Add Alma Linux 9 EOL date
2022-06-05 04:11:16 +02:00
Jakub Kuczys
22ede49462 Update Visual Studio Build Tools to 2022 (#5702) 2022-06-05 04:06:17 +02:00
Jakub Kuczys
e93057093e Add Ubuntu 22.04 install guide (#5720)
* Add Ubuntu 22.04 install guide

* Add Ubuntu 22.04 to End-user guarantees

* Add missing information about supported arches in install guide
2022-06-05 03:08:02 +02:00
Jakub Kuczys
cf85a6470f Wait for two 'Started Launcher' lines before connecting to managed LL (#5751) 2022-06-05 02:46:17 +02:00
Jakub Kuczys
9cdcf07773 Add Fedora 36 and RHEL 8.6 to list in version guarantees (#5701)
* Add Fedora 36 to list in version guarantees

* Add RHEL 8.6

* Drop Fedora Linux 34
2022-06-04 17:32:23 +02:00
Jakub Kuczys
6bb11ad227 Use Temurin 11 instead of discontinued AdoptOpenJDK on macOS (#5718) 2022-06-04 15:24:30 +02:00
Jakub Kuczys
3f1d02598e Replace removed git224 package with git236 in CentOS 7 guide (#5700) 2022-06-02 12:59:02 +02:00
Jakub Kuczys
53bf387f01 Pin Temurin version on Windows until fixed version exists (#5717) 2022-06-02 12:55:02 +02:00
aikaterna
1e8f4fc2a2 [Audio] Update Lavalink.jar build (#5712) 2022-06-01 01:05:52 +02:00
Jakub Kuczys
e36d1bccbf Use latest d.py docs rather than removed master docs (#5713) 2022-06-01 01:00:13 +02:00
aikaterna
d13d02ebfc Fix for using redbot name --edit for changing data location (#5541)
* Update __main__.py

* style
2022-05-31 18:40:35 -04:00
aikaterna
1cf497b128 Fix changing instance name with redbot --edit (#5540) 2022-05-31 18:36:07 -04:00
Kowlin
acdc1df084 Add support for set api Modals (#5637)
* Add support for set api Modals

Co-authored-by: TrustyJAID <TrustyJAID@gmail.com>

* Blaacckkkk!

* Swap locations of interaction and button.

* Clarified template tokens

* Update docs and some string

* More docs

* Rework the client

Co-authored-by: TrustyJAID <TrustyJAID@gmail.com>

* Goddamned black!

* Missed a few arguments

* Black... Again

* Update redbot/core/utils/views.py

Co-authored-by: TrustyJAID <TrustyJAID@gmail.com>

* Update redbot/core/core_commands.py

Co-authored-by: TrustyJAID <TrustyJAID@gmail.com>

Co-authored-by: TrustyJAID <TrustyJAID@gmail.com>
2022-05-20 13:58:18 -06:00
Jakub Kuczys
ec55622418 Update Downloader's git tests to work with Git 2.36+ (#5690)
There's no need to update RepoManager's code as:
- regex for parsing output about ambiguous refs properly treats the date
  as part of description regardless of ref type
- code for checking if module exists doesn't use the contents of the error message;
  the test only really checks for it to make sure that it triggers the error case
  we're actually testing for. We could instead just remove it too.
2022-04-30 23:28:17 +02:00
MAX
23023da09c [General] update [p]serverinfo 1 guild features. (#5655) 2022-04-18 23:47:30 +02:00
Kowlin
60b495091a Prevent an IndexError from occuring (#5430)
* Prevent an IndexError from occuring

If an page value is negative it doesn't properly loop around to the end.

* Update menus.py

* I'm smart 👍
2022-04-16 17:05:57 -04:00
Kreusada
22df591db2 Add FIFA World Cup Trivia List (#5639)
* Create fifa world cup trivia

* fix formatting

* add source

* Update redbot/cogs/trivia/data/lists/worldcup.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/worldcup.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/worldcup.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/worldcup.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/worldcup.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Netherlands change

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add Estadio Nacional Julio Martínez Prádanos

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add various rasunda alternatives

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add Republic of South Africa

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add various alternative names for Soccer City

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add alternatives for Luzhniki Stadium

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add Estádio Jornalista Mário Filho and Maracana alternatives

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add alternatives for Stade de Colombes

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add various match-ups for 2 year combos

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add Empire Stadium alias to Wembley

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add Estádio Jornalista Mário Filho to Maracana

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add alternatives for International Stadium

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add alternatives for Monumental de Núñez

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Treat double year as literal string

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-04-16 17:00:05 -04:00
Jakub Kuczys
27bed5010f Make controls in menu() optional (#5678)
* Make `controls` in `menu()` optional

You might wonder, shouldn't we pass `None` to functions from controls?
No, we shouldn't because when `None` is passed, only DEFAULT_CONTROLS
can be used and that means that the length of pages list won't change.

* Update usage in core and core cogs

* Add missing docstrings to `redbot.core.utils.menus` module
2022-04-16 13:29:12 -06:00
Kreusada
955b40ac6d Various updates to geography trivia (#5638)
* Various updates to geography trivia

* Remove discriminator from AUTHOR key
2022-04-12 16:36:07 -04:00
jack1142
96e8d8cdf5 Make DEFAULT_CONTROLS and ReactionPredicate.*_EMOJIS immutable (#5666)
* Make ReactionPredicate.*_EMOJIS immutable

* Make menus.DEFAULT_CONTROLS immutable

* Actually convert NUMBER_EMOJIS to tuple
2022-04-09 21:35:11 +02:00
jack1142
6cb2378e2e Stop suppressing exceptions by early-exiting in finally (#5673)
* Stop suppressing exceptions in entrypoints due to sys.exit in finally

* Remove returns in finally in Modlog API as well...
2022-04-09 20:49:45 +02:00
jack1142
02c0328002 Add info about supported arches to guides and version guarantees (#5677)
* Update version guarantees document with supported arches

* Add note about supported architecture to each install guide
2022-04-09 20:47:31 +02:00
jack1142
61c73f2f1f Add CentOS Stream 9 docs (#5537) 2022-04-09 20:17:10 +02:00
jack1142
841b922e9c Use absolute path to which to avoid aliases (#5547) 2022-04-09 20:16:31 +02:00
jack1142
56c9241de4 Allow passing channel to [p]streamalert and show platform in streamalert list (#5160)
* Streamalert list shows each platform the channels were added on

* Added argument to specify the discord channel where stream alerts appear

* Fixed styling

* Changed discord_channel type to discord.TextChannel

* Changed join to humanize_list to display the streams list, split the message concatenation into two lines for better readability

* Allow specifying discord channel for picarto and hitbox, fix style for youtube and twitch

* Since token_name from streamtypes can be None on Picarto and Hitbox, I added an attribute to the Stream class to hold the platform name

* Message now tells the user that the stream alert was disabled only for the specified channel.

* Address review

* fix style

* Consistency! Sort of...

Co-authored-by: douglas-cpp <douglasc.dev@gmail.com>
Co-authored-by: Douglas <douglas.carvalho@edu.unipar.br>
2022-04-09 20:08:41 +02:00
jack1142
c9f1a45854 Make --debuginfo more like [p]debuginfo (#5662) 2022-04-09 19:34:12 +02:00
jack1142
bc9f34c04b Fix invalid version error with _get_version()-provided version (#5670)
* Make sure that the repository we check is in the location we expect

* Merge `redbot._version` into `redbot`

* Generate VersionInfo in _get_version()

This way, if VersionInfo.from_str() generates exception due to invalid
version, we catch it.
2022-04-05 16:48:03 -06:00
jack1142
88d2cb3976 Suppress stderr in _get_version() (#5667) 2022-04-05 22:33:43 +02:00
Kreusada
0b8dec77c3 Remove caching and safety utilities (#5653)
* Remove caching

* Remove safety

* Remove unused private usage
2022-04-03 04:31:53 +02:00
TrustyJAID
2995a457f6 Fix AttributeError in new decorators added to requires (#5665) 2022-04-03 04:27:24 +02:00
jack1142
35f1681dc1 Include tag distance and commit hash in dev versions when possible (#5664)
* Include tag distance and commit hash in dev versions when possible

* Fix test
2022-04-02 19:51:34 -06:00
jack1142
febca8ccbb Migration to discord.py 2.0 (#5600)
* Temporarily set d.py to use latest git revision

* Remove `bot` param to Client.start

* Switch to aware datetimes

A lot of this is removing `.replace(...)` which while not technically
needed, simplifies the code base. There's only a few changes that are
actually necessary here.

* Update to work with new Asset design

* [threads] Update core ModLog API to support threads

- Added proper support for passing `Thread` to `channel`
  when creating/editing case
- Added `parent_channel_id` attribute to Modlog API's Case
    - Added `parent_channel` property that tries to get parent channel
- Updated case's content to show both thread and parent information

* [threads] Disallow usage of threads in some of the commands

- announceset channel
- filter channel clear
- filter channel add
- filter channel remove
- GlobalUniqueObjectFinder converter
    - permissions addglobalrule
    - permissions removeglobalrule
    - permissions removeserverrule
    - Permissions cog does not perform any validation for IDs
      when setting through YAML so that has not been touched
- streamalert twitch/youtube/picarto
- embedset channel
- set ownernotifications adddestination

* [threads] Handle threads in Red's permissions system (Requires)

- Made permissions system apply rules of (only) parent in threads

* [threads] Update embed_requested to support threads

- Threads don't have their own embed settings and inherit from parent

* [threads] Update Red.message_eligible_as_command to support threads

* [threads] Properly handle invocation of [p](un)mutechannel in threads

Usage of a (un)mutechannel will mute/unmute user in the parent channel
if it's invoked in a thread.

* [threads] Update Filter cog to properly handle threads

- `[p]filter channel list` in a threads sends list for parent channel
- Checking for filter hits for a message in a thread checks its parent
  channel's word list. There's no separate word list for threads.

* [threads] Support threads in Audio cog

- Handle threads being notify channels
- Update type hint for `is_query_allowed()`

* [threads] Update type hints and documentation to reflect thread support

- Documented that `{channel}` in CCs might be a thread
- Allowed (documented) usage of threads with `Config.channel()`
    - Separate thread scope is still in the picture though
      if it were to be done, it's going to be in separate in PR
- GuildContext.channel might be Thread

* Use less costy channel check in customcom's on_message_without_command

This isn't needed for d.py 2.0 but whatever...

* Update for in-place edits

* Embed's bool changed behavior, I'm hoping it doesn't affect us

* Address User.permissions_in() removal

* Swap VerificationLevel.extreme with VerificationLevel.highest

* Change to keyword-only parameters

* Change of `Guild.vanity_invite()` return type

* avatar -> display_avatar

* Fix metaclass shenanigans with Converter

* Update Red.add_cog() to be inline with `dpy_commands.Bot.add_cog()`

This means adding `override` keyword-only parameter and causing
small breakage by swapping RuntimeError with discord.ClientException.

* Address all DEP-WARNs

* Remove Context.clean_prefix and use upstream implementation instead

* Remove commands.Literal and use upstream implementation instead

Honestly, this was a rather bad implementation anyway...

Breaking but actually not really - it was provisional.

* Update Command.callback's setter

Support for functools.partial is now built into d.py

* Add new perms in HUMANIZED_PERM mapping (some from d.py 1.7 it seems)

BTW, that should really be in core instead of what we have now...

* Remove the part of do_conversion that has not worked for a long while

* Stop wrapping BadArgument in ConversionFailure

This is breaking but it's best to resolve it like this.

The functionality of ConversionFailure can be replicated with
Context.current_parameter and Context.current_argument.

* Add custom errors for int and float converters

* Remove Command.__call__ as it's now implemented in d.py

* Get rid of _dpy_reimplements

These were reimplemented for the purpose of typing
so it is no longer needed now that d.py is type hinted.

* Add return to Red.remove_cog

* Ensure we don't delete messages that differ only by used sticker

* discord.InvalidArgument->ValueError

* Move from raw <t:...> syntax to discord.utils.format_dt()

* Address AsyncIter removal

* Swap to pos-only for params that are pos-only in upstream

* Update for changes to Command.params

* [threads] Support threads in ignore checks and allow ignoring them

- Updated `[p](un)ignore channel` to accept threads
- Updated `[p]ignore list` to list ignored threads
- Updated logic in `Red.ignored_channel_or_guild()`

Ignores for guild channels now work as follows (only changes for threads):
- if channel is not a thread:
    - check if user has manage channels perm in channel
      and allow command usage if so
    - check if channel is ignored and disallow command usage if so
    - allow command usage if none of the conditions above happened
- if channel is a thread:
    - check if user has manage channels perm in parent channel
      and allow command usage if so
    - check if parent channel is ignored and disallow command usage
      if so
    - check if user has manage thread perm in parent channel
      and allow command usage if so
    - check if thread is ignored and disallow command usage if so
    - allow command usage if none of the conditions above happened

* [partial] Raise TypeError when channel is of PartialMessageable type

- Red.embed_requested
- Red.ignored_channel_or_guild

* [partial] Discard command messages when channel is PartialMessageable

* [threads] Add utilities for checking appropriate perms in both channels & threads

* [threads] Update code to use can_react_in() and @bot_can_react()

* [threads] Update code to use can_send_messages_in

* [threads] Add send_messages_in_threads perm to mute role and overrides

* [threads] Update code to use (bot/user)_can_manage_channel

* [threads] Update [p]diagnoseissues to work with threads

* Type hint fix

* [threads] Patch vendored discord.ext.menus to check proper perms in threads

I guess we've reached time when we have to patch the lib we vendor...

* Make docs generation work with non-final d.py releases

* Update discord.utils.oauth_url() usage

* Swap usage of discord.Embed.Empty/discord.embeds.EmptyEmbed to None

* Update usage of Guild.member_count to work with `None`

* Switch from Guild.vanity_invite() to Guild.vanity_url

* Update startup process to work with d.py's new asynchronous startup

* Use setup_hook() for pre-connect actions

* Update core's add_cog, remove_cog, and load_extension methods

* Update all setup functions to async and add awaits to bot.add_cog calls

* Modernize cogs by using async cog_load and cog_unload

* Address StoreChannel removal

* [partial] Disallow passing PartialMessageable to Case.channel

* [partial] Update cogs and utils to work better with PartialMessageable

- Ignore messages with PartialMessageable channel in CustomCommands cog
- In Filter cog, don't pass channel to modlog.create_case()
  if it's PartialMessageable
- In Trivia cog, only compare channel IDs
- Make `.utils.menus.menu()` work for messages
  with PartialMessageable channel
- Make checks in `.utils.tunnel.Tunnel.communicate()` more rigid

* Add few missing DEP-WARNs
2022-04-03 03:21:20 +02:00
Kreusada
c9a0971945 Reference how to reply in the [p]contact command with embed settings (#5529) 2022-04-02 02:57:06 +02:00
Draper
78e64ec559 add timestamps to all audio embeds (#5632) 2022-04-02 02:37:44 +02:00
jack1142
d932abad16 Use Guild.fetch_ban() over Guild.bans() (#5656) 2022-04-02 01:44:30 +02:00
jack1142
67e43eb00b Ignore d.py's |coro| substitution in Sphinx (#5648) 2022-03-31 15:12:31 +02:00
Draper
d8e20afa1d Fix an incorrect comparison in audio (#5643)
Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2022-03-31 12:40:29 +02:00
Draper
511de5163f Update Audio to use RLL 0.11.0rc0 (#5631)
* Replace player.manager to player.node

* Try using bot.is_closed instead of get_voice_ws.

* Use Shard.is_closed instead of bot.is_closed.

* Use RLL PR as dep.

* Update audio to use add dep to https://github.com/Cog-Creators/Red-Lavalink/pull/122

* few thing missing

* Missing `player.manager.node` -> `player.node` change

* Update setup.cfg

Co-authored-by: PredaaA <46051820+PredaaA@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2022-03-31 11:44:09 +02:00
Draper
9ec85d4819 Audio changes (#5593)
* Squash tested commits

* remove the code jack is concerned about

* Apply suggestions from code review

* more log lines

* more log lines

* format

* formatting

* style(Rename Xms and Xmx mentions): Rename Xms and Xmx to more use friendly names

- Change Xms to "Initial Heapsize"
- Change Xmx to "Max Heapsize"

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2022-03-28 08:23:30 -07:00
TrustyJAID
5a5b22003f Fix embed requested in DMs (#5635)
* Fix embed requested in DM's

* Add documentation

* black

* Address comments

* Unnecessary added line

* Use correct channel on context

* use correct var name

* More review stuff
2022-03-22 21:04:45 +01:00
jack1142
c69e8d31fd Reformat with Black 22.1.0 2022-03-22 18:37:17 +01:00
jack1142
f6d9632c8f Bump Black version to 22.1.0 2022-03-22 18:37:17 +01:00
jack1142
d87199779e Prefer home directory even for system users if it exists (#5022) 2022-03-21 10:43:52 -06:00
jack1142
ed4f2cf466 Switch from low-level loop.create_task and asyncio.ensure_future (#5626)
* Switch from low-level loop.create_task and asyncio.ensure_future

* Patch vendored discord.ext.menus to use modern APIs as well

That ext is no longer maintained by Danny anyway so...

* black
2022-03-21 10:24:46 -06:00
jack1142
7a5ada2d92 Make decorator combining in Requires more consistent (#5625)
* Allow combining bot_has_permissions() decos

* Improve consistency for Requires.user_perms
2022-03-21 10:23:23 -06:00
jack1142
aa55b08a0a Set Red._color before login rather than in on_ready (#5627) 2022-03-21 10:23:09 -06:00
jack1142
0f299ae195 Support all Messageables in bot.embed_requested() (#5576)
* Support all Messageables in bot.embed_requested

* Update usage in core

* Simplify [p]contact

This couldn't be done before this change.

I have also simplified getting embed color.

* Make `True` the new default for `check_permissions` kwarg
2022-03-21 10:22:55 -06:00
Draper
f763d29fd4 Add and use Red-Commons library (#5624)
* update RC dep

* welp 100% tested

* fix import

* 120% tested

* Call _early_init even earlier

Not really in scope of this PR but the original was merged
before I could share any feedback.

* explicitly import getLogger

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2022-03-18 23:41:42 +01:00
Leothelion
335988c916 Update Kazakh Capital City Answer (#5599) 2022-03-18 17:52:25 -04:00
TrustyJAID
c8ff3c4cce Catch overflow errors for mutes time conversion (#5605) 2022-03-18 17:48:32 -04:00
Kuro
193cb3b035 [Downloader] Add argument to immediately reload or not (#5623)
* Add argument to immediately reload or not

* Style

* More detailed (and clear) description

* Better desc (ig)

* plurality

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-03-18 15:47:41 -04:00
Draper
2d9548ec0e Audio cleanup (#5618)
* add different logging level callbacks for task exception logging

* Add callback to tasks which didn't have them

* The boring stuff - (apply .trace() and .verbose() to audio, stop using debug_exc_log, delete audio_logging.py)

* Unsured import cleanup

* use new lavalink method

* return so it doesn't log this twice.

* improve logging on main event handler
2022-03-16 09:42:17 -07:00
Draper
593eeb5362 Add a custom Logger class with both verbose and trace levels. (#5613)
* rearrange commits

* Update redbot/setup.py

* change rich log level colours
2022-03-15 16:20:37 -04:00
GhOsT
7d716a2d67 Fix formatting breaking with nested formatting utils in help (#5601)
* Fix formatting breaking with nested formatters.

* Remove useless f-strings

* Revert formatting to the one before PR #5435

* One more small formatting revert

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2022-03-06 17:48:48 +01:00
jack1142
02f1ad919d Ask if changes were tested in PR template (#5580) 2022-02-28 18:08:16 +01:00
TrustyJAID
58d8cb4d1f Fix grammar in uptime command (#5596) 2022-02-28 15:57:59 +00:00
aikaterna
2ee64618af Fix spelling error (#5588) 2022-02-23 02:48:37 +00:00
jack1142
a6590b0380 Update redgettext to version 3.4.2 (#5584) 2022-02-21 15:21:59 +00:00
jack1142
50f3168b14 Update redgettext to version 3.4.1 (#5583) 2022-02-21 15:10:58 +00:00
jack1142
299a537f84 Update redgettext to version 3.4 (#5582) 2022-02-21 15:56:33 +01:00
jack1142
eeffbf8231 Avoid potential memory leak in Filter cog (#5578) 2022-02-20 22:52:58 +01:00
jack1142
0338e8e0a8 Avoid 'editing' message with no changes when case is created (#5577) 2022-02-20 16:42:56 -05:00
jack1142
78dc1d4cd8 Update discord-ext-menus vendor to latest commit (#5579)
Vendor `discord.ext.menus` from commit `fbb8803779373357e274e1540b368365fd9d8074` at Rapptz/discord-ext-menus
2022-02-20 22:01:40 +01:00
crayyy_zee
8d46568180 Add typechecking to config from_id methods (#5564)
* [config] Add typechecking for parameters

* change instance check

* Knew it, shouldnt have added these

* black
2022-02-20 15:50:07 -05:00
jack1142
b0ab6186ef Ensure that registered Config defaults are serializable to JSON (#5557) 2022-02-20 15:49:39 -05:00
jack1142
9baf9ba546 Fix number of cogs in Getting started doc after Bank cog removal (#5516) 2022-02-20 15:48:59 -05:00
jack1142
669f3e3073 Emphasize lines with things to replace in autostart guides (#5548)
* Emphasize lines with things to replace in autostart guides

* Use 'default' pygments style instead
2022-02-16 12:47:22 -05:00
Dav
c6517d5087 [Core/Core Cogs] Prevent translation errors and use formatting utils (#5435)
* Use proper syntax for inline formatting in core_commands

* use proper formating utils in core and core cogs wherever reasonable

* tests are awesome

* ensure "(continued)" is translated in help.py

* add colons to translatable strings for easier context comprehension by translators

* Thx flame :)

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* good point

Co-authored-by: Dav <dav@mail.stopdavabuse.de>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2022-02-15 20:25:21 -05:00
Vexed
9ab307c1ef Remove specific number of steps in update docs (#5556)
* change 4 to a few bc 4 is a lie

* wait linux exists

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2022-01-29 18:30:15 +01:00
jack1142
e33985f969 Disallow crawling of versioned documentation in robots.txt (#5549) 2022-01-29 17:16:44 +01:00
Flame442
b05933274a [Audio] Fix UnboundLocalError in edge case (#5394)
* Fix UnboundLocalError in edge case

* Fix typehint for fetch

* Style
2022-01-12 09:20:22 -08:00
untir_l
05cd11b657 Fix typo in Audio seek command description (#5530) 2022-01-11 08:35:50 -08:00
jack1142
de53d15cf8 Update copyright (#5526) 2022-01-10 17:52:36 +01:00
jack1142
cfa8f15faa Update "copyright notice" for Dev cog (#5527) 2022-01-10 17:52:20 +01:00
aikaterna
6ff844e605 Fix formatting in error message about already installed cog (#5531) 2022-01-05 01:52:15 +01:00
jack1142
fbe378657c Red 3.4.16 - Changelog (#5520)
* Red 3.4.16 - Changelog

* Add contribs!
2021-12-31 19:08:06 +01:00
jack1142
a4ba249e27 Red 3.4.15 - Changelog (#5504)
* Red 3.4.15 - Changelog

* Use stronger words

* Add jar stuff

* Add 5499

* Minor grammar stuff

* add 5472

* Add 5452

* Add 5448

* Add date and contributors

* Update docs/changelog_3_4_0.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* the other thing

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2021-12-31 03:13:00 +01:00
jack1142
1ecbe6cebb Only check for permissions when check_permissions is True (#5510) 2021-12-31 02:51:06 +01:00
Just-Jojo
a787033e1d [Events] Rename guild remove listener (#5498)
* [Events] on_guild_leave => on_guild_remove

* [Events] on_guild_leave => on_guild_remove
2021-12-31 02:22:29 +01:00
jack1142
8cc004f70f Add non-interactive mode to redbot-setup (#5448)
* Simplify `redbot-setup backup` thanks to Click 8.0

* Add some of the missing type hints

* Fix unnecessary new lines in `redbot-setup` and `redbot-setup delete`

* Add default value for storage backend

* Add non-interactive mode to `redbot-setup`
2021-12-31 02:08:18 +01:00
jack1142
ff7c146b62 Make embeds in help output consistent (#5452)
* Add `check_permissions` kwarg to `bot.embed_requested()`

* Make embeds in help consistent regardless of why it's being sent
2021-12-31 02:01:23 +01:00
Kowlin
faab711ec8 Ensure Nitro users can't make CCs that are too long (#5499)
* Ensure Nitro users can't make CCs that are too long

Co-authored-by: TrustyJAID <TrustyJAID@gmail.com>

* Tox formatting

* Update to account for edits and better handling of randoms

Co-authored-by: TrustyJAID <TrustyJAID@gmail.com>
2021-12-31 01:39:39 +01:00
aikaterna
c49d0ec9d3 Update Lavalink.jar, Red-Lavalink and make changes to support it (#5474)
* Lavalink error handling update

* comment typo

* address review

* Update redbot/cogs/audio/core/events/lavalink.py

* Bump jar version

* Bump RLL version

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-12-31 01:16:28 +01:00
GhOsT
337f58f9fb Fix short help in docstrings for core cogs and commands (#5502)
* fix part of command description not appearing in the help command.

* Add more

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-12-30 22:31:01 +01:00
Flame442
dce2378806 Prevent unexpected timedelta matches (#5393)
* Prevent unexpected matches by asserting whitespace or eof at the end of matches

* Use a positive lookahead instead of a capturing group to support 1d6h syntax

* Use fullmatch instead of modifying regex strings
2021-12-30 00:46:36 +01:00
jack1142
9c05db1104 Allow mocking attachment-only msg, fix docstring, small refactor (#5446)
* Use the logic from `[p]mock` in `[p]mockmsg`, fix docstring

* Let people mock attachment-only messages

* Use empty string, not None
2021-12-26 22:04:36 +01:00
jack1142
90406be9ea Remove old note about updating Red in Unix install guides (#5439)
This was removed long ago from the Windows guide (#4119) but it seems like we never got around to removing it from Unix install guides as well.
This note is rather inaccurate and the source of truth for updating Red is available in the Updating Red document.
2021-12-26 21:50:54 +01:00
jack1142
d1df27bc14 Update supported OSes (add Alma Linux, RPi OS 11, drop EOL OSes) (#5440)
* Drop Fedora 33

By the time we release, it's going to reach EOL.

* Drop Raspberry Pi OS 10, add support for 11

* Bring RPi OS 10 back

* Add Alma Linux 8

* Fix-up RHEL EOL dates

* Add '(Legacy)' to Raspberry Pi OS 10

* Drop CentOS 8
2021-12-26 21:50:22 +01:00
jack1142
e5b8fc4585 Bump Python version in install guides to 3.9.9 (#5447) 2021-12-26 21:45:56 +01:00
jack1142
db0f4ce44d Add jack1142 as code owner of install/update guides (#5493) 2021-12-26 21:12:23 +01:00
Parnassius
5a047bf979 Make emptydisconnect disconnect when all vc members are bots (#5421)
* [Audio] Disconnect from voice chat when every connected user is a bot

* Update condition according to code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-12-26 19:09:37 +01:00
Stonedestroyer
6297bfcab6 Make invite URL part of public API (#5424)
* Make invite URL public API

* Add doc and RPC

* Lint

* Update redbot/core/core_commands.py

Co-authored-by: Matt <psykzz@users.noreply.github.com>

* Update redbot/core/bot.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* RPC handling,

* Fix appinfo

* Change docs

* Fix docs

* Change docs

* Update redbot/core/core_commands.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Docstring changes

* nit

Co-authored-by: Matt <psykzz@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-12-25 22:08:32 +01:00
Vexed
d27dbded8a Fix RPC cog load and unload by returning dicts (#5453)
* use dicts for CoreLogic package management returns

* address review

* failed_packages->notloaded_packages in _unload

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-12-25 21:11:48 +01:00
Alex
a228a0d0b3 Show role payday amounts in economyset showsettings (#5457)
* [V3/develop] show RolePaydayAmounts in showsettings command

* Update economy.py

* Switch to using a list (nitpicky optimizations)

https://docs.python.org/3/faq/programming.html#what-is-the-most-efficient-way-to-concatenate-many-strings-together

* Mark the text as translatable

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-12-25 18:08:13 +01:00
Jan
7db3339aba isolate direction of username within modlog (#5422)
* isolate direction of username within modlog

* Add link to Unicode's usage

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-12-25 17:34:02 +01:00
MAX
b091f13df5 [Core] Changed prefix length to 40. (#5476)
* Update core_commands.py

* Docs yes facebook's metaverse

*jokes on me*

* meta

* forgot here

* Update core_commands.py

* Forgot here

* And forgot here
2021-12-25 04:14:16 +01:00
Toby Harradine
e878483318 [Config] Add type-hints to _ValueContextManager methods (#5344)
Without these type-hints, I've found that PyCharm misidentifies the returned type, causing a number of false positives in static type checking.
2021-12-25 03:19:18 +01:00
MAX
551e6d9f55 Update host list with new locations for Hetzner and Contabo (#5475) 2021-12-25 03:12:03 +01:00
Vexed
cef55459c6 Fix issues with loading config.json when it doesn't exist (#5416)
* catch and handle FileNotFoundError when using --no-instance when config.json does not already exist

* move load_existing_config to data_manager.py

* use load_existing_config in create_temp_config

* Fix import in redbot-launcher

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-12-25 03:02:44 +01:00
aleclol
5e527cb27d Add necessary None checks to Core's usage of Requires.privilege_level (#5477)
* Check if it has a privilege level

* Let's fix this in warnings too

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-12-25 02:04:33 +01:00
Ryan
bae85c35c1 [Docs] Correct set api examples to be consistent for Spotify (#5444)
* consistant usage

* switch audiodb to youtube

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-12-25 01:05:23 +01:00
PredaaA
4e469ce15e Remove voice region field in [p]serverinfo (#5449)
* [General] Remove guild region on serverinfo

* Remove in string too.
2021-12-25 01:02:37 +01:00
Kreus Amredes
e068294cc8 Restrict [p]cleanupset notify to guild only (#5466) 2021-12-25 00:54:37 +01:00
krak3n
2c51182e8e Add plural forms to the responses of [p]leave command (#5391)
* Improve the response of `[p]leave` command

* Update core_commands.py

* Update core_commands.py

* style?

* fix maybe

* black

* fixed typo in docstring

* aaa

* style

* Few more changes

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-12-25 00:51:17 +01:00
sravan
442cad7917 [Mod] Typo in unban command (#5470) 2021-12-23 02:51:55 +01:00
Leet
e993e749ee Update links to installation guides in README (#5426)
* Update links to installation guides

* Update Windows link

This one redirects correctly but updated it anyways

* Update all red-discordbot.readthedocs.io links to docs.discord.red
2021-12-23 02:48:05 +01:00
Kreus Amredes
bf0fab8575 Remove Bank cog from labeler configuration (#5464) 2021-12-11 15:57:05 +01:00
Kowlin
0158dbab1d Reorganize [p]set command group (#5432)
* Reorganised Set command group

* Moved custominfo

* Tox styling

* Make `set locale&regionalformat` groups work same as server subcommands

* Use consistent method names for commands in `[p]set` group

* Update command names in docstrings

* Remove some weird rst formatting that bugs out my syntax highlighting

* Add checks to some command groups

* Update docs

* oops

* Minor fixes

* Move `[p]set api` group and its subcommands to other command groups

* Move `[p]set ownernotifications` group to other command groups

* black reformat

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-12-01 21:35:30 +01:00
palmtree5
6acdcdeae9 Move modlogset/bankset commands to core (#4486)
* Move bankset and modlogset to core commands

* Move prune over too

* Finish moving prune

* Move [p]economyset registeramount to [p]bankset registeramount

* style fix

* Fix circular import issue with another breaking change

* Apparently I missed a conflict and git still let me commit...

* Really git?

* Rename RawUserIds -> RawUserIdConverter, improve documentation

* Improve documentation of `is_owner_if_bank_global()`

* MENTION_REGEX -> USER_MENTION_REGEX

* Add 'bank.' prefix

* Fix command examples in docstrings

* Missing docstring change from `bankset prune`

* Missing changes for commands in modlogset

* Update docs

* Remove duplicated info in `economyset showsettings`

* Fix toctree in index.rst

* Add command group prefixes to names of functions for bankset/modlogset

* Remaining string updates due to command name changes

* Ensure that the bank folder is actually gone

Co-authored-by: palmtree5 <palmtree5+3577255@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-11-25 10:06:30 +01:00
jack1142
fc560db72d Stop fetching the messages when getting the cases in Modlog (#4977)
* Use PartialMessage when Case is fetched from Config

* Update docstring
2021-11-05 12:18:23 +01:00
jack1142
4ec0d2bb01 Add guarantees for supported OS versions (#5437) 2021-11-03 18:11:46 +01:00
jack1142
78c92cc766 Address common issues with load path configuration in docs (#5356)
* Add instructions on how to add pyenv to load path

* Support zsh in pyenv load path instructions

* Make instructions for Mac work when shell-specific profile file exists

* Includes are weird...

* .

* Fix my misunderstanding of what files zsh sources

* Operator precedence, or something like that
2021-11-02 12:38:06 -07:00
Kowlin
6c4e5af5ee Check to avoid an IndexError (#5429) 2021-11-02 11:53:42 -07:00
jack1142
3f4842603b Remove currently deprecated functionality (#5433) 2021-11-02 13:04:45 +01:00
jack1142
f071ec09e2 Try to fix base branch in Publish Release workflow *again* (#5340) 2021-11-02 13:02:01 +01:00
Predeactor
483ef36d1b Modernize syntax in chat formatting module and add success() (#5427)
* Downloader's plurial & Fix

* Don't forget pipinstall

* Fix syntax issue

* This f****** fix that took me too much of my time for nothing.

* Black

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Fix Jack's syntax, remove numbers & fix bad calculated cogs

* Black ofc

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Address my review comment

* Simplify

* this is kinda a lot but shh

* Change format to f-string

* Add success function to char_formatting

* Revert "Merge branch 'V3/develop' of github.com:Predeactor/Red-DiscordBot into master/chat-formatting-enhancement"

This reverts commit c338da7b66, reversing
changes made to f2422ad782.

* For once I would have appreciated if style checks were failing...

Co-authored-by: Predeactor <ubuntu@vps-35e65bf5.vps.ovh.net>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-10-27 14:34:20 +02:00
Rasmus Wriedt Larsen
42293afd43 Fix CodeQL workflow (#5412)
The new pip 21.3 (released 2021-10-11) uses in-tree builds when `pip install .` is used (see [release notes](https://pip.pypa.io/en/stable/news/#v21-3) and [implementation PR](https://github.com/pypa/pip/pull/10495)). This means CodeQL will see all files twice (once in the real location that is part of this repository, and one in the copy in the `build/` dir), which trips up the analysis.

When an editable install is used instead with `pip install -e .`, there is no `build/` dir, so the analysis will work again.
2021-10-20 16:50:01 +02:00
jack1142
7abc9bdcf1 Pre-fetch app owners and fail early on no owners (#4926)
* Pre-fetch app owners and fail early on no owners

* Improve command mention in error message

* Further change the order of startup actions
2021-10-20 12:13:07 +02:00
jack1142
6db5c866af Rename RedBase to Red, remove the old Red (#5159)
* Rename RedBase to Red, remove the old Red

* Update docs references

* add noindex directives
2021-10-20 12:12:55 +02:00
Crossedfall
a70f0b7872 [Docs] Removes LXC as an unsupported hosting platform (#5351) 2021-10-20 12:10:13 +02:00
Ryan
4348318fd1 Update JDK URL and add Python version upper-bound in Windows guide (#5403)
* Update Java URL

* Update choco package as well

* Use Windows-specific URL for Python downloads

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-10-20 11:41:43 +02:00
Kreus Amredes
b64ece3ee9 [Admin] Add [p]selfroleset clear command (#5387) 2021-10-17 18:51:04 +02:00
Flame442
d56f31a708 [Mutes] Fix vars not getting formatted due to previous PR (#5404)
* Fix vars not getting formatted due to #5364

* Only format a second time if needed

* Format only on string literals
2021-10-17 02:56:26 +02:00
Kowlin
67bcd72d9c Update the timestamping we forgot to Discord compatible timestamping (#5395) 2021-10-16 21:38:52 +02:00
Dav
1d34e9e47b [Downloader] Show repo name in findcog (#5383)
* show repo name in findcog

* how did i manage to overcomplicate this?

* for Kreusada

* I wanted to do that... but forgot
2021-10-16 02:10:57 +02:00
WreckRox
9aee8ce28f Fix descriptions for examples of ID-based command invocations in Mod (#5372)
* Fix wording in redbot/cogs/mod/kickban.py to match with the command example

* Made changes as requested in PR Review #770078179

* Added changes to docs/cog_guides/mod.rst as requested in PR Review #70784066

* Fixed kick wording

* Fix kick wording
2021-10-16 01:29:15 +02:00
krak3n
17dc9e0c47 [Mod] Indicate successful run in [p]voicekick (#5367) 2021-10-16 00:50:58 +02:00
MAX
b8535ee53e Add a tick on traceback command when it's sent to DMs (#5353)
* add a `tick` when sent to dm.

* confused ™️

* did i learn now? :P

* i'm not confused anymore :3
2021-10-16 00:47:13 +02:00
jack1142
4b70acb989 Do not include expected wait_for responses in translated strings (#5364)
* Do not include 'I agree' prompt in translation string

* Add more stuff

* Address review comment

* Address review comments
2021-10-16 00:02:35 +02:00
jack1142
334cd4fa2a Add optional message to send when bot can't react in ctx.tick() and ctx.react_quietly() (#4092)
* Update context.py

* Pre-emptive check to avoid hitting the API
2021-10-15 18:44:12 +02:00
Kreus Amredes
a8f35f762c Improve helpset showaliases docstring (#5376) 2021-10-07 12:22:35 -07:00
aikaterna
6eb922e7d9 [Audio] Remove extra whitespace (#5366) 2021-10-03 21:10:32 +02:00
Fixator10
b4037a80d8 fix possible issue when joined_at is None (#5361) 2021-10-02 11:08:17 -04:00
El Laggron
cb18a66336 Initialize driver before starting the backup (#5315) 2021-09-23 22:38:50 +02:00
jack1142
cddd99eba7 Red 3.4.14 - Changelog (#5335)
* Red 3.4.14 - Changelog

* Add contributor list

* proofreading 1

* Fix plural form
2021-09-23 21:08:47 +02:00
River
92cabd134d Update some link texts in docs for accessibility (#5310)
* Update some link texts for accessibility

* Fix stuff nearby while we're here

* Reword links to DigitalOcean

* Use better link text for `[p]triviaset custom`

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-23 18:41:51 +00:00
jack1142
2c8c97490b Maybe fix the base branch used in dev bump automation (#5307) 2021-09-23 17:56:33 +02:00
Leet
2ce8e65527 Only initialize and teardown driver if actually needed (#5313)
* Fix #5312

* Update setup.py

* put db actions under one if statement

* check backend type and improve displayed message

* accept format fix

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* fix whitespace

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* separate datapath delete from data delete

* Fix indentation

* Call `driver_cls.initialize()` outside try-finally

* Backup requires db server to run too + some simplifications

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-23 17:34:38 +02:00
MAX
d69326b1fe Use discord native timestamp in [p]uptime (#5323)
* support for discord's timestamp on uptime

* woops not supposed to remove `_`.

* ups

* ups x2

* Apply suggested change.

* hehe
2021-09-23 16:22:16 +02:00
jack1142
cbbb9d9b9b Split documents per OS, fix few things, drop and add few OSes (#5328)
* Exclude include files from being built

* Split install guides into multiple documents (one per OS/version combo)

* Update references

* Unify anchor names

* Update pyenv requirements in CentOS 7 guide

* Update install guides for RHEL derivatives to not use pyenv

* Add guide for Rocky Linux 8

* 8.4+ -> 8.4-8.x

* Add 'the'
2021-09-22 20:13:58 -07:00
aikaterna
b2e9b38a03 [Audio] Update Lavalink.jar build (#5329) 2021-09-23 02:32:11 +02:00
Kowlin
89e3a78ead Fix Case's modified_at attr and its format in message content (#5317)
* Fix modified_at field to properly format.

* let's just fix the type hints

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-14 02:42:20 +02:00
jack1142
eeed082542 Red 3.4.13 - Changelog (#5302)
* Add 3.4.13 section

* PR 5156 (issue 4997)

* PR 5178 (issue 5177)

* PR 5185, 5187

* PR 5184

* PR 5186

* PR 5165

* PR 5188

* PR 5225

* PR 5180

* PR 5181 (issue 4868)

* PR 5221 (issue 5216)

* PR 4659 (issue 4571)

* PR 5173

* PR 5155, 5241

* PR 5199

* PR 5205 (issue 4074)

* PR 5238 (issue 5237)

* PR 5169

* PR 5214

* PR 4981 (issue 4841)

* PR 4837 (issue 4836)

* PR 5218 (issue 4732)

* PR 5233

* PR 5211 (issue 5187)

* PR 5108

* PR 5223 (issue 5195)

* PR 5234

* PR 5243 (issue 4717)

* PR 5000 (issue 4140)

* PR 5206 (issue 5171)

* PR 5121 (issue 4655)

* PR 5217 (issue 5213)

* PR 5037

* PR 5109, 5163, 5172, 5191

* PR 4968

* PR 5048, 5092, 5149, 5207, 5209, 5215, 5219, 5220

* Fill 'Read before updating' section

* Add contributor list

* few fixes

* Apply suggestions from code review

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2021-09-09 23:48:51 +02:00
PhenoM4n4n
e5b236fb1c Add CommandConverter and CogConverter + add usage in Core (#5037)
* add commands, cog converter

* properly use type_checking

* make core commands use command converter

* update commands to use cogconverter

* fix undefined variable name, style

* Update redbot/core/commands/converter.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/commands/converter.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/core_commands.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/core_commands.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/core_commands.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/core_commands.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/core_commands.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* update cog argument names

* update documentation arg names

* update more docs

* This new Sphinx is annoying about this...

* I'm questioning my skills

* Fix name error in `[p]embedset showsettings` when command is not given

* Do not use the new cog converter in `[p]command enablecog`

This is needed so that a cog that isn't loaded but was disabled
can be enabled back.

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-07 23:43:29 +02:00
Kreus Amredes
63fd7cc95f [Docs] Update Cleanup docs with new cleanupset command group (#5245)
* Add cleanupset commands to cleanup docs

* fix spacing

* shown -> sent

* update command docstring

* Fix trailing whitespace and use same style for docs

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-07 21:12:46 +00:00
Ryan
33dddaf5b4 Add Debian 11 to install guide and clarify "Buster" as Debian 10 (#5217)
* Clarify Debian 10 as "Buster"

* Add Debian 11 Install

* This typo would of bugged my OCD...

* Clarify Debian 10 as "Buster"

* Add Debian 11 Install

* This typo would of bugged my OCD...

* Add apt upgrade line to doc

* Removing dupe for Debian 11
I'm not sure how that happened, but oh well...
2021-09-06 23:33:34 +02:00
palmtree5
3254698c78 Update deps, allow Python 3.9, drop Fedora 32 (#5121)
* Update deps + allow Python 3.9

* Add in updates from Jack's branch

* Fix multiple target for cross-reference warnings

* Update a few more Python 3.8 occurrences

* Bump further

* Don't install tox in CodeQL environment

* Bump Python version in docs to 3.9.7

* more bumps

* Add missing pin

* Stop using the deprecated distro.linux_distribution()

* Suppress deprecation warning

* Fix OpenSUSE Leap instructions

* Drop Fedora 32

* Add Python 3.10-dev to CI

* meh

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-06 18:43:29 +02:00
Just-Jojo
0dded8aa47 [Core] Add more APIs for allowlists and blocklists (#5206)
* [Core] Blacklist api

* [Core] Use to_add, remove star from other method calls

* various touch ups

* style

* fix doc style

* [Core] Remove iterable import

* [Core] Update commands to use the blacklist/whitelist api

* Change signatures to not use `*args`

* Update all usage of private cache to the new public APIs

* Update the docstrings

* Update the usage in diagnoser

Co-authored-by: Kreusada <67752638+Kreusada@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-06 18:38:07 +02:00
Zoë F
ed9bb77eec Add RelativedeltaConverter and parse_relativedelta (#5000)
* Added years and months to parse_timedelta

* Added new parse_datetimedelta along with classes for relative dates

* Switched datetime as dt to just datetime for clarity

* Changed to returning relativedelta instead of datetime

* Fixed single char typo

* After some digging, removed min and max from relative delta b/c of https://github.com/dateutil/dateutil/issues/350

* Add dateutil to intersphinx mapping

* Change uppercase D in RelativeDeltaConverter to a lowercase D

* Fix cross-references in docstrings

* Add new class and methods to __all__

* Remove get_relativedelta_converter()

* style

* Fix name of parse_relativedelta test

* more style

* Re-export new class and function in `redbot.core.commands`

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-06 02:50:21 +02:00
jack1142
86649e897f Add [p]diagnoseissues command (#5243)
* Split `Requires._transition_state` into reusable methods for Diagnoser

* (style) Fix line length

* Add missing .format()

* Add handling for user permissions, privilege level, Permissions rules

* Add missing awaits, use correct method in user perms check, add 'the'

* Fix .format() fields

* Add comment

* Add new file to labeler's configuration

* Add the command to the documentation

* All the work from DiagnoserCog

You can find the commit history of it here:
https://github.com/jack1142/DiagnoserCog

* Fix circular import

* Make channel argument optional

* Add a tip about channels from different servers
2021-09-05 19:01:46 +02:00
jack1142
d84c8efa34 Update Mac OS instructions to work properly on Apple Silicon (#5234) 2021-09-04 10:56:43 -07:00
jack1142
a0a433b13d Improve and add more usage of discord timestamps (#5241)
* Improve and add more usage of discord timestamps

* How did that whitespace get there?
2021-09-04 09:14:05 +02:00
PredaaA
4366af6f6c [Cleanup] Handle NotFound error of prompt in check_100_plus (#5191)
* [Cleanup] Handle HTTPException of prompt in check_100_plus

* Update redbot/cogs/cleanup/cleanup.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-04 00:38:03 +02:00
PredaaA
42edb12b2e [Trivia] Handle potential Discord errors in session (#5172)
* [Trivia] Handle potential Discord errors in session.

* Hm why did I put HTTPException in there

* Revert "Hm why did I put HTTPException in there"

This reverts commit dc5cb990cb.

* Revert "[Trivia] Handle potential Discord errors in session."

This reverts commit d90e45f9e0.

* Handle Discord errors in _error_handler.
2021-09-04 00:36:48 +02:00
Lui
36ea867dcf [Streams] Check non-existent streams more than once (#5223)
* [Streams] Check non-existent streams more than once

- For YouTube streams, it seems like the RSS feed may sometimes return
  an HTTP 404 for a channel, even though the channel exists.
- If this happens more than a few times, then we should declare the
  stream as non-existent, and purge it from the list of streams we
  check.

* [Streams] Move retry_count reset for YouTubeStream

- Reset after the RSS check, since that is the only place where we raise
  StreamNotFound in that function.

* [Streams] Increase retry to 20

* [Streams] Reduce retry count to 10
2021-09-03 16:25:01 +02:00
Samuel
cad7f400f9 Add commands for editing aliases (#5108)
* [Alias] Added alias edit and alias global edit

* Comment and whitespace only changes

* Docstring fix

* Remove more whitespace

* Add `the` before some English purists make a PR for this...

Co-authored-by: npc203 <npc203@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-03 01:50:08 +00:00
jack1142
6d40de8da3 Invalidate cache in filter clear commands 2021-09-03 03:37:25 +02:00
Enul
8880251749 [Mod] Add user hierarchy check to [p]rename (#5211)
* added hierarchy check for rename

added hierarchy check for rename from utils

* format and self check

changed formats and added statement if me != member

* black format

apply black formatting and fix typo

* tox style 

tox i guess

* tox again 

:<

* Update redbot/cogs/mod/names.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Fix styling

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-03 01:08:46 +00:00
aikaterna
17d24b28f1 [Audio] Update Lavalink.jar build (#5233) 2021-09-03 02:30:04 +02:00
Jamie
c4f8f65d4d Add toggleable notification of deleted messages count in Cleanup (#5218)
* Addition of cleanup notification.

* black

* subtract invoking message from count

* Update redbot/cogs/cleanup/cleanup.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* be explicity about kwarg

* address review

* style

* Fix type hints

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-03 01:12:28 +02:00
Kreus Amredes
4e2e4bfe6a [Mod] Send ban reason on Temp Bans (#4837)
* [Mod] Send ban reason on Temp Bans

* If none

* Locale friendly

* Fixes for black style

* Use double line break to distinguish between reason header

* Check settings

* Black

* Reduce the number of config calls

* remove additional config call

* fixes

* style

* We're already in `if reason` so this is always True

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-02 19:07:07 +02:00
Kreus Amredes
f628093208 [Filter] Add filter clear commands (#4981)
* [Filter] Add filter clear commands

* define messagepredicate

* actually send msg, lol

* deco fixes

* black

* [Docs] Update filter documentation

* fixes

* style

* Add missing whitespace

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-02 17:55:58 +02:00
jack1142
6f0a8b11d7 Add test for presence of upper and lower bound on Python version (#5198)
* Add test for presence of upper and lower bound on Python version

* [part 1/3] Test that this works, DO NOT MERGE

* [part 2/3] Test that this works, DO NOT MERGE

* [part 3/3] Revert unwanted changes, NOW YOU CAN MERGE!
2021-09-02 01:52:27 +02:00
jack1142
f6cf0d5670 Allow dots in the middle of repo names (#5214)
* Allow dots in the middle of repo names

* Screw you, Black
2021-09-02 01:45:25 +02:00
PredaaA
8eac787f7b [Streams] Improve config calls in stream alerts (#4968)
* [Streams] Improve config calls in stream alerts.

* config->guild_data, style changes

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-02 01:40:15 +02:00
jack1142
88abe469b6 Accept mentions in [p]cleanup user (#5169)
* Accept mentions in `[p]cleanup user`

* Updated spacing & formatting on info logging

* Whoops...

Co-authored-by: Kowlin <boxedpp@gmail.com>
2021-09-02 01:08:13 +02:00
Kreus Amredes
b0f93a3ce1 [Admin] Allow selfroleset command to consume multiple roles (#5238)
* Initial commit

* update docs

* remove usage kwargs

* style

* Type hint with SelfRole and not discord.Role

* fix docstring

* Various improvements, fixes

* i need to wake up

* more improvements

* AAAA

* add back check

* Improve converter error

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-01 22:37:45 +00:00
Vexed
f8664a4e8a [Help] Let owners set menu reaction timeout (#5205)
* initial help reaction timeout with min 15, max 300

* slight wording change

* docs!

* aaa

* Suggestions from code review, thank Jack!

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-09-01 18:35:11 +02:00
Kreus Amredes
6a8968e34d [Docs] Fix changelog entry from being under the wrong section (#5236) 2021-09-01 03:10:50 +02:00
Kreus Amredes
dbd25e92a1 Document parameters in remaining chat_formatting functions (#5215) 2021-09-01 02:51:59 +02:00
GhOsT
c57ef4828e [Core] add ctx.tick() to [p]invite (#5199) 2021-08-31 23:27:11 +02:00
Kreus Amredes
6bf85a42f8 [Downloader] Fix various formatting issues in cog update notices (#5185)
* again :P

* some more

* fix
2021-08-31 23:20:29 +02:00
Kreus Amredes
d15011e2c5 [Downloader] Suppress NotFound errors in [p]cog update command (#5109)
* [Downloader] Suppress NotFound errors when cog update message is deleted

* occurance 2
2021-08-31 23:19:15 +02:00
Kowlin
f05debc923 Initial support for Discord timestamping (#5155)
* Initial support for Discord timestamping

* Fix timezones

* Fix userinfo for users with member.joined_at equal to None

* Simplify

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-08-31 19:55:33 +00:00
PredaaA
b586c2f990 [Mod] Check if guild is unavailable in tempban expirations (#5173)
* [Mod] Check if guild.me is None else continue in tempban expirations.

* Check for guild.unavailable instead of guild.me being None.
2021-08-31 20:48:21 +02:00
Kreus Amredes
c34f1e2f01 [Mutes] Fix NotFound error when trying to delete message (#5163)
* [Mutes] Fix NotFound error when trying to delete message

* other occurances
2021-08-31 20:47:32 +02:00
Kreus Amredes
299d6c57d9 [Alias] Fix double plural grammar in alias docstring (#5092) 2021-08-31 20:46:12 +02:00
Grant LeBlanc
173127e015 [Trivia] Validate custom trivia file upload using schema (#4659)
* Add custom trivia list schema validation and test

* Address review

* Improve error formatting in trivia list test

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-08-31 20:44:25 +02:00
Twentysix
91ecd6560a [Docs] Add intents / public bots guide (#5221)
* [Docs] Add intents / public bots guide

* [Docs] Intent guide: update on d.py
2021-08-30 17:41:41 -04:00
Vexed
7413e3c350 [Logging] Make Rich more copy-/paste-able (#5181)
* commit work, mostly untested

* v minor refactor

* force new renderer

* Code style changes

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-08-30 22:15:26 +02:00
Kreus Amredes
d13d6477c5 [Docs] Update alias userdoc to reflect updated help menu layout (#5048) 2021-08-29 15:36:14 +02:00
Kreus Amredes
ee0627f41f [Docs] Getting started guide: fix incorrect information / typos (#5180) 2021-08-29 15:26:13 +02:00
Kreus Amredes
ec5428f1e9 [Docs] Fix argument formatting in Admin cog guide 2021-08-29 14:36:10 +02:00
Vexed
37c52d6066 [Docs] Add Oracle Cloud $300 credits to hosting guide 2021-08-29 14:33:00 +02:00
Kreus Amredes
48fa10343c [Docs] Fix warning block in Mod cog guide (#5220) 2021-08-29 14:31:13 +02:00
aikaterna
43071e3fa2 [Audio] Add a wait time before auto disconnect (#5188)
* Update lavalink.py

* Add comment

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-08-13 18:01:31 +02:00
jack1142
80e7a70f9e Fix base branch used for PyPI release? (#5212) 2021-08-13 04:08:39 +02:00
Kreus Amredes
11913806a4 fix typo (#5207) 2021-08-13 02:36:57 +02:00
fredster33
f42d675ac0 Update DO link (#5209) 2021-08-13 02:36:15 +02:00
Kowlin
e154a630df Add a per guild max volume setting (#5165)
* Oh great... someone touched Audio again.

* How did that get in there?

* Style? Style.
2021-07-16 14:45:54 -07:00
MAX
2b67b9d06d [Audio] UX improvements to [p]summon command (#5186) 2021-07-13 19:52:46 +02:00
Vexed
2ab46fbe41 use rich console print for red colour (#5184) 2021-07-07 04:46:47 +02:00
Kreusada
49cc9374d4 [Downloader] Fix formatting for red version requirement notices (#5183) 2021-07-06 18:50:10 +02:00
Just-Jojo
ad6b8662b2 [Warnings] Allow for 0 point warnings (#5178) 2021-07-03 23:52:59 +00:00
jack1142
9d35df2048 Add cherry_picker configuration (#5168) 2021-07-02 21:05:12 +02:00
jack1142
ec26687e9e Improve release correctness and safety by using GH Environments (#5167)
* Improve release safety by using GH Environments

* Exit early when just returning version
2021-06-30 17:24:18 +02:00
Kowlin
3b7f9e24b4 Refined debuginfo (#5156)
* Oh my gosh Kowlin is finishing work!?

* fix style

* use f-strings

* moar f-strings actually

* Fix style...

* I did a poor job of find-replacing things

* Improve code readability per previous Kowlin's style

* And reformat it in such a way that get jack through the day

* Okay maybe some whitespace

* Update core_commands.py

* Update core_commands.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-06-27 03:54:27 +02:00
Dav
0fb7c8bdba Raise on an uncompliant message in Context.maybe_send_embed() (#4465)
* Raise on uncompliant message

* just wait for me to be done flame! (grammar+testing)

* i liked this better
2021-06-24 08:22:58 +02:00
Draper
34b912bc7c Allow menu() to listen to both adding and removing reactions (#4517) 2021-06-23 18:48:06 +00:00
jack1142
a9dc93cf81 Version bump to 3.5.0.dev1 (#5154) 2021-06-23 20:33:02 +02:00
jack1142
52f96e043b Add simple PR template (#5150) 2021-06-18 18:34:42 -04:00
jack1142
5b58cdb449 Add missing changelog entries to Red 3.4.12 changelog (#5148)
* Add missing changelog entries to Red 3.4.12 changelog

* Update contribs list

* .

* Apply suggestions from code review

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2021-06-18 18:09:40 -04:00
Kreusada
8a6aa41d86 [CustomCommands/Docs] Fix argument name in [p]cc show command docstring (#5149)
* [CustomCom] Fix argument name in ``[p]cc show`` command docstring

* update docs
2021-06-18 17:48:46 -04:00
github-actions[bot]
e52fb2c086 Version bump to 3.4.13.dev1 (#5147)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-06-17 20:42:58 +02:00
github-actions[bot]
86c4d953a8 Version bump to 3.4.12 (#5145)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-06-17 19:53:56 +02:00
github-actions[bot]
539a475706 [i18n] Automated Crowdin downstream (#5146)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-06-17 19:53:18 +02:00
jack1142
36968a4bf0 Red 3.4.12 - Changelog (#5144)
* Red 3.4.12 - Changelog

* Add a comma...
2021-06-17 19:43:09 +02:00
jack1142
a99240f7c3 Remove support for Audio's Global API (#5143)
* Force-disable Audio's Global API functionality

* Remove owner message about global API

* Two more comments

* Update CODEOWNERS

* Bring back the owner notification, modified to not mention global DB

* Remove the global api group fully, remove the mentions of it
2021-06-17 19:27:56 +02:00
jack1142
be04ec1c86 Change default local cache level (#5140)
* Change default local cache level

* Update the owner message as well
2021-06-17 05:04:31 +02:00
Samuel
c3362f6eaa Update [p]addpath to use consume rest on the path argument (#5137)
Co-authored-by: npc203 <npc203@users.noreply.github.com>
2021-06-15 13:08:41 +02:00
Just-Jojo
b2db0674d5 [Warnings] (#5120) 2021-06-13 20:21:19 -04:00
Stonedestroyer
5ead38c284 Fix none issue (#5125) 2021-06-13 20:11:55 -04:00
aikaterna
8dffebbb34 [Audio] Change autoplay playlist url (#5135) 2021-06-13 14:44:49 +02:00
github-actions[bot]
5b03f04790 Version bump to 3.4.12.dev1 (#5133)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-06-12 19:04:24 +02:00
github-actions[bot]
8e6cf0be81 Version bump to 3.4.11 (#5131)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-06-12 18:53:40 +02:00
github-actions[bot]
5f0b4403bc [i18n] Automated Crowdin downstream (#5132)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-06-12 18:53:21 +02:00
jack1142
c23100eaca Red 3.4.11 - Changelog (#5130) 2021-06-12 18:46:34 +02:00
jack1142
1b6745549e Bump discord.py to 1.7.3 (#5129) 2021-06-12 18:31:38 +02:00
Kreusada
faf1ad4846 [Dev] Add ctx.tick() on successful debugs (#5107) 2021-06-12 17:52:06 +02:00
El Laggron
dafffd969f [Core] Limit server prefix length (#5117)
* Restrict prefix length

* Update docs
2021-06-12 17:41:29 +02:00
Onii-chan
a428e42f1f Update cogboard links (#5124)
* Update README.md

* Update guide_cog_creators.rst

* Update cog_manager_ui.rst

* Update README.md
2021-06-08 09:11:42 +00:00
Kreusada
ded5aff08c Move modlog guide to correct place in the labeler configuration (#5118) 2021-06-03 22:34:40 +02:00
jack1142
8f390147c1 Use rich.progress instead of tqdm (#5064)
* Use rich progress instead of tqdm

* Remove tqdm from deps
2021-06-03 21:37:53 +02:00
El Laggron
0ce2634bb3 [Core] Add toggle for the applications.commands invite scope (#5114)
* Add toggle for applications.commands invite scope

* Add support for i18n

* Fix formatting

Co-authored-by: Kowlin <boxedpp@gmail.com>
2021-06-03 17:36:28 +02:00
Draper
1ee4156ac6 Add Preda as code owner for audio files (#5095) 2021-05-31 14:52:18 +02:00
jack1142
1471ead0ce With each release we're getting one step closer... (#5090) 2021-05-28 20:44:58 +02:00
jack1142
d011b1f9af Version bump to 3.4.11.dev1 (#5089) 2021-05-28 20:40:15 +02:00
github-actions[bot]
fc4a995540 Version bump to 3.4.10 (#5086)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-05-28 20:17:54 +02:00
github-actions[bot]
ce4fd6cca8 [i18n] Automated Crowdin downstream (#5087)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-05-28 20:09:47 +02:00
jack1142
305161110e Red 3.4.10 - Changelog (#5077)
* Add 3.4.10 section

* PR 5082 (issue 4765)

* PR 5073 (issue 5008)

* PR 5071

* PR 5070

* PR 5066 (issue 5050)

* PR 5063

* PR 5066

* PR 5051

* PR 5041

* PR 5040 (issue 5039)

* PR 5035 (issue 5036)

* PR 5031 (issue 5032)

* PR 5028

* PR 5027 (issue 5026)

* PR 5025

* PR 5017

* PR 5004

* PR 4996

* PR 4987

* PR 4976

* PR 4971

* PR 5046

* PR 5044

* PR 5083

* PR 5030 (issue 4959)

* PR 5020

* PR 5018

* PR 5014

* PR 5012

* PR 4995

* PR 4994

* PR 4988

* PR 4980

* PR 4975

* PR 4970 (issue 4969)

* PR 4962

* PR 4960

* PR 4958 (issue 4956)

* PR 4954

* PR 4919

* PR 4886

* PR 4882

* PR 4875

* PR 4597

* PR 4082

* PR 4793, 4832, 4955, 4966, 5015, 5019, 5029, 5038, 5055, 5080, 5081

* PR 4979

* PR 5013

* PR 4991

* Reorder stuff

* Update date

* Add contributors list

* Mention the tracking issue for cog guides

* PR 4920 (issue 1734)

* PR 4985 (issue 1734)

* PR 5023 (issue 4595)

* PR 5085

* time to be explicit...

* Gotta include info about the new jar too...

* Apply suggestions from code review

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2021-05-28 19:56:30 +02:00
aikaterna
f0dab50097 [Audio] Update Lavalink.jar build (#5085) 2021-05-28 19:29:34 +02:00
Kreusada
b630e71d08 [Docs] Warnings Cog Guide (#4920)
* Initial commit

* labeler and index

* change parameter names and labeler

* fix typo

* docstrings, quotes and improved names

* merge conflict affect fixes

* remove aliases

* get from v3/develop

* update var names

* fixes

* improve grammar

* black
2021-05-28 19:06:52 +02:00
Kreusada
db86de3a7a [Docs] Permissions Cog Guide (#4985)
* Initial commit

* index and grammar

* Add permissions tag to permissions cog reference

* remove alias by default

* remove alias

* labeler

* updates
2021-05-28 19:06:42 +02:00
Kreusada
dd40f00279 [Docs] Trivia List Creation User Guide (#5023)
* Initial commit

* commits

* a few fixes

* caps formatting

* labeler

* a few formatting changes

* grammar for clarity

* grammar fixes
2021-05-28 19:06:32 +02:00
benno1237
177bd7f84e Update Dev's code block regex to support python language (#5083)
* Update dev_commands.py

* Update dev_commands.py

* Update redbot/core/dev_commands.py

regexes keep confusing me. thanks jack

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-05-27 17:44:22 +02:00
Vexed
210c07d5a7 [Downloader] Allow removal of multiple repos (#5082)
* add multi repo support + docstring

* update docs

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* style

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-05-27 14:47:41 +02:00
Kreusada
23997d7a71 [Docs] Modlog Cog Guide (#4919)
* Initial commit

* Docstring changes and index

* Add modlog cog guide to labeler
2021-05-26 13:30:23 -04:00
Lifeismana
c0f17c2155 Unify docstring (#5081)
To be the same as L725 and L1555
631adc282f/redbot/cogs/downloader/downloader.py (L725)
631adc282f/redbot/cogs/downloader/downloader.py (L1555)
2021-05-26 11:32:37 -04:00
TrustyJAID
631adc282f [General] Fix usage in choose help (#5015)
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2021-05-26 10:23:46 +01:00
jack1142
b8b8a38fbd Lower RTD build time (#5078) 2021-05-26 09:07:46 +01:00
Lifeismana
2d8dbad63b Docstring Fix (#5080)
* Missing word

* Make a little more sense
2021-05-25 17:58:10 +02:00
Draper
137713d9ca Update gitignore with more of Windows, Mac, Sublime, and PyCharm (#5079)
* Since i have these uncommitted locally sharing...

* clean up

* clean up

* noone can figure out how my pycharm got into this state .. but hey ho.

* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

* We don't need this comment, we already include these in gitgnore anyway

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-05-25 17:40:08 +02:00
Draper
0f4c409e84 Fix resume for auto play which was broken in RLL 0.8.0 update. (#5051) 2021-05-25 17:05:40 +02:00
Draper
ac0c5cc4c8 Fix resume for auto play which was broken in RLL 0.8.0 update. (#5051) 2021-05-25 17:04:45 +02:00
Draper
ca373052c5 Fix resume for auto play which was broken in RLL 0.8.0 update. (#5051) 2021-05-25 17:04:24 +02:00
jack1142
f8ecc32dbc Fix the bug with Twitch display name being set as Twitch login (#5066) 2021-05-25 09:32:32 +01:00
Vexed
982feda858 [Admin] Add logging to serverlock (#5073)
Co-authored-by: Twentysix <Twentysix26@users.noreply.github.com>
2021-05-24 12:03:43 +01:00
jack1142
2f7376169e Stop reloading unrelated modules (#4958) 2021-05-24 11:17:45 +01:00
jack1142
7459af25ba Specify that cleanup commands remove messages from current channel (#5070) 2021-05-23 15:24:17 +01:00
aleclol
820b21dccb [Mutes] Don't send dms to bots (#5071) 2021-05-23 15:24:08 +01:00
jack1142
c4a9d97a4b Include status code in APIError and handle APIError in the loop (#4995) 2021-05-23 15:23:58 +01:00
jack1142
b89c43eb0f Ensure nothing initializes colorama when it isn't needed (#5063) 2021-05-20 10:31:27 +02:00
Ryujin
a6c438e486 Update pronouns used for the bot in documentation (#5053)
* Update admin.rst

* Update admin.rst

* Update admin.rst

* Update admin.rst

* Update getting_started.rst

* Update admin.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-05-20 01:28:56 +02:00
Draper
994137426f check both connect and speak permissions before performing audio actions (#5012) 2021-05-19 21:29:40 +01:00
Draper
f3231682b0 Update application.yml + remove mixer support. (#5013) 2021-05-19 20:17:37 +01:00
jack1142
d5fbc0b01c Remove PM2 guide (#4991)
There's apparently no way to specify exit codes
for which the process should not be restarted.

This just shows how poor of a process manager PM2 is
so we really should not continue to recommend it in the documentation...

Ref:
https://stackoverflow.com/questions/43614017/how-to-only-restart-node-process-with-pm2-if-exit-code-0
2021-05-19 19:20:59 +02:00
jack1142
1c32186d0b Fix logging and handle NotFound exception in Case.edit() (#4975) 2021-05-19 18:10:15 +02:00
jack1142
8a7c4aa48c Bump discord.py to 1.7.2 (#5056) 2021-05-19 17:07:08 +01:00
Draper
3a9edd9434 Fix crash in [p]audiostats by using the new connected_at attr (#5046)
* This PR depends on Part 1 due to new `Player.guild` attribute and RLL bump to 0.8.1

- [player.store] notify_channel->channel
- [player.store] removed guild
- [player.store] removed connect
- changes in [p]audiostats

Co-authored-by: alec <50505980+aleclol@users.noreply.github.com>

* another one

* Update redbot/cogs/audio/core/commands/miscellaneous.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* style

Co-authored-by: alec <50505980+aleclol@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-05-19 17:56:53 +02:00
Kreusada
439033ea28 [Core] Improve regionalformat docstrings (#5055)
* [Docs] Update regionalformat docs

* [Core] Improve regionalformat docstrings
2021-05-19 14:47:29 +00:00
jack1142
e124ae3c11 Use ctx.send_interactive for SyntaxErrors in Dev cog
* Merge pull request #5041

* Use ctx.send_interactive for SyntaxErrors in Dev cog

* Paren in wrong place...
2021-05-19 15:36:18 +01:00
Kreusada
3ff2132570 [Core] Update [p]autoimmune remove docstring
* Merge pull request #5038

* update docstring

* update docs correspondingly
2021-05-19 15:10:31 +01:00
Draper
3f39a93e59 Stop shadowing variable in customcom's arg handling
* Merge pull request #5027

Stop shadowing variable in customcom's arg handling
2021-05-19 15:02:47 +01:00
jack1142
356922f4de Improve global exception handler log messages
* Merge pull request #4980

* Improve global exception handler log messages
2021-05-19 14:36:16 +01:00
jack1142
e2f0ac582b Add documentation for Case class in Modlog
* Merge pull request #4979

* Add documentation for Case class in Modlog
2021-05-19 14:10:19 +01:00
jack1142
9b66d19369 Fix KeyError for cached messages from deleted channels in Streams
* Merge pull request #5031

* Fix KeyError for cached messages from deleted channels in Streams
2021-05-19 14:03:28 +01:00
Kreusada
01f86091ab [Context] Fixup docstrings in react_quietly function
* Merge pull request #4955

* [Context] Add cross function, typo fixes in react_quietly()

* Remove cross function

* Remove cross variable
2021-05-19 13:35:36 +01:00
Danstr5544
56099d6b50 Attempt to DM users before applying a warn action.
* Merge pull request #5004
2021-05-19 13:06:51 +01:00
jack1142
fa4990f327 Fix --rich-traceback-extra-lines cli flag
* Merge pull request #5028
2021-05-19 13:00:31 +01:00
Kreusada
606c2f50ba [Help] Strip docstrings before shortening them (#4983)
* [Help] Strip docstrings before shortening them

* [Help] Use rstrip instead of full strip
2021-05-19 13:58:48 +02:00
jack1142
53276ea12a Update instructions to use Python 3.8.10
* Merge pull request #5025
2021-05-19 12:54:45 +01:00
Fixator10
c40efd479b [Mutes] Handle Forbidden in mute_channel
* Merge pull request #4994
2021-05-19 12:49:37 +01:00
Fixator10
a58ac7cd2e Change order of config calls in the Economy cog to only execute them when necessary.
* Merge pull request #5002
2021-05-19 12:40:12 +01:00
Vexed
31cb4c0604 Require read message hist perms for help menu (#5030)
[Help] Require read message history perms for reaction menu (#5030)
2021-05-19 12:28:13 +01:00
Kreusada
700802c303 Merge pull request #5014
* [General] Provide the urban command with embed color

* spelling consistency...
2021-05-19 12:25:54 +01:00
Draper
00d2d62f1b [Audio] Disallow all users from modifying Playlist 42069. (#5018) 2021-05-19 11:41:51 +01:00
Kreusada
c36665e755 [Modlog] Add confirmation prompt to [p]modlogset resetcases (#4976)
* [Modlog] Confirmation for resetting modlog cases

* We need to return there

* Update modlog.py

* style

* Update redbot/cogs/modlog/modlog.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-05-19 12:39:41 +02:00
bobloy
75ce67837a embedset - fix perm check for subcommands, add missing return (#4962) 2021-05-19 12:19:28 +02:00
Jamie
c83eae931b [Streams] Add guild only decorator to streams commands (#5035)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-05-19 11:58:50 +02:00
Draper
ea82119605 Ensure track is properly resumed in an edge case (#4996) 2021-05-19 10:25:19 +01:00
Draper
42101275d5 Fix crash in [p]audioset restart (#4987) 2021-05-19 11:21:50 +02:00
Draper
38da7370ec Bump RLL and improve logging (#5044)
* version bump

* - bump RLL
- logging changes
- player.channel.guild->player.guild
- small cleanup around logging changes

* missed one

* here this one too

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* add one missing player log

* missed one

* Format with Black

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-05-19 00:56:10 +02:00
DeltaX
c9431f7d90 [Audio] Fix local track documentation. (#4832)
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2021-05-18 23:09:32 +01:00
Fabian H
cb45ef6c42 Fixed grammatical mistakes in core_commands.py (#4966)
This fixes some issues from the recent commit 'Core Cog Guide'
2021-05-18 17:17:44 -04:00
Kreusada
410b2419dd [Docs] Mod Cog Guide (#4886)
* Initial commit

* Add some args

* bool prolog

* index

* Add more arguments

* more arguments, style fixes

* improve naming of arguments

* Fix up backlog

* Run black

* extra corrections from backlog

* Update tempban arg names

* backlog

* change prolog type

* Change kick argument prolog to member instead of user

* Update argument names

* missed a colon

* Update prolog to be friendly with non-positional args

* Edit through the decorator instead

* Add back docstring spacing

* black

* usage in decorator for name commands

* Fix command signature

* fixup docstring spacing

* style fixes

* Add spacing inside unban docstring

* Rename args instead of using usage

* black - simple

* Add labeler glob

* unify style

* rename variables instead of usage

* Update docstrings correspondingly

* run black

* update description in usage

* ehh this isn't necessary...

* fix up tags

* fix grammar and accuracy issues

* fix docstring too
2021-05-18 17:10:30 -04:00
Kreusada
5d905a93ac [Docs] Mutes Cog Guide (#4875)
* initial commit

* Update mutes.rst

* Add argument headers

* Change bool name for forcerole

* fixes

* Add mutes to toctree

* spacing adjustment

* Fix spacing between examples, use bullet points

* Add args header

* Add args header

* Add labeler glob

* unify style

* aaaaa wrong branch

* fix grammar and formatting errors
2021-05-18 17:06:50 -04:00
OofChair
99b29d0b8e Grammar fixes (#4793)
* Grammar fixes

I need manage roles permission ->> I need the manage roles permission

* Add quotes, capitalize "Manage Roles"

* Style
2021-05-18 16:39:21 -04:00
Philip
4bcfa8e486 Fix a typo in Track Stuck error (#5029) 2021-05-18 21:30:56 +01:00
PredaaA
48ed6c253e [Audio] Check if player.current is not None before resume (#4961) 2021-05-18 21:30:42 +01:00
PredaaA
9986cbe6b5 [Audio] Check required permissions in events (#4960) 2021-05-18 21:30:26 +01:00
PredaaA
e467833cee [Help] Add missing show_aliases value in help_settings.pretty (#4971)
* [Help] Add missing show_aliases value in help_settings.pretty

* Update redbot/core/commands/help.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-05-18 22:28:09 +02:00
Draper
1efcabada1 Cleanup [p]volume and fix infinite retrying in autoplay (#5045)
* This PR depends on Part 2 due to new store value

- cleanup of [p]volume
- a fix for infinite retrying

* update `[p]volume` help

* Update controller.py

* Update redbot/cogs/audio/core/commands/controller.py

meh still hardcoded in RLL .. will be removed in 0.9

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/audio/core/commands/controller.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-05-17 09:38:30 +00:00
Jamie
54e5307307 [Streams] Smashcast removal. (#5040)
* Remove smashcast

* style

* remove smash from cog guides
2021-05-15 08:54:56 -08:00
fredster33
737e4cc399 Fix dead link in CONTRIBUTING.md (+ grammar fix) (#4921)
* Fix 404 link

* Grammar edits
2021-05-15 03:33:22 +02:00
benno1237
4bdc828670 Added owner check for audiostats (#5017)
* Added owner check for audiostats

* Update redbot/cogs/audio/core/commands/miscellaneous.py

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Update miscellaneous.py

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2021-05-12 17:24:07 -07:00
Obi-Wan3
c04c2efeff [Docs] updates to the Linux and Mac auto-restart docs (#5020)
* [Docs] add `sudo systemctl disable` to Linux auto-restart docs

* [Docs] fix typo in Linux auto-restart docs

* [Docs] update Mac auto-restart docs

* [Docs] implement suggestions for Linux auto-restart docs

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* [Docs] update wording on Mac auto-restart docs

* [Docs] fix grammar in Linux auto-restart docs

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-05-12 10:59:54 -07:00
Kreusada
2374b4af59 [Downloader] Fix spacing in [p]cog install response (#5034) 2021-05-10 19:26:15 +00:00
Kreusada
d666c24bd4 [Docs] Reports Cog Guide (#4882)
* [Docs] Reports Cog Guide

* Add cog to toctree

* corrections for docs tox style

* Edit sig (#4881)

* fix typo

* Add labeler glob

* unify style

* decapitalize disable

* black
2021-05-07 20:51:15 -04:00
jack1142
1697d90c53 Stop shadowing variable in customcom's arg handling 2021-05-04 16:53:39 +02:00
Obi-Wan3
7f05841b96 [Downloader] Fix [p]cog uninstall examples (#5019)
* [Downloader] fix `[p]cog uninstall` examples

* [Docs] fix Downloader guide's `[p]cog uninstall` examples
2021-05-02 19:18:38 +02:00
jack1142
01561fbe07 Fix permissions for CodeQL workflow (#5009) 2021-04-22 20:00:24 +00:00
Kowlin
f89223bc74 [Templates] Remove unused fields (#5007)
* Remove unused fields

* Update order

* Revert "Update order"

This reverts commit ef77aeb08f.

* Fix my oopsie...
2021-04-22 21:34:31 +02:00
jack1142
336abcfbba Update workflows with needed permissions (#5003) 2021-04-20 18:43:18 +02:00
jack1142
925ae870ba Nuke PR template (#4999) 2021-04-19 19:39:41 +02:00
jack1142
0447b5648a Include bot as an argument to the cog class in the cog creation guide (#4988) 2021-04-17 16:37:59 -04:00
palmtree5
5de65a74b5 Mac autostart docs (#4082)
* Mac autostart

* Make requested changes to these instructions

* Add a note about how to view the logs
2021-04-15 17:58:22 -07:00
Kowlin
7434a7c8e2 Migrate issue templates over (#4982) 2021-04-13 23:23:23 +02:00
Kowlin
f21addb0f5 Goodbye sweet prince (#4973) 2021-04-09 01:10:38 +00:00
jack1142
39144ed7cd Update API url for Picarto.TV (#4970) 2021-04-08 21:20:34 +02:00
jack1142
aea0db4ef6 Include more files in distributions (#4964)
* Include LICENSE files in distributions

* Use pep517 isolated builds

* Update the GH Actions workflow
2021-04-08 02:35:47 +02:00
bobloy
0eaa0f494c [Docs] Core Cog Guide (#4597)
* Core guide initial commit

* Mydata docstrings

* Regenerated docs

* Lots more docstrings

* Add document link

* Up to load docstrings

* Black formatting

* docstring semantics

* "cog packages" for loads

* Refix line lengths

* Regenerate docs

* Remove link

* Regenerate docs with new code

* Some small docstrings

* Regenerate docs with new .. warning code

* More docstrings into the `set` command

* Bullet lists need blank lines.

* Regenerate docs

* Regenerate docs (fix bullet lists)

* set activity statuses docstrings

* Docstrings up to helpset pagecharlimit

* Regenerate docs

* Core guide initial commit

* Mydata docstrings

* Regenerated docs

* Lots more docstrings

* Add document link

* Up to load docstrings

* Black formatting

* docstring semantics

* "cog packages" for loads

* Refix line lengths

* Regenerate docs

* Remove link

* Regenerate docs with new code

* Some small docstrings

* Regenerate docs with new .. warning code

* More docstrings into the `set` command

* Bullet lists need blank lines.

* Regenerate docs

* Regenerate docs (fix bullet lists)

* set activity statuses docstrings

* Docstrings up to helpset pagecharlimit

* Regenerate docs

* Maxpages and delete delay docstrings

* spagetthi ctrl+v

* tagline and contact

* A little more contact

* Up to allowlist

* Up to command defaultdisablecog

* Regenerate docs

* Redo custominfo to not be terrible

* Up to default enabled cog

* More docs

* Up to command disabledmsg

* Disabled message stuff was missed

* Finish the rest of the docstrings

* Regenerate docs

* Longer description of the cog

* Regenerate Docs

* Fix some of the suggestions

* Apply additional suggests and some small rewording.

* Regenerate docs.

* Apply suggestions and make additional fixes

* Regenerate docs

* Clarifies it's only loaded.

* Regenerate docs.

* New formatting, more examples, some fixes

* Regenerate docs

* Adds consistant use of dashes to arguments

* More consistant punctuation

* Regenerate docs

* Add labeler detection

* Fix example and use clearing language for helpset verifyexists docstring

* Regenerate docs

* Add leave example and arguments

* Regenerate docs

* Regenerate docs

* Make embedset more readable

(933aefd3ee was the sphinx compatible update)

* Regenerate docs

* Black formatting

* Regenerate docs

* Adds docstring examples and arguments for multiple `embedset` subcommands

* Regenerate docs
2021-04-07 13:01:34 -04:00
Kreusada
19dcc52fb1 Update issue templates with new key name for description (#4957)
* Initial commit

* Use `description` instead of `about`
2021-04-06 22:04:21 +02:00
jack1142
1c7b1e0358 Fix dev bump in Publish Release workflow (#4952)
* Fix dev bump in Publish Release workflow

* I made a PR from the wrong branch...
2021-04-06 19:19:31 +02:00
Pred
82edaeeb81 [Downloader] Show repo's name (#4954)
* Add forgotten format

* leave me alone
2021-04-06 15:15:00 +00:00
jack1142
2f16d33971 Version bump to 3.4.10.dev1 (#4953) 2021-04-06 04:06:37 +02:00
jack1142
6a99becdb2 Update publish_release.yml 2021-04-06 03:57:06 +02:00
github-actions[bot]
062211d099 Version bump to 3.4.9 (#4951)
* Version bump to 3.4.9

* Update changelog_3_4_0.rst

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-04-06 03:50:53 +02:00
jack1142
84f1699b8f Red 3.4.9 - Changelog (#4950)
* Red 3.4.9 - Changelog

* Add info about d.py bump
2021-04-06 03:43:05 +02:00
jack1142
6cf54db308 Fix command error handlers (d.py micro bump) (#4949) 2021-04-06 03:35:55 +02:00
jack1142
fa25033be1 Fix dev bump in Publish Release workflow (#4948) 2021-04-06 03:22:01 +02:00
jack1142
36c9d9aaee Version bump to 3.4.9.dev1 (#4947) 2021-04-06 01:41:29 +02:00
github-actions[bot]
2c82a4ba2b Version bump to 3.4.8 (#4945)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-04-06 00:55:59 +02:00
github-actions[bot]
6cae1c0204 [i18n] Automated Crowdin downstream (#4946)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-04-06 00:55:36 +02:00
jack1142
1b6fc00039 Red 3.4.8 - Changelog (#4941)
* Add 3.4.8 section

* PR 3833 (issue 3699)

* PR 4801 (issue 4789)

* PR 4742 (issue 4731)

* PR 4898

* PR 4871 (issue 4766)

* PR 4878

* PR 4904 (issue 4900)

* PR 4897

* PR 4889 (issue 4888)

* PR 4877 (issue 4700)

* PR 4876

* PR 4869, 4870

* PR 4866

* PR 4865

* PR 4864

* PR 4942

* PR 4830

* PR 4821

* PR 4790

* PR 4746 (issue 4735)

* PR 4831 (issue 4720)

* PR 4049

* PR 4928

* PR 4914 (issue 4905)

* PR 4917 (issue 4916)

* PR 4940

* PR 4938

* PR 4004

* PR 4883 (issue 4808)

* PR 4933

* PR 2952

* PR 4910

* PR 4907

* PR 4908

* PR 4839

* PR 4906

* PR 4932

* PR 4565

* Add release date and contributor list

* Remove empty section

* Apply suggestions from code review

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2021-04-06 00:55:26 +02:00
jack1142
e2c0f2aca8 Revert "[Streams] Remove stream alert if stream not found (#4939)" (#4943)
This reverts commit 3c742e39d2.
2021-04-05 23:40:06 +02:00
jack1142
83deb7c563 Update instructions to use Python 3.8.9 (#4942) 2021-04-05 23:25:10 +02:00
jack1142
c574271cee Fix no dispatch on shared API token removal (#4917) 2021-04-05 14:28:23 -06:00
PredaaA
a6d15dc385 [Streams] Stop suppressing task cancelation in _stream_alerts() (#4940)
* Minimize the API calls

* Address Jack's review.

* [Streams] Actually cancel the _stream_alerts task.
2021-04-05 22:22:20 +02:00
jack1142
07099dd1dd allowed_by_whitelist_blacklist() - add guild param, deprecate guild_id (#4914)
* allowed_by_whitelist_blacklist() - add guild param, deprecate guild_id

* Add clarification to description of `guild`, `guild_id`, and `role_ids`

* style :|

* Update redbot/core/bot.py

Co-authored-by: TrustyJAID <TrustyJAID@gmail.com>

Co-authored-by: TrustyJAID <TrustyJAID@gmail.com>
2021-04-05 14:20:21 -06:00
Kreusada
d1ed41c46b [Image] Improve explanations of arguments in docstrings and help (#4874)
* Initial commit

* Give arguments their descriptions

* Add usage

* fixes for black
2021-04-05 16:16:41 -04:00
PredaaA
3c742e39d2 [Streams] Remove stream alert if stream not found (#4939)
* Remove stream if not found

* Address Jack's review.
2021-04-05 20:13:00 +00:00
PredaaA
9a7c178db5 [Streams] Minimize Twitch API calls (#4938)
* Minimize the API calls

* Address Jack's review.

* Check for self.id first.

* *inhales*

* Update redbot/cogs/streams/streamtypes.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Apply suggestions from code review

* Update redbot/cogs/streams/streamtypes.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-04-05 22:10:41 +02:00
jack1142
67fa735555 Use partial messages in Streams cog to avoid potential leakage (#4742)
* Use partial messages in Streams cog to avoid leakage

* Stop trying to save bot object to Config...

* Put guild id as part of message data

* Fix AttributeError

* Pass bot object to stream classes in commands

* ugh

* Another place we use this class in

* more...
2021-04-05 21:39:33 +02:00
Twentysix
c25095ba2d [Core] Use menus for [p]servers, improve [p]leave (#4831)
* [Core] Use menus for [p]servers, improve [p]leave

* Apply suggestions from code review

Co-authored-by: Samuel <50765275+npc203@users.noreply.github.com>

* Few more changes

* Add empty line...

* style

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: Samuel <50765275+npc203@users.noreply.github.com>
2021-04-05 19:37:23 +00:00
jack1142
adda30cbee Bump discord.py to 1.7.0 (#4928)
* Bump discord.py, but to the git version for now

* Import GuildConverter from d.py and deprecate our implementation

* Import PartialMessageConverter in our commands extension

* Use newly added `Cog.has_error_handler()` rather than private method

* Update snowflake regex to use 20 as max length

See Rapptz/discord.py#6501

* Use new supported way for custom cooldown buckets

* Include group args in command signature

* Update code to use `Client.close()` over `Client.logout()`

* Add StageChannelConverter and StoreChannelConverter

* Fix AttributeError in licenseinfo
2021-04-05 21:33:19 +02:00
jack1142
9008410fa4 Fix dropping db in redbot-setup delete (#3833)
* Fix dropping db in `redbot-setup delete`

* fix docstrings
2021-04-05 21:17:18 +02:00
Draper
b7d8b0552e I promise I'm not doing this on purpose (#4565)
* Prep for 0.7.2

* So What di i do here? I done Magic, magic only found in the tales of old.

* turns out formatting is something important

* fixes

* improved Error handling when Global API is enabled

* further improve resuming logic

* more of dat dark voodoo blood magic

* major tweaks to auto restore when auto play is enabled 👀

* fix duplicated "Auto play stated." message + Auto play restart :feelsgoodman:

* missed these

* fix the new duplicated fucking message bitch.

* Let discord handle player reconnects

* eh

* `Requires force install`, utilize new Exponential Backoff object on player and safer reconnect logic, emulating d.py and WL.

* hmmmmm gotta monitor

* mother fucking brackets

* Why didnt i consider this the first time?????????????

* new error code to handle?

* soooooooooooooooo these are import so why arent we ensuring they are set.

* improved logging

* improved logging

* aaaaaaaaaaaaaaa

* We need our own error and special handling to not conflict with dpy

* (Last Known Bug) Fix the infinite loop of 4006 that sometimes could happen as an edge case after a successful resume.

* This will require a force reinstall to install `RLL 0.8.0`, this properly fixes the bug mentioned on the previous commit.

* address "Localtrack names/paths need to be escaped." comment

* address Fixators crash mentioned in #AT

* style

* fix preda's crash mentioned in PR

* add a thing here add a thing there add a thing everywhere

* style

* fixes here, fixes there, and backbone for curated playlist.

* bypass aiohttp and githubs and cloudflare and yo mammas cache

* I propose the new style is no style.

* allow curated playlist to be updated it `[p]playlist update` and show the diff

* fix `[p]summon` not resuming playback until next track.

* Hopefully handle predas rate limits.

* what else did i break now

* Update Lavalink.jar build

* lets try this

* reset the queue

* Bring Edge commits over fix a bunch of shiz again

* Bring Edge commits over fix a bunch of shiz again

* Handle 4014 OPs, Change `skip_votes` key to be an int rather than guild object

* aaaaaaaaaaaaaaa im dumb

* ...

* Simplify some shiz + use a set instead of a list for votes.

Co-authored-by: aikaterna <20862007+aikaterna@users.noreply.github.com>
2021-04-05 21:02:24 +02:00
Pred
1199f160d0 Add plural forms to Downloader (#4004)
* Downloader's plurial & Fix

* Don't forget pipinstall

* Fix syntax issue

* This f****** fix that took me too much of my time for nothing.

* Black

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Fix Jack's syntax, remove numbers & fix bad calculated cogs

* Black ofc

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/downloader/downloader.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Address my review comment

* Simplify

* this is kinda a lot but shh

Co-authored-by: Predeactor <ubuntu@vps-35e65bf5.vps.ovh.net>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-04-05 16:37:36 +00:00
PredaaA
5ddc6d2ea8 [Streams] Handle Twitch ratelimits (#4883)
* [Streams] Handle Twitch ratelimits.

* Also handle possible API or client errors.

* Add Jack's changes request.

* Update redbot/cogs/streams/streamtypes.py

* Update redbot/cogs/streams/streamtypes.py

* Update redbot/cogs/streams/streamtypes.py

* Update redbot/cogs/streams/streamtypes.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-04-05 14:23:04 +00:00
aikaterna
6e764c7e04 [Audio] Update Lavalink.jar build (#4932) 2021-04-05 10:18:06 +02:00
Toby Harradine
18a23813c8 Better user feedback during slow backend migrations (#2952)
* Better user feedback during slow backend migrations

This uses a tqdm progress bar to keep the user updated on the progress of the migrations.

I didn't realise this was necessary until I did a migration from Mongo to Postgres on CASE, and it took quite a long time to complete, I started to doubt that it was actually making progress.

Also includes a utility to help with tqdm in slow asynchronous for-loops.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Make `async_tqdm` support async-for loops

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Reformat

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Remove unused method

* Remove quotes for the return type annotation

* Few style improvements

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-04-05 09:41:31 +02:00
jack1142
560e1dfc3d Add per-command embed settings (embed_requested) (#4049)
* Add per-command embed settings

* Update `[p]embedset showsettings`

* Use command.qualified_name in `[p]embedset` commands

* Fix the call to subcommand and simplify it

* And I oversimplified this

* Update end user messages to use 'guild' rather than 'server'

* meh

* This should be a named field

* Add check for Embed Links perm to confuse users a bit less

* Wrap this string in _()

* Let's use a different exception then...

* Let's clear the setting when we can in whole `[p]embedset`

* Add the order of checking to help of `[p]embedset`

* Add note about full evaluation order to subcommands
2021-04-04 13:37:46 -06:00
Pred
03d72dd5fa [Cleanup] Pre-set the variable to None in [p]cleanup before (#4931)
* [Cleanup] Handle missing message_id and reply

* Fix a new situation where we could end up with unwanted `None`

* I suck at this (style fix)

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-04-04 09:34:11 +00:00
PredaaA
847444eab1 [Mutes] Fix data conversion to shema_version 1 and add a note about it (#4934)
* [Mutes] Add a note about conversion to schema_version 1

* Only start the conversion if all_channels

* Actually do what the previous commit said

* okay this time is the right time

* Update mutes.py

* Move conversion to its own method

* Update mutes.py
2021-04-03 18:43:36 -06:00
Jamie
6c338f175b [Audio] ctx.message.guild -> ctx.guild + store ids rather than whole guild in skip_votes (#4867)
* ctx.invoke -> bot.invoke
ctx.message.guild -> ctx.guild

* remove the invoke stuff

* remove invoke stuff

* use id attrib instead of entire guild

* change type hinting too

* change second typehint
2021-04-04 00:01:10 +02:00
PredaaA
363a2e8a17 [Mod] Only loop through guilds in config when checking tempbans (#4907)
* [Mod] No longer loop through all guilds on check_tempban_expirations.

* Address Jack's review.

* I don't think this comment actually served any purpose

* Split this into more methods

* Small optimization for cases where the guild tempbans weren't updated

* Blackify

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-04-03 23:59:41 +02:00
PredaaA
edbd31413b Handle NSFWChannelRequired in events. (#4933) 2021-04-03 23:23:53 +02:00
Vexed
4813c68185 Add note about updating cogs to update message and docs (#4910)
* Add update note to the docs

* And now the DM

* consistent wording

* Clarify the command should be ran in Discord

* apply docs suggestions

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* apply events.py review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-04-03 20:38:57 +02:00
jack1142
0becf70b05 Use sphinx-prompt extension (#4908)
* Use sphinx-prompt extension

* Update PM2 guide

* Use an actual proper way to run Red with PM2

* Fix pm2 docs

Co-authored-by: Kowlin <Kowlin@users.noreply.github.com>
2021-04-03 16:52:11 +00:00
jack1142
0144cbf88b Add deprecated-removed directive to Sphinx (#4912)
* Add `deprecated-removed` directive to Sphinx

* Add equivalent function to internal utils
2021-04-03 18:48:17 +02:00
Kreusada
76bb65912e [Core] Improve responses to [p]set (server)prefix commands (#4898) 2021-04-03 03:10:53 +02:00
Kreusada
01637a9798 [Docs] Use pascal casing for example cog in cog creation guide (#4930) 2021-04-03 02:56:10 +02:00
Flame442
7c853db9f4 [Alias] Strip extra whitespace from fake command messages (#4871) 2021-04-03 02:33:29 +02:00
OofChair
a919610588 Use embed_color for embeds in Warnings cog (#4878)
* add  color 

* add color on line 315, fix line 340

* Black style

* fix color on line 341

* thanks jojo >_>

* dont need i18n here

* Black style again :D
2021-04-03 02:30:26 +02:00
Kreusada
49da854eb7 Add user/role names to [p](local)allow/blocklist list (#4839)
* start

* Get user inside blocklist/allowlist lists

* Changes to cover unknown or deleted users

* Use square brackets for clarity

* Implement the above commit for all four versions

* Much improved UI, removed `[]` to fit new format

* updates to support roles in local version

* add /role to unknown str

* Improve variable names

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-04-03 01:28:06 +02:00
Obi-Wan3
c168e55be9 [Warnings] fix raw namedtuple output (#4904) 2021-04-02 23:09:18 +02:00
PredaaA
35dfb04066 [Mutes] Add guild ID to mutes data (#4906)
* [Mutes] Add guild ID to mutes data.

* Actually make the whole thing works.

* config version as integer, and init task no longer in setup

* oops

* Fix cog_disabled_in_guild check.

* Add Trusty's requested changes.
2021-04-01 19:01:43 -06:00
PhenoM4n4n
fb701d8c72 Allow Cleanup before/after to accept message replies (#4790)
* cleanup after

* style

* bring back cleanup before

* style

* docstring

* make message id optional
2021-03-29 14:39:31 +02:00
jack1142
24fadad4cf Remove unnecessary escape (#4901) 2021-03-29 14:07:53 +02:00
jack1142
f30772a7bd Raise StreamNotFound for 404 errors in YouTube RSS feed (#4746)
* Raise `StreamNotFound` for 404 errors in YouTube RSS feed

* Catch `StreamNotFound` exception in bg task and remove such streams
2021-03-29 14:05:42 +02:00
jack1142
b71d278ae5 Use explicit name of the python packages for openSUSE Tumbleweed, add warning for Arch instructions (#4866)
* [Docs] Use explicit name of the python packages for openSUSE Tumbleweed

* Add warning for Arch Linux instructions

Co-authored-by: Kowlin <Kowlin@users.noreply.github.com>
2021-03-29 13:59:19 +02:00
jack1142
be00a59ab3 Fix the tracking of nicks that were set just before nick reset (#4830) 2021-03-29 13:54:37 +02:00
❥sora
d45a02166d a small typo (#4915) 2021-03-26 19:13:00 +01:00
Sougata das
a4db7a1028 Add meaningful error messages for bad arguments in [p]bank set (#4801)
* bot will give meaning full message for bad argument

* reformated python code and updated warning message!

* warning message updated

* warning message updated

* warning message updated(1)

* warning message updated(2)

* warning message updated(3)

* Address the review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-03-26 16:00:56 +01:00
jack1142
ef803072fa Update ambiguous oid parsing to detect candidates on Git 2.31+ (#4897)
* Update ambiguous oid parsing to detect candidates on Git 2.31+

* Update tests
2021-03-24 00:52:52 +01:00
jack1142
e5ffe86c4e Improve labeler configuration to include docs (#4902) 2021-03-21 01:25:47 +01:00
jack1142
d1bc4b4302 Small meta cleanups (#4893)
* Remove the unneeded pytest options from pyproject.toml

* Clean up setup.py from old readthedocs.org workaround

* Removes unused folder

* Simplify list of excluded files in black's configuration

* Fix returned exit codes in `make.ps1`

* Add Sublime's project files to `.gitignore`

* Update the link to Black in README and contributing guidelines
2021-03-16 19:51:48 +01:00
jack1142
6c903aacff Update Downloader tests to work with newer git versions (#4891) 2021-03-16 19:50:51 +01:00
Kreusada
1b3958515b [Reports] Improve usage in the report command's decorator (#4881)
* [Reports] Improve usage in the report decorator

* fix sig
2021-03-15 00:01:36 -04:00
Kreusada
fef56427ae [Docs] Add explanation for multiple arguments (#4889)
* [Docs] Add explanation for multiple arguments

* ordering fix

* Add example

* syntax
2021-03-14 23:47:53 -04:00
jack1142
18fea4e4a7 Remove duplicate questions in hockey trivia (#4887) 2021-03-14 04:49:24 +01:00
Pred
f82d613a11 how dare you... (#4885) 2021-03-13 18:18:55 -05:00
kingslayer268
0c3e772135 Added use spoilers functionality (#4877)
* Added use spoilers functionallity

* Update trivia.py

* Update session.py
2021-03-07 22:27:41 +01:00
kingslayer268
c78ee14617 Fix AttributeError in Context.delete_messages() (#4876)
delete_messages() isn't an attribute of DMChannels
2021-03-06 16:21:25 +01:00
TheDiscordHistorian
3782e9c1b9 fix a minor grammar issue (#4846)
The docstring says "cogs the folder" which should be "cogs folder"
2021-03-03 20:44:39 +01:00
kreusada
8d03fef566 [Docs] Image Cog Guide (#4821)
* [Docs] Images Cog Guide

* [Docs] Image Cog Guide

* Fixes for directory inside the index

* The cog is cakked IMAGE not IMAGES

* Potential fixes for failing checks

* Grammar fixes

* Some formatting updates

* Fix merge conflicts from 3.4.7

* Re-format for requested changes
2021-03-03 14:19:33 -05:00
OofChair
77896494c4 [Docs] Add nano package to Linux install guides (#4870)
* [Docs] Add installation instructions for nano

As some servers don't have nano preinstalled, I added the installation instructions here.

* Formatting fix

* Update autostart_systemd.rst

* Add nano to installation instructions

* Add nano to all OS installation instructions

* Remove nano from OSX installation

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Remove trailing whitspace

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Put nano at the end

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Put nano at the end

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Put nano at the end

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Put nano at the end

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update install_linux_mac.rst

* Minimize diffs

Co-authored-by: kreusada <67752638+kreusada@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-03-03 17:14:15 +01:00
OofChair
aad34f2b08 sudo -e -> sudo nano (#4869)
I changed this as it was mentioned in #4082. (https://github.com/Cog-Creators/Red-DiscordBot/pull/4082#issuecomment-789291030)
2021-03-03 00:19:59 +01:00
jack1142
85dc6f4cc9 Use brew install --cask instead of brew cask install (#4865) 2021-03-01 09:25:55 -08:00
jack1142
7126482449 Drop support for EOL systems and update instructions to use Python 3.8.8 (#4864)
* Drop support for EOL systems (Fedora 31, openSUSE Leap 15.1)

* Bump Python in Windows and pyenv install guides to 3.8.8
2021-02-28 15:45:48 +01:00
jack1142
9bb61ba882 Make files - fallback to python(3.8) from PATH if .venv doesn't exist (#4863) 2021-02-28 15:39:28 +01:00
jack1142
1ff976b3d0 Add make.ps1 cmdlet + activateenv command for Windows make scripts (#4087)
* Add missing command to `make.bat`'s help

* Add `activateenv` and `deactivateenv` commands to `make.bat`

* Add help to `Makefile`

* Add `make.ps1` cmdlet
2021-02-27 12:23:32 +01:00
jack1142
53c069a636 Auto-put PRs from release workflows in the proper milestone + minor things (#4862)
* Make workflow name use TitleCase

* Indicate in the PR description that it's a multi-part workflow

* Auto-put PRs from Prepare Release workflow in the proper milestone

* Rename "Publish the release" workflow to "Publish Release"

* Auto-put PR from Publish Release workflow in the proper milestone
2021-02-27 11:22:54 +01:00
Fixator10
bb90444979 [Changelog] Fix argument name in 3.4.6 changelog (#4861) 2021-02-26 21:37:35 +00:00
jack1142
19fc5a090c Version bump to 3.4.8.dev1 (#4860) 2021-02-26 19:08:12 +00:00
kreusada
0d53b2ab73 [Changelog] Fix URL (#4859) 2021-02-26 19:05:22 +00:00
jack1142
d3b448d50c Fix publish_release workflow (#4858) 2021-02-26 19:04:36 +00:00
github-actions[bot]
02667ef65d Version bump to 3.4.7 (#4856)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-02-26 19:53:11 +01:00
github-actions[bot]
51b73fdd1a [i18n] Automated Crowdin downstream (#4857)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-02-26 19:51:59 +01:00
jack1142
f926fab431 Fix prepare_release workflow (#4855) 2021-02-26 18:43:00 +00:00
jack1142
dbbaa88e8e Red 3.4.7 - Changelog (#4852)
* wip

* wip 2

* wip 3

* Add contribs list!
2021-02-26 19:31:25 +01:00
Kowlin
df5926b51a [Core] Clarify that the owner is a team in [p]info (#4851)
* Clarify that the owner is a team.

* This should do.

* Style check... for a comma, in your dreams Tox...

* Annndddd for the insane people who don't use embeds
2021-02-26 18:48:22 +01:00
jack1142
7d42c4c6c3 Minor text fix in Mutes cog (#4853) 2021-02-26 18:32:11 +01:00
Ellie Saurich
dfe84f9936 [Mutes] Wrong error message when muting fails (#4850)
* [Mutes] Wrong error message when muting fails

* This applies to both mute and unmuting of members.

Co-authored-by: Kowlin <Kowlin@users.noreply.github.com>
2021-02-26 08:22:04 +00:00
Jamie
649b4ebb15 add checks to 2 muteset commands (#4849) 2021-02-26 03:14:56 +01:00
jack1142
f476b842d5 Work around actions/labeler's upstream issue with label sync setting (#4844)
* Work around `actions/labeler`'s upstream issue with label sync setting

* Add comment about this being a workaround
2021-02-23 14:57:34 +01:00
kreusada
92ea92b617 [Docs] General Cog Guide (#4797)
* [Docs] General Cog Guide

* Doc Style Fixes

* Requested Changes

* Additional grammar fix that was missed

Co-authored-by: kreusada <67752638+kreus7@users.noreply.github.com>
2021-02-22 13:56:43 -05:00
Jamie
ae2bae058c change domain to .app (#4840) 2021-02-20 23:50:40 +01:00
palmtree5
b20fc9f6af [Docs] Trivia user guide (#4566)
* Start on Trivia user guide

* Finish command coverage + add to toctree

* wip note on list creation section

* Apply suggestions from code review

Co-authored-by: bobloy <alboblexloy@gmail.com>

* Update docs/cog_guides/trivia.rst

Co-authored-by: bobloy <alboblexloy@gmail.com>

* Drop list creation guide for now + fix formatting

* Apply suggestions from code review

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* permissions notes

Co-authored-by: bobloy <alboblexloy@gmail.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2021-02-20 14:38:18 -05:00
Kowlin
fc5eadd0cc [Meta] Issue template migration (#4809)
* Issue template migration

* Fixes pt. 1

* Fixes pt. 2

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-02-19 19:01:52 +01:00
jack1142
c5fbf5fb94 Change things up with Crowdin and release-related workflows (#4833)
* Alternative way of doing Crowdin...

* Limit the upload translations workflow to V3/develop

* Make the workflow close and reopen the PR automatically while I'm at it

* Add a workflow for preparing PRs for release

* Make the crowdin env vars local to the step requiring them

* Move dev bump to Publish Release workflow
2021-02-18 14:43:21 +01:00
jack1142
54bbdd61e1 Version bump to 3.4.7.dev1 (#4825)
* Version bump to 3.4.6

* Version bump to 3.4.7.dev1
2021-02-16 20:43:18 +01:00
jack1142
512ff7a4b5 Version bump to 3.4.6 (#4824) 2021-02-16 20:22:43 +01:00
jack1142
6881b20c20 Red 3.4.6 - Changelog (#4743)
* Fix some stuff from previous changelogs

* Add 3.4.6 section

* PR 4579

* PR 4710

* PR 4649 (issue 3931)

* PR 4714

* PR 4728

* PR 4740

* PR 4741

* PR 4738 (issue 4405)

* PR 4599

* PR 4733

* PR 4739 (issue 4676)

* PR 4742 (issue 4731)

* PR 3870

* PR 3833 (issue 3699)

* PR 4426

* PR 4715

* PR 4563 (issue 3752)

* PR 3040

* PR 4667

* PR 4726 (issue 4702)

* PR 4647

* PR 4709

* PR 4694 (issue 4693)

* PR 4745

* PR 4749

* PR 4768 (issue 4767)

* PR 4697

* PR 4770

* PR 4772 (issue 4771)

* PR 4758 (issue 4661)

* PR 4705, 4748, 4750, 4788, 4810

* PR 4572 (issue 3777)

* PR 4791

* PR 4754

* PR 4805

* PR 4778

* PR 4800

* PR 4801 (issue 4789)

* PR 4814

* PR 4815

* PR 4819 (issue 4818)

* PR 4822

* Revert entries for unmerged PRs (3833, 4742, 4801)

* PR 4785

* PR 4799

* Add list of contributors

* Add release date

* PR 4763, 4792

* Wew, I almost forgot!

* PR 4660

* Apply suggestions from code review

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/changelog_3_4_0.rst

* Update docs/changelog_3_4_0.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/changelog_3_4_0.rst

* Add Wyn

* What do you think of that, Flame?

* PR 4827

* Jack is dumb

* Jack is dumb 2

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2021-02-16 20:22:22 +01:00
github-actions[bot]
e80a00ec1b [i18n] Automated Crowdin downstream (#4829)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-02-16 19:22:05 +00:00
Flame442
7b04c04551 [Mod] Add two new settings to disable name/nickname tracking (#4799)
* Add default settings for name tracking

* Add configuration command for name tracking

* Check the track names settings before tracking

* *grumble*

* Fix permissions levels

* Update settings.py

* Use clean_prefix in inline, and don't use f-strings in `_()`

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-02-16 20:13:37 +01:00
PhenoM4n4n
62411bc2a5 Add a command for deleting usernames and nicknames to Mod cog (#4827)
* mod delete names

* sTyLe fOrMAttInG

* Remove `[p]deletemodkeys` and have `[p]deletenames` remove empty keys

* Rename `[p]deletenames` to `[p]modset deletenames`

* Fix wrong variable being used

* Add confirmation to avoid mistakes

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-02-16 19:58:00 +01:00
Wyn
bee022d1bb Make [p]selfrole without subcommand "toggle" the selfrole (#4826)
* Merge selfrole and remove into one command

replacement pr

* docs

add to the docs

* Update admin.py

remove register name

* Update admin.rst

* Fixes

* Fix the duplicated command decorators

* Minimize the diff

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-02-16 15:16:16 +01:00
Andy
1be7435fb5 fix grammar issues (#4763)
in line 28, it used to be "The message will be send to the user", I fixed it to "The message will be sent to the user".

Co-authored-by: Andy <76832778+AndyButAnnoying@users.noreply.github.com>
2021-02-15 23:32:44 +01:00
Andy
9b4363eff3 grammar fixes (#4792)
* grammar fixes

* author(s)
2021-02-15 23:31:01 +01:00
jack1142
dc68bc5d37 Fix error handling for API calls to videos endpoint in YouTube alerts (#4745) 2021-02-15 12:25:30 -09:00
Andy
5b670c074f Update [p]economyset slottime&paydaytime to use TimedeltaConverter and not accept negative integers (#4807)
* add a time converter, as well as not allowing negative integers

* timedeltaconverter

* styling and unused imports

* update docstrings

* update param name to "duration" instead of seconds

* make timedelta default_unit seconds

* better descriptions & docstrings

* docs for updated paydaytime & slottime

* Fix style

* Few minor fixes

* Cast `total_seconds()` return type to `int`

* Fix one of my own issues

* Make the duration argument catch-rest for convenience

* One more fix for the docs

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-02-15 22:25:03 +01:00
aikaterna
1a9ce2040a [Audio] Update manager.py for new Lavalink build (#4823) 2021-02-15 22:16:47 +01:00
Slave In Utero
4fa8a51ea1 gen-6-pokemon-trivia (#4785) 2021-02-14 23:23:37 -05:00
aleclol
acec5c6efe [Mod] Add default bot color to kick & ban DM (#4822) 2021-02-15 01:34:05 +01:00
aikaterna
d64944d5c3 Update Lavalink.jar build (#4819) 2021-02-15 00:50:58 +01:00
jack1142
6cfaffb8a8 Add i18n deco to Dev and Mutes cog (#4815)
* Add i18n deco to Dev cog

* Add i18n deco to Mutes cog
2021-02-15 00:19:34 +01:00
MAX
3122eb0447 Rename [p]cleanup spam to [p]cleanup duplicates (#4814)
* rename `spam` to `duplicates` and aliases it to `spam`

* style
2021-02-14 21:41:04 +01:00
github-actions[bot]
bf30f2078c [i18n] Automated Crowdin downstream (#4816)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-02-14 16:57:35 +01:00
jack1142
33850a2c35 Update Python version installed in instructions to 3.8.7 (#4770)
* Update Python version installed in instructions to 3.8.7

* Update the one in Windows instructions too
2021-02-13 17:31:14 -05:00
jack1142
40368cc379 Fix changing default state for a cog as enabled/disabled (#4768)
* Fix changing default state for a cog as enabled/disabled

* Add `, None`
2021-02-13 17:24:42 -05:00
kreusada
a9e572d55a [Reports] Use the bot's default colour for report output (#4800)
* [Reports] Use `ctx.embed_colour()` for report output

* Add context

Co-authored-by: kreusada <67752638+kreus7@users.noreply.github.com>
2021-02-13 17:07:48 -05:00
bobloy
4ca2fe0872 [Docs] Add information about the red index (#4778)
* Add information about the red index

* Update docs/guide_publish_cogs.rst

Co-authored-by: BreezeQS <70638053+BreezeQS@users.noreply.github.com>

Co-authored-by: BreezeQS <70638053+BreezeQS@users.noreply.github.com>
2021-02-13 13:08:33 -05:00
iStrqfing
dd9e60b15f [Trivia] [Overwatch] General + Hero Changes (#4805)
Current/up to date answers regarding some hero's health and abilities
Added more options for "What does Tracer say when using her ultimate?"
Competitive point changes for Season 6+ on August 29, 2017 patch
Mercy's major rework on September 19, 2017 patch
Hanzo's major rework on May 3, 2018 patch
Symmetra's major rework on June 6, 2018 patch
"Offense" and "Defense" categories have been merged into "Damage" on June 26, 2018 patch
McCree's roll cooldown decreased on October 9, 2018 patch
Torbjorn's health changed on March 19, 2019 patch
Sombra's translocator cooldown increased on October 15, 2019 patch
Orisa's fortify cooldown decreased on December 10, 2019 patch
Ana's sleep dart duration decreased on April 29, 2020 patch
Orisa's health changed on September 24, 2020 patch
McCree and Widowmaker's health changed on October 29, 2020 patch
Reinhardt's health changed on December 10, 2020 patch
Removed "What was the name of the Lunar New Year themed event in Overwatch?:" since this changes every year.
2021-02-13 12:02:56 -05:00
kreusada
ee33d46732 Grammar fixes (#4810) 2021-02-13 10:44:02 +01:00
MAX
4c58dcedfe Copy info about the bands from [p]eq set help to [p]eq help (#4794)
* Update equalizer.py

* style
2021-02-11 22:47:39 +01:00
kreusada
82595df730 [Utils] Spoiler Function for Chat Formatting (#4754)
* [Utils] Additional chat formatting functions

* [Utils] Updated docstrings to unify with other docstrings

* [Utils] Spoiler feature for chat_formatting

* Fixes for black style

Co-authored-by: kreusada <67752638+kreus7@users.noreply.github.com>
2021-02-11 22:31:47 +01:00
Neuro Assassin
1920212eda [Cleanup] Fix error when providing message snowflake above the maximum (9223372036854775807) (#4791)
* [Cleanup] Fix angry error

* haha just kidding, does not work

* change to be clearer

* update to module level

* cmon black

* added in wrong place
2021-02-11 22:30:16 +01:00
jack1142
7df1570d51 Various improvements in usage of Rich in Red (#4726)
* Use Rich's default console object instead of making one

* Bump Rich to version 9.8.2

* Disable indent guides in tracebacks

* Skip empty lines between stack levels in traceback rendering

* Use full width of the terminal when printing tracebacks

* Disabling syntax highlighting on the log messages

* Make logger name bold

* Make logger level bold

* Make URLs in console bold

* Change `bright_blue` and `blue` colors in syntax theme (NEEDS CHANGING)

* Show only one line per stack level in tracebacks

* Shuffle things in `redbot.logging` a bit

* Change logging handler while redirecting stdout in Dev cog

* Revert last two commits...

This reverts commit cf563bd06a6ae398da12713ceef3db9cc903d902.
This reverts commit 6dddf300726ddf89b8924441eed59b67b58faca0.

* Change Rich console to always print to sys.stdout (therefore ignoring stdout redirects)

* Pass cli_flags to init_logging()

* Add a flag to set the amount of extra lines in rich tracebacks

* First take on the syntax theme colors

* Use the Windows trick

* ARE YOU SERIOUS!?

* Remove dead code

* Use Monokai when Terminal application supports truecolor

* Syntax theme update

* Change logger name color

* This is not needed

* Adjust logging level colors

* Add a flag for showing local variables in Rich tracebacks

* change imports a bit

* Remove usage of blue color fully

* Stop highlighting in Red-DiscordBot splash

* Fix unreadable paths in tracebacks

* Make CRITICAL logging level more readable

* Make time in logs more readable

* Fix the first row being bolded in tables

* Update rich to 9.9.0
2021-02-11 14:20:10 -07:00
github-actions[bot]
663876fba3 Automated Crowdin downstream (#4804)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-02-11 13:20:38 +00:00
jack1142
ae87aa396a Bump Red's deps and all the pip deps used in our Actions (#4572)
* Bump Red's deps

* Bump deps in all our actions

* Don't bump flake8 in Lint Python action

* Bump apsw-wheels too
2021-02-11 02:40:36 +01:00
kreusada
bf624da51b Grammar fixes (#4788) 2021-02-05 09:48:34 -05:00
github-actions[bot]
0f8f33fed2 Automated Crowdin downstream (#4734)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-02-04 18:05:40 +00:00
jack1142
f9848a69b7 So close, and yet so far away - issue forms for the last time tonight (#4784) 2021-02-02 00:50:10 +01:00
Kowlin
082106eb21 Oh boy! more issue templates! (#4783)
* Oh boy! more issue templates!

* Add some descriptions to command_bug.yml

* Update enhancements.yml to refer to "components" since one might want to request API enhancement

* Update feature_request.yml

* Update command_bug.yml

* typo

* I don't think this would cause any issue but I would rather not need another PR

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-02-02 00:35:16 +01:00
jack1142
45f22404d4 Story likes to repeat itself - fix our issue template hopefully for good (#4782)
* Revert "Cut the list in half (#4781)"

This reverts commit 9737c1b5eb.

* Story likes to repeat itself

Yet again, Kowlin makes a small mistake that ends up with us making shitton of commits
2021-02-01 22:41:15 +01:00
jack1142
9737c1b5eb Cut the list in half (#4781) 2021-02-01 21:55:02 +01:00
Kowlin
7c86071a5d Lets "temporarily" remove these. (#4780) 2021-02-01 21:30:46 +01:00
Kowlin
86fbead609 First attempt at issue templates. (#4779)
* Lets try this new fancy thing

* Rename command_bug.md to command_bug.yml

* Update command_bug.yml

* Cog name before command name, thank you

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-02-01 21:21:12 +01:00
jack1142
8139587e5e Update d.py to 1.6.0, aiohttp to 3.7.3, Red-Lavalink to 0.7.2 (#4728)
* Bump d.py, aiohttp, Red-Lavalink

* Remove deprecation warnings that are no longer relevant

* Max concurrency things in `Command.prepare()`

* Two random things that date back to times older than d.py 1.1...
2021-02-01 14:49:50 +01:00
Danstr5544
d6de9c1b94 Add a way to reset rolepayday amounts (#4758)
* Add a way to reset rolepayday amounts

* Totally not fixing a typo...

* Jack found a Typo

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Max line length Compliancy

Thanks Jack (again lol)

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Including rolepaydayamount changes in docs

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-29 21:50:22 +01:00
bobloy
e24379973c Add guild_only check to [p]command listdisabled guild (#4772) 2021-01-29 21:27:01 +01:00
Predeactor
2bffbd9001 [Core] Fix commands using plural with the same user (#4750)
* [Core] Fix commands using plural with the same user

Some plural checking have also been added to the local blocklist/allowlist and the wording has been revised.

* AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

* BLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK

* the

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-29 19:03:24 +00:00
Dennis
51c17110ad Wrap Red-DiscordBot[postgres] in quotes in Unix install docs (#4697)
* Docs: added brackets escape note for Linux/macOS installation

* Corrected punctuation for bracket escaping note

* Use quotes - those work on cmd, bash, zsh, and probably other shells

* Minimize the diff

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-29 19:39:46 +01:00
Vexed
577dbfddb6 Add a note in systemd guide saying working instance is required (#4769)
* [Docs] Add note about pre-existing Red instance to systemd

* lets actually not just copy paste...
2021-01-28 17:18:02 +01:00
MAX
c11e9afec7 [mod] Improve help of ban/kick commands. (#4715)
* better explain on how to use.

* i.... dont know why i removed that dot.

* don't think that was meant to

* Update kickban.py

* smh

* style????

* hm?

* last try to fix style......

i dont even know how to do this :/

* failing style is fun, trynna learn.

* .....

* not the best way but lets try?

* yep, didnt work dropping softban.

* Update kickban.py

* grammar fix
2021-01-23 21:18:29 -05:00
jack1142
991cd46ea3 Add non-generic message when loading a cog with command name that is already registered (#3870)
* Add non-generic message when loading a cog with command name that is already registered

* Use regex instead and add i18n support

* This requires d.py 1.4
2021-01-23 13:49:03 -07:00
jack1142
ad48ef6efd Add filterhit case type to Filter (#4739)
* Add `filterhit` case type to Filter

* Wrong `__init__.py` :|
2021-01-23 13:36:53 -07:00
jack1142
69c8781cec Fix log rotation in Red (#4738)
* Fix log rotation in Red

* Update regexes to only work with single digit suffixes
2021-01-23 13:04:03 -07:00
jack1142
db20cad395 Strip the reason from whitespace in Mutes cog (#4749) 2021-01-23 12:52:50 -07:00
TrustyJAID
e106dfaece Add [p]listcases command and typing indicator to [p]casesfor (#4426)
* [ModLog] Add [p]listcases and typing indicator to casesfor

* weird

* Address review

* Update redbot/cogs/modlog/modlog.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-23 20:48:31 +01:00
Dav
aa0ee3385d [Mutes] Add ability to send DMs on mute/unmute (#4563)
* handle manual mutes/unmutes

Doing this in the Web-Editor is painful. Let's switch to VSC.

* embed version

* non embed

* config stuff

* testing done

* wow black

* Few things before I start local testing

* Fix new lines

* Make messages not depend on modlog

* Yay voicemutes

* black+import

* what is your ducking problem vscode

* adress review

* this is driving me mad

* Check the config in `_send_dm_notification` to avoid code repetition

* Fix incorrect type hints

* Remove no longer needed line changes

* Remove unused function

* Update the type hints from commit 946299 in the MixinMeta too

* Fixed wrong variable being passed to the method and ensure DMs aren't sent when we couldn't get the member object

* They call me dumb for a reason

* Stop overriding variable with duration + various formatting tweaks

* :(

* We need to differ between voice and text in two places, interesting...

* Show info about no reason provided in embed

* Apparently, the `reason` can also be an empty string :|

* Update redbot/cogs/mutes/mutes.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-23 11:29:18 +01:00
jack1142
2ce4a275fc Fix command usage of [p]choose command (#4733)
* Fix usage in more commands with variadic required arguments

* Restore filter.py
2021-01-22 19:24:27 -05:00
Fabian H
e23d21ec08 Fixed grammatical mistake in allowlist_add. (#4748)
Changed:

            await ctx.send(_("Users has been added to the allowlist."))

to:

            await ctx.send(_("Users have been added to the allowlist."))
2021-01-22 18:25:46 +01:00
El Laggron
cc885090e6 Docstring fixes for dev env values (#4747)
* Docstring change for add_dev_env_value

* Same for remove_dev_env_value
2021-01-22 18:24:19 +01:00
El Laggron
9b97244f9f [Dev] Customizable environment values (#4667)
* Make the dev env flexible

* Fix rst format in docstrings

* Reproduce current behaviour for _ in repl

* Prevent adding existing or reserved names

* Fix typo with environment

* Docstring changes

Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Get env before loop

* Hey I'm not the only one doing typos

* Keep new messages in env

* Clear exception of stack frames

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Include the `channel` variable in the reserved names

* And we're also missing `discord` :)

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-22 16:53:34 +01:00
Predeactor
7630e24822 [Core] Add plural forms in allowlist and blocklist commands (#4705)
* Plurial for blocklist/allowlist

* duh

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-22 02:56:07 +00:00
Lui
8dbabe24e0 [Streams] Use timezone-aware time (#4694)
* [Streams] Remove timezone replacement

* [Streams] Convert naive now time to UTC

* [Streams] Format with black
2021-01-21 16:29:54 +01:00
Lui
5b21d37571 [Streams] Change streamtypes log name (#4744) 2021-01-21 16:15:52 +01:00
bobloy
676f34185d [Core] Add sensible character lengths to activity statuses (#4663)
* Add sensible character lengths

* Add translation function

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-21 13:41:28 +00:00
Predeactor
edbbd76b3c Document that discord.DMChannel can be used in MessagePredicate (#4718)
* Allow "discord.DMChannel" for MessagePredicate

This closes #4707.

* Optional only takes a single type, use Union

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-21 11:42:10 +01:00
Fixator10
315b3e5c98 Add on_red_before_identify dispatch (#4647)
* add before_identify_hook with `on_identify` dispatch

* move before_identify_hook closer to other "hooks"

* add `red_` prefix to avoid potential conflict

* on_red_before_identify

Co-authored-by: Fixator10 <fixator10@users.noreply.github.com>
2021-01-21 10:20:20 +01:00
bobloy
41e980c517 Fix usage in [p]filter's commands, make commands consistent (#4599)
* Make *words a required argument.

* Also make delete consistant, and name not positional
2021-01-21 00:23:16 +01:00
Ryan
0358055cce [Docs] Document pyenv workaround for pm2 (#4709)
* add pyenv specific fixes to pm2

* switch note to code-block

* forgot a new line
2021-01-21 00:12:58 +01:00
PredaaA
dcf7368e54 Show command aliases in help with setting to disable (#3040)
* Update help.py

* Create 3040.enhance.rst

* remove towncrier entry

* Make it i18n friendly.

* That was uneeded to change this actually.

* ...

* ..

* .

* Add a setting for aliases.

* DOTS

* Update redbot/core/core_commands.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Address requested changes maybe

* New format + changes requested.

* okay we'll get there someday

* honk

* aaaaaaaaaaaaaaa

* Black

* Fix missing humanize_timedelta import.

* style

* Two things from my very old pending review, see commit desc

```py
            valid_alias_list = [
                af
                for a in aliases
                if (af := f"{a}")
                and len(af) < 500
                and ((a_counter + len(af)) < 500)
                and (a_counter := a_counter + len(af))
            ]
```
^ This can be simplified:
```suggestion
            valid_alias_list = [
                alias
                for alias in aliases
                if (a_counter := a_counter + len(alias)) < 500
            ]
```
Although I think it would be somewhat clearer to use a `for` loop rather than a list comprehension (+ we can just `break` when there's not gonna be another alias that could fit in the list since it's sorted):
```suggestion
            valid_alias_list = []

            for alias in aliases:
                if (a_counter := a_counter + len(alias)) < 500:
                    valid_alias_list.append(alias)
                else:
                    break
```

* style *again*

* use qualified name of the parent command

* meh

* another meh

* Revert the last commit...

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2021-01-20 23:40:27 +01:00
jack1142
4138410d33 Ensure no role hierarchy bypassing in Mutes (#4741)
* Ensure no role hierarchy bypassing on bad role configuration

* Do the same for `[p]muteset role`
2021-01-20 13:32:59 -07:00
jack1142
537656c365 Fix role position checks (#4740) 2021-01-20 13:32:43 -07:00
Dav
d7a3da49f0 [Mod] Make tempban not fail if no vanity url is set up (#4714)
* catch if a vanity url is not set up

* black

Co-authored-by: David Bauch <david.bauch@capgemini.com>
2021-01-17 23:42:00 +01:00
Grant LeBlanc
2b5d72c7a4 [Trivia] Add support for payout to multiple trivia winners (#4649)
* Add payout splitting for trivia game tie instances

* Add check for non-human players

* Apply suggestions from code review

* `pay_winner()` -> `pay_winners()`

* style

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-17 23:32:04 +01:00
Ryan
e4d24578b5 [Bank API] Cache global bank settings (#4723)
* cache global bank settings

* Make the global variable name clearer

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-17 23:08:59 +01:00
BreezeQS
2b72f9bb99 [Docs] Restructure of the Host List (#4710)
* Update hostlist

My first pr??

* Rephrase of unsupported warning

Exact reason for lack of container support added. Information about docker support added in case someone finds that repo and tries it.

* Remove azure from free list

Later found unreasonable to include it due to the 750 hours being spread across the entire year, ends up less than 24 hours a week.

* Oops

Fixed something that caused docs build to error

* Removal of extra space

Fix of spelling error noticed during review

Co-authored-by: bobloy <alboblexloy@gmail.com>

* Fix capitalization error

Idk if this was really necessary, but oh well

* Rephrase free tier note

* Rephrase docker warning

* Small changes

Added galaxygate and ramnode, removed contabo, rephrased a few things, added voice region tip.

* Small fix

Just realized i accidentailly removed Contabo

* Update docs/host-list.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/host-list.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/host-list.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/host-list.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/host-list.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/host-list.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/host-list.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/host-list.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/host-list.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/host-list.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/host-list.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/host-list.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: bobloy <alboblexloy@gmail.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2021-01-16 18:36:22 -05:00
bobloy
8d512e206a [Docs] Filter Cog Guide (#4579)
* Add filter to index

* Initial generated docs

* Start on docstrings

* More docstrings

* Some more docstrings

* Rest of the doc strings

* Regenerate docs

* Remove unnecessary language. Move to one line.

* Regenerate docs

* Update redbot/cogs/filter/filter.py

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update redbot/cogs/filter/filter.py

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update redbot/cogs/filter/filter.py

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/cog_guides/filter.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/cog_guides/filter.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/cog_guides/filter.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-16 02:10:45 +00:00
jack1142
19711d35b2 Update actions/labeler to use v3 version (#4730) 2021-01-13 04:16:07 +01:00
jack1142
1e1fff0d49 Someone can yell at me later... (#4729) 2021-01-13 04:03:26 +01:00
jack1142
21f75c0711 Fix the negation rules in labeler configuration (#4727) 2021-01-12 14:29:19 +01:00
Flame442
a2d0a364fe Fix auto labeler error from invalid yaml -> json (#4719) 2021-01-10 00:31:07 +01:00
github-actions[bot]
b76b6305d1 Automated Crowdin downstream (#4703)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-01-07 17:26:35 +00:00
Kowlin
beedc6d2c7 [CI/meta] Add automatic labeling of changed files. (#4674)
* Theoretically this should work!

* Update .github/labeler.yml

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update .github/labeler.yml

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update .github/labeler.yml

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update .github/labeler.yml

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update .github/labeler.yml

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update .github/labeler.yml

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* *ughhh*

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2021-01-07 18:09:14 +01:00
Vexed
ecf912bc4b Update docs for 2021 (#4706) 2021-01-01 19:33:48 +01:00
aikaterna
d0a0b3fc53 Update LICENSE for 2021 (#4704)
Thank god this disaster of a year is over, onto the next disaster!
2021-01-01 00:05:44 +01:00
Kowlin
6133075fd6 Bump version to 3.4.6.dev1 (#4691) 2020-12-24 17:40:13 +01:00
Kowlin
e218e092b0 Bump to 3.4.5 (#4690) 2020-12-24 17:23:16 +01:00
Neuro Assassin
7208cdb804 Red 3.4.5 - Changelog (#4692)
* PR 4687

* i dont even know anymore

* fix
2020-12-24 17:21:41 +01:00
github-actions[bot]
13cd751932 Automated Crowdin downstream (#4689)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-12-24 15:45:31 +01:00
Lui
1bdaa9d95e [Streams] Initialize all variables (#4687) 2020-12-24 15:43:05 +01:00
jack1142
67e776a640 Version bump to 3.4.5.dev1 (#4686) 2020-12-24 01:14:16 +01:00
jack1142
dc5f025e02 Version bump to 3.4.4 (#4685) 2020-12-24 00:48:32 +01:00
jack1142
2add689729 Red 3.4.4 - Changelog (#4684)
* Red 3.4.4 - Changelog

* Fix my failures

* Flame is a person too

* Apply suggestions from code review

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update changelog_3_4_0.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-12-24 00:43:51 +01:00
Flame442
3716bf25a7 [Docs] Create CC requirements docs (#4637)
* Create guide_cog_creators.rst

* Update guide_cog_creation.rst

* FTFY <3

* Bullet other details

* req changes

* Update docs/guide_cog_creators.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Apply suggestions from code review

Oh boy I didn't know they added this neat batch commit feature!

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update guide_cog_creation.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-12-24 00:22:10 +01:00
aikaterna
2f18133a93 [Audio] Update Lavalink.jar build (#4683) 2020-12-23 21:59:20 +01:00
Slave In Utero
e8aef1e923 [General] Add new available guild features in [p]serverinfo (#4678)
* add new available guild features

* Remove `ENABLED_DISCOVERABLE_BEFORE`

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-12-23 21:20:12 +01:00
jack1142
30dc6fe171 [Trivia] Remove empty string from answers (again) (#4673) 2020-12-23 21:07:24 +01:00
Kowlin
8ae84b7c81 [Streams] Remove the blank suppression of errors (#4680)
* [Streams] Remove the blank suppression of errors

* Okay, maybe do gracefully handle it a little bit...

* Update redbot/cogs/streams/streams.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-12-23 21:00:55 +01:00
Jamie
d01bca2314 Owners can bypass cooldowns with non persistent toggle (#4440)
* dev bypas cooldowns

* Toggleable within dev, new attrib

* Reuqested changes

* Remake content

* Looks like `reset_cooldown()` is under Command object :)

* Remove `await`

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-12-23 20:25:32 +01:00
Vexed
300346dcd4 [Docs] Update console image in Getting Started guide for Rich logging (#3905)
* update image

* MAXIMISE THE QUALITY

* add storage driver as JSON (#3935)

* fk

* REEEE

how am i faling to use git so much

* rich!

* make image width 696 pixels so it doesn't scale
2020-12-23 15:27:28 +01:00
Kowlin
ab80f46d2e [Core] Rich logging for not so rich people (#4577)
* Pop stash

* add rich to setup

* Added forceful enabling of rich logging

* revert some unintended pushed

* Fix possible unbound var
Fix possible 0 members w/out members intent

* One day I won't forget to do style passes

* So this is a thing apperently...

* Bump rich to 9.5.1

* Lock secondary deps

* Different stuff, see the full commit description for more info

- Change few things from print to log.info
- put the log handlers on the root logger instead of individual loggers
- capture warnings to a logger

* Modify log handler to show logger name

* Add a Triboolian to force disable rich

* Style checks

* shortened time, added logger name... again.

* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

* Style & linking

* Be or not to be? Whatever man, it's 4:30 in the morning, goto sleep >.<

* Reintroduce outdated message.

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-12-23 05:11:44 +01:00
Kowlin
afae84fa6b [CI] Update CodeQL to resolve warnings. (#4681)
* Update CodeQL to resolve warnings.

* Make CodeQL analyze our Python dependencies

* `fetch-depth` should be no longer needed

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-12-23 03:57:28 +01:00
Predeactor
d53ff57794 Shorten the audit log reason appropriately, remove unused vars (#4189)
* [Mod] Check for reason length & remove unused vars

This PR also remove unused variable.

* Blame me

* Apply Kowlin order.

Text will get truncate in audit logs in case we're going over 512 characters.

* This is already handled by ban_user()

* Use `get_audit_reason()` in `[p]tempban`

* Add a new kwarg to `get_audit_reason()` instead

* Include `[p]voiceban` and `[p]voiceunban`

* Include Mutes cog

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-12-23 03:22:59 +01:00
kreusada
d3ffb22e86 [Docs] Raspian Installation Directs to 404 (#4682)
I'd assume this would be an appropriate link to replace with.
2020-12-23 01:49:32 +01:00
jack1142
b36a702e62 Make command usage in help for required arguments consistent (#4589)
* Make command usage in help for required arguments consistent

* Bob 3

* Bob 1

* Docstring updates

* Address Flame's review

* Update cog guides in docs
2020-12-22 14:14:47 -05:00
bobloy
59e1e31634 Fix inviteset public link (#4641) 2020-12-19 21:06:38 +01:00
PhenoM4n4n
8280067b7e Improve grammar in max concurrency error (#4501)
* better concurrency grammar

* remove casing

* Apply Bread's suggestion per Draper's comment

Co-authored-by: Sean <29239704+Bakersbakebread@users.noreply.github.com>

* Thanks Pred

Co-authored-by: Predeactor <61093863+Predeactor@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: Sean <29239704+Bakersbakebread@users.noreply.github.com>
Co-authored-by: Predeactor <61093863+Predeactor@users.noreply.github.com>
2020-12-19 00:31:16 +01:00
github-actions[bot]
7f587ea46b Automated Crowdin downstream (#4664)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-12-18 19:10:17 +01:00
Neuro Assassin
92788a90c1 [CogManagerUI] Fix error when removing path from other OS (#4466)
* Fix error when removing path from other OS

* Update to draper's comment
2020-12-18 04:15:59 +01:00
Ryan
3a12a9b47f [Cleanup] Delete command message when using [p]cleanup self (#4640)
* delete command message

* only delete command if can_mass_purge
2020-12-17 20:37:38 +01:00
bobloy
d22ea2dd11 Warn when new slotmin/slotmax value will cause slots to not work (#4583)
* Properly handle slotmin/slotmax rules

* Use a variable to reduce config calls. No reason to process differently half way through a command anyways.

* Update redbot/cogs/economy/economy.py

* Add positive int converter for slotmin/slotmax

* Option to allow bad mins and maxes.

* Update economy.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-12-17 20:32:57 +01:00
Kowlin
e519286f5c Catch OverflowErrors in the timedelta converter (#4630) 2020-12-16 18:56:42 +01:00
Samuel
06ba425159 bot.remove_command returns a dpy command object instead of None (#4636)
* remove_command returns a dpy command object

* removed typehint at remove_command

* typing

Co-authored-by: npc203 <npc203@users.noreply.github.com>
2020-12-16 18:31:26 +01:00
Slave In Utero
6038ef5550 gen-5-pokemon-trivia (#4646) 2020-12-08 09:53:53 -08:00
github-actions[bot]
b04610b457 Automated Crowdin downstream (#4653)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-12-08 18:39:00 +01:00
Vexed
140693b171 [Docs] Update GC free credit period (#4658)
* [Docs] Update GC free credit period

* i am soo dumb
2020-12-05 17:33:50 +01:00
Ryan
63cc83c81b [Docs] Remove Ubuntu 16.04 from Install Docs (#4650) 2020-12-02 21:07:35 +01:00
El Laggron
e2a6d451c3 [Streams] Handle streams with past schedules (#4631)
* Resolve bug with [p]streamalert youtube

The command didn't handle channels that were not provided as IDs

* Provide a different message if the scheduled date has passed

* Ignore streams scheduled for more than an hour
2020-11-30 18:10:44 +01:00
github-actions[bot]
e2adb29cf3 Automated Crowdin downstream (#4638)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-29 22:04:43 +01:00
kreusada
1ca422a636 General geography category :D (#4618)
* General geography category :D

* Fixes

* Fixed typo

* Added some more questions

* Made some changes, and accuracy fixes, corrections

* *state, not actual river
2020-11-28 18:01:45 -05:00
palmtree5
04cb1befe6 [Docs] Streams user guide (#4521)
* Start on streams user guide

* Finish up streams guide

* Fix a typo in the doc page

* Fix the SAME typo in the relevant command's docstring while we're here

Co-authored-by: palmtree5 <palmtree5+3577255@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-11-27 13:52:56 -05:00
Ryan
da8705fb8f force path to be string (#4624)
Welp forgot to merge
2020-11-26 20:12:23 +00:00
bobloy
395c184eef [Docs] Economy Cog Guide (#4519)
* Started docstrings

* Add to index

* First generated guide

* Indented examples, some more docstrings

* Aliases are now `in ticks and fully qualified`

* More economy docstrings

* Started docstrings

* Add to index

* First generated guide

* Indented examples, some more docstrings

* Aliases are now `in ticks and fully qualified`

* More economy docstrings

* Regenerate docs

* Much more docstrings and regenerate docs

* Better explaination of `bank set` and grammar changes

* Regenerate docs

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-11-22 17:57:11 -05:00
bobloy
c7fd561cd5 [Docs] Downloader cog guide (#4511)
* Downloader cog guide initial commit

* Updated cogguide to prepare description on cog as well.

* Lots of docstring updates

* Even more docstrings

* Fix docstring and generate docs

* Switch to alphabetical

* Aliases are `in ticks and fully qualified`

* Fix grammer, arguments, and explain revision.

* Regenerated docs

* Avoid ticks in links

* New URL logic

* Additional grammar fixes

* Regenerate docs
2020-11-20 20:18:04 -05:00
github-actions[bot]
bc8f2311d9 Automated Crowdin downstream (#4627)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-19 22:18:05 +01:00
El Laggron
f129dcd1a9 [Streams] Resolve bug with [p]streamalert youtube (#4629)
The command didn't handle channels that were not provided as IDs
2020-11-19 18:50:00 +01:00
jack1142
f1d2be58c1 Add python-dateutil to primary deps and lock six with it (#4622) 2020-11-18 22:12:29 +01:00
El Laggron
6060da0f87 [Streams] Support Youtube stream schedules (#4615)
* Catch scheduled livestreams

* Announce scheduled streams and starts

* Add setting, fix bugs

* Add new dependency

* Black reformat

* Fix the duplicated messages bug

* Do not send messages for schedules

* Format embed
2020-11-18 21:48:36 +01:00
jack1142
13ca9a6c2e Version bump to 3.4.4.dev1 (#4616)
Kowlin would want me to admin merge this, so let's just do it.
2020-11-17 00:11:43 +01:00
jack1142
f1c5f4a8e4 Version bump to 3.4.3 (#4614) 2020-11-16 20:10:33 +01:00
jack1142
b7b21a06c8 Red 3.4.3 - Changelog (#4613)
* Red 3.4.3 - Changelog

* Oh man, now that I know this is a thing... Let's use it everywhere

* I can't type

* Apply suggestions from code review

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-11-16 19:59:50 +01:00
aikaterna
dc82ef758f [Audio] Update Lavalink.jar build (#4608) 2020-11-16 19:02:04 +01:00
github-actions[bot]
e50b32cc27 [i18n] Automated Crowdin downstream (#4596)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-16 18:26:02 +01:00
bobloy
224d89c6ff [Docs] Fix CustomCommands URL mistake (#4591) 2020-11-16 18:13:52 +01:00
Kian Bral
866728371b Ensure filenames are lowercase when uploading with [p]triviaset custom (#4594)
* added .lower() to when user uploads trivia filename

* Update PR to use casefold() not lower()

Co-authored-by: zephyrkul <zephyrkul@users.noreply.github.com>

Co-authored-by: zephyrkul <zephyrkul@users.noreply.github.com>
2020-11-16 17:42:13 +01:00
MAX
1747d901d1 [Mod] Support competing status in [p]userinfo command (#4611)
* Competing in userinfo

* Update names.py

* Update names.py
2020-11-16 17:25:41 +01:00
MAX
e87896815c [Core] Add [p]set competing command (#4609)
* Update core_commands.py

* style

* Update core_commands.py

* Update core_commands.py

* does this fix tho?

* C
2020-11-16 15:18:44 +01:00
jack1142
0f7a3bf6f8 Improve Java version regexes in Audio (#4604)
* Improve Java version regexes in Audio

* Can I fix this very small thing too :P
2020-11-15 22:04:45 -08:00
Predeactor
0a040ad8e3 Fix wrong words in docstrings of reaction and message predicates (#4593)
* Fix a wrong usage of word in docs

* Let's fix this while we're at it

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-11-11 17:34:33 +01:00
Flame442
a97cd64f48 [Modlog] Fix error when the bot can't read message history in the modlog channel (#4588) 2020-11-11 17:14:36 +01:00
bobloy
a1a44bf1cc [Downloader] Hide [p]cog reinstallreqs (#4590) 2020-11-11 16:39:33 +01:00
jack1142
48ec2dfee0 Bump versions of actions used by our workflows (#4586) 2020-11-09 20:26:49 +01:00
El Laggron
91f7f9ebf4 [Docs] CogManagerUI user guide (#4152)
* Getting started guide

* Remove DigitalOcean referral link

* Fix typos and mispells, thanks to @Flame442

* Remove cogs.red hyperlink until it is finished

* Add towncrier entry

* Add prolog.txt

This is not necessary for this PR but all of the other cog guides rely on this file.
The cog guides are individual branches based on this one, which is why I'm adding this file right now.

* Add changelog entry

* Add CogManagerUI guide

* Remove towncrier

* CogManagerUI update

* Apply suggestions from code review

Co-authored-by: Vexed <sebdazeley@gmail.com>

* Apply suggestions from code review

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Add section for downloader

Co-authored-by: Toby Harradine <Tobotimus@users.noreply.github.com>
Co-authored-by: Vexed <sebdazeley@gmail.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-11-08 10:27:15 -05:00
jack1142
a7ec40664e Fix reason variable shadowing in [p]massban (#4575) 2020-11-07 03:44:59 +01:00
github-actions[bot]
0089380bfd Automated Crowdin downstream (#4578)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-05 16:53:43 +01:00
github-actions[bot]
ffcf104dfc Automated Crowdin downstream (#4567)
Red I18n: "Context comments are changed edition"

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-02 17:32:43 +01:00
PhenoM4n4n
08c29d780b Fix leaderboard error in DMs for global banks (#4569) 2020-10-31 18:36:14 +01:00
jack1142
7c36709f76 Handle None case for until in on_member_join (#4568)
* Handle `None` case for `until` in `on_member_join`

* They said it can't be too long!
2020-10-29 18:12:57 -06:00
bobloy
80f0a297a9 [Docs] CustomCommands Cog Guide (#4490)
* Add to index, url matching links, and add link to customcommands.rst

* Some docstring rewriting

* Adding arguments and more details.

* Handle aliases, rest of arguments and examples.

* Black formatting

* Switch to alphabetical

* Apparently forgot to regenerate this.

* Update redbot/cogs/customcom/customcom.py

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/cog_guides/customcommands.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-10-28 23:49:51 -04:00
jack1142
a94f0d03dd Version bump to 3.4.3.dev1 (#4564) 2020-10-28 19:55:18 +01:00
jack1142
ac9149870e Version bump to 3.4.2 (#4561) 2020-10-28 19:31:13 +01:00
jack1142
f850ded822 Red 3.4.2 - Changelog (#4560)
* Changelog

* Add 4559

* Fix release date

* This contributor is important too :)

* We need to hire automatic grammar checker

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* update

* ...

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-10-28 19:24:50 +01:00
Draper
06b87368f6 [Audio] Allow LLSET in DMs (#4562) 2020-10-28 10:55:00 -07:00
aikaterna
af65b73fb2 [Audio] Update Lavalink.jar version (#4559) 2020-10-28 17:20:23 +00:00
Draper
0feacee7f2 [Audio] Fix local search (#4553) 2020-10-28 09:07:50 -07:00
jack1142
4aa84a5d22 Add better error logging for unexpected errors, add error messages for exceeded YouTube quota (#4552) 2020-10-28 11:37:56 +00:00
Draper
c95d526bc6 Merge pull request #4558 from jack1142/V3/never_trust_slime
Never trust Slime
2020-10-28 11:25:26 +00:00
jack1142
b77afeed34 Never trust Slime 2020-10-28 12:17:37 +01:00
Stonedestroyer
7db2ba556d Fixes concurrency spelling with time(s) (#4450)
* Change spelling

* Change for translation
2020-10-28 11:56:27 +01:00
PredaaA
bd0955ac44 [Streams] Remove the __del__ (#4512)
* [Streams] Remove the `__del__`

* Add a teardown function to call Streams.cog_unload()

* Apparently I forgot cog_unload is called automatically (Thanks @rapptz
lol)

Co-authored-by: palmtree5 <3577255+palmtree5@users.noreply.github.com>
2020-10-28 11:55:05 +01:00
jack1142
0d650f6765 Remove multi-line commands from Unix install docs (#4550) 2020-10-28 11:54:43 +01:00
jack1142
8b2c6226f6 Add metadata file to redbot --debuginfo (#4557) 2020-10-28 11:54:16 +01:00
bobloy
252951c706 [Docs] Cleanup Cog Guide (#4488)
* Autogenerated doc and index spot

* Update command descriptions

* Use qualified name in titles and new command descriptions

* Add arguments to descriptions and cleanup self examples.

* Examples are bulleted and indented.

* Handle aliases (none), examples are bulleted and indented

* Switch to alphabetical

* Fix X typo
2020-10-28 00:51:19 -04:00
jack1142
532ac6cfa9 I mean... Technically we fixed the security issue, right? (#4556) 2020-10-28 02:34:11 +01:00
Kowlin
868059f062 3.4.2.dev bump (#4549)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-27 21:24:19 +01:00
Kowlin
b496ebfba8 3.4.1 bump (#4548) 2020-10-27 20:47:45 +01:00
jack1142
726bfd38ad Merge pull request from GHSA-mp9m-g7qj-6vqr
* Query members for unchunked guilds in massban

* that thing that is a thing ;)
2020-10-27 20:46:49 +01:00
jack1142
21f9a6f0b6 3.4.1 you dummie!
The link will start working after the release.
2020-10-27 20:41:07 +01:00
Neuro Assassin
951a88f39f Red 3.4.1 - Changelog (#4193)
* Add 3.4.1 section

* PR 4184

* PR 4031

* PR 4364

* PR 4325

* PR 4328

* PR 4366

* PR 4024

* PR 4100

* PR 4360

* PR 4382

* PR 4418

* PR 4376

* PR 4389

* PR 4131

* PR 4326

* PR 4329

* PR 4359

* PR 4370

* PR 4375

* PR 4397

* PR 4404

* PR 4409

* PR 4415

* PR 4416

* PR 4424

* PR 4425

* PR 4435

* PR 4437

* PR 4439

* PR 4443

* PR 4451

* PR 4453

* PR 4455

* Address review

* PR 4058

* PR 4422

* PR 4434

* sigh

* PR 4446

* PR 4449

* PR 4463

* PR 4467

* Add aikaterna as contributor

* PR 4469

* PR 4470

* PR 4473

* PR 4474

* 4467 update

* PR 4481, and fix those doc fuckers.  also nuke something, blame jack for anything that goes wrong

* PR 4498

* PR 4499

* PR 4500

* PR 4502

* PR 4504

* PR 4507

* update PR 4504

* address review

* PR 3902

* PR 4492

* PR 4513

* PR 4515

* PR 3634

* PR 4527

* PR 4524

* PR 4523

* PR 4423

* wip

* Trusty

* Draper

* Draper 2

* Flame

* Flame 2

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Flame 3

* Trusty 2

* Flame 4

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-10-27 20:21:14 +01:00
Draper
a4a344d8eb Add bot.get_or_fetch_user/member methods (#4403)
* add 2 get_or_fetch methods

* style

* local tox didnt scream and blow up

* ewh extra space is ugly

* Jack meant this

* I think jack wanted this.

* Nope Jack desired this

* aaaaaaaaaaaaa Jack just say you are reviewing it come on

* add get_or_fetch_member

* Update redbot/core/bot.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Wubba Lubba Dub Dub

* woa!! this one was really HARD! (sweats)

* fiiiiire

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-27 18:21:20 +01:00
Draper
d421c1c240 [Audio] New stuff from RLL 0.7.0 (#4529)
* New stuff from RLL 0.7.0

* discard here

* formatting

* do this properly

* make it more unique

* bump RLL

* nuke `[p]llset restport`, only `[p]llset wsport` matters

* Update setup.cfg

* properly deprecate Rest port and Ensure Nodes are properly closed upon running LLSET commands

* restore player on a attempt reconnect

* restore player as a task

* ensure we send the signal only if not playing.

* register events a little earlier

* hmmm

* ffs

* update application.yml

* fix permissions edge case
2020-10-27 09:16:19 -07:00
Draper
af8af1934c Merge pull request #4546 from jack1142/V3/update_check_docs
Update check docs to use checks from commands package
2020-10-27 11:44:12 +00:00
jack1142
9a8f3480a1 Update check docs to use checks from commands package 2020-10-27 12:27:15 +01:00
TrustyJAID
085cd1bb49 Modlog account for very long case reasons (#4541)
* Modlog account for very long case reasons

* if
2020-10-27 02:12:06 +01:00
jack1142
b30a8b86a4 Plurality matters (use correct variable name) (#4542) 2020-10-26 19:02:39 -06:00
jack1142
0156ce132c Add Python <3.9 guard until we start supporting Python 3.9 (#4538) 2020-10-26 19:02:00 -06:00
TrustyJAID
b13dec10c5 Replace use of asyncio.gather with bounded_gather (#4537)
* Remove use of asyncio.gather

* black

* typo

* lol 1 character difference

* Let's try this instead

* another typo, it's too early to read

* Add max concurrency on makerole command and prevent multiple roles being added created
2020-10-27 01:20:43 +01:00
TrustyJAID
fd77e97712 [Mutes] Prevent modlog updates on unmute due to category channel sync (#4539)
* [Mutes] Prevent modlog updates on unmute due to category channel sync

* Try here

* would help to remember to change all the right things
2020-10-27 01:18:55 +01:00
jack1142
0b0ace10dd Fix unmute type for manually removed channel overwrites (#4540) 2020-10-26 18:16:11 -06:00
TrustyJAID
b6e96548d0 [Trivia] Add Hockey Trivia (#4384)
* Add Hockey Trivia

* Add more questions and address review

* cleanup authors for now

* Add missing authors

* address vexed's review

* new trivia

* Add New Jersey Devils Trivia

* Add Vancouver Canucks Trivia

* Address Flame's grammar review
do commit messages require proper grammar?
2020-10-26 19:26:58 -04:00
github-actions[bot]
b018c6a24d [i18n] Automated Crowdin downstream (#4476)
Kowlin told me I should just merge.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-26 21:26:02 +01:00
TrustyJAID
3ae5301a76 Fix auto channel unmute still applying after bot restart (#4536) 2020-10-26 19:22:33 +01:00
jack1142
bcc24d67d1 Properly iterate through dict's items in multi channel unmute (#4534) 2020-10-26 11:57:29 -06:00
jack1142
46c0f5e373 Fix TypeError in automatic multi channel unmutes (#4533) 2020-10-26 11:56:45 -06:00
jack1142
eeaac828d9 Fix KeyError in [p]muteset role (#4531) 2020-10-26 11:55:52 -06:00
Kowlin
2413c6abd3 [Core] Guild scoped I18n (#3896)
* Guild I18n

Never again!

* Finish off guild scoped i18n

* Black formatting

* Added guild only flags.

* Fix missing import.

* Added listing of guild i18n settings

* Added API support

* Added API support... properly!

* Added API support... for realsies!

* Auto-translate create_cases instances

You're welcome cog creators! Jack talked me into this!

* Fix get_regional_format to actually return properly

* Cleanup `set showsettings`

* Style pass

* Update redbot/core/core_commands.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/events.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/core_commands.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Fix missing import

* Improve caching

* Removal of unneeded function

* Fix some naming

* IDFK anymore...

* Reformat

* Update redbot/core/settings_caches.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/settings_caches.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/settings_caches.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Remove line number

* Fix global sets

* Set contextual locale manually where needed

* Reports cog is wonderful...

* Update redbot/core/core_commands.py

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Set contextual locale manually where needed in Mutes cog

* s

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2020-10-26 17:59:11 +01:00
TrustyJAID
7bb6e60c52 Move mutes to new cog, add role-based and temporary mutes (#3634)
* revert the revert the revert git is hard...

* and remove old mutes

* make voicemutes less yelly

* fix error when no args present in mute commands

* update docstrings

* address review

* black

* oops

* fix voicemutes

* remove mutes.py file

* Remove _voice_perm_check from mod since it's now in mutes cog

* remove naive datetimes
prevent muting the bot
prevent muting yourself
fix error message when lots of channels are present

* change alias for channelunmute
Be more verbose for creating default mute role

* add `[p]activemutes` to show current mutes in the server and time remaining on the mutes

* improve resolution of unmute time

* black

* Show indefinite mutes in activemutes and only show the current servers mutes in activemutes

* replace message.created_at with timezone aware timezone

* remove "server" from activemutes to clean up look since channelmutes will show channel

* better cache management, add tracking for manual muted role removal in the cache and modlog cases

* Fix keyerror in mutes command when unsuccessful mutes

* add typing indicator and improve config settings

* flake8 issue

* add one time message when attempting to mute without a role set, consume rate limits across channels for overwrite mutes

* Don't clear the whole guilds settings when a mute is finished. Optimize server mutes to better handle migration to API method later. Fix typehints.

* Utilize usage to make converter make more sense

* remove decorator permission checks and fix doc strings

* handle role changes better

* More sanely handle channel mutes return and improve failed mutes dialogue. Re-enable task cleaner. Reduce wait time to improve resolution of mute time.

* Handle re-mute on leave properly

* fix unbound error in overwrites mute

* revert the revert the revert git is hard...

* and remove old mutes

* make voicemutes less yelly

* fix error when no args present in mute commands

* update docstrings

* address review

* black

* oops

* fix voicemutes

* Remove _voice_perm_check from mod since it's now in mutes cog

* remove naive datetimes
prevent muting the bot
prevent muting yourself
fix error message when lots of channels are present

* change alias for channelunmute
Be more verbose for creating default mute role

* add `[p]activemutes` to show current mutes in the server and time remaining on the mutes

* improve resolution of unmute time

* black

* Show indefinite mutes in activemutes and only show the current servers mutes in activemutes

* replace message.created_at with timezone aware timezone

* remove "server" from activemutes to clean up look since channelmutes will show channel

* better cache management, add tracking for manual muted role removal in the cache and modlog cases

* Fix keyerror in mutes command when unsuccessful mutes

* add typing indicator and improve config settings

* flake8 issue

* add one time message when attempting to mute without a role set, consume rate limits across channels for overwrite mutes

* Don't clear the whole guilds settings when a mute is finished. Optimize server mutes to better handle migration to API method later. Fix typehints.

* Utilize usage to make converter make more sense

* remove decorator permission checks and fix doc strings

* handle role changes better

* More sanely handle channel mutes return and improve failed mutes dialogue. Re-enable task cleaner. Reduce wait time to improve resolution of mute time.

* Handle re-mute on leave properly

* fix unbound error in overwrites mute

* remove mutes.pt

* remove reliance on mods is_allowed_by_hierarchy since we don't have a setting to control that anyways inside this.

* black

* fix hierarchy check

* wtf

* Cache mute roles for large bots

* fix lint

* fix this error

* Address review 1

* lint

* fix string i18n issue

* remove unused typing.Coroutine import and fix i18n again

* missed this docstring

* Put voiceban and voiceunban back in mod where it's more appropriate

* Address review 2 electric boogaloo

* Make voicemutes use same methods as channel mute

* black

* handle humanize_list doesn't accept generators

* update voicemutes docstrings

* make voiceperm check consistent with rest of error handling

* bleh

* fix modlog case spam when overrides are in place

* <a:pandaexplode:639975629793787922>

* bleck

* use total_seconds() instead of a dict, sorry everyone already using this lmao

* <:excited:474074780887285776> This should be everything

* black

* fix the things

* bleh

* more cleanup

* lmao hang on

* fix voice mutes thingy

* Title Case Permissions

* oh I see

* I'm running out of funny one-liners for commit messages

* oof

* ugh

* let's try this

* voicemutes manage_permissions

* Cleanup mutes if they expire when member is not present

* black

* linters go brr

Co-authored-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-10-26 02:52:11 +01:00
Draper
38169a82df small PR adding [p]llset info and [p]audioset logs (#4527)
* small PR adding `[p]llset info` and `[p]audioset logs`

* fixed + improvements

* Zip file properly
2020-10-25 14:46:59 -07:00
aikaterna
18986bcc42 [Mod] Fix + more info for modset defaultduration (#4525)
* [Mod] Fix + more info for modset defaultduration

* Update settings.py

* Duration must be greater than zero

* Don't need the extra parens here
2020-10-25 20:43:44 +01:00
Draper
ce6c17debc Add data path and metadata file to [p]debuginfo, add missing info to non-embed version (#4524)
* Add data path to `[p]debuginfo`, add missing info in non-embed version

* More things

* cast to str

* another reorder
2020-10-23 18:39:24 +01:00
Chloe
e3359e9b3f Fixed possible exception thrown when balance field is missing during schema conversion (#4523)
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2020-10-23 18:39:14 +01:00
jack1142
c1ab10e202 another reorder 2020-10-23 19:14:08 +02:00
jack1142
1d23c1f2bc cast to str 2020-10-23 19:11:57 +02:00
jack1142
ef1582832d More things 2020-10-23 19:09:08 +02:00
jack1142
95e342f4f4 Add data path to [p]debuginfo, add missing info in non-embed version 2020-10-23 18:28:44 +02:00
Draper
ca078e7cd9 Fix a crash when calling [p]modset showsettings (#4518)
* Fix a crash when calling `[p]modset showsettings`

* Update redbot/cogs/mod/settings.py

* be more explicit
2020-10-22 11:05:40 -07:00
PredaaA
b8a2cf3f91 Move bot_in_a_guild from redbot.core.checks to redbot.core.commands (#4515) 2020-10-22 09:58:18 +01:00
jack1142
e1226c6c88 Update to d.py 1.5.1, explicitly request privileged intents (#4423)
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2020-10-21 19:55:25 +01:00
PredaaA
34fe88da29 [Menus] Handle ctx.me that can be None when clearing reactions (#3902) 2020-10-21 14:23:36 +02:00
Draper
454ff90d09 excluse streams from queue duration (#4513) 2020-10-20 10:34:32 -07:00
Draper
e31196d19f Audio Fixes (#4492)
* handles #4491

* add typing indicators to audio playlists commands like discussed with aika.

* recheck perms upon change of token to avoid needing a reload.

* Ensure the player lock is always released... on rewrite to this as a callback to the task.

* ffs

* resolves#4495

* missed one

* aaaaaaaaa

* fix https://canary.discord.com/channels/133049272517001216/387398816317440000/766711707921678396

* some tweaks

* Clear errors to users around YouTube Quota
2020-10-20 09:57:02 -07:00
Neuro Assassin
335e2a7c25 Bump aiohttp-json-rpc dependency (#4506)
* Bump aiohttp-json-rpc

* Well thats sad
2020-10-18 21:17:05 +02:00
Flame442
694d379aef [Core] Add default embed colour to [p]set showsettings (#4498)
* Add default color to [p]set showsettings

* I didn't want to since I thought it would be too long, but sure

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-18 21:11:38 +02:00
Jyu Viole Grace
f4ef3ea8eb Merge pull request #4507
* change `boosters` to `boosts`
2020-10-18 15:36:53 +01:00
palmtree5
ec90199950 Add a setting for adding a tick reaction when help is DMed (#4467)
* Tick response for help command

* Make this a setting instead

Co-authored-by: palmtree5 <palmtree5+3577255@users.noreply.github.com>
2020-10-18 16:10:00 +02:00
Stonedestroyer
08bd0567ad Grammar fixes (#4500)
* Grammar fixes

* More changes

* Grammar

* Error grammar

* Spelling

* Grammar

* REsolves grammar

* grammar

* grammar

* grammar

* grammar

* grammar

* grammar

* grammar

* grammar

* "commited" > "committed"

* apostrophe

* more grammar

* grammar

* `funtion` to `function`

* grammar in alias cog

* grammar in cleanup cog

* grammar in customcom cog

* grammar in mod cog

* grammar in reports cog

* fix grammar in streams cog

* missing apostrophe

* grammar fix in trivia cog

Co-authored-by: Jyu Viole Grace <24418520+thisisjvgrace@users.noreply.github.com>
Co-authored-by: Jyu Viole Grace <thisisjvgrace@users.noreply.github.com>
2020-10-18 08:52:56 +01:00
aikaterna
963b8b0d29 Update Lavalink.jar build (#4504) 2020-10-18 08:46:41 +01:00
Fixator10
009dc9ae4d fix exception for empty strings in [p]choice (#4499) 2020-10-18 08:46:11 +01:00
maxbooiii
33cf275862 [Core] added some missing dots. (#4493)
* core added missing dots

* lower-case
2020-10-18 08:45:32 +01:00
Vexed
4fdea931b9 [Docs] More detailed info about args in Getting Started (#4058)
* initial removal and partial re-adition

* lets not miss a line in removal

* dont merge yet

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* yep ready now i think

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-18 02:26:58 +02:00
Predeactor
4453b5653a Fix [p]cleanup self not working in DMs for non-owners (#4481)
* Fix cleanup self not working in private.

This fix #4408.

* Apply Jack's logic.

* Obviously Black fault.
AGAIN!

* Apply Jack's trick.

* This is not a converter so let's move this to a different file

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-18 02:07:08 +02:00
Stonedestroyer
152ca39719 Creating bot account and enabling intents guide (#4502)
* Test

* Docs

* Fixes

* Nesting

* grammar fixes

* Update docs/bot_application_guide.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update docs/bot_application_guide.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update docs/bot_application_guide.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update docs/bot_application_guide.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/cli.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* More clear

* remove double `and`

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-18 01:52:11 +02:00
Kowlin
9ae733181b Handle verified bots, improve errors in [p]set username (#4463)
* handle verified bots, and more specific errors

* stuff

* fuck, I forgot

* Improve errors by splitting into few different messages

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-17 02:45:52 +02:00
Dav
f5de382946 [Mod] Add default tempban duration setting (#4473)
* Add support for default duration in kickban.py

* add setting command and info to settings view

* add config key

* black

* Thx jack

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* adress review

* Address review

* typo

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-16 00:15:14 +02:00
PhenoM4n4n
dc817aeeac Allow [p]ban to hackban and rename [p]hackban to [p]massban (#4422)
* ban revamp

* black & converters fix

* discord.object

* Update redbot/cogs/admin/admin.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* remove discord.user converter

* black

* .

* Update redbot/cogs/mod/kickban.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/kickban.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/kickban.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/kickban.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* incomplete

* massban support

* black

* Use 2-tuple to separate result and the message in `ban_user()`

This also fixes the issue with `True` being equal to `1` which caused a problem with previously returned types

* Whoops...

* trailing whitespace...

* I missed this one

* Update kickban.py

* Update kickban.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-15 23:20:20 +02:00
jack1142
47c4edf335 Update Windows instructions to not install Python 3.9 (#4480)
* Update install_windows.rst

* Add more info

* Add more info pt.2
2020-10-14 21:35:05 +01:00
Stonedestroyer
e1c745fe3c Remove ruledropper (#4449) 2020-10-14 21:34:45 +01:00
Vexed
c441857a4c [Core] Add two missing full stops to licenseinfo (#4020)
* full stops

* hereafter -> hereinafter

* Add the other stop that was here...

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-14 22:25:08 +02:00
Jyu Viole Grace
51bc5fed7d whosthatpokemon - Gen IV (#4434) 2020-10-14 08:16:59 -07:00
Draper
2da9b502d8 Audio Cog - v2.3.0 (#4446)
* First commit - Bring everything from dev cog minus NSFW support

* Add a toggle for auto deafen

* Add a one off Send to Owners

* aaaaaaa

* Update this to ensure `get_perms` is not called if the API is disabled

* Apply suggestions from code review

Co-authored-by: Vuks <51289041+Vuks69@users.noreply.github.com>

* silence any errors here (in case API is down so it doesnt affect audio)

* update the message to tell the mto join the Official Red server.

* remove useless sutff, and change dj check order to ensure bot doesnt join VC for non DJ's

* ffs

* Update redbot/cogs/audio/core/tasks/startup.py

Co-authored-by: Twentysix <Twentysix26@users.noreply.github.com>

* Aikas Review

* Add #3995 in here

* update

* *sigh*

* lock behind owner

* to help with debugging

* Revert "to help with debugging"

This reverts commit 8cbf17be

* resolve last review

Co-authored-by: Vuks <51289041+Vuks69@users.noreply.github.com>
Co-authored-by: Twentysix <Twentysix26@users.noreply.github.com>
2020-10-12 11:39:39 -07:00
aikaterna
29ebf0f060 [Core] Strip commas on cog command when pagified (#4468) 2020-10-11 17:44:47 +02:00
aikaterna
ec94327b15 [Core] Pagify cog unload output properly (#4469)
* [Core] Pagify cog unload output properly

When you unload a large amount of cogs (close to message limit on characters), the character count is easily pushed over 2k characters on the command response with the cog names each being wrapped in 2x backticks. The current implementation breaks in the middle of cog names or wherever else it feels like it. 1600 might have been a safe value for splitting but at 1500 I don't see how multiple short cog names could make it break at least.

* Address review
2020-10-11 17:43:12 +02:00
aikaterna
5c00810166 Use bot name instead of "Red" in [p]info and [p]restart (#4470) 2020-10-11 17:21:54 +02:00
PredaaA
804219df29 Use bot.get_user() instead of get_all_members() in [p]dm (#4472) 2020-10-11 17:19:49 +02:00
MeatyChunks
6ea2a403be [General] Fix error on long titles in [p]urban (#4474)
There's a few titles that are greater than 256 which causes a console error. The example I saw was scrolling through the pages of `[p]urban Jackin' Off` which leads to http://synonyms-chokin-the-chicken-spanking-the-monkey-flogging-the-do.urbanup.com/3169366
2020-10-11 17:14:21 +02:00
Stonedestroyer
4f2763c26c Add wheel to pre-requirements installed by make files (#4475) 2020-10-11 17:09:55 +02:00
Predeactor
8ff5a71a5d Update the link to 3rd-party cogs in README to use Red-Index (#4482) 2020-10-11 17:02:54 +02:00
Draper
d6c2e8c8c3 Add bundled install extras. (#4443)
* add an `[all]` extras_requires

* can go here

* add a [dev] which includes [all] + development extras (style, test, docs)

* special case all and dev in update message

* Optimize by changing the place of the check for "special" extras

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-10 01:32:29 +02:00
Vuks
b45e62f354 [Core] add [p]set api list and [p]set api remove (#4370)
* add get_shared_api_keys

* add set listapi command

* fix typo

* refactor `[p]set listapi` into `[p]set api list`

* remove unnecessary check

* fix decorators

* corrected wording

* add remove_shared_api_services

* add `set api remove`

* further typo sniping

* bugsniping

* minor typo

* aaaaaaaaa

* Apply suggestions from code review

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* update api docstring to reflect new subcommands

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* update framework_apikeys.rst with new methods

* Update redbot/core/bot.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* rewrite get_shared_api_services into a special case of
get_shared_api_tokens

* rewrite api_list to include keys and tokens in response

* don't show secrets

* better api_remove response

* black

* remove nonexistent method

* remove unnecessary import

* fix wording

* Improve docstrings and type hints

- added overloads to help out developers a bit more
  * this wasn't necessary, but development tools work better
    with this information
- fixed type hint to use Union as now
  its return type depends on whether `service_name` is passed
- updated docstrings to contain information about the added behavior

* Use `humanize_list()` rather than `str.join()`

This is done for consistency within Red
and it makes the list have the last element joined
with `and` (or its equivalent in chosen locale)

* Use `.format()` after translation is applied

If `.format()` is used before `_()`, the search for translation is done
with the string that already has the dynamic text added,
which results in no matches.

* Add plural support

* Improve error message

Updated message to be more specific
(used phrases: "None of the services" and "had any keys set")
and a bit more nice to the user (judging word "anyway" removed)

* Improve readability of `[p]set api list`

It's a lot clearer when the sublists are indented,
especially on mobile where code blocks aren't colored at all.

New look:
https://user-images.githubusercontent.com/6032823/94614944-3bbd7c80-02a7-11eb-89e4-64bdf06c650b.png

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-05 22:10:14 +02:00
jack1142
8b477db0a6 Update pyenv instructions to install Python 3.8.6 (#4457) 2020-10-03 09:02:34 -08:00
github-actions[bot]
80d99af5b0 Automated Crowdin downstream (#4462)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-03 00:30:26 +02:00
Kai K
d26335b01b [Trivia] MLB Trivia (#4455)
* Create mlb.yaml

* Update mlb.yaml

* Update mlb.yaml

* Update mlb.yaml

* Update mlb.yaml

* Update mlb.yaml

* Update redbot/cogs/trivia/data/lists/mlb.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update mlb.yaml

* Update mlb.yaml

* Update mlb.yaml

* Update mlb.yaml

* Update mlb.yaml

* Update redbot/cogs/trivia/data/lists/mlb.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/mlb.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/mlb.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/mlb.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/mlb.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update redbot/cogs/trivia/data/lists/mlb.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update mlb.yaml

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-10-01 19:09:45 -04:00
Draper
e79aa21b55 Add util functions extracting end_user_data_statement directly from cog's info.json (#4404)
* get_end_user_statement

* add get_end_user_statement

* I hate docs

* lets make Jack and Zeph happy as they want a version that raises.

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/utils/__init__.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* rename to `get_end_user_data_statement`

* aaaaaaaaaaaaaaa

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-09-29 20:58:30 +02:00
Draper
bf63da3655 Stop backing up lavalink logs (#4453) 2020-09-28 08:50:42 -07:00
Fixator10
d6791111f3 fix [p]set nickname when no nickname specified (#4451) 2020-09-28 13:14:49 +02:00
jack1142
23d454cbbe Fix deprecation mention for shared libs in docs (#4374)
* Fix deprecation mention for shared libs in docs

* Update docs/guide_publish_cogs.rst

Co-authored-by: Vexed <sebdazeley@gmail.com>

Co-authored-by: Vexed <sebdazeley@gmail.com>
2020-09-27 21:28:18 -04:00
absj30
f9741cdd27 Fix typo at function's "end_game" docstring (#4186)
Co-authored-by: Ailton Jr <ailton@edu.unipar.br>
2020-09-27 21:28:07 -04:00
Sharky
3699c246df [Mod] Account for duplicated mentions (#4359)
* Account for duplicated mentions

* Spelling fix + Wording change

* Requested changes *hopefully*

* forgot to formattttttttttttttttttttttt

* Improve the consistency with existing commands in inconsistent `[p]modset` group

* What was the point of defining `guild` if you didn't end up using it, Jack!?

* I hate you, web editor ಠ益ಠ

* You could have just copy-pasted this Jack, seriously...

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-09-27 21:27:53 -04:00
jack1142
284080ec83 Update events.py (#4431) 2020-09-27 21:27:29 -04:00
jack1142
a2ae485286 Deprecate is_allowed_by_hierarchy() core util (#4435) 2020-09-27 21:27:22 -04:00
jack1142
a74547bb4e Update Getting started guide with the link to Index (#4439)
* Update Getting started guide with the link to Index

* Update docs/getting_started.rst

Co-authored-by: Twentysix <Twentysix26@users.noreply.github.com>

Co-authored-by: Twentysix <Twentysix26@users.noreply.github.com>
2020-09-27 21:27:15 -04:00
github-actions[bot]
a6ff5b8e9c Automated Crowdin downstream (#4445)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-24 22:01:14 +02:00
github-actions[bot]
a09dddb2cf Automated Crowdin downstream (#4432)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-24 02:14:41 +02:00
Dav
d7da0b4081 [Mod] Pluralize properly in userinfo (#4397)
* Pluralize properly in userinfo

* black

* totally didn't forget roles

* Almost seems like you have a point there...

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Yes... right... this one too

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Yes, yes we do.

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-09-21 00:39:44 +02:00
Flame442
47d9069108 [Core] Catch errors about blocked DMs in [p]traceback (#4329) 2020-09-20 19:42:28 +02:00
bobloy
ddc5660f2c Add custom groups tutorial to Config's docs (#4416)
* Add `Config.custom` tutorial to docs

* Red V2 Data transfer example brought up-to-date as well

* Update docs/framework_config.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update docs/framework_config.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update docs/framework_config.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update docs/framework_config.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update docs/framework_config.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update framework_config.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-09-20 02:57:37 +02:00
Kowlin
88503bbf24 [Mod] Correctly log and store the previous (nick)name (#4131) 2020-09-20 02:42:12 +02:00
zephyrkul
8a75d75d83 Add quote() function to chat formatting utilities (#4425)
* add quote to chat_formatting

* ...

* jack's request
2020-09-20 02:12:11 +02:00
Dav
980b5fa1c2 [Warnings] Improve consistency in [p]warningset's commands (#4409)
* Be consistent with bool setters in warnings cog

* black
2020-09-20 00:16:42 +02:00
PredaaA
343efba4d5 Handle aiohttp errors in [p]set avatar (#4437)
* [Core comands] Handle aiohttp errors in set avatar

* Update redbot/core/core_commands.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-09-19 19:51:38 +02:00
Dav
4e1ce7524b [Modlog API] Handle deleted channels in Case.message_content() (#4415)
* Handle deleted channels in case.message_content()

* remove avatar_url + black
2020-09-19 19:39:59 +02:00
TrustyJAID
fec25fcaba Accept discord.Objects for cases, add last_known_username param in create_case() (#4326)
* [Modlog] Fix typehints for create_case

* Simplify Logic after review

* discord.abc.User to catch both member and user objects and other potential discord.Object's being sent

* fix typehints and Case.edit()

* fix docstrings in create_case

* Add note about last_known_username

* fix the weird thing that scared me
2020-09-19 19:05:00 +02:00
Jamie
6162b0f2bd [Trivia] Fix machamp/machoke (#4424)
* fix machamp/machoke

* swap order
2020-09-14 08:33:49 -07:00
jack1142
6f600b71d3 Exclude locales folders from code ownership (again) (#4418) 2020-09-10 20:33:11 +02:00
github-actions[bot]
f6fccfc949 Automated Crowdin downstream (#4417)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-10 20:32:04 +02:00
Kowlin
e1b02b2952 Escape regex on spotify URL (#4414) 2020-09-09 11:03:22 +01:00
Kowlin
a80a5ec96e Create codeql-analysis.yml (#4413)
* Create codeql-analysis.yml

* Remove the matrix support

* Remove autobuild and strategies
2020-09-09 01:12:27 +02:00
Kowlin
a9656dea38 Delete no-NO in favor of nb-NO (#4396) 2020-09-05 02:48:55 +02:00
github-actions[bot]
f8fcabfe10 Automated Crowdin downstream (#4395)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-03 17:26:47 +02:00
Kingsley Zhong
ea7e142494 Add hierarchy checks to [p]warn (#4100)
* Update warnings.py

* Cleanup the code and pass style check.

Co-authored-by: Kowlin <boxedpp@gmail.com>
2020-09-03 16:23:03 +02:00
github-actions[bot]
e1a9b31e9b Automated Crowdin downstream (#4394)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-03 15:48:34 +02:00
Nathaniel F
59f69c7727 [General] URL encode user input for [p]urban and [p]lmgtfy (#4024)
* URL encode user input in the general cog

Adds URL encoding to `[p]lmgtfy` via `urllib2.parse.quote_plus()`
and to `[p]urban` via `aiohttp.ClientSession.get`'s `params` argument

* Black reformatting
2020-09-03 00:35:27 +02:00
jack1142
0200c2cb3f Clarify documentation of modlog.create_case() (#4389) 2020-09-02 23:09:59 +02:00
jack1142
b11359eebb Add float -> int migration to Bank (float was a bug) (#4386)
* Add float -> int migration to Bank (float was a bug)

* wrong refs

* Cause ctx manager compares before and after values...
2020-09-01 02:04:19 +02:00
jack1142
4adf328fac Update .gitignore with .vscode folder (#4387) 2020-09-01 01:25:46 +02:00
Stonedestroyer
f81cf5960f Fix typos in doc string. (#4360) 2020-09-01 00:53:25 +02:00
jack1142
2bf9c1260c Update CODEOWNERS (#4367)
* Update CODEOWNERS

* Prepend with backslash, add downloader fixtures

* Update CODEOWNERS

* Schemas are closely related to Downloader...

...so I should know about the changes to those.

* Would be nice to add my name (thanks Draper)
2020-08-31 16:40:31 +01:00
Vexed
8956f63229 [Mod] Dots and properly capitalise Discord (#4377) 2020-08-31 14:25:43 +01:00
Ian Martin
7d24413846 Ensure Bank API only works with Integers. (#4376)
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2020-08-31 14:24:44 +01:00
PythonTryHard
e1261b92d1 Typo fix on [p]invite command (#4382) 2020-08-31 14:21:15 +01:00
Fixator10
8c89993cd5 JSON schemas for cogs and repos (#4375)
* JSON schemas for cogs and repos

* newline at the end

* capitalization

* Remove *.json from .gitignore

* Remove empty line

* resolve requested changes

* resolve requested changes, again

Co-authored-by: Fixator10 <fixator10@users.noreply.github.com>
2020-08-30 20:20:48 +02:00
github-actions[bot]
ec7c2ca4b9 Automated Crowdin downstream (#4373)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-30 17:42:37 +02:00
jack1142
85afe19455 Bump black to 20.8b1 (and reformat) (#4371)
* Bump black version

* Reformat with black
2020-08-29 19:12:28 +02:00
Ryan
56b54d4d34 [Docs] Update shields in Readme (#4378)
* python shield option 1

* python shield option 2

* updates shields

* swap pypi and d.py

* new format

* no caps
2020-08-29 04:06:54 +02:00
Neuro Assassin
3534e59cb8 [Dev] Add repl pause (#4366)
* [Dev] Add repl pause

* Update redbot/core/dev_commands.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Address reviews

* Address reviews x2

* Small consistency fix

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-08-25 13:24:40 +02:00
Kowlin
eeb5f651b2 Stop the insanity that is this inconsistent command name! (#4328) 2020-08-25 05:18:50 -06:00
TrustyJAID
b0250b91cc Merge pull request #4325 from zephyrkul/patch-1
[customcom] Gracefully handle timeouts in cc edit
2020-08-25 05:16:37 -06:00
Theo Suricate
ef839722f4 Added length validation for [p]set name and [p]set nickname (#4364) 2020-08-24 14:59:09 +01:00
maxbooiii
5cd3a5b5af missing dots (#4031) 2020-08-23 03:13:09 +02:00
bobloy
d80d7c939c Fix typo in lint python workflow (#4201) 2020-08-20 21:26:33 +02:00
github-actions[bot]
8c7848f18b Automated Crowdin downstream (#4327)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-20 19:30:44 +02:00
zephyrkul
7d66263948 [cc] don't send success on failure 2020-08-18 18:40:32 -06:00
zephyrkul
7d6662e6b1 [customcom] properly catch TimeoutErrors 2020-08-18 18:32:06 -06:00
Jay Turner
3e6a73ae8c [Economy] Add embed to leaderboard (#4184) 2020-08-18 14:42:36 +01:00
jack1142
94784f366f Dev bump (3.4.1.dev1) (#4197) 2020-08-18 02:10:46 +02:00
Kowlin
bc04937a6a Actually change the version before release! (#4195) 2020-08-18 01:13:01 +02:00
jack1142
29f8cc79ba Red 3.3.12 - Changelog (#4194)
* Red 3.3.12 - Changelog

* Fix date (duh, we're too slow)
2020-08-18 01:00:44 +02:00
zephyrkul
089c253d1d [ctx] Suppress all mentions in maybe_send_embed (#4192)
* [ctx] Suppress all mentions in maybe_send_embed

Whether this method should mention shouldn't be tied to an unrelated setting.

* black

* Update changelog_3_4_0.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-08-18 00:20:03 +02:00
jack1142
d8e780b228 Red 3.4.0 - Changelog (#4059)
* Add 3.4.0 changelog

* Fix some stuff in previous changelog

- Remove empty section
- Fix alphabetical order in contributor list
- Add missing Flame to contributor list
- Fix the length of rst header underline

* PR 4050

* PR 3993

* PR 4064 (issue 4028)

* PR 4077

* PR 3956

* PR 4079

* PR 4089 (issue 4088)

Co-Authored-By: Dav <dav@mail.stopdavabuse.de>

* PR 4099

* PR 4097

* Add Trusty to contributor list

* PR 4116

* PR 4043 (issue 3945)

* PR 4072

* PR 4109

* PR 4110

* PR 4102

* PR 4112

* PR 4161

* PR 4121

* PR 4134, 4143

* PR 4085

* PR 2982 (issue 2906)

* PR 3679 (issue 3605)

* PR 4148 (issue 4147)

* PR 4011

* PR 4022 (issue 4013)

* PR 4135 (issue 4122)

* PR 4167

* PR 4141

* Add NeuroAssassin to contributor list

* PR 4129

* PR 4149

* PR 4105, 4127 (issue 4106)

* PR 3845

* PR 4142

* PR 4163

* PR 4176

* PR 4172 (issue 4066)

* PR 4038 (issue 3786)

* PR 3081

* PR 4137 (issue 4118)

* PR 4017

* PR 4182

Co-Authored-By: Dav <dav@mail.stopdavabuse.de>

* Add Kowlin to contributor list

* PR 4182

* PR 4169

* PR 3084

* Add `douglas-cpp`, `MeatyChunks`, `zephyrkul` to contributor list

* PR 4138

* Add some anchor

* Add release date

Co-authored-by: Dav <dav@mail.stopdavabuse.de>
Co-authored-by: palmtree5 <3577255+palmtree5@users.noreply.github.com>
2020-08-18 00:04:15 +02:00
El Laggron
a9fce2dcf2 [Docs] Fix the horizontal bars in alias user guide (#4191) 2020-08-17 16:08:12 +02:00
El Laggron
6067c8d55e [Docs] Alias user guide (#3084)
* Getting started guide

* Remove DigitalOcean referral link

* Fix typos and mispells, thanks to @Flame442

* Remove cogs.red hyperlink until it is finished

* Add towncrier entry

* Add prolog.txt

This is not necessary for this PR but all of the other cog guides rely on this file.
The cog guides are individual branches based on this one, which is why I'm adding this file right now.

* Add changelog entry

* Add alias cog guide

* QA changes

* More QA changes

considering -> assuming
red is a girl, not non-binary

* Fix some mistakes

* Fix references

* More and better examples, with arguments

* A first quick fix for review

* An attempt to fix the review by @Flame442

* Delete 1734.docs.3.rst

Co-authored-by: Toby Harradine <Tobotimus@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-08-17 15:35:44 +02:00
zephyrkul
0ab6abf462 [Filter] Add missing parentheses (#4185) 2020-08-17 15:25:15 +02:00
Douglas
306de3a64c Don't send message about DMing ACL when command's called from DM (#4188)
* Only send a message telling the user the file will be send via DM if the original message didn't come from a DM

* Remove unused import for AsyncIter

* Changed channel instance comparison to discord.DMChannel

Co-authored-by: douglas-cpp <douglasc.dev@gmail.com>
2020-08-17 15:22:38 +02:00
jack1142
929fd04613 EUD things for Downloader (#4169)
* Initial commit

* Send pagified as with other Downloader's things
2020-08-17 01:27:46 +02:00
Dav
581bdaa496 [Core] Make core_commands.py comply with #4048 (#4138)
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2020-08-16 11:37:29 +01:00
Trent Kable
341fd254fb Add allowed_mentions and mention everyone check to stream alerts (#4182)
* [streams]allowed_mentions on stream announcement

Allows role mentions for discord.py 1.4+
# Type

[x] Bugfix
[ ] Enhancement
[ ] New feature

Description of the changes

Referencing line 747. Gives permissions to mention role on stream announcement.

* Update streams.py

* Add `mention_everyone` defaults

Lines for reference:
- [751-753]:
```py
if can_mention_everyone:
  await self.save_streams()
  return # if bot can mention everyone already, let's stop here```
- [722-774]: 
```py
if can_mention_everyone:
  mentions.append(role.mention)
  return # if bot can mention everyone already, let's stop here (part two)```

Hopefully, this is what you had in mind? Humbly admit I may not have a business in biting this piece but looking forward to feedback on the best methodology for the wanted outcome.
Thanks!

* *sweats*

* imagine variable naming

Should complete all passes.

* misplaced unindent on return

* Update redbot/cogs/streams/streams.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/streams/streams.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/streams/streams.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* You're a beast jack

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* this would cover all channels in guild (think)

* give this a reeeeee

* Update streams.py

* adds channel argument

https://github.com/Cog-Creators/Red-DiscordBot/pull/4182#pullrequestreview-468012281

* image style checking, self

* imagine

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-08-16 00:59:53 +02:00
Kowlin
bf581b9f97 [Streams] Allow for consume all on messages (#4183)
* Added consume all to streams.

* Updated help doc

* Styling checks, man...
2020-08-15 15:04:05 +02:00
jack1142
46eb9ce7a0 Remove things past deprecation time (2020-08-05) (#4163) 2020-08-15 13:47:28 +02:00
Dav
0adaebb290 [Docs] Clarify EUD statement (#4180)
* add a comma

* be a little more specific
2020-08-14 08:41:00 +02:00
github-actions[bot]
d1b7e0eafb Automated Crowdin downstream (#4181)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-14 08:40:04 +02:00
Dav
914f82f352 [Modlog] add timestamp to [p]casesfor and [p]case (#4137)
* add timestamp to casesfor and case

* [Casereader] add timestamp + i18nify

* of course it was needed...

* Update redbot/cogs/modlog/modlog.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/modlog/modlog.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* well that was easier than expected

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* thx for the help jack

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-08-13 23:17:02 +02:00
El Laggron
8e611b466e [Docs] Admin user guide (#3081)
* Getting started guide

* Remove DigitalOcean referral link

* Fix typos and mispells, thanks to @Flame442

* Remove cogs.red hyperlink until it is finished

* Add towncrier entry

* Admin guide

* Add prolog.txt

* Use substitutions for arguments

* Some grammar fixes

* Add prolog.txt

This is not necessary for this PR but all of the other cog guides rely on this file.
The cog guides are individual branches based on this one, which is why I'm adding this file right now.

* Add changelog entry

* Add serverlock

* Apply suggestions from code review

Co-Authored-By: Vexed <51716387+Vexed01@users.noreply.github.com>

* Suggestions from vexed

* Update to new admin commands

* Delete 1734.docs.2.rst

* Apply the changes requested by reviewers

Plus add a small tuto on how to make a bot private

* Fix arguments inconsistency

* Remove ctx from argments

* Update docs/cog_guides/admin.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Quotes aaaaaa

Co-authored-by: Toby Harradine <Tobotimus@users.noreply.github.com>
Co-authored-by: Vexed <51716387+Vexed01@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-08-13 05:12:58 -04:00
DevilXD
6e63ed4e60 Use aware objects when storing and reading UTC timestamps (#4017)
* Use aware objects instead of naive ones

* Use aware objects when storing and reading UTC timestamps

* Remove unneeded parentheses

* Fixed naive and aware objects unable to be compared here

* Address feedback

* Fix the newly added `modlog.create_case()` calls

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-08-12 10:46:32 +02:00
Sharky
73a34eacd6 [Mod] Add kick and warn to mention spam (#4038)
* Mention spam addition

Adjust code to allow for warning and kicking in mention spam automoderation.

Added new subcommand group, mentionspam. Which will display settings of warn, kick, ban, mentionspam when called.

Adjust config to account for this.

* Condense config + removal of comments

Condense config into one variable to make one call.

Removed unneeded comments I left.

* Add warning casetype

Copied over from warnings cog

* Update strings + change function names

* Changed prints and logs. Account for showsettings, removed blocking.

If this style breaks, blame draper...

* Black format...still blaming draper.

* Adding period at end of description

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* config migration

* Fix TypeError, add default information.

* Max_mention wording change

Thanks to @zephyrkul for suggesting the word changes.

* Require argument for max_mention

* Fix warn modlog case creation

* Fix casetype conflict

maaaaaaaaaagicccccccccc timeeeeeeeeeeeeeeeeeeeeeeeee

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-08-11 23:24:22 -04:00
jack1142
9798538438 Remove provisional note from NoParseOptional, fix and start using UserInputOptional (#4142) 2020-08-10 20:20:02 +01:00
Dav
35b0224690 [Mute] Indicate that a guild mute/unmute is currently being processed. (#4172)
Co-authored-by: fixator10
2020-08-10 20:19:44 +01:00
jack1142
05ef5fa3a6 Preparations for d.py 1.4 (includes breaking changes related to mass mentions) (#3845)
Co-authored-by: PredaaA <46051820+PredaaA@users.noreply.github.com>
2020-08-10 20:19:00 +01:00
Tinonb
7707c862d1 Removed Also And Installation (#4176)
In line 60 I removed the word also as it implies that the bot can is already being hosted by someone but you can host it too. I also removed the word installation from line 65 and changed it to installing as that makes more sense or you would have to change the word updating.
2020-08-09 23:40:27 -04:00
jack1142
01a6ef3a8f Add variation selector-16 as appropriate to emojis across Red (#4127) 2020-08-10 03:05:57 +02:00
jack1142
4385aac90c 3.3.11 changelog (#4173)
* 3.3.11 changelog

* Update docs/changelog_3_3_0.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/changelog_3_3_0.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/changelog_3_3_0.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* Update docs/changelog_3_3_0.rst

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-08-10 01:16:47 +02:00
Flame442
c9e4c18f17 [Trivia] Remove an unnecessary .format (#4175) 2020-08-10 01:16:26 +02:00
El Laggron
c8526d42b4 [Docs] Bank user guide (#4149)
* Getting started guide

* Remove DigitalOcean referral link

* Fix typos and mispells, thanks to @Flame442

* Remove cogs.red hyperlink until it is finished

* Add towncrier entry

* Add prolog.txt

This is not necessary for this PR but all of the other cog guides rely on this file.
The cog guides are individual branches based on this one, which is why I'm adding this file right now.

* Add Bank cog guide

* Add changelog entry

* Bank guide

* Nope get out from here potato

* Remove reference to the payday command

* reword + drop a character

Co-authored-by: Toby Harradine <Tobotimus@users.noreply.github.com>
Co-authored-by: palmtree5 <3577255+palmtree5@users.noreply.github.com>
2020-08-09 14:20:12 -08:00
Douglas
e9017e8fe2 [Trivia] Fix unresolved reference to bank.BalanceTooHigh (#4170)
Co-authored-by: douglas-cpp <douglasc.dev@gmail.com>
2020-08-08 17:01:45 +02:00
Vexed
61df4f88b3 [Core] A few data API grammar improvements (#4164)
* stuff

* .

* oops

* aaaaaaaaaa
2020-08-07 00:22:08 +02:00
Jyu Viole Grace
fcbb07a333 [Trivia] whosthatpokemon - Generation III (#4141)
* whosthatpokemon - Gen III

* link redirect to red cdn
2020-08-06 23:34:54 +02:00
Draper
989269c732 Lavalink.jar bump for internal manager (#4168) 2020-08-06 22:04:22 +02:00
Vexed
b363398b28 Docs improvements after watching two self-proclaimed incompetent people install it (#4119)
* the thing

* right

* hmm

* review
2020-08-06 21:51:59 +02:00
PredaaA
fc2277bc88 [Audio] Send an more user friendly message at "Track Stuck" errors (#4061)
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2020-08-06 20:23:49 +01:00
Dav
a9bd1c60e6 [Reports] Give friendly error if no report channel set (#4136) 2020-08-06 21:12:05 +02:00
Dav
297ba8f2b7 [Core] Typo fix (#4035) 2020-08-06 18:54:44 +02:00
jack1142
09933e22f6 Update discord-ext-menus vendor to commit 84caae8038d0d3adc860957ccef05baeec2e2dd8 (#4167) 2020-08-06 17:44:40 +01:00
github-actions[bot]
5f52fb872a [i18n] Automated Crowdin downstream (#4166)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-06 17:19:59 +02:00
Dav
f65ff87b96 [Docs] Clarify documentation for Context.clean_prefix (#4135)
* change docstring for Context.clean_prefix

* "tyop"
2020-08-06 03:54:48 +02:00
Michael H
068ce24513 [Core Commands] Add Help settings view (#4022)
* add help settings view

* Update redbot/core/commands/help.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* natural language handling of time intervals is useful

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-08-06 03:38:34 +02:00
Michael H
29543ed118 avoid issue with not having before_invoke called (#4129) 2020-08-06 03:34:55 +02:00
maxbooiii
39ae4a3b58 [Streams] Change hitbox to smashcast. (#4161)
* [Streams] Change hitbox to smashcast.

as hitbox is now smashcast.

* Add files via upload

* reee

* :thonk:

* oof

* Add missing new lines at end of file

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-08-05 17:04:36 -08:00
Michael H
4f808306ba Add a provisional API for replacing the help formatter (#4011)
* Adds an API for replacing the help formatter

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* add note about provisionality

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-08-06 02:12:14 +02:00
jack1142
6cef336417 Remove unused try except blocks in modlog.create_case() usage (#4095) 2020-08-05 19:40:52 +01:00
Jamie
0cc04706f6 [Streams] Attempt to fix unclear error in youtubestream (#4148) 2020-08-05 19:39:28 +01:00
jack1142
c673bb0979 Fix the errors related to installed module having invalid commit data (#4086) 2020-08-05 19:35:57 +01:00
Neuro Assassin
5221b1e4a3 Fix missing self argument in [p]licenseinfo (#4154) 2020-08-04 14:13:23 +02:00
MeatyChunks
8e0dbb7185 Fix amount of messages in log message of [p]cleanup message (#4156)
Fixes #4155
2020-08-04 12:14:13 +02:00
jack1142
775528ce9b Reject package (extension) names that can't be valid Python identifiers (#3679)
* Reject package names that can't be valid Python identifiers

* Add info to `[p](re)load`

* Improve internal consistency of package vs cog
2020-08-03 15:17:27 +02:00
Draper
1a3e264b2a Make humanize_list() use babel. (#2982)
* Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now
`[p]bankset maxbal` can be used to set the maximum bank balance

Signed-off-by: Guy <guyreis96@gmail.com>

* Migrates ``humanize_list`` over to babel, and uses the existing `get_babel_locale` function to get a valid locale based on bot locale.

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Migrates ``humanize_list`` over to babel, and uses the existing `get_babel_locale` function to get a valid locale based on bot locale.

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Fixes docs

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Add reference to Babel's `format_list`

* Add Babel to intersphinx

* remove towncrier entry

* Migrates ``humanize_list`` over to babel, and uses the existing `get_babel_locale` function to get a valid locale based on bot locale.

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Fixes docs

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Add reference to Babel's `format_list`

* Fix order, make the parameters keyword-only

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-08-03 15:17:05 +02:00
Michael H
c5a553a600 Document prefix preservation (#4085)
* Document prefix preservation

* more docs

* ref fix

* update reservations to include dunders

* meh

* Add a broad exclusion in the guarantees section
2020-08-03 15:09:29 +02:00
Michael H
c0b1e50a5f Begin work on a data request API (#4045)
[Core] Data Deletion And Disclosure APIs

 - Adds a Data Deletion API
   - Deletion comes in a few forms based on who is requesting
   - Deletion must be handled by 3rd party
 - Adds a Data Collection Disclosure Command
   - Provides a dynamically generated statement from 3rd party
   extensions
 - Modifies the always available commands to be cog compatible
   - Also prevents them from being unloaded accidentally
2020-08-03 15:09:07 +02:00
jack1142
bb1a256295 Update __init__.py (#4153) 2020-08-03 14:07:04 +01:00
github-actions[bot]
7e7a3a6488 Automated Crowdin downstream (#4133)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-01 16:58:27 +02:00
jack1142
36f1fa15a5 Bump pytest to version 6.0.1 and yarl to 1.5.1 (#4126)
* Update pytest to version 6.0.1

* remove some awful monkeypatching

* use new import mode

* Update yarl to 1.5.1
2020-08-01 16:40:19 +02:00
Michael H
3b5183de43 [RPC] Fix for non-rpc users (#4143)
* [RPC] Fix for non-rpc users

  - RPC probably needs rewriting.
  - Also, I noticed some extremely sharp edges
  and a potential crash point (unrelated to the fixed issue)
  on windows that the side effects from have been mitigated here
  partially.

* sysexit on initialization failure
2020-08-01 02:45:51 +02:00
Michael H
bbd08eda3e [RPC] Shutdown properly (#4134)
* [RPC] Shutdown properly

* stop doesn't mean stop, somehow

* 1 more time

* so much salt
2020-07-30 16:11:37 +02:00
Predeactor
dce10d7282 Propose more info on simple serverinfo (#4121)
* Propose more info on simple serverinfo

* Fixed black + serverinfo

* Fix black (Sorry)

* Merge jack's suggestions

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Change separator

👍

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Black

* Update general.py

Co-authored-by: Ubuntu <ubuntu@vps-35e65bf5.vps.ovh.net>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-07-30 01:30:50 +02:00
jack1142
82d8af1fb1 Make docs tox workflow not stop after first warning (#4090) 2020-07-29 02:50:13 +02:00
Twentysix
6c68aa9dcd [CustomCom] [p]cc show - Handle missing cooldowns (#4112)
The old dataconverter didn't add cooldowns by default and `[p]cc show` expects them to be present
2020-07-29 02:48:50 +02:00
Jyu Viole Grace
7458eefa01 [Trivia] whosthatpokemon2 trivia - Generation 2 Pokémons (#4102)
* Generation 2 Pokemons for whosthatpokemon trivia

* replace "pokemon" with "Pokémon"
2020-07-29 02:46:03 +02:00
jack1142
8ada1ee152 Only accept positive integers in [p]cleanup commands (#4115) 2020-07-29 02:44:36 +02:00
Michael H
d73ad3115f Prevent LicenseInfo command from being a source of user command spam (#4110)
* Prevent LicenseInfo command from being a source of user command spam

* add dep-warn explaining whats needed for this

* name issues

* Tests...

* An empty commit unbroke some of it, but still style issues
2020-07-29 02:39:37 +02:00
MeatyChunks
832bdfde22 [Economy] Prevent forbidden error when blocked by user (#4120)
Stop `[p]payouts` throwing a console error if the user has blocked the bot. Probably too spammy to put the payout message in chat.
2020-07-29 01:46:20 +02:00
Jamie
260a2d5c78 Use mod/admin_or_permissions instead of just mod/admin. (#4109)
* Update modcheck.

* _or_permissions for set nickname & serverprefix
2020-07-29 01:38:19 +02:00
Jamie
57247c5d87 [Streams] Mixer removal (#4072)
* [streams] Mixer is dead soon

* remove Mixer from readme
2020-07-29 01:38:03 +02:00
jack1142
e0616c37a9 Fix the copyright in LICENSE file (#3985)
* Fix the copyright in LICENSE file

* Update LICENSE

Co-authored-by: Kowlin <Kowlin@users.noreply.github.com>

* Update LICENSE

Co-authored-by: Kowlin <Kowlin@users.noreply.github.com>

Co-authored-by: Kowlin <Kowlin@users.noreply.github.com>
2020-07-29 01:36:15 +02:00
jack1142
3aa6f51dfb Bump dependencies (this switches to HTML 5 writer in Sphinx & changes config.json dir on Mac) (#3982)
* Bump deps

* use html5 writer

* appdirs<1.4.4 compatibility fix

* more bumping

* Revert "appdirs<1.4.4 compatibility fix" (Jack did a dumb)

This reverts commit cc5299d987.

* And another ~~one~~ bump!

I'm gonna blame Neuro for being nice and contributing to aiohttp-json-rpc.

* just one more and pls merge this Kowlin

* Kowlin, pls merge
2020-07-29 01:16:12 +02:00
Michael H
1d80fe9aec Create cog disabling API (#4043)
* create cog disbale base

* Because defaults...

* lol

* announcer needs to respect this

* defaultdict mishap

* Allow None as guild

- Mostly for interop with with ctx.guild

* a whitespace issue

* Apparently, I broke this too

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* This can probably be more optimized later, but since this is a cached value, it's not a large issue

* Report tunnel closing

* mod too

* whitespace issue

* Fix Artifact of prior method naming

* these 3 places should have the check if i understood it correctly

* Announce the closed tunnels

* tunnel oversight

* Make the player stop at next track

* added where draper said to put it

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-07-28 20:52:36 +02:00
jack1142
97379afe6d Fix the cog_before_invoke hook in Admin (#4124) 2020-07-28 15:29:20 +01:00
github-actions[bot]
fb96392e73 Automated Crowdin downstream (#4103)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-28 03:05:19 +02:00
jack1142
0293a108f0 Add workflow_dispatch trigger to Crowdin workflow (#4113) 2020-07-28 02:17:54 +02:00
PredaaA
28b5be21b3 [General] Change PUBLIC feature to COMMUNITY in serverinfo (#4116) 2020-07-25 22:05:11 +02:00
aikaterna
ae4be2c23c Merge pull request #4111 from thisisjvgrace/fix-gen1-trivia
[Trivia] whosthatpokemon - Gen 1 - replace "pokemon" with "Pokémon"
2020-07-24 10:57:41 -07:00
Jyu Viole Grace
5bca214863 use "Pokémon" instead of "pokemon" 2020-07-24 14:56:13 +05:30
Ryan
6ab007bc1d [CustomCom] Add missing await (#4108) 2020-07-23 23:37:31 +02:00
TrustyJAID
583f093eb0 [Admin] fix erroneous await in _ready.set() (#4107) 2020-07-23 23:19:18 +02:00
Michael H
0d8a899a65 [chat formatting] Add Variation Selector-16 as appropriate (#4105)
- Ensures consistent rendering across devices
  - See:
  https://unicode.org/Public/emoji/12.1/emoji-variation-sequences.txt
2020-07-23 19:40:25 +02:00
jack1142
676bf1bd60 Update chocolatey install commands per chocolatey.org (#4098) 2020-07-23 12:34:19 +01:00
jack1142
e88c67465c Update pyenv instructions to install Python 3.8.5 (#4094) 2020-07-23 12:32:53 +01:00
jack1142
8c484f86a9 Make bordered() use + for corners if ascii_border=True (#4097) 2020-07-23 12:32:41 +01:00
Draper
5fba9bc4ed [Audio] Ensure TrackEnqueueError is always handled (#3879)
Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-07-23 12:32:32 +01:00
jack1142
0635921d6b Remove operating systems that reached EOL (#4099) 2020-07-23 10:38:47 +01:00
Michael H
ec262d4c30 [Announcer] Don't die with a lack of channels (#4089) 2020-07-20 18:51:27 +01:00
jack1142
5507816c42 Give friendlier error when package can't be found during bot startup (#4079) 2020-07-20 10:53:54 +01:00
github-actions[bot]
dcc77cf24f Automated Crowdin downstream (#4078)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-20 03:30:58 +02:00
Michael H
a35bcecf94 Fix state transition for subcommands modified by permission hooks (#3956)
* [Permissions] Fix state transition for subcommands modified by
permission hooks

* docs
2020-07-18 21:40:23 +02:00
Michael H
1852420b98 [Core] Add Red.message_eligible_as_command (#4077)
* [Core] Add `Red.message_eligible_as_command`

  - This is a small utility function which makes it easy for cog
  creators to treat non-command messages as commands correctly.

  - This also modifies `Red.ignored_channel_or_guild`'s signature to
  explicitly add support for passing a message object (the only needed
  attributes are entirely shared with context)

* Update redbot/core/bot.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* address review

* Rename

* remove webhhok check, the issue wasn't possible under normal operation

* Ah yes, ctx.bot in a method of the bot...

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-07-18 15:38:57 +02:00
jack1142
c9ce4a78e6 Exclude locales folders from code ownership (#4071) 2020-07-14 13:35:44 +02:00
jack1142
500f91f0cd Fix no message when unregistered reason is used in [p]warn (#3840) 2020-07-14 10:43:51 +01:00
Vexed
1ee32b77dd [Mod] [p]mute|unmute voice now take action instantly (#4064)
* make mute and unmute have the same fail string

* now add the jucy bits

* hmm no

This reverts commit a445bd8415.

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-07-12 18:44:34 +02:00
jack1142
c4d295b25d Ignore that the rule for model doesn't exist when trying to remove it (#4036) 2020-07-10 21:42:31 +01:00
jack1142
fdf2ed6ecc Make [p]tempban respect default_days setting (#3993) 2020-07-10 21:40:04 +01:00
jack1142
326ae76fe0 Fix the error for empty author list in [p]findcog (#4042) 2020-07-10 21:37:41 +01:00
github-actions[bot]
a7a18ad956 Automated Crowdin downstream (#4060)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-09 18:53:49 +02:00
Vexed
cf3636df3c Change wording in VPS providers document (#4050)
* change wording

* hmm

* as discussed in ac

* Update docs/host-list.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update docs/host-list.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* fix it

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-07-09 18:12:46 +02:00
Kowlin
a59ff57c27 Dev bump for 3.3.11 (#4056) 2020-07-09 08:55:40 +02:00
Kowlin
0cd3bede0d 3.3.10 release bump. (#4054) 2020-07-09 08:45:17 +02:00
Neuro Assassin
637fa37fad Red 3.3.10 - Changelog (#3967)
* Add 3.3.10 or 3.4.0 section

* PR 3981

* PR 3951

* PR 3975

* PR 3974

* PR 3964

* PR 3884

* Various things

* PR 3972

* PR 3970

* Add contributor

* PR 3980

* Add Draper as contributor

* PR 3973

* PR 3965

* PR 3987

* PR 3901

* PR 3906

* PR 3958

* PR 3895

* PR 3920

* PR 3915

* oops

* I don't like info

* PR 3969

* PR 3990

* PR 3911

* PR 3921

* PR 3938

* PR 3608

* Update entries about PR 3608

* PR 4012

* PR 4030

* PR 4026

* PR 4039

* PR 3994

* PR 3991

* PR 4023

* Actually fix conflicts

* A lot of PRs.

* And stamp a date on top of it.

* Fun fact, we format it with YYYY-MM-DD...

* Forgot Sinbad, 👀 Sorry

* Update changelog_3_3_0.rst

Co-authored-by: Neuro Assassin <wrbrown70@yahoo.com>
Co-authored-by: Kowlin <Kowlin@users.noreply.github.com>
2020-07-09 08:41:56 +02:00
aikaterna
07dcf38291 Update Lavalink.jar version (#4055) 2020-07-09 08:28:00 +02:00
Lui
ff1f7362ee Bump d.py dependency (#4053) 2020-07-09 07:38:49 +02:00
Draper
d30e83b5fc Reduce config calls when changing white/blacklist and use sets for their cache (#3910)
* optimise use of config ctx manager to reduce calls to config

* fine you potato

* since jack said yes i'll abuse it

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* difference_update and update

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/settings_caches.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* one last tweak

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-07-08 19:25:14 +02:00
Dav
14349d0649 Make strings in help command *truly* translatable (#4044)
* make help.py translatable

* jack's not-review 1

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* pylint is going crazy her, not sure what I'm missing

* Jack's now-this-is-actually-a-review 1

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Jack's review 2

* Let's not bother Dav with one missing backtick

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-07-08 15:11:04 +02:00
Dav
49b19450fd [Mod] Make tempbans permanent when using [p]hackban (#4025)
* Remove users from tempban unban list when hackbanning them

* black and missing bracket

* make sure this actually gets processed

* let the user know when a tempban was upgraded

* say more things

* reduce config calls

* jack loves performance

* adress review

* review the 2nd
2020-07-08 01:15:42 +02:00
Dav
5b612b8ac7 [Docs] Update framework_i18n.rst (#4018)
* Update framework_i18n.rst

* Update framework_i18n.rst

* -h flag note

* Add hyphen

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-07-08 00:53:03 +02:00
Draper
e0b922c949 Make localwhitelist check if caller will still be able to use bot after changes (#3903)
* Check invokers theoretical perms in localwhitelist add before completing command

* remove unnecessary code

* add check to remove

* ignore bot owner and server owner

* Update core_commands.py

* lets not crash shit
2020-07-07 20:08:06 +02:00
Michael H
60df447550 Add settings view commands (#4041)
Any group which sent help + settings views has had the settings view
  split into a seperate command. This ensures that custom help behavior
  does not interfere with settings views.
2020-07-07 00:53:41 +02:00
Vexed
2cf7a1f80d [Core] Docstring full stops and a few other grammar fixes (#4023)
* core full stops/other grammar fixes

* need to read better (i'm keeping it on two lines)

* apply review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-07-06 20:21:45 +02:00
jack1142
4dd0fb97fe Stop putting text about invite when invite isn't sent in tempban message (#3991) 2020-07-06 18:57:16 +01:00
Vexed
12bce6a560 [Image] Update instructions for setting the GIPHY API (#3994)
* update wording for giphy api

* of cource master draper
#3938 - make the command untranslateable

* i18n <your_api_key_here>

* commas to parens as discused in discord
2020-07-06 19:11:04 +02:00
Michael H
d869410d36 Add .gitattributes to ensure project consistent line endings (#4037)
- Renormalized as well
2020-07-06 18:53:10 +02:00
Draper
31bb43ca38 Vendor discord.ext.menus (#4039)
Vendor `discord.ext.menus` from commit `cc108bed812d0e481a628ca573c2eeeca9226b42` at https://github.com/Rapptz/discord-ext-menus

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-07-06 17:37:52 +02:00
jack1142
07e480ff7a Stop using git ls-files *.py for style check (#4040) 2020-07-06 14:45:46 +01:00
MiniJennJenn
c251804162 Trivia Update (#4026)
Co-authored-by: hatred2k <hatred2k@gmail.com>
2020-07-06 09:29:56 +01:00
github-actions[bot]
ff72e415aa Automated Crowdin downstream (#4033)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-02 19:04:35 +02:00
aikaterna
7d30e3de14 [Utils] Fix regex for role mentions in MessagePredicate (#4030) 2020-07-01 03:29:16 +02:00
bobloy
8b529f488b Add 'discord.com/invite' to docs of filter_invites() function (#4027) 2020-06-30 14:49:45 +02:00
github-actions[bot]
b5930155df Automated Crowdin downstream (#4016)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-06-25 17:20:12 +02:00
bobloy
632840384b Add discord.com to supported domains in INVITE_URL_RE (#4012)
* Support for discord.com

* Modified to support discord.com requiring `/invite`

* Non-capturing
2020-06-24 20:06:11 +02:00
jack1142
a96e814af4 Add project_urls and improve our use of classifiers (#4006) 2020-06-22 21:18:53 +02:00
jack1142
b49b53934d Update deprecation warnings (#3608)
* Make deprecation notice specify minor release based on soonest date

* Stop specifying a specific release in shared libs deprecation notice

* Add actual deprecation warning for `APIToken` (OMG, this is so cool)

* Add dates (2020-08-05 for all)

* address review

* improve consistency

* Add __dir__ and show APIToken in docs (or maybe I want to annoy Flame)

* fix module name when importing non-existent name from parent package

* Fix stack level used by depr warn in `redbot.core.commands`
2020-06-22 03:25:33 +02:00
Dav
df410529b0 [i18n/Streams] Change strings mentioning commands to use {command} variable (#3938)
* hopefully all strings in streams.py

* black streams.py

* don't touch docstrings

* uniformity is good

* thx draper

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* aaaaaaaaaaaaaaaaaaaaaa

* translate more

* sure, joining some strings for jack

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* more strings to join

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* yup... I missed this

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* jaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaack blaaaaaaaaaaaaaaaaaaaaaack

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-06-21 20:38:31 +02:00
Draper
477186d09d Add map(), find() and next() methods to AsyncIter (#3921)
* properly handle prefixes

* Docsss and typehinting

* aaaaaaaaaaa

* Apply suggestions from code review

* ffs

* docs

* docs

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* skip await if map is none

* implement `.next()`

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-06-21 19:47:48 +02:00
Draper
81f146a2ef [Mod] Only send the DM about migration if at least 1 scope entry has a non-default value (#3911)
* Only send notify_owners in mod migration if at least 1 scope entry has a non default value

* update string

* use asynciter on these potentially large loops

* check server settings too
2020-06-21 19:45:35 +02:00
Jamie
84d0282815 [Streams] Invalidate old bearer token when api key is updated. (#3990) 2020-06-21 18:44:38 +01:00
Vexed
d2de3c109a [Downloader] Differentiate core and local cogs in [p]findcog (#3969) 2020-06-21 17:59:52 +01:00
Draper
aad36c7430 Expose info about internally managed jar in [p]audioset info (#3915)
* since i have no clue when RW will be release ... lets add this as it helps out a lot

* update branch name regex

* recheck version after download since now we are showing it.
2020-06-20 01:07:39 +02:00
Vexed
4c62c67fd4 [redbot.setup] Ask for confirmation when passed instance name contains hyphens + allow to use dots (#3920)
* Change regex and the error message

* few changes see ^^^ GH comment

if it doesn't pass the RegEx `[a-zA-Z0-9_\.]*` then:
- if on Linux and contains a "-" anywhere, not allowed
- if it contains a space or starts with a "-", not allowed
- if the top two don't trigger, then `confirm()` with the user.

* black why

* 3.3.9

* fk

* ty aika

* review :aha:

* oopsie

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* this is just vexed tries and jack fixes

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* quite sad really

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-06-19 16:16:22 +02:00
Flame442
144b7b36d0 [Mod] Consistency periods & proper logging (#3895)
* Consistency periods & proper logging

* woooo jack

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update kickban.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-06-19 12:58:40 +02:00
Dav
802641ce6b Use timedelta converter for ban duration and add option to pass delete days to [p]tempban (#3958)
* add duration atribute

* sanity checks

* add days parameter

* maybe resolve conflicts?

* black and make linting happy

* right... I need to send this

* but I still need to return... oops
2020-06-19 01:51:06 +02:00
Vexed
2d63e3d6aa Print getting started guide on startup when bot is in no guilds (#3906)
* Link getting started guide

* 3.3.9

* fk
2020-06-19 01:13:01 +02:00
Vexed
728252ac87 Fix capitalisation in cog creation docs (dev version note) (#3968) 2020-06-19 01:05:48 +02:00
Draper
79d042ad29 [Streams] Only send message about missing client secret once (#3901)
* Send Notify owner messages only when a key has been invalidated since last notify_owner

* grammar

* welp im dumb

* Black and lower config call frequency

* Update redbot/cogs/streams/streams.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* dont use a generic name now to avoid a config migration later

* be even more explicit with var name

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-06-18 23:39:52 +02:00
Neuro Assassin
dd4095b15b [Permissions] Fix integer commands and empty dict rules (#3987) 2020-06-18 21:44:47 +01:00
Vexed
1cf8308d03 [Downloader] Embed version of findcog (#3965) 2020-06-18 21:37:46 +01:00
Jamie
4e890814ff [Filter] Add listing commands (#3973) 2020-06-18 21:23:16 +01:00
Draper
175fbebd73 Move logic for fetching latest Red version info to internal util (#3904)
* Only Send out of date message to Final builds available on PyPi

* Only Send out of date message to Final builds available on PyPi

* sorted the resulting list so that the newest build is first in the list

* forgot about this one

* well jack is a bitch but we love him.

* simplify logic

* Add the new function to `__all__`

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-06-18 22:21:59 +02:00
Jyu Viole Grace
879d21c528 [Trivia] addition of Lord of the Rings trivia (#3980) 2020-06-18 17:32:15 +01:00
Jyu Viole Grace
c7202b353d [Trivia] Minor correction in greekmyth trivia (#3970)
* [Trivia] Minor correction in greekmyth trivia

In greekmyth trivia, there is a question: `Who is the God of Medicine and the son of Apollo?` and the only answer written in the yaml file is `Asclepius` , however `Aesculapius` or `Hepius` can also be considered as a right answer. 

Source: https://en.wikipedia.org/wiki/Asclepius

* Lord of The Rings trivia

* Added AUTHOR key

* Revert "Added AUTHOR key"

This reverts commit d60e336771.

* Revert "Lord of The Rings trivia"

This reverts commit d7365e87b9.

Co-authored-by: Jyu Viole Grace <thisisjvgrace@users.noreply.github.com>
2020-06-18 17:05:12 +02:00
Vexed
3a0574eae8 [Core] Change [p]embedset user docstring and message to explicitly say DMs only (#3972)
* change docstring and message to explicitly say DMs

* didn't think i'd need to run black...

* wrong branch...

This reverts commit aa6aa5cf4b.

* wait its the right branch

* review - seperate enabled & disabled strings

* review

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2020-06-18 16:00:08 +02:00
jack1142
70c733e146 Use a task instead of awaiting for delete delay (#3884) 2020-06-18 15:50:42 +02:00
jack1142
a64c28aa44 Fix unnecessary typing before running commands in Downloader (#3964) 2020-06-18 15:47:12 +02:00
aikaterna
35365a7154 [Downloader] Add command to list pinned cogs (#3974) 2020-06-18 15:43:59 +02:00
aikaterna
9594284f6c [Trivia] Fix whosthatpokemon urls (#3975) 2020-06-18 14:42:01 +02:00
github-actions[bot]
0358473af5 Automated Crowdin downstream (#3984)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-06-18 14:33:59 +02:00
jack1142
8d553a3fc6 Improve command error responses (#3951)
* Update settings.py

* Update modlog.py
2020-06-18 13:46:20 +02:00
Vexed
373dcded2c add the space (#3981) 2020-06-17 15:00:49 +02:00
jack1142
e59d52bae4 Dev bump (#3960) 2020-06-12 01:50:37 +02:00
jack1142
fa00314b77 Bump to 3.3.9 (#3959) 2020-06-12 01:24:06 +02:00
jack1142
7aad3ae3b5 Red 3.3.9 - Changelog (#3876)
* Add 3.3.9 or 3.4.0 section

* PR 3889

* PR 3890

* PR 3891

* PR 3781

* PR 3900

* PR 3899

* PR 3916

* PR 3892

* PR 3941 (issue 3940)

* PR 3907 (issue 3102)

* PR 3878 (issue 3877)

* PR 3880

* PR 3925

* PR 3923

* PR 3942

* PR 3935

* PR 3946

* PR 3954

* PR 3955 (issue 3107)

* Add "Read before updating" section

* PR 3957

* Update the changelog header with version number and date
2020-06-12 01:23:44 +02:00
jack1142
6c56e47083 An update to Windows docs structure for our beloved users! (#3894) 2020-06-12 01:23:06 +02:00
Michael H
6c048fad01 [Permissions] Prevent guild owner lockouts (#3955)
* [Permissions] Prevent guild owner lockouts

  - Guild owners will always be able to access the guild configuration
  commands in permissions
  - This includes `permissions explain` and `permissions canrun` as
  informational tools useful for ensuing a correct configuration

  resolves #3107

* minor nitpicking over ordering consistency

* a single new line for style compliance

* Fix a typo + alphabet went wrong

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-06-12 00:31:41 +02:00
Dav
593079dbbb [Mod] Make tempban more consistent with other ban commands. (#3957)
* add duration atribute

* sanity checks

* obviously that didn't work...

* insert facepalm here
2020-06-12 00:30:11 +02:00
aikaterna
2761244d2e [Bank] Display in settings if bank is global (#3954)
* [Bank] Display in settings if bank is global

* Address review

* Address review
2020-06-11 20:29:24 +02:00
Vexed
f58f6bb6d2 Update dm docstring for readability and grammar (+ period in contact) (#3946)
* update `dm` docstring

* few changes

* hmm

* cant make my mind up how to word it

* fk i forgot "and"

this is the last one, i promise

* add missing full stop in `contact` as im in this area of core_commands

* oh, see ^^^ review

* `click on` instead of `select`

Co-authored-by: Vexed01 <>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-06-11 19:31:49 +02:00
Draper
da83e02749 Show storage type in start up message (#3935)
* Lets show active storage on start up message

* Lets show active storage on start up message

* let's make it like in `[p]debuginfo`

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-06-11 19:05:32 +02:00
Draper
76efb16f96 [UX] Add "server" alias for commands that have "guild" in name (#3947) 2020-06-11 18:56:57 +02:00
Predeactor
d411873503 Only trigger cooldown when message is parsed in [p]contact (#3942) 2020-06-11 18:54:11 +02:00
Flame442
f0a4c1c252 [Core Commands] Fix [p]set custominfo error (#3923) 2020-06-11 18:46:30 +02:00
Flame442
1f845a4119 [Filter] Fix confusing behavior detecting quotes (#3925)
* Probably make filter better

* because I'm a stupid dumb idiot, *jack*
2020-06-11 17:00:55 +02:00
Draper
17496ff5cf [Audio] Fix DM Crash (#3880)
Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-06-11 16:50:23 +02:00
aikaterna
e3322af384 [Audio] Redefine max length with livestream exception (#3878)
* Redefine max length with livestream exception

* Address review

* is_track_too_long -> is_track_length_allowed for a more accurate description of what the function actually is doing
* we now rely on Track.is_stream for determining whether item is a livestream (or unseekable/non-known audio length like OGG files) for determining whether it can bypass the user-set max track length
* Removal of passing track length/an int to is_track_length_allowed - will always pass the full Track object now

* Address review
2020-06-11 16:38:43 +02:00
Draper
b1d394eac5 [Core] Add a text only version to [p]info (#3907)
* ...

* Finish implementation

* some people think an embedless world brings joy ... I agree to disagree.
2020-06-11 15:07:27 +02:00
jack1142
fd8ff7d7cf Add missing class docstrings in Downloader, Reports and Streams (#3892)
* add class docstring to downloader

idk what to say rly
um hi all nice to be back after about 6 months
pls no hate my PRs
apoligies if i get in the way
if you read this far then you deserve an achievement um i dunno what err how about the achievement of unboredness

* add class docstring to reports

* add class docstring to streams

* black formatting

oops lets not forget what tox checks for

* wording changes

* add cog board link

* hmm actually no (undo)

* wait grammar exists? who knew...

* remove admin only commands

* Review

* Remove always
  - and consequently reorganise the words
* Add "one or more"
* Fix spelling of creator
  - changed from creater
2020-06-11 15:01:06 +02:00
Dav
bc19b0d103 [Alias] Remove guild_only deco from main alias command group (#3941)
* Update alias.py

* alias help and show

* well... avoid the dumb
2020-06-11 15:00:38 +02:00
Vexed
aea6f68598 [Docs] Add Oracle to VPS Hosting, new specific links (#3916)
* Add the rst

* Add Oracle
* Add links to Always Free VPSes
* Add mention EC2 is 12 months only

* more description + update AWS link
2020-06-09 21:23:44 +02:00
Vexed01
332bcae24f Review
* Remove always
  - and consequently reorganise the words
* Add "one or more"
* Fix spelling of creator
  - changed from creater
2020-06-05 19:47:45 +01:00
github-actions[bot]
4335b3b2d4 Automated Crowdin downstream (#3913)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-06-04 14:22:16 +02:00
Draper
d6435eff85 make audioset autoplay guild-only (#3899) 2020-06-04 13:33:33 +02:00
Predeactor
2c313594da Typo Fix (#3900)
As always, a new typo is fixed forever.
2020-06-03 21:13:44 +02:00
Neuro Assassin
bc21f77976 Fix setting guild prefixes when the prefixes aren't in cache (#3897) 2020-06-02 03:02:35 +02:00
Dav
dbcb179523 Allow to hide moderator from warnings sent to the users + warn channel fix (#3781)
* add toggle to allow switching off sending the name of the person who uhhh used? the warning

* the Kowlin way of life

* reduced config calls to stay in line with #3766 and hopefully didn't break anything (as per Draper suggestion)

* more performance magic

* found an error + black

* forgot warning channel existed

* await... seriously... how long have you done async stuff now dav?

* unify (most) config calls in ``[p]warn``

* fix all the things
2020-06-01 02:58:36 +02:00
Vexed01
35e83855a8 remove admin only commands 2020-05-31 13:15:38 +01:00
Vexed01
6b086e3eb2 wait grammar exists? who knew... 2020-05-31 11:16:39 +01:00
Vexed01
049f23071c hmm actually no (undo) 2020-05-31 10:18:58 +01:00
Vexed01
e6c46bf4da add cog board link 2020-05-31 09:21:34 +01:00
Flame442
6984dca394 [Mod] Preemptive fix for the next dpy update (#3891) 2020-05-31 03:56:21 +02:00
Neuro Assassin
7a86cc4bf3 [Core] Add bot.set_prefixes() (#3890)
* Add bot.set_prefixes; change set serverprefix and set prefix to new method

* Address requested changes

* Apply suggestions from code review

* One more

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-05-31 00:57:49 +02:00
Vexed01
219586d55d wording changes 2020-05-30 19:57:34 +01:00
Vexed01
6a00c0ee7e black formatting
oops lets not forget what tox checks for
2020-05-30 19:42:33 +01:00
Vexed01
873c7be99e add class docstring to streams 2020-05-30 19:34:01 +01:00
Vexed01
c9cfa92b04 add class docstring to reports 2020-05-30 19:33:32 +01:00
Vexed01
ff46ca546d add class docstring to downloader
idk what to say rly
um hi all nice to be back after about 6 months
pls no hate my PRs
apoligies if i get in the way
if you read this far then you deserve an achievement um i dunno what err how about the achievement of unboredness
2020-05-30 17:19:54 +01:00
Draper
f1ba57b78b [Audio] Lyrics typo - p.s It feels dirty making a PR this small (#3889) 2020-05-30 15:39:50 +02:00
jack1142
4cf83b9ef4 Remove 26 from CODEOWNERS (#3886)
* Update the wildcard to Stonedestroyer

* Or maybe remove it
2020-05-30 02:54:35 +02:00
Kowlin
3702e2e998 Bump to 3.3.9.dev1 (#3875)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-05-29 01:27:40 +02:00
Kowlin
30c1adfe5b Bump to 3.3.8 (#3874) 2020-05-29 01:11:02 +02:00
jack1142
c75035bf6e Red 3.3.8 - Changelog (Bonus changelog for 3.3.7 included) (#3800)
* Add 3.3.7 changelog

* Add 3.3.8 or 3.4.0 section

* PR 3815 (issue 3814)

* PR 3822

* PR 3817, 3823, 3837

* PR 3816

* PR 3819

* PR 3829 (issue 3796)

* PR 3844 (issue 3834)

* PR 3851

* PR 3855 (issue 3854)

* PR 3857

* PR 3459 (issue 3353, 3459, 3467, 3471, 3485, 3501, 3506)

* PR 3861

* PR 3862

* PR 3744

* PR 3873

* PR 3847

* PR 3856

* PR 3867

* PR 3843

* PR 3826 (issue 3825)

* PR 3864

* PR 3849

* PR 3793

* PR 3805 (issue 3778)

* Update version in header and add release date
2020-05-29 01:10:28 +02:00
jack1142
59358e7bac Stop showing instance names in redbot-setup help's syntax (#3838) 2020-05-29 01:08:37 +02:00
Dav
19fa0b968f Mention the need of shutdown/startup in update docs (#3849)
* [Docs] Update docs now mention need to restart

Previously the update docs never mentioned that you have to restart yur bot for the update to take effect.

* That actually makes sense...

* Aaand those should probably be turned off as well

* jack and draper.... oi

* Update docs/update_red.rst

* Update docs/update_red.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-05-29 00:14:41 +02:00
jack1142
f2d02a6f46 (again) Handle the ints for user objects in Modlog appropriately (#3805)
* Handle the ints for user objects in Modlog appropriately (#3784)

* God, this is stupid

* Add logging of unexpected exceptions

* Add more specific info for Forbidden error

* add i18n support
2020-05-29 00:09:37 +02:00
jack1142
05ec73266c Fix behavior of is_owner for team applications and put all owner IDs in one attribute (#3793)
* blah

* you idiot

* Me likey Danny's way

* Add a warning when bot has no owner set
2020-05-29 00:03:23 +02:00
jack1142
a9acb80132 Use bot.send_help_for in [p]alias help instead of "hacky way" (#3864)
* Use `bot.send_help_for` instead of this "hack" in `[p]alias help`

* This isn't needed here
2020-05-28 23:58:52 +02:00
jack1142
ed89f70f98 Fix uses of re.sub() (#3826)
* Fix uses of `re.sub()` (pt. 1)

* Fix uses of `re.sub()` (pt. 2)

* Fix uses of `re.sub()` (pt. 3)

* Fix uses of `re.sub()` (pt. 4)

* Revert commands.py
2020-05-28 23:51:53 +02:00
jack1142
45afaa8ec8 Make the checks in [p]alias global add and [p]alias add consistent (#3797) 2020-05-28 23:50:44 +02:00
jack1142
4757c2c945 Add get_babel_regional_format() to redbot.core.i18n.__all__ (#3827) 2020-05-28 23:44:57 +02:00
jack1142
65395185c3 Add lib folder to pkg_resources's working set (#3843) 2020-05-28 23:41:06 +02:00
Draper
f2f3ac7d42 Special case new RLL message (RLL 0.5.1 bump inside) (#3868)
* specialcase new RLL message

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Bump RLL to 0.5.1

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-05-28 23:33:43 +02:00
jack1142
cb999bda7b Stop being destructive on generic DownloaderException (#3867) 2020-05-28 23:33:20 +02:00
Draper
cd14bccdc8 Get fucked Java 8. Long live Java 11 (till we kill you for your big brother Java 13) (#3873)
* Get fucked Java 8. Long live Java 11 (Till we kill you for your big brother Java 13)

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* welp lets simplify this

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-05-28 23:02:23 +02:00
jack1142
cf6966058e Revise install instructions (+ install Java 11 everywhere, and update pyenv to use Python 3.8.3) (#3847)
* Use `openjdk-r` ppa for Ubuntu 16.04

* Don't add `deadsnakes` ppa for Ubuntu 20.04

* Use Java 11 for Arch Linux

* Update getting started guide to recommend Ubuntu 20.04 over 18

* Use Java 11 for Fedora Linux

* Use Java 11 for openSUSE Tumbleweed

* remove unneded `-u` for ubuntu 20.04 and 18.04

* use `openjdk-11-jre-headless` in all ubuntus

* use headless jre everywhere

* add non interactive flag to zypper calls

* Add emphasis on info about pyenv's warning

* reverse order of Ubuntu LTS versions

* Install Git 2.11+ with `yum replace` on CentOS/RHEL 7

* Add `--gpg-auto-import-keys` flag to non-interactive `zypper ar` usage

* update pyenv instructions to use Python 3.8.3

* Install git after installing everything else in CentOS 7 instructions

* use zypper flags properly

* improve the sentence a little

* I like consistency

* add missing `sudo`s in CentOS instructions

* add tk-devel to CentOS instructions per pyenv's recommendations

* Install gcc 8 from SCL in CentOS 7

* use git222 instead of git2u on CentOS 7

* Add missing `source ~/.bashrc` line

* use git224 instead of git222 on CentOS 7

* use yum swap over yum-plugin-replace in CentOS 7
2020-05-28 22:59:25 +02:00
jack1142
74b209bcc8 Add a TOC tree for version sections + emphasise venv removal in older versions (#3856)
* Add a TOC tree for version sections

* Add emphasis on virtual environment removal
2020-05-28 22:51:30 +02:00
jack1142
4a97020b78 Remove the docstring remains of regex in [p]cleanup self (#3871) 2020-05-28 22:51:04 +02:00
github-actions[bot]
e0d8942741 Automated Crowdin downstream (#3872)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-05-28 22:44:32 +02:00
Draper
4f25e6c1ad Add information on how to update to out of date message (#3744)
* add a more detailed update help

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* ...

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* a bit more clarity

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* sure thing Jack

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* add a disclaimer to the update command saying if the user faces any difficulties to check the system appropriate docs and/or support server

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* add translation support

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* better translation support for these

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Update redbot/core/events.py

Co-Authored-By: Flame442 <34169552+Flame442@users.noreply.github.com>

* Apply suggestions from code review

Co-Authored-By: Flame442 <34169552+Flame442@users.noreply.github.com>

* review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Revert black fuckery

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* aaaaaaaaaaaaaaaaaaaaaaaaaaa

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* address jacks review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/events.py

* Update redbot/core/events.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/utils/_internal_utils.py

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-05-27 08:39:53 +02:00
jack1142
81b4a1978b Update CODEOWNERS for subpackages in Audio cog (#3869) 2020-05-26 21:08:50 +02:00
Neuro Assassin
87d828a1b0 [Docs] Add information about provisional status of RPC (#3862) 2020-05-25 21:26:46 +02:00
github-actions[bot]
e52ff98cad Automated Crowdin downstream (#3860)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-05-25 00:09:55 +02:00
Predeactor
7cabc876f5 [Audio] Typo fix (#3861) 2020-05-22 17:54:40 +02:00
Draper
8fa47cb789 Merge V3/feature/audio into V3/develop (a.k.a. audio refactor) (#3459) 2020-05-20 22:30:06 +02:00
Neuro Assassin
ef76affd77 Fix local blacklist and whitelist commands (#3857) 2020-05-19 02:22:05 +02:00
Sean
38a034e59b Don't allow to warn other bots (#3855) 2020-05-17 17:03:51 +02:00
Predeactor
fb26ecf577 Fix casing and add missing dot in two commands (#3851) 2020-05-15 15:55:28 +02:00
github-actions[bot]
de99aac3ad Automated Crowdin downstream (#3850)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-05-14 22:07:36 +02:00
Darius St. Clair
4d9d224917 Add pagination to [p]alias list and [p]alias global list (#3844) 2020-05-14 17:05:35 +02:00
Kowlin
ac46b51d41 Update the issue templates (#3842)
* Create config.yml

* How do I typo things sometimes...

* Update .github/ISSUE_TEMPLATE/config.yml

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-05-10 03:32:54 +02:00
Toby Harradine
7aff7962f0 Fix creation of IdentifierData in config raw methods (#3829)
* Fix creation of IdentifierData in config

Also adds some new tests regarding partial primary keys.

Resolves #3796.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-05-09 15:11:23 +10:00
Flame442
1a96f276f8 Fix typo in [p]customcom show (#3837) 2020-05-08 16:48:35 +02:00
github-actions[bot]
480c3129bd Automated Crowdin downstream (#3830)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-05-07 16:37:33 +02:00
Michael H
981661ea68 Simplify the inheritance of the bot (#3822) 2020-05-07 03:08:20 +02:00
PredaaA
51f7d6cea2 Show default avatars in [p]userinfo when no avatar is set (#3819) 2020-05-07 02:37:06 +02:00
Qais Patankar
7d28581915 Fix 'authentification' typo (#3823) 2020-05-06 20:20:52 +02:00
Neuro Assassin
4a0f23b0ea Stop allowing spaces in custom commands names (#3816) 2020-05-01 18:32:22 +02:00
Flame442
aaee2d9294 Fix incorrect docstring in [p]helpset maxpages (#3817) 2020-05-01 18:30:58 +02:00
Michael H
d5c960096e Modify CustomCommands to use on_message_without_command (#3811) 2020-05-01 18:30:32 +02:00
jack1142
0c94ce6cc3 Make server lock work again (#3815) 2020-05-01 18:29:57 +02:00
jack1142
f280eea788 Dev bump (#3804) 2020-04-28 03:15:06 +02:00
Kowlin
af7b0e4e1f Update to 3.3.7 (#3803) 2020-04-28 02:07:39 +02:00
Kowlin
ef35fc0c5f Revert "Handle the ints for user objects in Modlog appropriately (#3784)" (#3802)
This reverts commit e595f1859a.
2020-04-28 02:03:22 +02:00
Kowlin
ca1f39a260 Update __init__.py (#3799) 2020-04-27 20:21:25 +02:00
Kowlin
b92d61e154 Update version to 3.3.6 (#3798) 2020-04-27 20:06:42 +02:00
jack1142
70ff884ebb Red 3.3.6 - Changelog (#3738)
* Add 3.3.6 section

* PR 3746

* commit b8ac70e

* PR 3747

* PR 3759 (issue 3758)

* PR 3764

* PR 3766

* PR 3767

* PR 3776

* PR 3757

* PR 3773 (issue 3772)

* PR 3740

* PR 3774

* PR 3784 (issue 3778)

* PR 3782

* PR 3783

* PR 3783

* PR 3718

* PR 3742

* PR 3791

* PR 3792

* PR 3794

* PR 3780

* PR 3790

* PR 3795

* PR 3714 (issue 3115)

* PR 3788

* Add release date
2020-04-27 19:58:41 +02:00
TrustyJAID
6f6c536236 [Alias] Create caching to call config less frequently (#3788) 2020-04-27 02:25:41 +02:00
jack1142
a1095285e4 Fix migrations from JSON driver (#3714) 2020-04-27 01:32:52 +02:00
Neuro Assassin
00d20f14b9 Add [p]cc raw command giving raw (escaped) response (#3795) 2020-04-27 01:31:43 +02:00
jack1142
560e0f7334 Add docs for updating Red (#3790)
* wip

* Add 3.0.2 or older instructions

* rephrase

* emphasis

* another rephrase

* Add 3.2.0+ instructions for Linux & Mac

* change indents
2020-04-26 19:35:59 +02:00
Draper
fc2dce6882 [Driver] Ensure JSON driver has a singular lock per cog name (#3780) 2020-04-26 18:21:48 +02:00
Draper
bd3d0dd64d Show current driver in [p]debuginfo (#3794)
Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-04-26 16:07:57 +02:00
jack1142
f824d09ed3 Update install docs to include Ubuntu 20.04 (#3792) 2020-04-25 01:54:07 +02:00
aikaterna
d7c5f86ce7 [Audio] Update Lavalink.jar version (#3791) 2020-04-24 19:15:19 +02:00
PredaaA
c760b43e5a Allow to disable escaping in chat formatting utils (#3742)
Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-04-24 18:17:19 +02:00
jack1142
b1fe807b47 Don't run command checks on each message starting with a prefix (#3718) 2020-04-24 18:12:25 +02:00
jack1142
0d6a7eb797 Stop fetching bans when checking for tempban expiration (#3783) 2020-04-24 18:11:41 +02:00
Kowlin
bf6390d72e Fix Owner ID failsafe (#3782)
* Fix Owner ID failsafe

* Update redbot/core/bot.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Let's go with a different approach (first commit)

* Let's go with a different approach (last commit)

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-04-24 18:03:58 +02:00
jack1142
e595f1859a Handle the ints for user objects in Modlog appropriately (#3784) 2020-04-24 04:08:08 +02:00
jack1142
06930ebe2c Patched the Patch where the Patch patched too much 2020-04-24 03:33:12 +02:00
jack1142
08c96a6794 Change pyenv instructions to update pyenv when it's already installed (#3740)
* Change pyenv instructions to update pyenv when it's already installed

* Use latest Python version
2020-04-24 03:30:11 +02:00
github-actions[bot]
61db89e89d Automated Crowdin downstream (#3785)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-04-23 14:44:20 +02:00
Draper
a2c0e4ca2e Fix sleeping and improve documentation for AsyncIter (#3776)
* welp

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* moar docs

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* moar docs

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove unnecessary items in `:exclude-members:`

* Make whitespace in docstrings consistent

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-04-21 13:45:03 +02:00
jack1142
b08a950c37 Stop using localised display name in stream url (#3773) 2020-04-20 20:03:34 +02:00
Draper
ad979180e5 Make the largest loops lazier and async to avoid blocking (#3767)
* lets reduce config calls here

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Lets normalize how we name config attributes across the bot.

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* ....

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Just a tiny PR improving config call in a lot of places (Specially events and Help)

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* stop using `bot.guilds` in `on_command_add`

* Just a tiny PR improving config call in a lot of places (Specially events and Help)

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* missed this one

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* nothing to see here

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* lets reduce config calls here

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Just a tiny PR improving config call in a lot of places (Specially events and Help)

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* stop using `bot.guilds` in `on_command_add`

* missed this one

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* welp

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* welp

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* welp

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* jack

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Update redbot/cogs/mod/kickban.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/filter/filter.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* jack

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* make all large loops async to avoid blocking larger bots

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* ...

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* okay now working AsyncGen

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* may or may not have forgotten black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Apply suggestions from code review

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* jack's review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* DOCS

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* DOCS

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Apply suggestions from code review

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* jack

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Apply suggestions from code review

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/utils/__init__.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/core/utils/__init__.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* avoid loop if possible and if not only iterate once

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-04-20 19:56:28 +02:00
jack1142
465812b673 Add a command to remove bot's avatar (#3757)
* Add a command to remove bot's avatar

* blah
2020-04-20 19:40:14 +02:00
Draper
f59e77002b Optimize config calls in few places (#3766)
* Just a tiny PR improving config call in a lot of places (Specially events and Help)

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* missed this one

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* welp

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* welp

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* welp

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* jack

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Update redbot/cogs/mod/kickban.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* jack

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-04-20 19:29:36 +02:00
Draper
e4018ec677 Normalize names of attributes with Config instances (#3765)
* Lets normalize how we name config attributes across the bot.

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* ....

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* nothing to see here

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-04-20 19:12:57 +02:00
Draper
df7ca65108 Reduce calls to config in the on_command_add event (#3764)
* lets reduce config calls here

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* stop using `bot.guilds` in `on_command_add`

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-04-20 19:10:58 +02:00
github-actions[bot]
d12fcac9af Automated Crowdin downstream (#3761)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-04-18 17:16:57 +02:00
Ryan
66fc28ec1b [Trivia] Correct spelling of compact disc in games.yaml (#3759) 2020-04-15 00:08:17 +02:00
Kowlin
10ad2a559a [Core] Support setting avatar via attachment (#3747)
* [Core] Support avatars via attachments

* Fix the thing I was actually annoyed about.

* Updated error texts

* English is a damn annoying language.
2020-04-13 02:27:55 +02:00
MiniJennJenn
b8ac70e59a Update leagueoflegends.yaml 2020-04-12 17:41:42 -04:00
jack1142
7492636818 Fix ignored channels list in [p]ignore (#3746)
* Fix ignored channels list

* Update settings_caches.py

* Update core_commands.py
2020-04-12 00:09:05 +02:00
github-actions[bot]
36a0eabf4a Automated Crowdin downstream (#3739)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-04-09 21:27:35 +02:00
jack1142
cf4fdbbab1 dev bump (#3736) 2020-04-09 00:39:48 +02:00
Kowlin
f1b6b5f6f9 Update changelog_3_3_0.rst (#3737) 2020-04-09 00:32:20 +02:00
Kowlin
e06b3fceb5 Version bump (#3735) 2020-04-09 00:26:43 +02:00
jack1142
4628dd07e4 Red 3.3.5 - Changelog (#3727)
* Add 3.3.5 section

* PR 3730

* PR 3734

* Remove empty sections and add release date
2020-04-09 00:24:09 +02:00
jack1142
55a3d9b157 Properly check for command's existence in [p]alias add (#3734) 2020-04-09 00:19:14 +02:00
jack1142
c70c1d97e5 Revert "[CI] Less weekly churn from automated tasks (#3548)" (#3732)
This reverts commit f6c85cd37a.
2020-04-08 17:25:30 +02:00
Kowlin
da4e4d4ad0 Stop Outdated field from showing in [p]info when up-to-date (#3730)
* Oudated-B-Gone!

* Meh

* mehhh
2020-04-07 10:01:51 +02:00
Kowlin
3d9ee3f2b4 Dev version bump, for realzies (#3726)
* Damn tests that keep breaking if you forget a single damn number!

Who designed this shit?!

* Update __init__.py
2020-04-05 04:10:32 +02:00
Kowlin
b9331ffa55 Update __init__.py (#3725) 2020-04-05 04:05:53 +02:00
jack1142
2b0935c4aa Red 3.3.4 - Changelog (#3706)
* Add 3.3.4 section

* PR 3710 (issue 3545)

* PR 3708

* PR 3717

* PR 3723

* PR 3707

* Add release date, remove unused section
2020-04-05 03:58:39 +02:00
Kowlin
9d7047864e Version bump (#3724) 2020-04-05 03:57:50 +02:00
jack1142
20d507dbef Fix bank check (used in Bank, Economy and Trivia cogs) 2020-04-05 03:49:02 +02:00
jack1142
be7d1d2cd2 Bump deps (includes d.py bump) (#3723) 2020-04-05 03:34:53 +02:00
github-actions[bot]
587968710f Automated Crowdin downstream (#3719)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-04-04 06:28:55 +02:00
jack1142
a0b30bb3ae Fix Flame's irk with code blocks in windows install guide (#3722)
* Update install_windows.rst

* God, I'm an idiot
2020-04-04 03:08:39 +02:00
kennnyshiwa
60e954634d Include domains added in #3717 in filter_invites's docstring (#3721) 2020-04-02 20:17:46 +02:00
kennnyshiwa
ffecf1ed15 Fix redbot.core.utils.common_filters.INVITE_URL_RE regex (#3717)
* Fix invite_url_re

Found that the regex used previously could falsely catch strings such as discord member and discord gggggg which aren't invites and shouldn't be caught, testing with this regex string still catches all invite url variations while allowing these other previously caught strings to keep working

* Update redbot/core/utils/common_filters.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-04-02 09:11:12 +02:00
jack1142
b7a142c21e Include versions for pre-requirements in Windows install guide (#3708)
* Update install_windows.rst

* Update install_linux_mac.rst
2020-03-30 10:00:01 +02:00
jack1142
5716cebb0f Send error in [p]alias add when target command doesn't exist (#3710) 2020-03-30 06:48:51 +02:00
jack1142
ff68538085 Bump version to 3.3.4.dev1 (#3705) 2020-03-29 00:02:01 +01:00
Kowlin
7c251b8017 Bump version to 3.3.3 (#3703)
* Bump version to 3.3.3

* Update manager.py
2020-03-28 23:51:09 +01:00
jack1142
bf5917177a Red 3.3.3 - Changelog (#3660)
* Add 3.3.3 section

* PR 3630 (issue 3628)

* PR 3589 (issue 3145)

* PR 3631

* PR 3627

* PR 3504 (issue 3465)

* PR 3632 (issue 3626)

* PR 2929 (issue 2800)

* PR 3646 (issue 3590)

* PR 2382

* PR 3659

* PR 3653 (issue 3633)

* PR 3668 (issue 3583)

* PR 3663

* PR 3666 (issue 3584)

* PR 3656

* PR 3644

* PR 3420 (issue 3307)

* PR 3643 (issue 3642)

* PR 3638 (issue 3636)

* PR 3665 (issue 2988)

* PR 3667 (issue 3044)

* PR 3689 (issue 3685)

* PR 3688

* PR 3675 (issue 3436)

* PR 3695 (issue 2826)

* PR 3027

* PR 3637 (issue 3639)

* PR 3674 (issue 3443)

* PR 3690

* PR 3673 (issue 3507)

* PR 3652 (issue 3645)

* PR 2573

* PR 3657

* PR 3678 (issue 3448)

* PR 3684

* PR 3700

* PR 3669

* PR 3649 (issue 3648)

* PR 3676 (issue 3596)

* PR 3677 (issue 3588)

* PR 3672 (issue 3233)

* PR 3704

* Add release date
2020-03-28 23:50:50 +01:00
jack1142
dacfb931bb remove dis (#3704) 2020-03-28 23:45:37 +01:00
jack1142
97d77f5c51 Make checks in Bank, Economy and Trivia cogs Permissions-friendly (#3672)
* Create converters.py

* Update trivia.py

* Create checks.py

* Update checks.py

* Update checks.py

* Update trivia.py

* Update checks.py

* Update checks.py

* Update trivia.py

* Update bank.py

* Update economy.py

* Update trivia.py

* Update checks.py

* Update checks.py

* Update __init__.py
2020-03-28 23:24:12 +01:00
jack1142
fce8186759 Add [p]set regionalformat command to set regional formatting (#3677)
* Add `[p]set region` command to set regional formatting

* Add Babel to intersphinx

* rename 'region' to 'regional format`
2020-03-28 23:23:02 +01:00
jack1142
d35f6abca0 Use Babel in [p]set locale to allow any valid locale (#3676)
* Use Babel in `[p]set locale` to allow any valid locale

* Remove `[p]listlocales` and link to Crowdin in `[p]set locale`

* import babel.Locale as BabelLocale to avoid confousion
2020-03-28 23:11:25 +01:00
jack1142
cf31c22e5d Revert "Add changelog label to merged PRs (#3664)" (#3702)
This reverts commit 3d7ff7a149.
2020-03-28 23:06:41 +01:00
jack1142
3f7c2e8842 Update dev_commands.py (#3649) 2020-03-28 23:05:50 +01:00
PredaaA
ecdcc27749 Fix count of streaming members and a typo in [p]serverinfo (#3701) 2020-03-28 20:15:16 +01:00
kennnyshiwa
497d244f95 Show member's activities in [p]userinfo command (#3669)
* [mod] status improvements in userinfo command

Adds support for statues in the userinfo command including custom status, playing and listening improvements

* fix style

* maybe fix style now

* Update redbot/cogs/mod/names.py

Co-Authored-By: Draper <27962761+Drapersniper@users.noreply.github.com>

* fix spaces

* address review and add emojis

* fix broken variable

* Update redbot/cogs/mod/names.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/names.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/names.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/names.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/names.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update names.py

* Update names.py

* Update redbot/cogs/mod/names.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update names.py

* Update redbot/cogs/mod/names.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/names.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-03-28 19:44:56 +01:00
jack1142
a738736d6b Update __init__.py (#3700) 2020-03-28 19:30:16 +01:00
jack1142
a4ce2d01ce Use choco upgrade, not choco install (#3684)
* Use `choco upgrade`, not `choco install` and add `--version` for Python

* Update install_windows.rst

* actually, nah
2020-03-28 16:08:25 +01:00
jack1142
41c2b76d8d Make [p]cog checkforupdates indicate when cog can't be updated on current Red/Python version 2020-03-28 15:53:10 +01:00
jack1142
35ebc4899e Log failures when requesting Twitch bearer token (#3657)
* [Streams] Log failures when requesting Twitch bearer token

* Oops

* Style
2020-03-28 15:51:36 +01:00
jack1142
9552d210f5 Remove towncrier (#3661) 2020-03-28 02:46:15 +01:00
Neuro Assassin
9370b5110e Add [p]cc search command (#2573)
* Add search command for Custom Commands

* Spelling mistake

* Create 2573.feature.rst

* Remove `bot.db` usage, improve returned message

* remove towncrier entry

* Fix CI errors

* Fix more CI errors

* Add `@staticmethod` decorator

Co-authored-by: Toby Harradine <Tobotimus@users.noreply.github.com>
Co-authored-by: Michael H <michael@michaelhall.tech>
Co-authored-by: Kowlin <Kowlin@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-03-28 02:11:36 +01:00
jack1142
7009be8922 white/blacklist commands now properly require at least one user passed (#3652) 2020-03-28 01:38:46 +01:00
jack1142
c1a96c83fb Update _internal_utils.py (#3673) 2020-03-28 01:37:59 +01:00
jack1142
5d66e4eaf8 Update streamtypes.py (#3690) 2020-03-28 01:35:51 +01:00
jack1142
ed267d17f2 [ModLog] Keep last known username in case's data (#3674) 2020-03-28 01:34:40 +01:00
jack1142
6e91ebeb3d Use surrogateescape when decoding subprocess's stream (#3639)
* use surrogateescape when decoding subprocess's stream

* stop using surrogateescape for logging
2020-03-28 01:14:54 +01:00
jack1142
d70c6e1734 Update mod.py (#3683) 2020-03-28 01:05:25 +01:00
PredaaA
4de4c32c0e Bump Red-Lavalink (#3687) 2020-03-28 00:46:09 +01:00
Jeremiah Boby
637ae34839 Print quickstart guide at the end of redbot-setup (#3027)
* Print quickstart guide during setup

Resolves #3025

* Refer users to stable documentation
2020-03-26 22:33:57 +01:00
jack1142
d23144bc61 [Docs] Fix Mac instructions in the install guide (#3675)
* Update install_linux_mac.rst

* Address review

* Use new Homebrew installer

* Add python@3.8 to PATH
2020-03-26 22:33:12 +01:00
FancyJesse
e90868072e [Cleanup] Add [p]cleanup spam command (#3688)
* Added `[p]cleanup spam` function

* formatting

* accepts number and considers command message to total counts

* use existing kwarg instead

Safer to use the before kwarg as other messages might get included accidentally between invoking and executing

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* safer way to compare embeds and skip attachment only msgs

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* keeps the original message before the spam starts

* now asks if its ok to delete 100+ spam msgs if found

* unnecessary calculations, just add after

* code styling and reverted history oldest_first option

* switched to recommended logging formatting, thank you jack1142

* now using `get_messages_for_deletion()`, added needed limit kwarg

* ugh forgot to swap em

* duh

* small string clarification

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-03-26 22:32:10 +01:00
Kowlin
980d2a8dc3 Removal of Dispatch, since its not working. (#3696)
* Removal of Dispatch, since its not working.

* Add changelog behavior
2020-03-26 14:13:30 +01:00
github-actions[bot]
eef5ddb416 Automated Crowdin downstream (#3697)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-03-26 14:06:51 +01:00
jack1142
3d7ff7a149 Add changelog label to merged PRs (#3664) 2020-03-26 13:56:10 +01:00
Stonedestroyer
287edb755d Fix misleading error appearing when repo name is already taken (#3695)
* Error string change

* String
2020-03-26 13:26:05 +01:00
Dav
8c612a96c8 [Streams] Make preview picture for stream alerts bigger (#3689) 2020-03-25 11:22:33 +01:00
jack1142
efe67e2acc [Image] Add [count] argument to [p]imgur commands (#3667)
* Update image.py

* Update image.py

* welp

* Update image.py

* Add `count` arg to `[p]imgur subreddit`

* me dumb (a little)
2020-03-24 00:42:27 +01:00
jack1142
2cdf3c16ab Make command errors translatable (#3665)
* Make command errors translatable

* style

* moar style

* Update events.py

* Separate strings to make it better for translators
2020-03-24 00:35:32 +01:00
PredaaA
a88b2af4a9 [General] Fix streaming count in serverinfo command. (#3680)
* [General] Fix streaming count on serverinfo command.

* Update general.py

* Update general.py

* is
2020-03-21 22:23:56 +01:00
TrustyJAID
b9f07e8684 [Mod] Move deletedelay to core (#3638)
* Move deletedelay to core

* line lengths

* address review

* move settings change

* fine...
2020-03-21 18:39:58 +01:00
TrustyJAID
d957e44e1e Fix issues with the black/whitelist cache (#3643)
* Fix issues with the black/whitelist cache

* Address review

* address review

* or
2020-03-21 18:14:49 +01:00
Stonedestroyer
15e3437001 [Trivia] Commands for managing custom trivia lists (#3420)
* Trivia upload

* Second push

* Black

* A bit further

* Logic fix

* Getting closer

* Almost there

* Abomination ready for review.

Abomination ready for review.

* Upload trivia review

* Black

* Fix debug

* Delete a trivia

* List cleaned.

* Make it nicer

* Pass black

* Unlink file

* Translation

* Thanks Jack

* Beautify

* Black

* Fix

* Handling empty custom lists

* Use existing fileobject.

* Black

* Test

* Change up

* Black

* Changelog

* Typo error

* Fix up issues.

* Fixes stuff.

* Styling

* Add reactions

* Reactions

* Add safe handling of reactions

* Style

* Fix grammar and remove obsolete code

* Timeout

* Fix

* Requested changes

* Styling

* Fixes

* Typehint

* Remove

* mistake

* Constant

* Style

* return
2020-03-21 16:30:33 +01:00
jack1142
eebea59fe3 Remove usage of loop arg in calls to start_adding_reactions (#3644)
* fix stacklevels of warnings

* stop using loop arg when calling start_adding_reactions

* [Audio] Stop using loop arg when calling start_adding_reactions
2020-03-20 20:44:57 +01:00
jack1142
5074f2dbab Improve error message for OSError in [p]repo add (#3656)
* Update downloader.py

* Update downloader.py
2020-03-20 20:40:59 +01:00
github-actions[bot]
0f364a6d13 Automated Crowdin downstream (#3671)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-03-19 23:38:27 +01:00
jack1142
d9db03bca3 Tell the command caller when bot was unable to send warn (#3653) 2020-03-19 08:23:07 +01:00
jack1142
b9e2e1098f [Trivia] Forbid use of non-finite numbers in [p]triviaset subcommands (#3668)
* Update trivia.py

* style
2020-03-19 08:21:54 +01:00
jack1142
a126da5f23 Prevent PyPI's unavailability from causing command failure (#3663) 2020-03-19 08:19:01 +01:00
jack1142
23eae27a8f Update session.py (#3666) 2020-03-19 08:17:32 +01:00
github-actions[bot]
3e1bb88ab7 Automated Crowdin downstream (#3650)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-03-18 20:48:15 +01:00
PredaaA
4de7ce32dd [General] Add shard ID to serverinfo if bot uses multiple shards (#3659)
* [General] Add shard ID on serverinfo if there is over than two shards

* Update general.py

* Update general.py

* Update general.py

* Update general.py
2020-03-16 01:42:35 +01:00
PredaaA
6128d54601 [General] Add toggle to [p]serverinfo that shows more details (#2382)
* Improvements of "serverinfo" command

- Added some more informations about the server.
  (Verification level, AFK channel and timeout, custom emojis and special features).
- Added custom texts for Region (and Verification levels).
- Added more details about members (Number of humans, bots, and all status).
- Show special features only if the server has one.
- Show "Verified" logo only if the server is verified.
- And changed the footer by adding how many time the bot as join the server.

* Black formatting for serverinfo

* Black formatting fix and Sinbad suggestions

* Fix the discord.errors.NotFound on server command

Added exception on server command for the phrase "To leave a server, just type its number.".

* Update core_commands.py

* Delete core_commands.py

* Create core_commands.py

* Update core_commands.py

* Update core_commands.py

* Delete core_commands.py

* Create core_commands.py

* Update core_commands.py

* Update core_commands.py

* Little changes on serverinfo command

- Adding "lurkers" check, for the new feature that are on bot which allow users to join a server in read-only (Works only on verified servers for now)
- Adding streaming status.
- Adding mobile status with suggestion of Sinbad.

* Black style fix

* Add verbose for serverinfo and disable lurkers

I've added a bool that are False by default and sent the original serverinfo command, and if set to True send my edited version.
And I've disabled the lurkers detection until this bug (https://github.com/discordapp/discord-api-docs/issues/855) isn't fixed.

* Add of India region

* Code cleanup

* Emojis are not needed to be translated

* Update serverinfo

* Changelog.

* Update 2382.enhancement.rst

* Adress Jack's requests changes.

* oops

* Put guild description first + few last nitpicks

Co-authored-by: PredaMart <46051820+PredaMart@users.noreply.github.com>
Co-authored-by: Toby Harradine <Tobotimus@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-03-15 23:46:21 +01:00
Dav
4d81887bcf [Core] Unify commands that set bot's activity status (#3646)
* alias [p]set game

* Implement suggestions
2020-03-12 22:46:19 +01:00
Ianardo DiCaprio
2e5dc82692 [Warnings] Add setting for warn channel and DMing warns toggle (#2929)
* Initial Commit

* Add changelog

* Review changes

* Changed to use contextlib.suppress

* Update warnings.py

* Update redbot/cogs/warnings/warnings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/warnings/warnings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/warnings/warnings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/warnings/warnings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/warnings/warnings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/warnings/warnings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/warnings/warnings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/warnings/warnings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/warnings/warnings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Rename 2932.bugfix.rst.txt to 2932.bugfix.rst

* Rename 2929.enhance.rst.txt to 2929.enhance.rst

* Update redbot/cogs/warnings/warnings.py

Co-Authored-By: Draper <27962761+Drapersniper@users.noreply.github.com>

* Update redbot/cogs/warnings/warnings.py

Co-Authored-By: Draper <27962761+Drapersniper@users.noreply.github.com>

* Update redbot/cogs/warnings/warnings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Rename 2929.enhance.rst to 2929.feature.rst

* Update warnings.py

* Add files via upload

* Update warnings.py

* Black

* Update warnings.py

* black

* Update warnings.py

* Update warnings.py

* Delete 2932.bugfix.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2020-03-12 21:17:59 +01:00
jack1142
4afe1ff569 Use correct prefixes when sending messages to owners (#3632)
* use correct prefixes when sending messages to owners

* make internal util for this instead

* oops

* fix circular import

* let's add back the actual fix I made this PR for...

* fix wrong logger name

* improve log message
2020-03-12 17:31:33 +01:00
Kowlin
3ff127d514 Automated Crowdin downstream (#3640) 2020-03-05 22:01:26 +01:00
Kowlin
ea3ca66303 Handle users leaving the server while we're applying mutes (#3627)
* Handle when users leave a server while we're applying mutes

Goddamn guilds with >100 text channels >.<

* Damn you tox.

* Damn you Bread.

* Fixed a bug whereby Guild would always return a success

Also handled error checking on NotFound so that the propper handling can be done.

* Fixed flake8 compile error (whoops)

* Revert "Fixed flake8 compile error (whoops)"

This reverts commit ec8b672347.

* Revert "Fixed a bug whereby Guild would always return a success"

This reverts commit 8d08ac31af.

* Apply the lost commits that we actually want

Since cherry picking is hard.

* Isn't the English language FUN!?

* *sigh*
2020-03-01 21:11:46 +01:00
jack1142
279f0e4f6c Update streamtypes.py (#3631) 2020-02-29 17:47:50 +01:00
Stonedestroyer
61fc00dc08 [Permissions] Alwaysavailable error message (#3504)
* [Permissions] Fix message for always available commands.

* Changelog
2020-02-29 16:29:31 +01:00
jack1142
d6f9ddc3af Check permissions before trying to clear reactions (#3589) 2020-02-29 16:00:19 +01:00
Stonedestroyer
b52c838018 Fix game command empty argument. (#3630) 2020-02-29 15:35:44 +01:00
jack1142
e0de25ed65 dev bump (#3624) 2020-02-28 22:23:59 +01:00
Kowlin
03a2c11225 Bump the version to 3.3.2 (#3622) 2020-02-28 22:15:07 +01:00
jack1142
52480783ee 3.3.2 changelog (#3621)
* 3.3.2 changelog

* few fixes

* add contributors

* that one last change from milestone
2020-02-28 21:48:32 +01:00
Michael H
f6361992e3 Use a metaclass for config's singletons (#3137)
* Usea metaclass for config's singletons

* make this a little safer
2020-02-28 21:37:35 +01:00
jack1142
eedec4ff02 fix: use clean prefix in code blocks (#3591) 2020-02-28 21:23:13 +01:00
jack1142
7b042be9db bump Red-Lavalink (#3623) 2020-02-28 21:21:17 +01:00
jack1142
b2cba6b6d7 docs(utils): add headers for each event predicate (#3595) 2020-02-28 21:20:59 +01:00
jack1142
0ff000d660 Fix config conversion in image cog (#3617) 2020-02-28 21:18:23 +01:00
jack1142
4e4420af2e Replace [p] with clean prefix in install messages (#3592) 2020-02-28 21:17:45 +01:00
jack1142
9ea7262352 Bump deps (includes d.py and Sphinx bump) (#3609) 2020-02-28 20:37:30 +01:00
jack1142
227009733e Revert "new mention behavior, new filter behavior (#3553)" (#3619)
* Revert "new mention behavior, new filter behavior (#3553)"

This reverts commit 066bf516d9.

* keep invalid escape fix
2020-02-28 20:34:51 +01:00
aikaterna
136fcd7bb2 [Audio] Update Lavalink.jar version (#3620) 2020-02-28 18:50:13 +00:00
Flame442
67ab59106f [Trivia] Better handling for session errors (#3606)
* Better handling for session errors

* Use `stop` instead of `end_game`, translation support
2020-02-28 19:47:01 +01:00
jack1142
e8b975a095 [Core] Use new PyPI urls (#3607)
* fix: use new PyPI urls

* Update core_commands.py

* Update core_commands.py
2020-02-28 02:43:21 +01:00
Stonedestroyer
ad4a75bdc1 Deprecation warning - alternative (#3615)
* Alternative solution

* BLACK

* Args

* Changes

* style

* Ordering

* Debug shows warnings

* style
2020-02-28 02:22:50 +01:00
jack1142
582f64b2e7 fix some deprecation warnings (#3610) 2020-02-28 02:21:58 +01:00
Michael H
d4e982faea Fix Red specific behavior of invoke_without_command (#3614) 2020-02-28 01:40:28 +01:00
github-actions[bot]
4db77c9051 Automated Crowdin downstream (#3616) 2020-02-28 01:02:44 +01:00
Dav
0397401216 [Docs] randomize_color now has its own docstring (#3491)
* randomize_color now has it's own docstring and definition

* hi CI

* reverse CI trigger

* reversed work on embed.py

* Changed docs file
2020-02-22 22:37:25 +01:00
Draper
6c062ab1e2 [Core] Update licenseinfo command to conform with non-American English. (#3460)
* Update the licence command to confirm with non-American English and keep it inline with the `colour`/`color` command

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* What is Black

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* improve error handling

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-02-22 20:52:01 +01:00
Dav
106804ad45 [Docs] Make Getting started guide explain use of quotes for arguments with spaces (#3555)
* getting_started.rst now explains use of quotes for arguments with spaces

* double quotes

* proposal 1

* proposal 2

* fix typo

Co-Authored-By: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-02-22 00:12:08 +01:00
jack1142
4745f9e999 [Trivia] Remove empty string from answers (#3581)
* [Trivia] Remove empty string from answers

* another one

* nobody minds that I put this change too, right?
2020-02-20 22:27:22 -05:00
jack1142
901c4f7b80 Update core_commands.py (#3585) 2020-02-20 22:25:36 -05:00
jack1142
5ee73cdf63 Add clearer error when pages isn't made of embeds nor strings in menu() (#3571)
* Update menus.py

* Update menus.py
2020-02-20 22:25:14 -05:00
jack1142
54b712fa71 Fix type hints for var-positional parameters in whitelist/blacklist commands (#3577)
* Fix type hints in whitelist/blacklist commands

* fix formatting (yay for black diff in CI again)
2020-02-20 22:23:45 -05:00
zephyrkul
e70fcef651 [Core] Utilize clean prefix (#3579)
* [core] use clean prefix

* forgot an import
2020-02-20 18:58:41 +01:00
github-actions[bot]
6779a76b68 Automated Crowdin downstream (#3580) 2020-02-20 13:21:37 +01:00
jack1142
cd48e06060 Update layout.html (#3575) 2020-02-19 03:24:28 -05:00
jack1142
4956e67348 [Mod] Delegate send_to_owners call in initialize() to a task (#3573)
* fix(mod): delegate send_to_owners call in initialize() to a task

* enhance(mod): reorder cog's setup()
2020-02-19 02:12:50 -05:00
jack1142
9a8c134c97 docs: add a warning on latest version of docs (#3570) 2020-02-18 21:53:07 -05:00
Michael H
ef101ccb9a [Docs] Cog Creator Guidelines (#3568)
* Cog Creator Guidelines

* print

* docs warnings

* Apply suggestions from code review

Co-Authored-By: Flame442 <34169552+Flame442@users.noreply.github.com>

* more feedback handling

* one more

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-02-17 22:42:13 -05:00
jack1142
bb90a50ae4 i18n fixes for #3562 (#3565) 2020-02-17 12:11:42 -05:00
Dav
6c62817de5 [Core] Setting the bot's game/listening/watching displays new text in chat message and is capped at 128 chars. (#3562)
* Le code.

* Say Status instead of Game/Listening/Watching
2020-02-17 11:48:43 -05:00
jack1142
7c06d9a638 Update install_windows.rst (#3564) 2020-02-17 11:47:09 -05:00
Fixator10
ae7773cfcf [Mod] fix exception caused by typo (#3559) 2020-02-17 11:46:14 -05:00
Dav
d7b73eb50f [Warnings] Fix inconsistency for warnreason (#3561) 2020-02-17 16:55:28 +01:00
jack1142
eff1014911 Add logging for unexpected OSError in [p]repo add (#3558)
* Update downloader.py

* Update downloader.py

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2020-02-17 11:57:04 +00:00
Michael H
f6c85cd37a [CI] Less weekly churn from automated tasks (#3548)
* Less weekly churn pls

* be smarter here *just in case*
2020-02-16 22:53:02 +01:00
Michael H
888c47cdd2 Payday: Fix missing await (#3554) 2020-02-15 14:47:33 +01:00
TrustyJAID
74a3eba08f [Mod] Move ignored guilds and channels to core (#3472)
* Move ignored guilds and channels to core
Add caching for ignored guilds and channels
Add caching for whitelist and blacklist
Fix #3220
Add consume-rest for whitelist and blacklist commands to add multiple users or roles in one command

* Add ability to ignore channel categories

* black

* moveignorechannels should be owner only and cleanup changes

* add changelog entries

* address Feedback
2020-02-15 01:21:09 -05:00
jack1142
78192dc1af [Downloader] Add schema validation to info.json file processing (#3533)
* schema v1

* set hidden to True for shared libs

* fix test data

* add warning about invalid top-level structure

* don't show full traceback for JSONDecodeError
2020-02-15 00:18:47 -05:00
PredaaA
ed6d012e6c [Streams] Use new Twitch API and Bearer tokens (#3487)
* Update streams.py

* Update streams

* Changelog.

* Adress Trusty's review

Co-authored-by: Michael H <michael@michaelhall.tech>
2020-02-15 00:14:34 -05:00
Draper
04b5a5f9ac [Streams] Significantly reduce number the quota usage for YouTube Data api (#3237)
* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Pre-tests

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh*

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Streams + black formatting

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* lets not spam the logs shall we

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* lets be extra sure

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* [Streams] Fix Twitch token for streamalert (#2)

* [Streams] Fix Twitch token for streamalert

* [Streams] Fix Twitch token for streamalert

Co-authored-by: PredaaA <46051820+PredaaA@users.noreply.github.com>
2020-02-15 00:06:03 -05:00
jack1142
a763726c89 Update alias.py (#3546) 2020-02-14 09:20:32 -05:00
jack1142
3991a2d88f [Docs] Restructure venv instructions (put them in install guides) (#3495)
* docs: restructure venv instructions

* docs: add a warning about PowerShell usage
2020-02-14 09:19:51 -05:00
jack1142
48e2dad3a4 Indicate instructions for different venv types in systemd guide better (#3538)
* Update autostart_systemd.rst

* Update autostart_systemd.rst
2020-02-14 09:16:33 -05:00
Dav
e7969992c3 [Warnings]Make it possible to add reason with unwarn (#3490)
* Unwarn now able to have a reason

* black

* Update string to say Run instead of Do

Co-Authored-By: Draper <27962761+Drapersniper@users.noreply.github.com>

* Make error for unregistered reason less agressive

Co-Authored-By: Draper <27962761+Drapersniper@users.noreply.github.com>

* Removing unneccessary lines and not putting the user input through the translator.

* Because black hates me, here black formatting with adjusted line length

* Trigger CI

* Now always sendes a message when an invalid reason is passed, not only if the command author was an admin, guild owner or bot owner.

* That should do the trick

* Correct

* Make Reason optional

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: Draper <27962761+Drapersniper@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-02-14 09:13:44 -05:00
Hugo Hedlund
6ddaff6260 Payday should store the last time it was used so it can be compared to the cooldown value rather than using a cooldown deco that won't reset if cooldown goes lower (#3496)
* Payday #3438 Changed next_payday to last_payday

* Created towncrier entry

* [PR #3496] Requested changes

* rm .vs
2020-02-14 09:13:18 -05:00
jack1142
9e1f358f82 Add make stylediff command and run it in tox (#3535)
* Update Makefile

* Update make.bat

* Update tox.ini
2020-02-14 09:09:52 -05:00
Michael H
066bf516d9 new mention behavior, new filter behavior (#3553)
* new mention behavior, new filter behavior

* and here too, ffs

* docs and reformat

* review handling
2020-02-14 09:07:16 -05:00
Michael H
a44047bfe3 We require a network connection, don't start before the network is ready (#3549) 2020-02-13 20:40:25 +01:00
github-actions[bot]
0913b68a1e Automated Crowdin downstream (#3543) 2020-02-13 12:54:28 -05:00
zephyrkul
42a23277cd [Dev] Allow top-level await in code statements (#3508)
* [dev] allow top-level await in code statements

* style

* use staticmethod, cls is unneeded

* add asyncio and aiohttp to env

* fix repl

* add __builtins__ to repl env

* style...

* fix debug with no coro

* add `optimize=0` to eval
2020-02-13 12:29:10 -05:00
jack1142
cc30726ab6 Skip publish actions for forks (#3544) 2020-02-13 17:43:42 +01:00
Michael H
c2143fdf86 [commands module] functools.partial support (#3542)
* No reason we can't support this

* meh

* there we go...
2020-02-12 09:28:52 -05:00
zephyrkul
da3f86d6ba Make systemd guide clearer on obtaining username and python path (#3537)
* [docs] make username clearer

* make systemd docs even more clear

* fix first code block
2020-02-11 19:11:36 +01:00
chasehult
26fdbf63ee string (#3536) 2020-02-10 04:10:59 -05:00
Michael H
7bee668888 [CI] Stop messing with our contributor data with automated PRs (#3534)
* CC: Kowlin

* *sigh*

* Their own docs said that was allowed in expressions...

* python linting needs it too

* Quit with the dumb

* whoops
2020-02-09 21:18:02 +01:00
Kowlin
7f6418b18f Fixed Commiter (#3532) 2020-02-09 00:53:37 +01:00
Cog-Creators Bot
4370ec922b Automated Crowdin downstream (#3531)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-02-08 19:49:30 +01:00
Kowlin
ec97f0c316 Updates to the Crowdin CLI (#3530) 2020-02-08 19:14:33 +01:00
jack1142
84870f2fa2 Add black config to pyproject.toml (#3493)
* chore: add black config to pyproject.toml

* enhance: make files will now use settings from pyproject.toml

* docs: update CONTRIBUTING.md
2020-02-08 07:47:39 -05:00
DiscordLiz
42a4d10ea5 Update websockets & Show DeprecationWarnings from all modules (#3527)
related : #3526
2020-02-08 07:45:45 -05:00
DiscordLiz
8e3a76186b [Mod] Use a better converter for Hackban & Unban (#3524)
closes #3523
2020-02-08 07:43:03 -05:00
DiscordLiz
9a278213bd Use development versions of CI tools (#3525)
Allows assignment expressions to not break PRs
2020-02-08 07:29:18 -05:00
Kowlin
c6bc4c1bd6 First attempt automated crowdin (#3521) 2020-02-07 22:44:40 -05:00
jack1142
17b8ef09c6 Update guide_publish_cogs.rst (#3520) 2020-02-08 02:15:10 +01:00
jack1142
8f7ba02ab1 [Warnings] Stop using inspect.getsource to check for is_owner check (#3516)
* Update helpers.py

* Create 3515.misc.rst

* Update helpers.py
2020-02-06 19:42:36 -05:00
Flame442
246f9ce17f Adds traceback logging to task exception handling (#3517) 2020-02-06 18:46:54 -05:00
trundleroo
8d73838d80 Update announcer.py (#3514)
* Update announcer.py

* Update announcer.py
2020-02-06 18:27:32 +01:00
Kowlin
1fc4ece14c Updated readme badges. (#3511) 2020-02-05 17:32:35 -05:00
Michael H
0adc960c60 dev bump (#3512) 2020-02-05 17:32:05 -05:00
Michael H
c426aefd1a Version 3.3.1 (#3510)
* 331

* okay sphinx
2020-02-05 23:21:38 +01:00
Michael H
00cf395483 Handle deprecations in asyncio (#3509)
* passing loop to certain things was deprecated. additionally, `asyncio.get_event_loop()` is being deprecated

* awesome, checks are functioning as intended

* fun with fixtures

* we can just stop misuing that anyhow

* Update redbot/pytest/downloader.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-02-05 17:16:13 -05:00
Kowlin
61ed864e02 CI ports from Travis CI (#3435)
* Attempt 1, I suppose.

* Add the remaining 2 out of 3 jobs

* Spacing matters T_T

* So does formatting...

* More formatting fixing.

* First attempt at postgres services.

* Postgres attempt 2

* Update tests.yml

Flatten a python version I suppose.

* Update tests.yml

* Update tests.yml

* Update tests.yml

* Update tests.yml

* I wonder if this works lmao

* this is fun™

* let's go back

* add fail-fast

* Added publishing workflows

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-02-05 16:02:05 -05:00
Lane Babuder
90b099395b Adding CentOS 8 Documentation (#3463)
IUS will not be supporting RHEL 8, so utilizing epel-release and telling the system to use standard git is the best option.
2020-02-03 16:57:09 -05:00
aikaterna
12e6f44135 [Core] No DMing the bot (#3478)
* [Core] No DMing the bot

* Return early if target user is a bot
2020-02-03 16:26:33 -05:00
PredaaA
e44fc69d14 [Core] Add a cli flag for setting a max size of message cache (#3474)
* Add an arg in cli to change message cache size

* Add an arg in cli to change message cache size

* Changelog

* Actually pass None in message_cache_size

* Update cli.py

* Add a cli arg to disable message cache.

* Add a cli arg to disable message cache.

* well go away you useless

* you actually are an int

* Check if message cache is higher than 0 when set it.

* Use sys.maxsize as max cache size.

* Update cli.py

* Add bot.max_messages property.

* typos

* 🤦

* style
2020-02-03 16:14:45 -05:00
jack1142
8454239a98 [Mod] Fix shorthelp for [p]modset dm (#3488)
* Update settings.py

* Update settings.py

* Create 3488.misc.rst

* Update settings.py
2020-02-03 16:14:19 -05:00
jack1142
64106c771a Allow to edit prefixes through redbot --edit (#3486)
* feat: allow to edit prefixes through `redbot --edit`

* enhance: allow to setup multiple prefixes

* fix: gotta break out of the loop

* fix: gotta sort prefixes in reversed order

* fix: editing prefix shouldn't save it as token

* fix: sort prefixes when using flag too

* chore(changelog): add towncrier entry

* docs: update help for `--edit` flag
2020-02-03 16:08:48 -05:00
jack1142
17234ac8fa Add -e flag to journalctl command in systemd guide so that it takes the user to the end of logs automatically. (#3483)
* Make journalctl's pager go to the end of logs automatically

* Aaaaaaaand changelog
2020-02-01 01:26:39 +01:00
Kowlin
b64802b92f Fix for the unknown days argument on hackban. (#3475) 2020-01-30 18:55:11 +01:00
jack1142
6fa02b1a8d [Docs] Trigger update on sudo add-apt-repository (#3464) 2020-01-27 18:41:57 -09:00
Michael H
7420df9598 let's fix this for dev testers (#3458) 2020-01-27 03:35:16 -05:00
Michael H
00bcd480e7 dev bump (#3455) 2020-01-26 20:39:38 -05:00
Michael H
0d3c72f356 changelog and bump (#3454) 2020-01-26 20:18:25 -05:00
Michael H
97a9fde5fd slowmode should properly error out on 7 hours now (#3453) 2020-01-27 02:01:22 +01:00
Michael H
a664615a2d shortdoc should be formatted too, + generic replacement method (#3451) 2020-01-27 01:25:58 +01:00
Michael H
3d4f9500e9 [Permissions] Ordering fix (#3452) 2020-01-27 01:00:08 +01:00
Michael H
a8450580e8 [Commands Module] Improve usability of type hints (#3410)
* [Commands Module] Better Typehint Support

  We now do a lot more with type hints

  - No more rexporting d.py commands submodules
  - New type aliases for GuildContext & DMContext
  - More things are typehinted

  Note: Some things are still not typed, others are still incorrectly
  typed, This is progress.

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-01-26 17:54:39 -05:00
Draper
8654924869 [Audio] Allow lazy searching for playlist across scopes (#3430)
* Allow lazy searching for playlist cross scope

* Chore
2020-01-26 16:38:49 -05:00
jack1142
068585379a docs: deprecation of shared libraries has been postponed to 3.4 (#3449) 2020-01-26 12:16:44 -05:00
jack1142
fc5fc08962 [Downloader] Log errors from initialization task (#3444)
* Update downloader.py

* Create 3444.misc.rst

* enhance(downloader): don't type infinitely on init error

* fix(downloader): unindent `_ready_raised` check

* Update downloader.py
2020-01-26 12:16:13 -05:00
Stonedestroyer
41fdcb2ae8 [Core] Embeds toggle for channels. (#3418)
* [Core] Embedset toggle for channels.

* Typo fix

* Add to contact as well

Thanks Jack.

* Add guild only and check.
2020-01-26 12:15:22 -05:00
Ianardo DiCaprio
de4804863a [Mod] Option to DM user with kick/ban reason. (#2990)
* FUCK

* FUCK

* FUCK

* Update kickban.py

* Update settings.py

* Update kickban.py

* Update kickban.py

* Add files via upload

* black

* Update kickban.py

* Update kickban.py

* Update redbot/cogs/mod/kickban.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/kickban.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update settings.py

* Update kickban.py

* Update and rename 2990.enhance.rst.txt.txt to 2990.enhance.rst.txt

* Update settings.py

* Rename 2990.enhance.rst.txt to 2990.enhance.rst

* Update redbot/cogs/mod/kickban.py

Co-Authored-By: DevilXD <DevilXD@users.noreply.github.com>

* Update redbot/cogs/mod/kickban.py

Co-Authored-By: DevilXD <DevilXD@users.noreply.github.com>

* Update redbot/cogs/mod/settings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/settings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update changelog.d/mod/2990.enhance.rst

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/settings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/settings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/kickban.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/kickban.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update kickban.py

* Update settings.py

* Update kickban.py

* Update kickban.py

* Update redbot/cogs/mod/kickban.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update kickban.py

* Update kickban.py

* Update mod.py

* Update settings.py

* Fix SyntaxError

* Don't pass "No reason was given." to modlog case

* Update settings.py

* Update 2990.enhance.rst

* black

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
Co-authored-by: DevilXD <DevilXD@users.noreply.github.com>
2020-01-26 04:18:13 +01:00
Michael H
2ac4dde729 update for d.py 1.3 (#3445)
* update for d.py 1.3

* Update redbot/core/commands/commands.py

Co-Authored-By: Danny <Rapptz@users.noreply.github.com>

* a few more places we use owner info

* add the cli flag + handling

* set fix

* Handle MaxConcurrencyReached.

* Bump `aiohttp-json-rpc`

Co-authored-by: Danny <Rapptz@users.noreply.github.com>
Co-authored-by: Kowlin <Kowlin@users.noreply.github.com>
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-01-25 18:59:08 -05:00
Michael H
498d0d22fb resolves #3443 (#3447) 2020-01-25 18:57:07 -05:00
jack1142
2a38777379 [Downloader] Do the initialization in task to avoid timeout on bot startup (#3440)
* enhance(downloader): run init in task

* chore(changelog): add towncrier entry

* fix: address review
2020-01-24 12:38:42 -05:00
jack1142
01c1fdfd16 [Mod] Make [p]hackban use default days setting too. (#3437)
* Update kickban.py

* freaking whitespace
2020-01-24 10:30:32 +00:00
Draper
0a8e7f5663 stop dc interacting with repeat (#3426) 2020-01-23 17:05:50 -05:00
Ianardo DiCaprio
1755334124 [Mod] Default days in [p]ban command are now configurable (#2930)
* Initial Commit

* Added changelog

* Update redbot/cogs/mod/settings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/settings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/settings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Update redbot/cogs/mod/settings.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Rename 2930.enhance.rst.txt to 2930.enhance.rst

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-01-23 20:37:11 +01:00
zephyrkul
40c0d8d83b [systemd] fix which cmd for pyenv (#3434) 2020-01-22 23:20:35 -05:00
DevilXD
ee53d50c3a Help delete pages delay feature (#3433)
* Added 'deletedelay' feature for help

* Fixes

* More fixes

* Use better message when disabling

* Added changelog entry

* Addressed feedback

* Improved the pages check

* Added additional command check

* Improved command description

* Final feedback improvements
2020-01-22 17:15:51 -05:00
Stonedestroyer
8570971f68 [Core] Make bot name adjustable in bot. (#3429)
* First draft

* Up for discussion

* Revert "Up for discussion"

This reverts commit 2f00b7ded8.
2020-01-22 12:52:06 -05:00
Stonedestroyer
e1a110b1bf [Misc] Typo fixes (#3427)
* [Misc] Typo fixes

* Changelog

* Trivia list

* Update 3427.misc.rst

* Changelog
2020-01-22 10:00:52 +00:00
Michael H
77235f7750 [commands] Implement __call__ to commands.Command (#3241)
* This is technically awesome, but let's not document it for public use rn

* changelog
2020-01-20 23:23:15 +01:00
jack1142
c7fd64e0c8 [Downloader] Improve InstalledCog converter's error message (#3409)
* Update converters.py

* Create 3409.misc.rst
2020-01-20 17:09:55 -05:00
Flame442
8f04fd436f Catches discord.NotFound in utils.mod.mass_purge (#3414)
* Catches `discord.NotFound` in `mass_purge`

* Create 3378.bugfix.rst
2020-01-20 17:09:17 -05:00
Stonedestroyer
b085c1501f [General] Max amount to roll (#3395)
* [General] Rolls max amount

Adds max amount to roll.

* Removed redundant code.

* QA changes

* Add typehinting.
2020-01-20 16:49:46 -05:00
Stonedestroyer
7f390df879 [Customcom] Fix error on exiting customcom interactive menu. (#3417)
* [Customcom] Fixes error on exit

* Changelog

* Fixed spelling.

* Typehinting
2020-01-19 18:08:31 +01:00
Flame442
54e65082bc [Admin] Notify when the user has/doesn't have the role when att… (#3408)
* Update admin.py

* Create 3010.enhance.rst
2020-01-18 18:10:25 +00:00
Michael H
826dae129e dev bump (#3406) 2020-01-17 20:23:16 -05:00
jack1142
12da3bd89e Update changelog_3_2_0.rst (#3405) 2020-01-17 20:06:32 -05:00
Michael H
b089be7b49 fixup docs (#3404) 2020-01-17 19:57:27 -05:00
Michael H
33ea3a1419 version bump w/changelog (#3403) 2020-01-17 19:47:22 -05:00
Stonedestroyer
66cae71d90 [Docs] Changed python version references on docs (#3402)
* [Docs] Changes Python references to Python 3.8

* [Misc] Remove obsolete mention to Zenhub
2020-01-18 01:05:39 +01:00
Michael H
6219f0da67 [Modlog API] Add resolution for people inpacted by bad casetypes (#3333)
* add resolution for people inpacted by bad casetypes

* *some* amount of notice on this

* Fine.

* clearer warnings

* actually, unnneded
2020-01-17 18:51:49 -05:00
Michael H
7f2e5a0b70 [Docs] Remaining doc improvements for 3.2.3 (#3400)
* double the fun

* double

* pluralize this
2020-01-17 18:00:24 -05:00
Michael H
d52f8974fd Stop special casing help in bot.embed_requested (#3382)
- However, we are not changing the signature
  - This was previously special cased for reasons related to the older
  version of the help formatter we used and never re-evaluated for need.
  - We should leave the signature as is both for lack of breaking, and
  for potential future changes

// actually this was already done once in GH-2966 but got accidentally overwritten
2020-01-17 23:59:37 +01:00
Draper
2c12e4f6bf [Audio] Show symbolic link folders (#3376)
* Fixes Bump play

* Fixed #3332

* Revert "Fixed #3332"

This reverts commit d76d3acb

* Revert "Fixes Bump play"

This reverts commit 3839bdaf

* *sigh*

* *sigh*

* *sigh*

* use iglob + async iterator

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

*  + fixes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-17 17:07:49 -05:00
Michael H
b88bd5d44d More exit tweaks (#3392) 2020-01-17 23:07:34 +01:00
Draper
41b283ce5d [Audio] Show correct time remaining for bumped tracks (#3375)
* Fixes Bump play

* *sigh*
2020-01-17 17:00:29 -05:00
Michael H
cd7f4681a4 Cache prefixes (#3150)
* Cache prefixes

 - This works towards #3148
 - Ends up centralizing some logic
   - Including that prefixes should be a reverse sorted list

* handle global prefix attempts at none

* fix prefix set for server

* cache using guild id
2020-01-17 16:49:25 -05:00
jack1142
d1b7f836db Update auto_labeler.yml (#3396) 2020-01-17 22:45:41 +01:00
Draper
3d1e6eab00 [Audio] Add backticks to commands in docstrings, fix GH-3140 (#3374)
* docstring change

* remove backticks

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Seems like i cant read

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Rename 3140.enchance.1.rst to 3140.enhance.1.rst
2020-01-17 22:30:29 +01:00
Stonedestroyer
48ccd9070c [Core] Adds server IDs to servers command. (#3393)
* [Core] Adds server ID to servers command.

* Changelog
2020-01-17 06:08:31 -05:00
jack1142
67fbcb1b4a enhance(downloader): pagify any output that might be too long (#3388) 2020-01-17 04:44:10 -05:00
Stonedestroyer
a203fe34cf [Typo Fix] Permissions (#3390)
* [Typo Fix] Permissions

* Changelog file
2020-01-17 04:43:37 -05:00
Michael H
85438e7454 [Setup] Fix data deletion. (#3384)
* I'm ready to 🔪 some of these entrypoints

* If we're gonna teardown here, may as well do it right
2020-01-17 01:09:09 +01:00
Redjumpman
d6d14617d2 Update __init__.py (#3381)
Removed redundant check.
2020-01-16 13:18:20 -05:00
jack1142
a1b95e5072 enhance(downloader): log git commands that failed (#3372) 2020-01-15 20:54:23 -05:00
jack1142
29feab638a Update install_linux_mac.rst (#3371) 2020-01-15 20:45:35 -05:00
Michael H
60dc54b081 Allow pre_invoke to be used by 3rd party cogs safely. (#3369)
* Okay, so there's a lot in this diff

* fix docstrings

* meh

* fix misleading var name

* meh...

* useful typehints

* Apply suggestions from code review

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* dep warn in locations suitable

* Fix this...

* Apply suggestions from code review

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-01-15 20:44:21 -05:00
flaree
27e6f677e8 [Docs] Modlog Example: action -> action_type (#3368)
* action -> action_type

* Changelog.
2020-01-14 22:15:55 -05:00
jack1142
d8199201a5 [Changelog] Clarify breaking change related to setup() function (#3367)
* Update changelog_3_2_0.rst

* Update changelog_3_2_0.rst

* Update changelog_3_2_0.rst
2020-01-14 22:14:20 -05:00
Michael H
a7f0e2b7c6 Globally ensure send_messages for commands (#3361)
* wew

* typo fix, thanks Danny
2020-01-14 17:42:40 -05:00
jack1142
79dcd22ff6 Update bank.py (#3366) 2020-01-14 12:53:28 -05:00
jack1142
2be4080bc6 stop messing with distutils's internal just to copy directory (#3364) 2020-01-14 12:52:18 -05:00
jack1142
b646c2fd98 [Docs] Add links to operating systems + minor readability improvements (#3365)
* add operating systems links + some minor readability improvements

* meh, let's add this too, draper
2020-01-14 11:54:44 -05:00
Dav
90c0f76ae4 [Warnings] Make [p]warnings usable on base of permissions (#3327)
* new code

Added the admin check to warnings and removed the part where the user could check themselves.

Added new mywarns which replaces part of the old behaviour of warn

* Update warnings.py

* Create 2900.enhance.rst

* Fixed command name

Because appearently I can't remember a command for 10 seconds

* Commands in backticks

Put command names in changelog in double backticks after being advised to do so in discord

* made user not optional, and the other thing sinbad requested

* switched parts. magic

resolves #2900
2020-01-13 17:57:39 -05:00
Michael H
3c53b89040 [Help] formatting additions (#3339)
* formatting additions

* I really need to redo this module later

* fix some casing
2020-01-13 11:50:45 -05:00
Michael H
a7987a83fd Exit code handling (#3360)
* Exit code handling

* clear up a docstring
2020-01-13 11:37:49 -05:00
Michael H
ef8b57a1d2 Add a command to set the bot description (#3340)
* description-command

* Cap the description length

* mmk
2020-01-13 10:12:31 -05:00
Michael H
ab2e87a8fb Start making use of typehints for devs (#3335)
* Start making use of typehints for devs

* changelog
2020-01-13 09:46:05 -05:00
jack1142
088360ec51 Make Red shutdown when resetting token (#3358)
* Update __main__.py

* Update __main__.py
2020-01-12 20:26:01 -05:00
Draper
7bdd177713 [3.2.3][Audio] Correct an unsupported LoadType (#3337)
* Limit Playlists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* logging improvements

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* logging improvements

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* sigh

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-12 18:35:49 -05:00
Draper
81b6d5bb93 why the hell is this here (#3357)
Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-12 18:35:23 -05:00
jack1142
5eb4bda600 Update install_linux_mac.rst (#3336) 2020-01-12 18:25:01 -05:00
jack1142
cb49c5d420 [Downloader] Improve partial-uninstall message in [p]cog uninstall (#3343)
* Update downloader.py

* Let's use more of Flame's suggestions.

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-01-12 18:21:00 -05:00
Draper
a984971774 [3.2.3][Audio] Fixes some Playlists strings (#3347)
* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-12 18:20:31 -05:00
Draper
9f027cc3e0 [3.2.3][Audio] Improved Playlist cooldowns (#3342)
* Improved Playlist cooldowns

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Improved Playlist cooldowns

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* formatting

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-12 18:19:36 -05:00
Flame442
fe7770c833 [Admin] Fixes hierarchy issues in [p]selfrole and [p]selfroleset (#3331)
* More fixes

* Update admin.py
2020-01-12 18:01:45 -05:00
Draper
8514dbe96a [3.2.3][Docs]Only support venv and virtualenv users (#3351)
* Limit Playlists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* docs

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* jack

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* update pip

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* flame's review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-12 17:42:59 -05:00
Draper
ed76454ddb ... (#3350)
Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-12 17:42:17 -05:00
jack1142
54711b2054 [Docs] Update autostart guides to use -O flag (#3354)
* Update autostart_systemd.rst

* Update autostart_pm2.rst
2020-01-12 17:41:29 -05:00
Draper
fdfbfe7b60 [3.2.3][Audio] Full fix for #3328 (#3355)
* Limit Playlists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Hotfix

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Hotfix

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* [Audio] Hotfix an edge case where an attribute error can be raised (#3328)

* Limit Playlists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Hotfix

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Hotfix

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* flame's review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Delete 3328.hotfix.1.rst

* lets be extra safe here

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-12 17:37:50 -05:00
Draper
d6936c87f3 chore (#3348)
Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-12 17:37:04 -05:00
Michael H
a105217e83 Merge pull request #3356 from mikeshardmind/temp-branch
Merge an audio dix into dev
2020-01-12 17:28:31 -05:00
Draper
e52c20b9e7 [Audio] Hotfix an edge case where an attribute error can be raised (#3328)
* Limit Playlists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Hotfix

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Hotfix

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-12 16:20:46 -05:00
jack1142
4754160055 [Docs] Update Debian/Raspbian instructions (#3352)
* Update install_linux_mac.rst

* Update install_linux_mac.rst

* Update install_linux_mac.rst
2020-01-12 16:08:34 -05:00
jack1142
d2b9504c3b [Docs] Add "Fork me on GitHub" ribbon (#3306)
* docs: add "Fork me on GitHub" ribbon

* chore(changelog): add towncrier entry
2020-01-12 11:13:58 -05:00
Michael H
b0b76c5a00 *exasperated sighs* (#3326) 2020-01-10 06:46:18 -05:00
Michael H
deab24e916 3.2.2 (#3324)
* page sizing changes

* docs
2020-01-10 06:43:35 -05:00
Michael H
2bb9b87db9 dev bump (#3322) 2020-01-10 00:14:06 -05:00
Michael H
5bd044d646 3.2.1 Hotfix (#3321) 2020-01-10 00:10:59 -05:00
Michael H
371292e03a prevent an empty iterable issue (#3320) 2020-01-10 00:04:12 -05:00
Michael H
acc5baec7d possible mongo fix (#3319)
* possible mongo fix

* prevent swallowing the exception

* better log str
2020-01-09 23:56:05 -05:00
Michael H
ed692bcaa5 This shouldn't be possible normally, but we've have enough issues with it (#3318) 2020-01-09 19:20:34 -09:00
Michael H
7352f76b87 mark dev (#3315) 2020-01-09 22:36:45 -05:00
Michael H
ad505b2b2f Version 3.2.0 (#3314)
* Thanks Caleb!

* version bump
2020-01-09 18:24:04 -09:00
Flame442
6ce421363d Grammar and content fixes for the 3.2 changelog (#3313)
* yall need better grammar...

* Update changelog_3_2_0.rst

* Delete 2940.enhancement.1.rts

* Delete 2940.enhancement.2.rst

* Delete 3058.enhancement.rst

* Delete 2924.fix.rst

* Delete 2945.fix.rst

* Delete 3060.fix.rst

* Delete 3069.fix.rst
2020-01-09 22:14:38 -05:00
Michael H
248259b312 Revert "remove the ugly dep handling (#3311)" (#3312)
This reverts commit f010df7082.
2020-01-09 20:48:23 -05:00
Michael H
f010df7082 remove the ugly dep handling (#3311) 2020-01-09 20:11:30 -05:00
Michael H
69e2ebf2e7 [docs] Proofreading based updates to release notes (#3310)
* updates thanks to proofreading by draper

* more
2020-01-09 18:19:31 -05:00
Michael H
c852505a62 Release notes (#3309) 2020-01-09 17:46:35 -05:00
Michael H
d3e8d99bdf [3.2.0] Changelog (#3303)
* changelog

* refs
2020-01-09 12:59:55 -05:00
jack1142
a9d3e271b0 [Docs] Update Linux install guides for python 3.8.1 (#3302)
* Update install_linux_mac.rst

* Update install_linux_mac.rst
2020-01-09 12:43:05 -05:00
Michael H
139119e954 kill the changelog check, we'll GH Action it (#3301) 2020-01-09 12:20:51 -05:00
Michael H
09a3a87cef update black target version (#3300) 2020-01-09 11:35:19 -05:00
jack1142
83e93916e8 [CI Docs] Allow linkcheck to retry before declaring link broken (#3276)
* Update conf.py

* Create 3276.misc.rst
2020-01-09 17:13:49 +01:00
Draper
3546dd14d0 change executor to 1 (#3299)
* Limit Playlists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* 1

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-09 11:13:32 -05:00
Draper
e75b5b3be5 Limit Playlists (#3298)
Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-09 11:10:57 -05:00
Michael H
ed3b4e5b29 Embed pagination fixing (pt2) (#3248)
* I hate embeds

* changelog

* until splitting the fields, ensure a field

* make this work, from a user perspective
2020-01-09 16:50:04 +01:00
Michael H
9698baf6e7 [3.2.0 Docs] Some clarifications (#3292)
* docs

*  changelog

* Fix python for choco

* k

* little more
2020-01-09 16:16:10 +01:00
Michael H
26677004f1 Handle regression in redbot edit (#3297)
* fixes #3296

* changelog

* k

* @Kowlin

* *sigh*
2020-01-09 16:14:38 +01:00
Michael H
25f0c37a20 jar-bump (#3291) 2020-01-09 09:38:34 -05:00
jack1142
ab3b567cd8 [Core] Use owner set in config (#3294)
* Update bot.py

* Create 3293.misc.rst

* style: forking whitespace
2020-01-09 08:52:34 -05:00
Michael H
a0f548fc0b minimize the launcher (#3289)
* minimize the launcher

* changelog
2020-01-09 08:51:17 -05:00
Kowlin
e3720bb4a6 Updated to GH Scripts (#3295) 2020-01-09 14:09:41 +01:00
Michael H
b35b8d98c3 bump red lavalink (#3290) 2020-01-08 20:05:25 -05:00
Michael H
2612453597 [3.2.0] dep update (#3288)
* dep update

* changelog + 1 which was previously missed
2020-01-08 18:35:01 -05:00
Flame442
42d83e80a3 [Trivia] Fix various things changed by game updates (#3236)
* Fix various things changed by game updates

* oops...

* Create 3236.bugfix.rst
2020-01-08 18:20:59 -05:00
Draper
44e680ee41 [3.2]Audio] some hotfixes to avoid crashing the bot (#3286)
* Add a command to toggle daily queues, and  restrict playlist length to 10k tracks and try to avoid some blocking calls

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Add a command to toggle daily queues, and  restrict playlist length to 10k tracks and try to avoid some blocking calls

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* indents

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* forgot single tracks

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* formatting plus some other fixes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* formatting plus some other fixes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-08 17:04:52 -05:00
Michael H
965416de73 [Docs] Ensure users have setuptools and wheel (#3262)
* Ensure users have setuptools and wheel

* changelog
2020-01-08 19:44:33 +01:00
Michael H
1c75c47a9c Allow migrating away from mongo (#3253)
* Restore mongo driver

* make it possible to convert

* style

* add in known issues with other backends while at it
2020-01-08 13:41:35 -05:00
Michael H
35c27c5741 Be quieter in expected shutdown cases (#3261)
* Be quieter in expected cases

* lets put this in the log file

* inline description use because setuptools entrypoint scripts are dumb

* Another setuptools entrypoint related issue

* maybe don't crash the bot on tasks

* improve the handling a bit more + document some of the lower level bits from the perspective of 'why?'

* Adding myself to codeowners on this one

* Let's not clobber our exit code

* And, there we go

* finish that thought

* right, I bumped the python version for (part of) this

* Update redbot/__main__.py

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* Okay, we should be good now

* correct exit code enum use

* cosmetic

* minor fix for linux and ctrl+c

Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-01-08 19:39:52 +01:00
jack1142
af859aa755 [Downloader] Move author key handling to RepoJSONMixin, fix NameError (#3285)
* Update downloader.py

* Update json_mixins.py

* Update installable.py

* changelog pt 1

* changelog pt2

* edit of changelog pt1

* edit of changelog pt 2 (last commit before review)

* Kidding, this is the last one before review.
2020-01-08 13:08:55 -05:00
Kowlin
f5949f2664 Cleaning up the Flake8 workflow (#3283) 2020-01-08 12:24:27 -05:00
Kowlin
96e9e55642 Added an auto labeler. (#3282) 2020-01-08 12:21:42 -05:00
Michael H
778c701b87 May as well handle that part... (#3281) 2020-01-07 17:47:54 -05:00
Michael H
a73b174d9f update translation catalogs (#3280) 2020-01-07 17:16:21 -05:00
Draper
17123c1d88 [3.2][Audio] Add a limiter of 500 to the Visible queue (#3279)
* Add a limited of 500 to the Visible queue and somce asyncio sleep every n tracks to assist with queue loading so it stops being blocking

* add a text for queue

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* add asyncio sleep on playlist queue command

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Better error handling for large playlists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* remove files even if it errors

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2020-01-07 16:33:10 -05:00
zephyrkul
45860ca2a6 [CustomCom] Use humanize_list for iterable arguments (#3277)
* [cc] use humanize_list on lists

* [cc] need classmethod

* add changelog
2020-01-06 16:49:08 -05:00
jack1142
d3c97eedfe [Downloader] Fix AttributeError in [p]findcog for cogs that weren't installed through Downloader (#3278)
* Update downloader.py

* Create 3278.misc.rst
2020-01-06 16:48:43 -05:00
jack1142
a2b68ea7fc [Docs] Update Python version for docs (#3258)
* Update .readthedocs.yml

* Create 3258.misc.rst
2020-01-06 07:13:55 -05:00
Draper
62aad10008 [3.2][Audio] Database migration fix (#3275)
* Missed this due to the mess of a fork i had

* chore
2020-01-06 05:28:56 -05:00
jack1142
474bb0904e [Core, Downloader] Clear lib folder on minor Python version change, add [p]cog reinstallreqs command (#3274)
* feat(downloader): add `[p]cog reinstallreqs` command

* enhance: clear lib folder on minor Python version change

* chore(changelog): add towncrier entries

* enhance: warn user about detected change in OS or arch

* enhance: use actual prefix instead of `[p]`

* Whoops...

Co-Authored-By: Michael H <michael@michaelhall.tech>

* enhance: wrap message sending in try except

Co-authored-by: Michael H <michael@michaelhall.tech>
2020-01-05 19:21:49 -05:00
jack1142
b0f840c273 [Core] Add Red.wait_until_red_ready() function to wait until post connection startup is done (#3273)
* enhance: add `Red.wait_until_red_ready()` for post connection startup

* enhance: fill `bot.owner_id` in our `on_ready`

* enhance: log missing destinations in `get_owner_notification_destinations`

* chore(changelog): add towncrier entries

* chore(changelog): use past form of verb "add"
2020-01-05 18:38:59 -05:00
Michael H
9ec78d1455 Fix ctx.clean_prefix for *new* discord behavior (#3249)
* I just love when discord changes important syntax without warning

  - sarcasm approaching dangerous levels

* changelog
2020-01-04 14:08:35 -05:00
jack1142
f2d2b9a682 [Setup] Stop logging to disk (#3269)
* Update setup.py

* Create 3269.enhance.rst

* Update 3269.enhance.rst
2020-01-04 02:10:19 -05:00
Michael H
23fe991c36 Update games.yaml (#3268) 2020-01-04 01:34:35 -05:00
Michael H
d9d2e0017e patchup name error from 3254 (#3267) 2020-01-04 00:39:48 -05:00
jack1142
b6ca8f7d2c [Core] Escape markdown in python executable path in `[p]debuginfo` command. (#3254)
* Update core_commands.py

* Create 3254.misc.rst
2020-01-03 22:44:33 -05:00
jack1142
cacfa163ce [Docs] Fix broken docs for commands.Context.react_quietly (#3257)
* Update context.py

* Create 3257.docs.rst
2020-01-03 22:43:00 -05:00
Michael H
d00609bb8a pyflakes (#3266) 2020-01-03 22:22:10 -05:00
Draper
b59f136ece [3.2.0][Audio] Daily playlist (#3199)
* Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now
`[p]bankset maxbal` can be used to set the maximum bank balance

Signed-off-by: Guy <guyreis96@gmail.com>

* Initial Commit

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* I need to make sure I keep aika on her toes.

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Fixes a few missing kwargs and case consistency

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Fixes a few missing kwargs and case consistency v2 and typos

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Reset cooldowns + add changelogs

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Add 3 extra file formats.

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* IRDUMB - fix capitalization.

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Fix a silent error, and some incorrect messages.

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Remove unnecessary emojis from queue when they are not needed

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Remove duplicated call in `[p]playlist update`

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Remove duplicated call in `[p]playlist update`

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Resolve conflicts

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Bring all files up to date + Black

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Facepalm

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* *Sigh*

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* *Sigh* 2.0

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-DiscordBot into audio-misc-pt1

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

# Resolve Conflicts:
#	redbot/cogs/audio/audio.py
#	redbot/cogs/audio/utils.py

* Import missing Typecheck

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix Broken docstrings

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Sort Local Tracks

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* 🤦

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Reorder the sorting of local tracks,
`alphanumerical lower then alphanumerical upper`
`a comes before A, but B comes after A`

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black formatting

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Make the local file sorting case insensitive

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Add global blacklist/whitelist + fix some issues with original server based whitelist/blacklist

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove the pre-commit yaml

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Nottin to see

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Further improvement to the blacklists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Further improvement to the blacklists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix  the __str__ method on LocalTracks Object

* Rename LocalTracks.to_string_hidden() to LocalTracks.to_string_user() To keep it inline with the Query object

* Remove encoding pragmas + a few typo fixes

* Update some typehints + fix some typos

* Remove this duplicate call

* Black

* fix capitalization

* Address preda's review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove the API from the audio cog

 - Is in direct conflict with goals stated in #2804
 - Features this was intended to enable can be enabled in other more
 appropriate ways later on

* changelog

* Address Aika's review

* Black

* *sigh* dont use github web ui

* Fuck windows Long live linux... *sigh* no lets ensure windows users can still use local tracks

* Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-DiscordBot into refactoring

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

# Conflicts:
#	redbot/cogs/audio/audio.py

* 👀 + chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* facepalm

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* facepalm... again y u h8 me bruh

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fuk this fuk u tube fuck python fuck all

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* awyehfqwajefhnqeffawefqa eqewarfqaesf qwef qaf qwfr

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fuck everything

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* oh lord saviour resus i love you just make this work

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Change logic to be no errors within last 10 seconds... this should be a valid work around discord ratelimits caused by the spam

* Remove auto deletion

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* See I did a ting

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* irdumb

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Add an is_url attribute to Query objects

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black

* Address Aikas review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Hyperlink Playlist names

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Make shit bold

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* why was this here

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* why was this here

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Initial commit

* Workinnng

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Improve SQL Statements +  migrate from SQL Alchemy + Databases to APSW

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* apsw tested and working

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chose

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Migrate Playlist to DB 3 TODO
1 Migrate Config to Schema 3 without playlists
and update get_playlist methods

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Revert "Migrate Playlist to DB 3 TODO 1 Migrate Config to Schema 3 without playlists and update get_playlist methods"

This reverts commit 4af33cff

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Implement schema migration

* Lets not touch the deps since #3192 is already adding them

* chore

* *sigh* Black

* Follow the existing logic and always default Playlist to guild scope

* wghqjegqf black

* Update usage of last_fetched and last_updated to be Ints... However column migration still pending

* Some bug fixes

* Update usage of last_fetched and last_updated to be Ints... However column migration still pending

* working

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* partial match

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* better partial match

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* I thought i done this before

* Delete 3195.misc.1.rst

Wrong PR

* Thanks Sinbad

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Thanks Sinbad

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Log Errors  in init ...

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Update error logs.

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Create index

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Create index

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* :Drapersweat:

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Revert "Chore"

This reverts commit edcc9a9f

UGHHHH

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* KMS

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Allow removing tracks from queue by URL

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Words matter

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh*

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* arghhh CONFLICTS

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Review sinbads latest comment ..

ToDo.. Nuke existing playlist - check version and set version

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* migrate the DB schema to v3 (to keep in line with the schema visioning of Config

* Add a Todo

* *sigh* conflicts and black

* *sigh* black

* Passively delete playlist deletion mechanism

* Delete Old entries on startup

* Since we are dropping the table mightaware make these into JSON for future proofing

* Don't Dump strings in JSON field ? :think:

* Move some things around to make easier to use 1 connection to the Audio DB

* Move some things around to make easier to use 1 connection to the Audio DB

* *sigh*

* Clean up api

* *sigh* black

* Red + reorder some variables

* 🤦

* how could i forget this .......

* Black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* #automagically

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* FINAFUCKINGLY

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* FINAFUCKINGLY

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove unused config default

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove the API from the audio Cog (Properly)

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Missed these changes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* ARGHHH

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Crerrypick - Some fixes I've noticed while running through the code line by line

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Translation + UX (show playlist author ID if can't find user)

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* missed this one

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* this is no longer needed ....

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Im a fucking idiot

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* merger v3/develop

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

Co-authored-by: Michael H <michael@michaelhall.tech>
2020-01-03 21:58:11 -05:00
Michael H
25999cea10 Docs fix (2) (#3265)
* Fix docs building

* And 1
2020-01-03 21:48:28 -05:00
Draper
95e8d60729 [3.2][Audio] Part 6 (Last? maybe?) (#3244)
* Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now
`[p]bankset maxbal` can be used to set the maximum bank balance

Signed-off-by: Guy <guyreis96@gmail.com>

* Initial Commit

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* I need to make sure I keep aika on her toes.

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Fixes a few missing kwargs and case consistency

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Fixes a few missing kwargs and case consistency v2 and typos

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Reset cooldowns + add changelogs

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Add 3 extra file formats.

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* IRDUMB - fix capitalization.

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Fix a silent error, and some incorrect messages.

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Remove unnecessary emojis from queue when they are not needed

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Remove duplicated call in `[p]playlist update`

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Remove duplicated call in `[p]playlist update`

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Resolve conflicts

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Bring all files up to date + Black

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Facepalm

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* *Sigh*

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* *Sigh* 2.0

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-DiscordBot into audio-misc-pt1

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

# Resolve Conflicts:
#	redbot/cogs/audio/audio.py
#	redbot/cogs/audio/utils.py

* Import missing Typecheck

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix Broken docstrings

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Sort Local Tracks

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* 🤦

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Reorder the sorting of local tracks,
`alphanumerical lower then alphanumerical upper`
`a comes before A, but B comes after A`

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black formatting

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Make the local file sorting case insensitive

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Add global blacklist/whitelist + fix some issues with original server based whitelist/blacklist

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove the pre-commit yaml

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Nottin to see

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Further improvement to the blacklists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Further improvement to the blacklists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix  the __str__ method on LocalTracks Object

* Rename LocalTracks.to_string_hidden() to LocalTracks.to_string_user() To keep it inline with the Query object

* Remove encoding pragmas + a few typo fixes

* Update some typehints + fix some typos

* Remove this duplicate call

* Black

* fix capitalization

* Address preda's review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove the API from the audio cog

 - Is in direct conflict with goals stated in #2804
 - Features this was intended to enable can be enabled in other more
 appropriate ways later on

* changelog

* Address Aika's review

* Black

* *sigh* dont use github web ui

* Fuck windows Long live linux... *sigh* no lets ensure windows users can still use local tracks

* Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-DiscordBot into refactoring

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

# Conflicts:
#	redbot/cogs/audio/audio.py

* 👀 + chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* facepalm

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* facepalm... again y u h8 me bruh

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fuk this fuk u tube fuck python fuck all

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* awyehfqwajefhnqeffawefqa eqewarfqaesf qwef qaf qwfr

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fuck everything

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* oh lord saviour resus i love you just make this work

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Change logic to be no errors within last 10 seconds... this should be a valid work around discord ratelimits caused by the spam

* Remove auto deletion

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* See I did a ting

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* irdumb

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Add an is_url attribute to Query objects

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black

* Address Aikas review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Hyperlink Playlist names

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Make shit bold

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* why was this here

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* why was this here

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Initial commit

* Workinnng

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Improve SQL Statements +  migrate from SQL Alchemy + Databases to APSW

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* apsw tested and working

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chose

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Migrate Playlist to DB 3 TODO
1 Migrate Config to Schema 3 without playlists
and update get_playlist methods

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Revert "Migrate Playlist to DB 3 TODO 1 Migrate Config to Schema 3 without playlists and update get_playlist methods"

This reverts commit 4af33cff

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Implement schema migration

* Lets not touch the deps since #3192 is already adding them

* chore

* *sigh* Black

* Follow the existing logic and always default Playlist to guild scope

* wghqjegqf black

* Update usage of last_fetched and last_updated to be Ints... However column migration still pending

* Some bug fixes

* Update usage of last_fetched and last_updated to be Ints... However column migration still pending

* working

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* partial match

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* better partial match

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* I thought i done this before

* Delete 3195.misc.1.rst

Wrong PR

* Thanks Sinbad

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Thanks Sinbad

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Log Errors  in init ...

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Update error logs.

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Create index

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* :Drapersweat:

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Revert "Chore"

This reverts commit edcc9a9f

UGHHHH

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Allow removing tracks from queue by URL

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Words matter

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh*

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* arghhh CONFLICTS

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Review sinbads latest comment ..

ToDo.. Nuke existing playlist - check version and set version

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* migrate the DB schema to v3 (to keep in line with the schema visioning of Config

* Add a Todo

* *sigh* conflicts and black

* *sigh* black

* Passively delete playlist deletion mechanism

* Delete Old entries on startup

* Since we are dropping the table mightaware make these into JSON for future proofing

* Don't Dump strings in JSON field ? :think:

* Move some things around to make easier to use 1 connection to the Audio DB

* Move some things around to make easier to use 1 connection to the Audio DB

* *sigh*

* Clean up api

* *sigh* black

* Red + reorder some variables

* 🤦

* how could i forget this .......

* Black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* #automagically

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* FINAFUCKINGLY

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* FINAFUCKINGLY

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove unused config default

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove the API from the audio Cog (Properly)

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Missed these changes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* ARGHHH

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Some fixes I've noticed while running through the code line by line

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Translation + UX (show playlist author ID if can't find user)

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* missed this one

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* this is no longer needed ....

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* 🤦

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fix new lines in error messages

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black

* Sinbads Review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Sinbads Review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* copy paste

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* imrpove backups

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Im a fucking idiot

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix #3238

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* humans

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* humans

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* add play alias to playlists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Im dumb ...

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Im dumb ...

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fix new line

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fix new line

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* show playlist count on playlist picker

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* DJ/Vote system fixes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* DJ/Vote system fixes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* fix currency check

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* show playlist count on playlist picker

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* DJ/Vote system fixes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* DJ/Vote system fixes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* fix currency check

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix duplicate messages on timeout

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fix SQL Statement logic

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fix SQL Statement logic

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Markdown escape

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Markdown escape

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Markdown escape fix

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Markdown escape fix

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* clean up local cache more frequently

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* clean up db more frequently

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Await in hell

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* im dumb

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* im dumb

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black cuz I hate red

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black cuz I hate red

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* StringIO to ByteIO

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* StringIO to ByteIO

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* im dumb

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* :Facepalm: the whole purpose of this is so its offline so this can be backed up without being blocking

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Run write queries on ThreadPoolExecutor

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Backup Audio.db

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* im dumb

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* blaaaack

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh*

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* formatting

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* remove duplicated string of code

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* ffs awaits

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

Co-authored-by: Michael H <michael@michaelhall.tech>
2020-01-03 20:36:09 -05:00
Michael H
1d2dd19244 Fix docs building (#3263) 2020-01-03 19:13:14 -05:00
PredaaA
743ce71c5c [Streams] Fix TypeError in TwitchStream class and change stream_alert function for Twitch (#3042)
* Update streamtypes.py

* Create 3042.bugfix.rst

* Black the things.

* Fix Twitch streams alert and [p]streamalert twitch

* Update 3042.bugfix.rst
2020-01-02 19:28:57 -05:00
jack1142
42e3f73088 [Core] Fix missing `await in code of redbot --edit`. (#3256)
* Update __main__.py

* Create 3256.misc.rst
2020-01-02 18:53:40 -05:00
Kowlin
ec6877dbc6 Update the licence info to 2020 (#3259)
* We're somewhat on time for once!

* Helps to update RTD

* Added changelog
2020-01-02 18:37:26 -05:00
Jonas Bohmann
c8f753db0d Fix typo '.foramt()' -> '.format()' in cogs/admin/admin.py (#3255)
* Fix typo '.foramt()' -> '.format()'

* Add changelog file
2020-01-02 12:48:13 -05:00
Flame442
e776b5ca1a [Admin] Code prettification and bugfixing (#3250)
* Facelift for Admin

* Remove unnecessary converter, reorder existing steps

* Delete admin.py

* Delete __init__.py

* Delete test_admin.py

* Remove one extra unneeded check

* Create 3250.bugfix.1.rst

* Create 3250.bugfix.2.rst

* Create 3250.bugfix.3.rst

* Create 3250.bugfix.4.rst

* Create 3250.misc.1.rst

* Create 3250.misc.2.rst

* Create 3250.misc.3.rst

* Create 3250.breaking.1.rst

* Create 3250.breaking.2.rst

* ...

* I hate black...
2020-01-02 09:11:27 -05:00
jack1142
36e2cde04d Move [p]backup command to cli command - redbot-setup backup (#3235)
* refactor: replace backup command with cli command

* chore(changelog): add towncrier entries
2020-01-02 09:03:32 -05:00
jack1142
f3e7c2028c [Setup] Use instance name in default data path (#3171)
* enhance(setup): use instance name in default data path

* chore(changelog): add towncrier entries

* enhance(setup): tell user that instance name is case-sensitive
2020-01-02 08:59:22 -05:00
jack1142
f3c57b6730 [Docs] Fix driver docs showing twice (#3035)
* docs(config): fix doubled docs for drivers

* enhance(drivers): add docstrings to enums that show in docs

* chore(changelog): add towncrier entries
2020-01-02 08:54:25 -05:00
jack1142
bc90f5186a [Downloader] Actually use disabled key in updates (#3203)
* fix(downloader): actually use disabled key in updates

* chore(changelog): add towncrier entry
2020-01-02 08:49:31 -05:00
jack1142
62b679b1b9 Replace links to v3-develop docs with links to stable docs (#3186)
* Update customcom.py

* Update permissions.py

* Create 3186.docs.rst

* Create 3186.docs.rst

* Rename 3186.docs.rst to 3186.misc.rst

* Rename 3186.docs.rst to 3186.misc.rst
2020-01-02 08:48:33 -05:00
jack1142
ab747d2432 [Utils] Privatize internal utils (#3240)
* refactor(utils): privatize some utils

* chore(changelog): add towncrier entry

* refactor: update internal utils imports
2020-01-02 08:44:55 -05:00
jack1142
debed501b2 [Docs] Remove API Reference for downloader, add page about publishing cogs (#3234)
* docs: add info about publishing cogs, remove downloader reference

Co-authored-by: Redjumpman <Redjumpman@users.noreply.github.com>

* chore(changelog): add towncrier entries

* docs: fix broken reference in 3.1.0 changelog

Co-authored-by: Redjumpman <Redjumpman@users.noreply.github.com>
2020-01-02 08:28:50 -05:00
Michael H
a80e20067c do better with loop cleanup (#3245)
* do better with loop cleanup

* changelog

* remove redundant line

* Do this a bit better than the initial pass

* Improve windows support

Make some other things coroutines to work with improved design

* Wish we'd have done this right from the start...

* Update deps surrounding this

 - see bpo-23057
 - neccessary for windows users
 - nice for consistent support channel info / feature availability

* dep issue

* Fix tests

* duplication plugin py version

* actually handle this

* Reconfigure some checks with codeclimate, disable pylint for now

* style

* Is my exasperation showing yet?

* handle some stupid stuff

* meh

* dep changelog
2020-01-01 19:26:32 -05:00
Michael H
22268eed9d Help newline... (#3247)
* whee

* change
2019-12-31 16:01:51 -05:00
Draper
f7e2617911 Fix an attribute error that can be raised in humanize_timedelta if seconds = 0 (#3231)
* Migrate Playlist to DB 3 TODO
1 Migrate Config to Schema 3 without playlists
and update get_playlist methods

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Revert "Migrate Playlist to DB 3 TODO 1 Migrate Config to Schema 3 without playlists and update get_playlist methods"

This reverts commit 4af33cff

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Allow removing tracks from queue by URL

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Words matter

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh*

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix an attribute error that can be raised here is seconds = 0

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix an attribute error that can be raised here is seconds = 0

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* go away

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh*

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2019-12-29 09:37:50 -05:00
jack1142
f9211ff50f [Downloader] Fix UnboundLocalError in cog update that happened when cogs were already up-to-date. (#3230)
* Update downloader.py

* Create 3229.misc.rst
2019-12-27 18:53:38 -05:00
jack1142
aabdabf3bc [Core] Prevent users from locking out themselves or guild owner with localblacklist (#3221)
* Update core_commands.py

* Update core_commands.py

* Create 3207.bugfix.rst

* Update core_commands.py

* Create 3221.bugfix.rst

* Update redbot/core/core_commands.py

Co-Authored-By: Michael H <michael@michaelhall.tech>

* Update bot.py

* Rename 3221.bugfix.rst to 3221.bugfix.1.rst

* Create 3221.bugfix.2.rst

* Update bot.py

Co-authored-by: Michael H <michael@michaelhall.tech>
2019-12-27 17:33:22 -05:00
jack1142
de229f63fe [Downloader] Add more information to [p]repo info, [p]cog info and [p]findcog (#3225)
* Update downloader.py

* Update downloader.py

* Update downloader.py

* Create 3225.enhance.1.rst

* Create 3225.enhance.2.rst

* Create 3225.enhance.3.rst

* Update downloader.py

* Style fix, ready for review
2019-12-27 17:14:04 -05:00
jack1142
75c4bee8a3 [Core] Tell user that the (local) whitelist/blacklist is empty when using a list command. (#3219)
* Update core_commands.py

* Create 3219.bugfix.rst
2019-12-27 17:07:43 -05:00
zephyrkul
60a1b3294d [CustomCom] add Query typehint for URI-based CCs (#3228)
* [cc] add Query typehint for URI query ccs

* Create 3228.enhance.rst
2019-12-27 11:43:25 -05:00
Michael H
ef99174585 prevent abuse cases with qualname length (#3223) 2019-12-26 17:20:59 -05:00
Michael H
8b18526f46 [Help] Fix embed size calculation for additional text (#3208)
* Fix size calculation for additional text

* changelog

* ffs

* because of course that's a thing

* *sigh*

* prevent an edge case

* more

* ...

* ...
2019-12-26 16:53:03 -05:00
Michael H
12af6232e2 [Docs] Config best practices (#3189)
* config best practices, resolves #3149

* Update framework_config.rst

* update to config wording
2019-12-26 15:34:59 -05:00
Michael H
153f4d20f1 exta info in docs about context attrs (#3151)
* exta info in docs about context attrs

* changelog

* slight addition for clarity
2019-12-26 15:34:37 -05:00
jack1142
df5cfabfe5 [Core] Use [p] for command prefix in help docstring of [p]removepath (#3214)
* Update cog_manager.py

* Create 3214.misc.rst
2019-12-24 22:57:21 -05:00
Michael H
bf6297aaf2 Add a small wrapper for APSW use (#3202)
* Add a small wrapper for APSW use

* changelog
2019-12-22 13:18:31 -05:00
jack1142
b72c05d3d4 [Core] Print a link to the guide explaining how to obtain token when Red prompts for it (#3204)
* Update cli.py

* Create 3204.enhance.rst
2019-12-21 03:55:32 -05:00
Michael H
a36e95c286 Remove a large amount of fetch_user calls (#3075)
* Non-audio changes

* address Flame's feedback
2019-12-21 01:15:34 -05:00
jack1142
b457f8d1c1 [Core] Add deprecation warnings about removal of shared libraries. (#3106)
* feat: add deprecation warning when importing shared libs

* enhance(downloader): add shared libs deprecation warns

* enhance: add deprecation warning when (re)loading cogs

* docs(downloader): add deprecation note about shared libs

* chore(changelog): add towncrier entries

* style: split long tuple unpacks in multiple lines

* fix: argument to `humanize_list` has to be a sequence
2019-12-20 02:06:53 -05:00
jack1142
9d027747d1 [Backup] Fix generation of repos.json file in backup process (#3114)
* fix: generation of `repos.json` file in backup process

* chore(changelog): add towncrier entry
2019-12-20 02:03:46 -05:00
Draper
6bf9ff5637 [Audio] Fix console spam caused by disconnect_timer if a player is destroyed before the task completes (#3123)
* Remove servers from the auto disconnect/pause list is their players no longer exist...
Prevents a console spam

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2019-12-20 01:59:09 -05:00
Draper
0b042532fd [Audio] Fix Attribute error raised by is_alone method when channel was None (#3122)
* Fix attribute Fixes #3120

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2019-12-20 01:58:08 -05:00
Draper
61f467a323 Audio converters - Remove all da fetches (#3089)
* Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now
`[p]bankset maxbal` can be used to set the maximum bank balance

Signed-off-by: Guy <guyreis96@gmail.com>

* Update Audio Scope converters to respect changes done in #3075
To be merged after #3075

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Change logs

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix Typo

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix an attribute error when the converter returned None

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* 🤦

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* 🤦 2x

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Address Aika's review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2019-12-20 01:55:34 -05:00
Michael H
02bb1fc390 add apsw-wheels to deps (#3192) 2019-12-20 01:51:33 -05:00
Michael H
e32eecd6e7 [Docs] Update windows deps instructions (#3188)
* update windows deps instructions

* changelog

* be more explicit that manual dependency handling is an excersice left to the reader

* let's only grab the MSVC C++ stuff here...

* Meh

* update language

* Update install_windows.rst

* it's really that easy
2019-12-14 21:00:08 -05:00
jack1142
988536f96b [Downloader] Possible solution for "partial" unload of cog in [p]cog uninstall (#3180)
* Update downloader.py

* Create 3180.bugfix.rst

* Rename 3180.bugfix.rst to 3179.bugfix.rst

* Update redbot/cogs/downloader/downloader.py

Co-Authored-By: Michael H <michael@michaelhall.tech>
2019-12-11 18:28:52 -05:00
jack1142
335ded674e [Core] Add Python executable field to [p]debuginfo command (#3184)
* Update core_commands.py

* Create 3184.enhance.rst
2019-12-11 16:40:27 -05:00
jack1142
b6ae7a6d21 [Core] Add redbot --debuginfo flag (#3183)
* [Core] Add `redbot --debuginfo` flag

* Update cli.py

* Create 3183.enhance.rst

* Update __main__.py

* Update __main__.py
2019-12-11 15:49:57 -05:00
Draper
c67b6cd443 [Audio] Say no to busylooping :Awesome: (#3176)
* Say no to busylooping :Awesome:

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chrore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* black y u do dis 2 me

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Return regardless if error is raised here
2019-12-09 20:26:26 -05:00
Flame442
8cba47f382 Fixed [p]announce failing due to errors messaging the owner. (#3166)
* Fixed owner message behavior

* Create 3166.bugfix.rst

* Reduce messages

* Fix plurality
2019-12-08 18:04:57 -05:00
Vexed
203cde9805 Slightly reword installation guide to attempt to stop people using dev (#3079)
* create

* add the code

* change de logs

* lets remember linux exists

* fix formtting and change wording

* change the wording a bit more... after running `sphinx-build` it def looks like i used bold a lot

god that was a long commit mesage

* review changes

* draper's review (see description)

i have put or worse partially to scare users and partially as there are other possible effects of a downgrade

* review

* clarity
2019-12-08 18:02:40 -05:00
Tomas S
064d97f87b [Downloader] Catch and handle erorr in update_all when target repository/branch is missing (#3080)
* [Downloader] Catch and handle erorr in update_all when target repository/branch is removed from remote

* Rewrite fix, remove ctx from repo_manager, edit docstring, add annotations

* Text formatting

* Group failed repo messages into padded table, catch single updated repo fails

* Error catching v2; repo_manager design change

* Docstrings, typos and changelog

* Add Optional to update_repos annotatition

* Wrong logic

* Clear-er log message.

* add format_failed_repos, change _repo_update for failed messages

* Merge cog updating with fail repo logic; Filter out failed repos

* Merge cog updating with fail repo logic; Cog updating logic shuffled to support sending fails at the end

* Docstring typo

* format_failed_repos - proper docstring

* repo_manager.update_repos argument name fix

* downloader._cog_checkforupdates added missed failed message

* downloader._cog_update_logic place back return on some errors

* Purge unused stuff from downloader._repo_update

* downloader._cog_update_logic Change exception catching

* _cog_update_logic purging obsolete

* Remove obsolete 'message' from _cog_checkforupdates

* Fix forgotten ctx.send

* Wording

* Removed obsolete 'message'

* Fix wrong type hint in , update docstring

* repo update logic fix

* format_failed_repos type hint and docstring repair

* Extend _get_cogs_to_check with 'update_repos'

* Fix type mangling in _get_cogs_to_check

* fix: typo

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>

* _repo_update; Added single repo up-to-date message
2019-12-08 17:59:53 -05:00
jack1142
9a051ef2c6 [Downloader] Fix [p]findcog not working with different levels of imports (#3178)
* Update downloader.py

* Create 3177.bugfix.rst
2019-12-08 17:58:43 -05:00
jack1142
0f62614055 [Downloader] Disable all git auth prompts on clone/pull (#3159)
* fix(downloader): disable all git auth prompts on clone/pull

* chore(changelog): add towncrier entry
2019-12-07 19:54:49 -05:00
jack1142
672050727f [Downloader] Ensure consistent output from git commands (#3160)
* fix(downloader): ensure consistent output from git commands

* chore(changelog): add towncrier entry
2019-12-07 19:31:43 -05:00
jack1142
d136d594f4 [Changelogs] Remove info about branch support in revision argument (#3158)
* chore(changelog): remove info about branch support

* chore(changelog): fix grammar issue
2019-12-07 19:29:41 -05:00
Flame442
b4186d6724 Clarifies what [p]backup does (#3172)
* Clarify `[p]backup`

* Create 3172.enhance.rst
2019-12-07 19:24:07 -05:00
jack1142
02d6b7d658 [Launcher] To make experience with launcher amazing /s (#3175)
* Update launcher.py

* Create 3174.bugfix.rst

* Revert launcher.py

* Update launcher.py

* Update launcher.py
2019-12-07 18:56:23 -05:00
Flame442
d07e718ab8 Fixes errors on repo add from empty string values for install_msg (#3153)
* Fixes errors on repo add from empty string values for `install_msg`

* Create 3153.bugfix.rst
2019-12-02 11:41:28 -05:00
jack1142
f0836d7182 [Core] Dispatch on_red_api_tokens_update event on api keys update (#3146)
* feat: dispatch `on_red_api_tokens_update` event on api keys update

* docs: add event reference in Shared API Keys docs

* chore(changelog): add tonwcrier entries

* fix: wrap dispatched api tokens in MappingProxyType

* docs: reflect change of type change to read-only Mapping
2019-11-23 16:58:35 -05:00
jack1142
bc5c2513f6 [Audio] Improve help string for [p]audioset emptydisconnect (#3051)
* enhance(audio): improve help string for [p]audioset emptydisconnect

* chore(changelog): add towncrier entry
2019-11-22 18:59:38 -05:00
Vexed
ec834a0666 Audio playlist capitalisation changes (#3048)
* commit une

* changelog

* help me whi can i mot thnik

* i can make changelogs correctly
2019-11-22 18:54:39 -05:00
PredaaA
77742179c0 [Core] Add [p]listdisabled command (#3118)
* Update core_commands.py

* Create 3115.feature.rst

* Rename 3115.feature.rst to 3118.feature.rst

* Add a message if there's any disabled commands.

* Use the same format as [p]command disable/enable

* Make strings more i18n friendly.

* Flame's requested changes.
2019-11-22 18:54:01 -05:00
kennnyshiwa
a3140b6659 [audio] adds typing indicator to playlist dedupe (#3058)
* [audio] adds typing indicator to playlist dedupe

* [audio] not sure what happened here lol

* [audio] forgot the return

* add changelog

* [audio] fix for black
2019-11-22 18:53:42 -05:00
jack1142
4b62598a3d [Downloader] Make Repo.clean_url work with relative urls. (#3142)
* fix(downloader): return string, catch ValueError for relative urls

* chore(changelog): add towncrier entry
2019-11-19 13:14:22 -05:00
Michael H
ddfabb0c0e Changes from 3.1.8 (#3139) 2019-11-18 23:45:32 -05:00
Michael H
51298f156b pt2 (#3132) 2019-11-17 11:08:30 -05:00
Michael H
141b48d3cf Add .codeclimate.yml (#3131)
- This is still not ready to be used as a PR check
  - Can be used to get an idea of where we can look to clean up code
2019-11-17 11:00:26 -05:00
jack1142
5a7c36c581 chore(changelog): fix wrong references in changelog entries for Downloader (#3130) 2019-11-17 16:35:48 +01:00
jack1142
8a90996b36 [Downloader] Add Repo.clean_url and use it in [p]findcog (#3129)
* enhance(downloader): add `Repo.clean_url` and use it in `[p]findcog`

* chore(changelog): add towncrier entries
2019-11-17 10:25:15 -05:00
jack1142
548a50b984 [Docs] Add information about `info.json's min_python_version` key in Downloader Framework page. (#3125)
* docs(downloader): add missing `min_python_version` key

* chore(changelog): add towncrier entry
2019-11-15 22:28:17 +01:00
jack1142
19e8e60a4d [Audio] Stop player before destroying on emptydisconnect (#3119)
* fix(audio): stop player before disconnect in emptydisconnect

* chore(changelog): add towncrier entry
2019-11-14 13:05:48 -05:00
Vexed
6aeca83c63 Increased clarity of wording in info command (#3121)
* make branch + preliminary code

* correction

* towncrier

* sinbad's changes
2019-11-14 13:04:00 -05:00
Draper
33178ef034 [Audio-3.2] Fix an issue with mixplaylist being recognised as single tracks (#3104)
* Fix an issue with mixplaylist being recognised as single tracks

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Add changelogs

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>
2019-11-11 11:59:51 -05:00
flaree
710b520da9 [Docs] get_shared_api_keys -> get_shared_api_tokens (#3110)
* keys -> tokens

* Changelog
2019-11-09 14:58:10 -05:00
Michael H
b3363acf77 reorder some startup to prevent heartbeat issues (#3073)
* reorder some startup to prevent heartbeat issues

* changelog

* handle startup cleanup in audio

* style

* rebased to handle conflict

* be a little smarter to prevent (some) infinite hangs

* Fix a pre-existing NoneType Error

* Migrate config before things are using it...

* another place we should ensure we're ready

* rename-toavoid-issues

* fix cache ordering and mis-use of ensure_future

* remove incorrect typehints

* style
2019-11-09 14:19:57 -05:00
Michael H
6852b7a1d1 License info command (#3090)
* Adds a licenseinfo command

* good enough for now

* changelog

* *sigh* Fine, have it your way Draper

* thanks Flame
2019-11-09 14:06:07 -05:00
Kowlin
418f957332 Update the issue templates (#3109)
This update will automatically attach the relevant labels to the dedicated issue templates.
2019-11-09 13:54:41 -05:00
Vexed
a05508a9f2 [Docs] It's 2019. Let's not say it's 2018. (#3105)
* guys... it's still not 2018

* changelog

i miss git

* review
2019-11-09 15:50:40 +01:00
Michael H
dd899c804a Remove the mongo driver (#3099)
* kills mongo

* changelog

* more refeences to mongo needed to go
2019-11-08 14:48:04 -05:00
jack1142
1651de1305 [Core] Add redbot --edit cli flag (replacement for [p]set owner&token) (#3060)
* feat(core): add `redbot --edit` cli flag

* chore(changelog): add towncrier entries

* refactor(core): clean up `redbot --edit`, few fixes

* fix(core): prepare for review

* chore(changelog): update towncrier entry to use double ticks :p

* style(black): ugh, Sinbad's git hook isn't perfect (using worktrees)

* fix: Address Flame's first review
2019-11-08 12:07:32 -05:00
Bakersbakebread
078210b54c change to_check.guild to getattr() (#3101)
* change to_check.guild to getattr()

* add webhook check

* changelog

* Update changelog.d/3100.bugfix.rst

Co-Authored-By: Michael H <michael@michaelhall.tech>
2019-11-08 09:43:21 -05:00
jack1142
e2c8b11008 [V3 Downloader] Revision tracking (#2571)
* feat(downloader): Install cog from specific commit in repo (initial commit)

- Repo and Installable have commit property now
- New class inheriting from Installable -
InstalledCog (old one from converters.py removed)
- New Repo.checkout() method, which is also async ctx manager
ref #2527

* fix(downloader): Keep information about repo's branch in config

- This is needed to make sure that repo can go back from detached state in some rare unexpected
cases
- current branch is determined by `git symbolic-ref` now as this command errors for detached
HEAD

* feat(downloader): Update repo without cogs, update single cog

The most important part of issue #2527 has been added here
- `[p]repo update` command added
- new conf format - nested dictionary repo_name->cog_name->cog_json
  installed libraries are now kept in conf too
  - `InstalledCog` renamed to `InstalledModule` - installed libraries use this class
  - `Downloader.installed_libraries()` and `Downloader.installed_modules()` added
  - `Downloader._add_to_installed()` and `Downloader._remove_from_installed()`
    now accept list of modules, of both cogs and libraries
- `[p]cog install` tells about fails of copying cog and installing shared libraries
- `[p]cog update` will truly update only chosen cogs (if provided) or cogs that need update
  - pinned cogs aren't checked
  - before update, repos are updated
  - to determine if update is needed `Repo.get_modified_modules()` is used
- `[p]cog pin` and `[p]cog unpin` commands for pinning/unpinning cogs added
- `Repo.checkout()` allows to choose ctx manager exit's checkout revision
- `Repo.install_cog()` returns `InstalledModule` now and raises CopyingError (maybe breaking?)
- `Repo.install_libraries()` returns 2-tuple of installed and failed libraries (maybe breaking?)
- `RepoManager.get_all_cogs()` added, which returns cogs from all repos
- `RepoManager.repos` property added, which contains tuple of `Repo`

* test(downloader): Repo.current_branch() throws an exception, when branch can't be determined

* style(downloader): rename _add_to_installed to _save_to_installed

This method is used for both adding and updating existing modules in Config

* refactor(downloader): add ctx.typing() for few commands

`[p]cog install` is nested hell, can't wait for moving install logic to separate method

* fix(downloader): refactor and fix `set` usage

* perf(downloader): update commits for ALL checked modules to omit diffs next time

This will also disable running git diff for cogs that have the same commit as the latest one

* style(downloader): few style improvements

- use of mutable object in method definition
- make Repo._get_full_sha1() public method
- too long
line
- don't use len to check if sequence is empty

* feat(downloader): add `[p]cog updateallfromrepos` and `[p]cog updatetoversion` commands

- moved cog update logic into `Downloader._cog_update_logic()` (lack of better name)
  - splitted
whole cog update process into smaller methods
  - might still need some improvements
- added new
methods to `Repo` class:
  - `is_on_branch()` to check if repo is currently checked out to branch

- `is_ancestor()` to check if one commit is ancestor of the other
- fix for
`Downloader._available_updates()` behaviour
broken by commit
5755ab08ba67556b3863e907c6f44d80f4f13d88

* feat(downloader): try to find last commit where module is still present

Enhancements:
- `Installable` now has `repo` attribute containing repo object or `None` if repo is
missing
- `Downloader._install_cogs()` and `Downloader._reinstall_libraries()` are able to install
modules from different commits of repo
- `Repo.checkout()` as ctx manager will now exit to commit
which was active before checking out
- unification of `rev` and `hash` terms:
All function
parameters are explicitly called `hash`, if it can only be commit's full sha1 hash or `rev` if it
can be anything that names a commit object, see
[link](https://git-scm.com/docs/git-rev-parse#_specifying_revisions)
- new
`Repo.get_last_module_occurence()` method, which gets module's Installable from last commit in which
it still occurs

* docs(downloader): Add basic description for `InstalledModule`

* fix(downloader): cog ignored during updates if its commit was missing

After config format update, commit string is empty until update and when such cog was checked and it
wasn't available in repo anymore, it was ignored

* refactor(downloader): Installing cogs from specific rev will pin them

* perf(downloader): Don't checkout when current commit equals target hash

- changes to `Repo.checkout()`:
  - `exit_to_rev` is now keyword only argument
  - added
`force_checkout` to force checkout even if `Repo.commit` value is the same as target hash

* refactor(downloader): Repo._run() stderr is redirected to debug log now

- added two keyword arguments:
  - `valid_exit_codes` which specifies valid exit codes, used to
determine if stderr should be sent as debug or error level in logging
  - `debug_only` which
specifies if stderr can be sent only as debug level in logging

* style(downloader): stop using `set` as arg name in `_load_repos()`

* feat(downloader): pass multiple cogs to `[p]cog (un)pin`

* refactor(downloader): accept module name instead of instance, fix spelling

* style(downloader): few small style changes

* fix(downloader): add type annotations + fixes based on them

- fix wrong type annotations and add a lot of new ones
- add checks for `Installable.repo` being `None`
- fix wrong return type in `Downloader._install_requirements`
- show repo names correctly when updating all repos
- fix error when some requirement fails to install

BREAKING CHANGE:
- type of `Repo.available_modules` is now consistent (always `tuple`)

* tests: use same event loop policy as in Red's code

* enhance(downloader): fully handle ambiguous revisions

* build(deps): add pytest-mock dependency to tests extra

* fix(downloader): minor fixes

* feat(downloader): add tool for editing Downloader's test repo

This script aims to help update the human-readable version of repo
used for git integration tests in ``redbot/tests/downloader_testrepo.export``
by exporting/importing it in/from provided directory.

Note
----
Editing `downloader_git_test_repo.export` file manually is strongly discouraged,
especially editing any part of commit directives as that causes a change in the commit's hash.
Another problem devs could encounter when trying to manually edit that file
are editors that will use CRLF instead of LF for new line character(s) and therefore break it.

I also used `.gitattributes` to prevent autocrlf from breaking testrepo.

Also, if Git ever changes currently used SHA-1 to SHA-256 we will have to
update old hashes with new ones. But it's a small drawback,
when we can have human-readable version of repo.

Known limitations
-----------------
``git fast-export`` exports commits without GPG signs so this script disables it in repo's config.
This also means devs shouldn't use ``--gpg-sign`` flag in ``git commit`` within the test repo.

* tests(downloader): add git tests and test repo for them

Also added Markdown file that is even more clear than export file
on what the test repo contains.
This is manually created but can be automated on later date.

* test(downloader): add more tests related to RepoManager

These tests use expected output that is already guaranteed by git tests.

* chore(CODEOWNERS): add jack1142 to Downloader's folders

I know this doesn't actually give any benefit to people that don't have
write permission to the repo but I saw other big fella devs doing this,
so I think this might be advisable.

* enhance(downloader): allow easy schema updates in future

* enhance(downloader): more typing fixes, add comments for clarity

* feat(downloader): add python and bot version check to update process

follow-up on #2605, this commit fully fixes #1866

* chore(changelog): add towncrier entries

* fix(downloader): use `*args` instead of `commands.Greedy`

* fix(downloader): hot-reload issue - `InstallableType` now inherits from `IntEnum`

There's desync of `InstallableType` class types due to hot-reload
and `IntEnum` allows for equality check between different types

* enhance(downloader): ensure there's no cog with same name installed

should fix #2927

* fix(downloader): last few changes before marking as ready for review
2019-11-07 20:36:16 -05:00
aikaterna
d85fb260e7 [Audio] Expose FriendlyException on play command (#3085)
* [Audio] Expose FriendlyException on play command

* Add changelog
2019-11-06 17:41:18 -05:00
Jeremiah Boby
e79a08e392 Add autostart documentation for venv users (#3028)
* Add documentation for venv users

Resolves #3005

* Add changes to changelog.d

* Use "redenv" over "path/to/venv"
2019-11-06 12:29:01 -05:00
Toby Harradine
7e9b1b87e6 Allow keeping data in redbot-setup delete (#2965)
* Allow keeping data in `redbot-setup delete`

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Add changelog entry

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-11-06 12:24:54 -05:00
Michael H
b8cbaa2fa0 Merge 3.1.7 (#3098)
* uvloop + python3.8

* Lavalink bump to 3.2.1_846

* [Release] 3.1.7

- Handles a dependency issue for python3.8
- Updates the Lavalink jar used
  - This include's Nin's stat fix
  - Streaming from Soundcloud is working again, at least for now.

* 3.1.7
2019-11-05 08:13:32 -05:00
Michael H
ddd9c4c6b0 [Permissions] Ensure defaults are cleared when clearing all rules (#3041)
- fixes #3037
2019-11-04 23:09:01 +01:00
Kowlin
a729a474b1 Added documentation for PM2 (#2105)
* Added PM2 documentation

* Grammar fix

* Build error fix.

* Just work T_T

* Update docs/autostart_pm2.rst

Co-Authored-By: Vexed <51716387+Vexed01@users.noreply.github.com>

* Update docs/autostart_pm2.rst

Co-Authored-By: Vexed <51716387+Vexed01@users.noreply.github.com>

* Create 2105.docs.rst
2019-11-04 16:52:01 -05:00
palmtree5
911aed5fe2 [Docs] Getting Started Guide improvements (#3083)
* Add MS Azure to the list of hosting providers

* Fix some typos, wording, incorrect commands

* towncrier

* Update docs/getting_started.rst

Co-Authored-By: Michael H <michael@michaelhall.tech>
2019-10-23 23:45:25 -04:00
El Laggron
53606a4bbc [Docs] Do not overwrite rst_prolog (#3082)
* Do not overwrite rst_prolog

* Add towncrier entry
2019-10-23 17:51:35 -04:00
Ryan
3b653f93fc [Docs] Update Cog Creation guide install (#3021)
* Use stable instead of dev version

* changelog entry

* Rename 3020.docs.rst to 3021.docs.rst

* update wording in Getting Started

* add note about package layout

* fix some formatting

* spellcheck

* add cookiecutter note

* Update 3021.docs.rst
2019-10-23 17:51:12 -04:00
Michael H
17c8cbb057 Add support for accessing config by ids (#3022)
* Add support for accessing config by ids

* update-changelog with methods
2019-10-22 16:25:01 -04:00
El Laggron
ee293876d9 [RPC] Set custom port with flags (#2429)
* [RPC] Set custom port with flags

* Add changelog entry
2019-10-21 22:46:56 -04:00
jack1142
3b0fa0c05d [Core/Downloader] Add 3rd-party lib folder to sys.path before loading cogs (#3062)
* fix(core,downloader): add lib folder to sys.path before loading cogs

* chore(changelog): add towncrier entry

* fix(core): always append 3rd-party lib path to the end of `sys.path`
2019-10-21 22:43:00 -04:00
jack1142
8267ad9aab [Docs] Add missing descriptions for function returns (#3054)
* docs: add missing descriptions for function returns

* chore(changelog): add towncrier entry
2019-10-21 22:41:35 -04:00
jack1142
a3b6aafaca [Docs] Link to Getting started guide at the end of installation guides (#3032)
* docs: link to Getting started guide at the end of installation guides

* chore(changelog): add towncrier entry
2019-10-21 22:38:24 -04:00
jack1142
2dbed96be1 [Audio] Restart Lavalink after unexpected shutdown (#3034)
* fix(audio): lavalink not getting restarted after unexpected shutdown

* chore(changelog): add towncrier entry
2019-10-21 22:37:07 -04:00
Draper
2ba6fb17ca [Audio] Handle Missing SQL deps more gracefully (#3066)
* Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now
`[p]bankset maxbal` can be used to set the maximum bank balance

Signed-off-by: Guy <guyreis96@gmail.com>

* Remove duplicated call in `[p]playlist update`

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Handle both ModuleNotFoundError and ImportError and pull a more complete error message to forward to the user and fix grammar.

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Since we aren't 100% certain of message length here due to using the error message for the raised error ... lets use pagify so this doesn't bite us in the future.

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* .... Lets not reinvent the wheel

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Address Jack's review
2019-10-21 22:36:24 -04:00
Michael H
3723b4b1ea Merge 3.1.6 (#3069)
* Version Bump

 - d.py 1.2.3 -> 1.2.4
 - Red 3.1.5 -> 3.1.6

This fixes a critical issue with voice connections.

* Merge changelog
2019-10-18 17:54:27 -04:00
jack1142
172dd58903 [Docs] Change links to d.py docs to use pinned version instead of v1.0.1. (#3053)
* docs: change links to d.py docs to use stable version instead of v1.0.1

* chore(changelog): add towncrier entry

* docs: add |DPY_VERSION| substitution and :dpy_docs: role

* chore(changelog): update towncrier entries to reflect new changes
2019-10-17 07:58:39 -04:00
Draper
a9a547e56d [Audio] Formatting Sucks ... lets standardize it a little ahead of PR1.5 (#3059)
* Formatting Sucks ... lets standardize it a little ahead of PR1.5

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Finish applying this logic to other instances where it is relevant + change logs

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>
2019-10-16 22:43:57 -04:00
jack1142
d42a2d5140 [Core] Fix error message about guild-only command and add dm-only error message (#3057)
* enhance(core): fix guild-only error message, add dm-only error message

* chore(changelog): add towncrier entries
2019-10-16 08:17:04 -04:00
Flame442
428bf55480 Makes bot.send_filtered return the message that is sent (#3052)
* Makes bot.send_filtered return the sent msg

* Create 3052.enhance.rst

* :that:

Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com>
2019-10-13 19:32:24 -04:00
Draper
36f494ba63 [Audio] One PR to rule them all, One PR to find them, One PR to bring them all, and in the darkness bind them (all-in-one pr) (#2904)
* 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>
2019-10-10 22:09:01 -04:00
Flame442
9b60816ebd [Downloader] Catch OSErrors from invalid repo names (#3029)
* [Downloader] Ensure repo names only contain the characters stated

* Create 2827.bugfix.rst

* [Downloader] Catch OSErrors from invalid filenames

* Update 2827.bugfix.rst

* Style

* do the thing again

* Update 2827.bugfix.rst
2019-10-04 22:19:00 -04:00
El Laggron
ea77de5d56 [Docs] Getting started guide (#2659)
* Getting started guide

* Remove DigitalOcean referral link

* Fix typos and mispells, thanks to @Flame442

* Remove cogs.red hyperlink until it is finished

* Add towncrier entry

* Add prolog.txt

This is not necessary for this PR but all of the other cog guides rely on this file.
The cog guides are individual branches based on this one, which is why I'm adding this file right now.

* QA changes

* More QA changes

considering -> assuming
red is a girl, not non-binary
2019-10-03 12:47:46 -04:00
DiscordLiz
05eba603a5 Prevent error on empty install message. (#3024)
* Prevent error on empty install message.

* Create 3024.bugfix.rst
2019-10-02 20:38:52 -04:00
Vexed
37f27d8ae4 [Docs] Git Install Updates, note about launcher deprecation, capitalise some words (#2998)
* commit

* add launcher depricate to linix/mac

* sorry linux i still ignored you

capitalise some linix stuff i couldnt be bothered to do before

* remove mentions of launcher & update changelog enrty
2019-09-29 07:43:53 -04:00
Vexed
759ca3ba7e Quotes in helpset tagline for clarity (#3012)
* Add quotes to clarify helpset tagline

Add quotation marks to helpset tagline's response so two consecutive full stops don't appear.

* more commiting

* make travis/black happy

* for review

make no longer repeat tagline
2019-09-29 07:42:44 -04:00
jack1142
59e7d063a0 [Tunnel] Add use_cached and images_only kwargs to files_from_attach (#2887)
* feat(tunnel): add `use_cached` kwarg

re #2885

* feat(tunnel): add `images_only` kwarg

re #2885

* chore(changelog): add towncrier entry
2019-09-28 17:28:14 -04:00
jack1142
6e3ccc1a21 [Commands] cls parameter can now be passed to group like in d.py (#2881)
* fix(commands): ``cls`` parameter can now be passed like in d.py

* chore: add changelog entry

* Update changelog.d/2881.misc.rst

Co-Authored-By: Toby Harradine <Tobotimus@users.noreply.github.com>

* Rename 2881.misc.rst to 2881.enhance.rst
2019-09-28 17:24:49 -04:00
jack1142
80628a28a7 [Core] Give friendly error when provided instance name doesn't exist. (#2969)
* Update data_manager.py

* Towncrier entry
2019-09-28 17:22:45 -04:00
Aurorum
6bb1004bcd [Trivia] Greek Myth: Caduceus Typo (#2994)
* [Trivia] Greek Myth Typo

* Changelog entry
2019-09-28 17:18:58 -04:00
jack1142
6170a56648 [Docs] Link directly to installing Red from installing requirements using chocolatey section (#2995)
* docs: link directly to installing Red from installing using chocolatey

* chore(changelog): add towncrier entry
2019-09-28 17:18:08 -04:00
Draper
f3b6c4cf32 Fixes [p]trivia leaderboard not running. (#2983)
* Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now
`[p]bankset maxbal` can be used to set the maximum bank balance

Signed-off-by: Guy <guyreis96@gmail.com>

* Adds `invoke_without_command` to `[p]trivial leaderboard`

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
2019-09-28 17:12:43 -04:00
Michael H
83483abfa5 Reserves command names (#2977)
* Reserves command names

  - Currently, only reserving ``cancel``
  - This should only impact matching command qualified names
  - This also checks aliases
  - This makes cc and alias use the new module constant with info about
  this
  - Module constant is available for use by 3rd party cogs which may
  dynamically create responses.

* Change misleading var name

* style

* Thanks Flame!

* Handles issues with CC
2019-09-28 16:58:40 -04:00
Michael H
e38c08ab12 fix uptime for uptime of less than a second (#3009)
* fix uptime for uptime of less than a second

* changelog

* More conclusive fix
2019-09-28 15:35:26 -04:00
Michael H
c288185a16 Fix a misplaced changelog file (#3019) 2019-09-28 09:59:21 -04:00
Flame442
b9ed8b84f5 [CustomCom] Use simple by default (#3013)
* Allow creating simple CCs by default

* Create 3013.rst

* Screwed up the filename
2019-09-28 02:46:40 -04:00
Michael H
ee162f6f9e Fixes an issue with allowed_by_whitelist_blacklist (#3017) 2019-09-27 16:12:29 -04:00
Friesi
101e977939 Change the hierarchy issue messages (#3016)
* Change the hierarchy issue messages,
because they are difficult to translate with the verb variable.

* Fix typos

* Add changelog entry

* Reformatting with black
2019-09-27 12:10:35 -04:00
Michael H
25614620db More privatization, and some error helpers (#2976)
* More privatization, and some error helpers

This makes a lot more things private. Continued from #2967, fixes #2984
Adds public methods for various things.

Below is a brief summary of things available elsewhere, though this
particular set of changes may warrant a detailed section in the release notes.

 - bot.db.locale -> redbot.core.i18n.get_locale
   - Note: This one already existed.
 - bot.db.help -> redbot.core.commands.help.HelpSettings
 - bot db whitelist/blaclist? -> bot.allowed_by_whitelist_blacklist
   - This has also been made a single cannonical function for this
   purpose including check usage
 - bot color? -> bot.get_embed_color/bot.get_embed_colour
 - bot.id.api_tokens? ->

   - bot.get_shared_api_tokens
   - bot.set_shared_api_tokens
   - bot.remove_shared_api_tokens

 -bot.db.prefix -> bot.get_valid_prefixes
   - (Note: This is a wrapper around bot.get_prefix)

 Other changes include
  - removing `bot.counter` as it was never used anywhere
  - Adding properties with helpful error messages for moved and renamed
  things
  - making bot.uptime a property with an error on set
  - adding a migration to the bot config for shared_api_tokens

* Remove overly encompassing message redaction, eval is a risk, dont run in dev if you cant manage it

* address Flame's feedback

* rephrase example

* changelog extras

* You saw nothing
2019-09-26 12:55:05 -04:00
Michael H
62dcebff94 [Downloader] findcog no longer attempts to find cogs for commands without them (#2970)
* findcog no longer attempts to find cogs for commands without them

* changelog

* full stop
2019-09-26 12:19:58 -04:00
Michael H
af97175839 Fix an issue with clearing permission rules (#3015)
Fixes #3014
2019-09-26 11:41:11 -04:00
Michael H
1ee5238ad7 Remove a specific f-string usage in the launcher. (#3002)
* @Kowlin I saw that error

* style
2019-09-23 16:52:48 +02:00
Draper
575e55cb0f Fixed crash originated in bank.set_balance (#2997)
* Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now
`[p]bankset maxbal` can be used to set the maximum bank balance

Signed-off-by: Guy <guyreis96@gmail.com>

* Pushed the Fix for new issue introduced by #2926

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Changelogs

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Rename changelog to a misc

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Address Flame's review

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Correct an outdated reference in the docs

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Reword docstring for the RuntimeError

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
2019-09-22 02:05:27 -04:00
Michael H
ee3be8b633 Extra info (#3008)
* Extra info

* changelog
2019-09-20 16:55:46 +02:00
Flame442
7f22d27d51 Fixes the logic of MessagePredicate.greater and MessagePredicate.less (#3004)
* Fixes the logic of MessagePredicate.greater and MessagePredicate.less

* Create 3004.bugfix.rst
2019-09-18 17:15:24 -04:00
Michael H
4546ca9ba6 Clarify usage of humanize_timedelta (#3000)
- resolves #2986
2019-09-15 19:32:07 -04:00
Flame442
1e97597bc2 [Trivia] Overwatch - Remove a blank answer (#2996)
* Remove a blank answer

* Create 2996.bugfix.rst
2019-09-15 01:09:35 -04:00
DevilXD
77f1da30ea Tempban logging improvement (#2993)
* user and guild are logged now

* Added changelog entry

* Make sure Forbidden always triggers this as well
2019-09-13 18:40:54 -04:00
jack1142
682b86c193 [Permissions] Possible solution for clearing out usage of commands with <who_or_what> (#2992)
* style(permissions): clear out usage of commands with <who_or_what>

* chore(changelog): add towncrier entry

* style(permissions): fix black formatting
2019-09-09 15:29:19 -04:00
jack1142
cdb7a02cb8 [Core] Fix infinite typing for commands with cooldown (#2987)
* fix(core): cooldown error can't reinvoke command (infinite typing issue)

* chore(changelog): add towncrier entry
2019-09-07 19:25:02 -04:00
Flame442
0be3b1acd7 Fixes the strings of [p]set usebotcolor (#2974)
* Fixes the help text of `[p]set usebotcolor`

* Create 2974.bugfix.rst
2019-09-02 09:43:56 -04:00
Michael H
4f1f49d96f [Modlog] userinfo stops breaking with high numbers of roles on a user (#2971)
* Fixes it, I guess

* changelog

* reluctant handling of what the people want here

* mypy would have prevented this one
2019-09-02 09:38:19 -04:00
Michael H
6075c5bde0 Rename bot.db as bot._config (#2967)
* Rename `bot.db` as `bot._config`

  - Continues work towards strong version guarantees
  - Added methods for cog use for a few things which were previously
  only accessible via direct access.
  - Retained private use in a few internal use locations, though most
  methods were updated away from this.
  - Updated documentation for shared api token users

* changelog

* more detail

* docstring fixes

* Apparently, I forgot to commit something I had locally

  - + a copy/paste failue in the changelog

* *sigh*:

* *sigh*
2019-09-01 15:42:28 -04:00
Toby Harradine
d86cc7a854 Bump dependencies (no more SSL errors) (#2939)
Also made the Makefile work slightly nicer with other tools, e.g. IDE run configurations, by allowing the python executable to be set as an env var.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-09-01 09:29:54 +10:00
Toby Harradine
25fb389a7d [Docs] Update linux install docs, redo venv docs (#2920)
* [Docs] Update linux install docs, redo venv docs

Some of our pre-req installation docs needed updating on Windows - this adds new sections for Fedora Linux and Debian/Raspbian Buster, and also removes some unnecessary pre-requirements from other distributions. These have all been tested on fresh VPSes, installing Red both in venvs and with --user, and they all seem to work.

Also, apparently the venv docs were too scary before. These changes try to make it clear that it's easier to use than users may think.

This also includes a little note to stop users from accidentally installing Python with pyenv after installing pre-requirements on Ubuntu.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Add changelog entries

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Update officially supported platforms in README.md

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Combine sections and add openSUSE

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Include example of using `--user` flag

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Use `py -3.7` on Windows outside of venv

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Reorganise changelog entries

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-08-30 18:08:26 -04:00
Flame442
d9e774f079 [Docs] Typo fix (#2953)
* Fixed a typo

* Create 2953.misc.rst
2019-08-30 17:41:40 -04:00
Draper
7959e0c916 [Bank] Allow Bot Owner/Guild Owners to remove invalid users from the bank (#2845)
* Add command to remove dead members from bank

* Add a global check

* Added a FIXME so `bank_local_clean` is updated once bulk-update is implemented
Added a brief warning to warn devs not to use the `_get_base_group` as it can mess up their config files
Removed a redundant existence check

* Updated  commit to reflect changes requested in review

* Updated  commit to reflect changes requested in review

* 🤦

* Return command to run with user id so we don't worry about safeguarding the command agaisn't invalid formats

* Braaaainnn

Removed aliases that used old naming scheme

* TL:DR  Added global bank support, and rework permissions

Renamed `bank_local_clean` to `bank_prune`
Added support for global banks to `bank_prune`
`bank_prune` will now raise `BankPruneError` if trying to prune a local bank and `guild` is not supplied

Renamed `cleanup` subgroup to `prune`
`prune` subgroup will have 3 commands:
  `user`   :  Deletes the bank account for the specified member : Accepts `Union[discord.Member, discord.User, int]`
  `global` :  Prune global bank accounts for all users who no longer share a server with the bot
  `local`  :  Prune local bank accounts for all users who are no longer in the guild

Changed check for `prune` subgroup to be `@check_global_setting_admin()`
[p]bank prune local  : Can be run by Guild owners only
[p]bank prune global : Can be run by Bot Owner only
[p]bank prune user   : Can be run by Admins, Guild owners and Bot Owner

* Yikes ... Updated kwarg name

* Fixed unexpected unindent: docstring of redbot.core.bank.bank_prune:14:Field list ends without a blank line

* ...

* 3rd time lucky?

* 4th time lucky?

* Fix Docstring

* Initial commit to address review by Flame

* Updated code to reflect Flame's comments

* Skip pruning of unavailable guilds

* Fixed typo in string

* *sigh* black is the bane of my existence

* addressed Flames commends
Fixed [p]bank prune user, When run via DM it will now return an error message to the user (Thanks jack1142)

* Time to get some sleep

* 'DM' > 'DMs' in string

* Add towncrier entries

Signed-off-by: Draper <guyreis96@gmail.com>

* Update to reflect Flame's review

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
2019-08-30 17:35:25 -04:00
DJtheRedstoner
ef3ac77bd8 Fix issues with embed_requested() (#2966)
* Fix issues with embed_requested()

* Update embed_requested()

Make embed_requested()'s user settings only affect DM's

* Towncrier for #2966
2019-08-30 17:20:34 -04:00
Flame442
efcf91e934 Catch discord.errors.Forbidden when DMing a user the invite message (#2948)
* Catch discord.errors.Forbidden when DMing a user the invite message

Uses the same error message as `[p]help`

* Create 2948.bugfix.rst

* You saw nothing
2019-08-29 21:19:19 -04:00
aikaterna
b8a7a66566 [Core] Inviteset public and perms help cleanup (#2963)
* [Core] Inviteset public and perms help cleanup

* Towncrier entry
2019-08-29 21:18:43 -04:00
Draper
e04eed4a89 [Bank] Allow bank managers to set the maximum allowed balance in the bank (#2926)
* Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now
`[p]bankset maxbal` can be used to set the maximum bank balance

Signed-off-by: Guy <guyreis96@gmail.com>

* Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now
`[p]bankset maxbal` can be used to set the maximum bank balance

Signed-off-by: Guy <guyreis96@gmail.com>

* Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now
`[p]bankset maxbal` can be used to set the maximum bank balance

Signed-off-by: Guy <guyreis96@gmail.com>

* Rename method 🤦

Signed-off-by: Guy <guyreis96@gmail.com>

* Updated this to be aware of #2925

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Addressed Flames review + Fixed 1 bug in errors.py + `[p]leaderboard` and `[p]bank balance` will set the users balance to max balance if the bank maxbal is lower than the previous user balance

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Missed this clarification

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* address Flames review

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
2019-08-29 21:05:31 -04:00
jack1142
b490942bcd [Core] Various fixes to redbot-setup delete (#2958)
- ``redbot-setup delete`` no longer errors about "unexpected keyword argument" (fix #2955)
- ``redbot-setup delete`` no longer prompts about backup when user passes ``--no-prompt`` option (fix #2956)
- ``--[no-]backup``, ``--[no-]drop-db`` and ``--[no-]remove-datapath`` in ``redbot-setup delete`` command are now on/off flags. ``--no-prompt`` was changed to flag too, but it doesn't have ``--prompt`` equivalent as there's no much point in having it
- ``redbot-setup`` now uses `click.confirm` for confirmation prompts and thy now also have default values for user convenience
2019-08-30 08:23:31 +10:00
jack1142
26cc85806e [Utils] Stop using : in backup's filename - Windows doesn't accept it (#2957) 2019-08-28 12:01:02 +10:00
Michael H
2c8152606c [Modlog] Reduce potential for bad API calls (#2945)
- brings a fix over from #2934
2019-08-28 08:45:56 +10:00
Draper
3c1b6ae4cf [Utils] Add humanize_number() function to chat formatting (#2836)
This adds babel as a dependency, and also includes `redbot.core.i18n.get_babel_locale()`
2019-08-28 08:44:52 +10:00
ZeLarpMaster
6c3a3fea66 Fixing typo in starwars trivia (#2903)
* Fixing typo in starwars trivia

Been pointed out to us by kDals#5653

* Add a changelog entry
2019-08-27 12:44:07 -04:00
jack1142
fb9fec282b [Mod] Fix recording username changes (#2919)
* fix(mod): past names are now properly recorded in `on_user_update` event

* chore(changelog): add towncrier entry

* chore(changelog): specify what commands were affected
2019-08-27 12:42:56 -04:00
Michael H
bbd30411fd Fixed small docstring inconsistency (#2924)
* Fixed docs inconsistency

* Added changelog entry

* Changed category from bugfix to misc
2019-08-27 12:40:36 -04:00
Draper
2056f9f8d0 [Bank] Check recipient balance before completing transfer (#2925)
* 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>

* Black.... you are supposed to trigger before commits

Signed-off-by: Guy <guyreis96@gmail.com>

* Added `BalanceTooHigh` to the docstrings of `bank.transfer_credits()`

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Bring this in line with #2926 to reduce conflicts,`is_global()` already is called inside `get_currency_name` and as such it does not need to be called outside

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>
2019-08-27 12:40:11 -04:00
Michael H
68018c924e [Economy] House always wins in slots (#2875)
* [Economy] House always wins in slots

 - Expected payout is negative
 - No flat increase payouts, all payouts are multiplicative

* actually do math properly

* UX + Changelog

* How the hell did I mess that up?!
2019-08-27 12:38:56 -04:00
DiscordLiz
0c773134f2 [Mod] Fix modset deletedelay (#2943)
* [Mod] Fix modset deletedelay

  fixes #2942

* Style guide fix
2019-08-27 09:27:24 -04:00
DevilXD
0d16e27070 Changed category from bugfix to misc 2019-08-27 10:34:44 +02:00
Toby Harradine
326c53d6c4 Quick fix for postgres config details prompt (#2951)
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-08-27 14:25:05 +10:00
Toby Harradine
d1a46acc9a PostgreSQL driver, tests against DB backends, and general drivers cleanup (#2723)
* PostgreSQL driver and general drivers cleanup

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Make tests pass

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Add black --target-version flag in make.bat

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Rewrite postgres driver

Most of the logic is now in PL/pgSQL.

This completely avoids the use of Python f-strings to format identifiers into queries. Although an SQL-injection attack would have been impossible anyway (only the owner would have ever had the ability to do that), using PostgreSQL's format() is more reliable for unusual identifiers. Performance-wise, I'm not sure whether this is an improvement, but I highly doubt that it's worse.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Reformat

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Fix PostgresDriver.delete_all_data()

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Clean up PL/pgSQL code

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* More PL/pgSQL cleanup

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* PL/pgSQL function optimisations

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Ensure compatibility with PostgreSQL 10 and below

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* More/better docstrings for PG functions

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Fix typo in docstring

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Return correct value on toggle()

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Use composite type for PG function parameters

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Fix JSON driver's Config.clear_all()

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Correct description for Mongo tox recipe

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Fix linting errors

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Update dep specification after merging bumpdeps

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Add towncrier entries

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Update from merge

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Mention [postgres] extra in install docs

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Support more connection options and use better defaults

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Actually pass PG env vars in tox

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Replace event trigger with manual DELETE queries

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-08-26 22:02:26 -04:00
Flame442
57fa29dd64 Rename two changelog files from fix to bugfix (#2949) 2019-08-27 11:42:31 +10:00
Michael H
bfa55922cf Add note for using towncrier with standalone PRs (#2915) 2019-08-27 11:39:51 +10:00
El Laggron
43da727a9f [Utils] Text to file (#2849) 2019-08-26 10:13:21 +10:00
jack1142
580c4429e8 Add pip-wheel-metadata folder to .gitignore (#2941) 2019-08-20 10:37:23 +10:00
PredaaA
3498f8ccb6 Remove commas for explanations about how to set API keys (#2905)
This removes commas in explanations about how to set API keys in streams, image and audio cogs, since it has been changed in #2692.
2019-08-18 09:50:48 +10:00
Aurorum
5e9b3d9190 [Trivia] Michael Jackson & Prince Lyrics (#2894)
I thought it'd be fun to offer lyrics as a trivia, but it can be tricky selecting songs which are known widely enough that a significant number of people have a reasonable chance of answering the questions correctly.

As such, to narrow down the scope, these add trivia questions for Michael Jackson and Prince, two of the most well-known artists across the world whose musical collections are extensive and popular enough to dedicate an entire trivia too.

They're comprised of a variety of lyrics, two lyrics for each song. Players need to name the song from the lyric. Most of the songs are well-known songs from the artist, but there are plenty of challenges too.
2019-08-18 09:31:32 +10:00
Flame442
dfb4212d43 [Docs] Fix user parameter to predicates being typed as discord.TextChannel (#2914) 2019-08-18 09:05:22 +10:00
Ianardo DiCaprio
b1ccfab6d2 [Mod] BugFix (#2932)
* Initial Commit

* Add files via upload
2019-08-13 14:33:03 -04:00
Michael H
984a97d958 [Core Commands] remove set owner and set token (#2928)
* remove set-owner and set token

* whoops, wrong number on the changelog

* whoops, git didnt detect the rename cause I didnt add the file
2019-08-13 13:57:16 -04:00
DevilXD
463546f102 Added changelog entry 2019-08-08 17:12:58 +02:00
DevilXD
477a17d0b9 Fixed docs inconsistency 2019-08-08 17:06:11 +02:00
Draper
556af32bb5 Stop saving JSON files with indents (#2921)
Stop saving json files with 4 indents, this will significantly reduce file size and improve `.set()` performance for config saves when using the JSON driver.

Signed-off-by: Draper <guyreis96@gmail.com>
2019-08-07 10:13:31 +10:00
Toby Harradine
ef8b9b81c3 [ModLog] Optimise get_next_case_number() (#2908)
* [ModLog] Optimise get_next_case_number()

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Address reviews

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Add changelog entry

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Delete get_next_case_number

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Add modlog.get_latest_case() and fix `[p]reason`

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-08-02 10:49:22 -04:00
Toby Harradine
9362dd9465 Merge V3/release/3.1.5 into V3/develop 2019-07-31 09:43:35 +10:00
Toby Harradine
6c9c57c14d Bump version to 3.1.5
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-31 09:23:18 +10:00
Toby Harradine
404c5f6dc0 [Audio] Bump Lavalink version to 3.2.1_823
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-31 09:22:16 +10:00
DiscordLiz
20091cc10a [ModLog API] Add default casetypes, remove need for a specific auditlog action (#2901)
* I know this needs a changelog entry and docs still

* update tests for new behavior

* update docs, filter; add changelog

* Ready for review

* stop fetching the same Audit logs when the bot is the mod

* I forgot to press save

* fix a comprehension

* Fix AttributeError

* And the other place that happens

* timing fixes
2019-07-27 15:37:29 -04:00
Michael H
6280fd9c28 disabled help hideaways (#2892)
* disabled help hideaways

* can_see fix
2019-07-27 02:36:21 -04:00
Toby Harradine
af096bc1cc Config locks (#2654)
* Config locks

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Add locks for all_XXX

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Remove a word

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Add acquire_lock kwarg for value context manager

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Add towncrier entry

Signed-off-by: Toby <tobyharradine@gmail.com>

* Fix issues with `get_custom_lock` and `get_members_lock`

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-23 16:50:07 -04:00
Michael H
a8091332b8 [Docs] Add version guarantees (#2882)
Make some version guarantees.

We also need to do a pass over the existing things this would cover and decide if any of them should be made private.
2019-07-19 11:50:33 +10:00
DevilXD
7ba50c91a2 Fixed remove_command error when trying to remove a non-existent command (#2889)
* Fixed remove_command error when trying to remove a non-existent command

* Added changelog entry
2019-07-18 05:49:40 -04:00
DevilXD
0ba9eaeccc Slowmode now accepts integer only inputs as seconds (#2884)
* Slowmode now accepts integer only inputs as seconds

* Added changelog entry
2019-07-17 08:47:37 -04:00
Michael H
d4b6fdea92 Add towncrier (#2873)
* Adds towncrier as our changelog system.
* Updates our contributor guidelines for this.

Resolves #2872
2019-07-17 11:12:43 +10:00
Toby Harradine
f0f274e1e1 Bump version to 3.1.4
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-16 11:26:25 +10:00
Toby Harradine
e9f014df07 Revert "Update Crowdin configuration file" (#2878)
This reverts commit 03e59ea9.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-16 10:44:49 +10:00
Toby Harradine
778eadd418 [ModLog] Fix get_case() and get_casetype() (#2877)
This fixes `[p]reason` and `[p]case` with cases that were created after 3.1.3.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-15 20:18:21 +10:00
Toby Harradine
3de9d15410 [CustomCom] Set Requires.ready_event before invoking CC (#2876)
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-15 20:13:06 +10:00
Michael H
3b0567d261 bump (#2864) 2019-07-14 00:17:44 -04:00
Michael H
49a75b5f19 command translator quick fix (#2870)
* command translator quick fix

* command translator quick fix
2019-07-14 13:55:47 +10:00
Toby Harradine
8676dd3ce3 [i18n] Update translation catalogs (#2867)
* [i18n] Update translation catalogs

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Install redgettext 3.1 in travis crowdin deployment

Last time the catalog templates were updated, redgettext 3.0 was used. I'd rather Travis didn't upload them after extracting with an older version.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-13 23:52:18 -04:00
Toby Harradine
d5c412e3df [Permissions] Fix Requires.ready_event.set() on subcommands (#2868)
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-13 23:05:07 -04:00
Toby Harradine
1d2980f8fa [Permissions] Send help on missing argument (#2865)
* [Permissions] Send help on missing argument

Resolves #2851.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* [Permissions] Use varargs instead of Greedy converter

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-13 21:52:28 -04:00
jack1142
3e80edcdfd [Docs] Add awaits and missing imports in usage examples (#2860)
Well, the modlog examples had to be changed a lot, because `await` obviously won't work in regular method.
2019-07-14 11:30:10 +10:00
aikaterna
be184b57dd [Audio] Update equalizer permissions (#2813)
* [Audio] Update equalizer permissions

* Reformat header on eq list for i18n

* Style
2019-07-13 20:48:13 -04:00
Toby Harradine
f83f378528 [Core] Make Requires.verify() wait until rules are loaded (#2857)
* Make Requires.verify() wait until rules are loaded

Also ensures `Requires` objects are reset when unloaded, particularly in case a `Command` object manages to stay in memory between cog unload and load, and its permissions rules change between those events.

Also, this PR re-ordered some of the event loop policy stuff, because it was required that the event loop policy be set before creating any `Requires` objects. This may or may not have an effect on other `get_event_loop()` calls elsewhere (either in our code, a dependency's, or asyncio's). Either way, these effects would be a *correction*, and any bugs that arise from it are likely to have been occurring silently beforehand.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Remove calls to `remove_listener()` in permissions

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Fix adding rules for permissions cog/commands itself

Also addresses feedback

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Clean up indentation when setting uvloop policy

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Use `set(walk_commands())` to traverse `Group` subcommands

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-13 20:47:40 -04:00
Michael H
21a6384ebf [Modlog] Fix get_case for missing cases (#2858)
Due to the modlog redesign, the detection for a missing case changed. This fixes `get_case` for this.

This resolves #2844.
2019-07-14 10:47:16 +10:00
Toby Harradine
03e0683dd7 [ModLog] Actually prevent duplicate kwarg error
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-13 14:39:50 +10:00
Michael H
ac2813012a [Core] Cog load fixes (#2854)
* split out some fixes from red#2853

* address feedback

* feedback
2019-07-12 22:11:06 -04:00
Toby Harradine
e34eca557b [ModLog] Prevent duplicate kwarg error (#2848)
* [ModLog] Prevent duplicate kwarg error

The `name` key used to be set in the Config for casetypes.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Don't mutate `data` argument

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-12 20:17:00 -04:00
Flame442
687b88ca6f Added some periods to some strings (#2852) 2019-07-12 18:29:27 -04:00
DevilXD
776c75ba86 Fixed [p] not being replaced in code blocks (#2846) 2019-07-09 03:22:52 -04:00
aikaterna
55ff9bedb7 [Audio] Check for player when not connected (#2842) 2019-07-08 13:17:50 +10:00
Toby Harradine
2bdc3ac10c [General] Fix KeyError in [p]urban
Resolves #2841.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-07 18:51:36 +10:00
Toby Harradine
f2039300c2 [Mongo] Use escaped identifiers to extract inner value (#2832)
This was causing a KeyError to be raised whenever a key containing $ or . was part of the identifiers path, even if the value was actually in the dict.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-07-05 18:02:18 -04:00
Cog-Creators Bot
03e59ea9d3 Update Crowdin configuration file 2019-07-05 20:21:25 +02:00
Draper
a89a156f8e [Context] Adds react_quietly method to context (#2834)
* [Context] Adds react_quietly method to context

This allows developers to emojis to command messages
This is a modified version of tick()

It accepts True/False for Tick/Cross emoji and in addition to that any other emoji the bot can see

* Removed True/False support from react quietly

* Stopped catching InvalidArgument on react_quietly so that is propagated to devs
2019-07-03 15:26:22 -04:00
Michael H
0eb22c84ff [Bank API] Add cost decorator (#2761) 2019-07-03 10:07:19 +10:00
aikaterna
d1593b8069 [Audio] Catch unhandled internal folder types (#2824)
The `folder:` and `localfolder:` prefixes are used internally with some localtracks strings to define what to do with the item when it's cycled through the search function. Users theoretically should have never seen this issue as [p]search is used on the user side for YouTube and Soundcloud searching and not local searching, but this handles the issue where a folder is being passed to these functions that doesn't exist.
2019-07-02 13:15:34 +10:00
aikaterna
93391d028c [Audio] _enqueue_tracks clarification/fix (#2822)
Resolves #2820.

Added some comments to clear up a little of the mystery in a couple places.
2019-07-02 13:11:44 +10:00
Flame442
142fb0ad08 [Trivia] Car list fixes (#2825) 2019-07-02 12:03:12 +10:00
jack1142
942dca43d3 [Downloader]: RepoManager: don't load repos in __init__ (#2829)
Loading repos is already done in initialize() method.
This could actually turn out badly
if both
of git processes would touch the same repo at the same time.

This also fixes create_backup in
setup.py - now it properly generates repos.json
2019-07-02 11:57:30 +10:00
jack1142
081bf663a4 test(core): ignore pylint's ImportErrors for distro package (#2830) 2019-07-01 21:54:56 -04:00
Toby Harradine
55e309125e Add uvloop as Posix+CPython dependency and tweak new Make recipes (#2819)
- uvloop is now a dependency on non-Windows CPython systems
- `make setupenv` renamed to `make newenv`
- `make syncenv` added to sync local venv to current dependencies
- `dev-requirements.txt` moved into `tools` directory
2019-07-02 11:53:38 +10:00
Flame442
7323e8eb67 [Trivia] Beethoven corrections for entertainment list (#2823) 2019-07-01 09:29:26 +10:00
Michael H
098540b9e5 [Core] Fix user output on cog load/reload (#2767)
* [Core] Fix user output on cog load/reload

  - Properly fixes the load/reload exception handling
  - Fixes some i18n use here to not make assumptions about other
  languages pluralization rules.

* Fix some typos

* Address Flame's Feedback

* It's important to save before committing ...

* formatting

* Fix some formats...
2019-06-29 12:16:28 -04:00
Elizabeth Sherrock
10412c4f51 Fix broken link in set color docstring (#2803) 2019-06-30 01:35:47 +10:00
PredaaA
2f8b1a21c7 [Audio] Fix config set in shuffle and repeat commands (#2812)
Resolves #2811 and also the same thing in repeat command.
2019-06-30 01:28:29 +10:00
PredaaA
03fe3ee720 [i18n] Fix some missing i18n strings in the whole bot (#2633) 2019-06-30 01:13:53 +10:00
Michael H
8a72840de0 [Utils] Modify chmod use in safe_delete (#2701)
- Takes a pessmisitc approach that it's possible chmod succeeds, but
 deletion fails and does not make the entire dir world writeable
2019-06-30 00:45:44 +10:00
Ryan
8bf86f33a3 [Readme] Update RTD and d.py URLs (#2771) 2019-06-30 00:33:41 +10:00
Michael H
8637f8a852 [Filter] Fix cache invalidation (#2810) 2019-06-30 00:30:09 +10:00
Toby Harradine
bff7e214ab Kill JsonIO and fix JSON driver caching issues (#2796)
* Kill JsonIO and fix JSON driver caching issues

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Ensure lock covers critical region in set()

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Make tests pass

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Use pickle over deepcopy in Config

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Fix temp instance creation

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Serialise value before doing anything in set()

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-06-27 14:49:45 -04:00
Toby Harradine
f3bbfdc64d Fix duplicate commands in fuzzy help (#2798)
* Fix duplicate commands in fuzzy help

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Use help command's filter for all fuzzy

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-06-27 13:31:44 -04:00
Toby Harradine
461f56bca1 Kill Pipfile, update dependencies, and add dep bumping tools (#2806)
### Replacement for pipenv's environment setup
First of all, there's a new Make recipe for all devs and contributors on both Windows and Posix, `make setupenv`, which is kind of a replacement for `pipenv install --dev`. It creates a virtual environment in `.venv` using the inbuilt `venv` module, clearing out any existing virtual environment if needed first. Then it installs all dev dependencies using our new `dev-requirements.txt` file. `CONTRIBUTING.md` has been updated to reflect all of this.

### Dependency version bumping tool
Secondly, I've added a python script, `tools/bumpdeps.py` to help with bumping dependency versions. It has its own Make recipe too, `make bumpdeps`. This script won't work on Windows (yet). It reads the `tools/primary_deps.ini` file, which contains the primary requirements of Red and its extras with loose version specifiers, and outputs all pinned dependencies, in `setup.cfg` format. It's not a foolproof dependency resolver, it's quite simple, but it's bound to help out a lot. It'll try to give warnings if there might be a version conflict, but updating `setup.cfg` with its output and then doing `pip install -r dev-requirements.txt` will allow pip to issue warnings if something is conflicting.

So to add a new dependency, add it to `tools/primary_deps.ini` in the appropriate place, and either use `make bumpdeps` to completely update all dependencies, or simply add it to `setup.cfg` manually with its sub-dependencies, and all versions pinned.

### Sphinx 2.1.2 (docs changes)
The sphinx update brought along the ability to disable type annotations being rendered in function and method signatures, and I have gladly gone and done that. Type annotations should already be specified under the "Parameters" section, and the way sphinx renders them in function signatures makes them much harder to read.

Also, documented classes will now display what classes they inherit from.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-06-28 00:16:14 +10:00
aikaterna
d1d4ec3e38 [Audio] No capitalization needed (#2801) 2019-06-27 08:13:01 -04:00
aikaterna
a0f34bbbd9 [Audio] Move DJ role check in [p]summon (#2799) 2019-06-27 10:48:06 +10:00
Toby Harradine
49819a2eeb [ModLog] Fix get_all_casetypes() (#2807)
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-06-26 20:39:22 +10:00
Toby Harradine
f91d8610ae [ModLog] Use custom scopes for ModLog Config (#2766)
Modlog was the biggest culprit for seriously large documents in the MongoDB backend, since it stored all cases as nested dicts in the guild scope. So, for example, on the Fortnite server, the guild document for Kowlin's bot had exceeded 8MB. 

This commit gives each case its own document. It also does the same for casetypes. Not only does it remove the possibility of the document exceeding the maximum size in MongoDB, it's also just more efficient for all backends.

Other misc changes: Fixed a bunch of type-hints, and also added more support for when an object related to a case (user, moderator, channel etc.) can't be found (because it was deleted or something rather)

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-06-26 00:52:33 +10:00
kennnyshiwa
52f5d5cd6a [Mod] add role mentions to userinfo and reverse role sorting (#2759)
* add role mentions to userinfo and reverse role sorting

This small PR adds the role mentions to userinfo and reverses the sorting so that the top most role of a user is at the left of the embed

* Remove sorting as it's handled by d.py
2019-06-24 02:39:03 -04:00
aikaterna
870b615364 [Audio] Queue & misc cleanup (#2784)
* [Audio] Queue & misc cleanup
2019-06-24 01:09:04 -04:00
aikaterna
25ccc11dc4 [Audio] Add [p]summon (#2786) 2019-06-24 01:05:01 -04:00
aikaterna
f2b7ce9546 [Audio] Add equalizer (#2787)
* [Audio] Add equalizer

* [Audio] Add equalizer
2019-06-24 00:58:20 -04:00
DiscordLiz
6bdc9606f6 [Core] Multiple mod admin roles (#2783)
* Adds Schema versioning
  - Adds Migration tool
  - Adds tool to migrate to allow multiple admin and mod roles
  - Supports Multiple mod and admin roles

* Ensures migration is run prior to cog load and connection to discord

* Updates to not rely on singular mod/admin role id

* Update requires logic for multiple mod/admin roles

* Add new commands for managing mod/admin roles

* Feedback

Update strings
Update docstrings
Add aliases

* Use snowflakelist

* paginate

* Change variable name

* Fix mistake

* handle settings view fix

* Fix name error

* I'm bad at Ux

* style fix
2019-06-23 23:36:00 -04:00
Toby Harradine
71d0bd0d07 Various Config and Mongo Driver fixes (#2795)
- Fixes defaults being mixed into custom groups above the document level when doing `Group.all()`
- Fixes `Config.clear_all()` with Mongo driver
- Fixes `Group.set()` with Mongo driver on custom groups above the document level
- Fixes `IdentifierData.custom_group_data` being set to the wrong thing in `BaseDriver.import/export_data` (although this was an inconsequential bug)

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-06-24 12:55:49 +10:00
Michael H
6ae3040aac [Filter] Make name filtering behavior consistent (#2794)
- Uses the updated filter check
  - This is also a performance gain on large servers with filter names
  enabled.
2019-06-23 16:39:24 +10:00
aikaterna
065396abab [Audio] Change Lavalink.jar version checking (#2785) 2019-06-23 14:10:31 +10:00
Toby Harradine
1804314f45 [Audio] Improve Lavalink download/connection exception handling (#2764)
- More errors will be logged to the console with clearer messages when something goes wrong
- Downloading the Lavalink Jar will abort after 5 failed attempts. The connect task will also abort if an unhandled exception occurs whilst downloading or connecting to Lavalink. After this occurs, instead of responding "Connection to Lavalink has not yet been established" to commands, the bot will respond "Connection to Lavalink has failed". This has no effect on other commands which don't involve connecting to Lavalink (e.g. settings commands).
- Logs this message when Lavalink jar is successfully downloaded: `Successfully downloaded Lavalink.jar (<x> bytes written)`
- Uses [`tqdm`](https://github.com/tqdm/tqdm/) to display a progress bar whilst downloading Lavalink.jar.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-06-23 14:09:59 +10:00
DevilXD
ff894ecbe7 [Docs] Add warning about PATH on Windows (#2791) 2019-06-23 13:55:48 +10:00
jack1142
0bf54fae52 [Admin] Convert set to list because set is not JSON serializable (#2792) 2019-06-23 13:33:27 +10:00
MeatyChunks
3c66c602f6 [Help] Prevent spamming when a user blocks the bot (#2790)
Currently the bot sends an error message for each page of help, this should make it only send once.
2019-06-22 01:41:11 -04:00
aikaterna
e854716236 [Audio] Fix for escape character prefixes (#2789) 2019-06-21 22:19:57 -04:00
jack1142
beb16b81a9 docs(config): wrong code example in Value.__call__ (#2780)
fix #2775
2019-06-21 21:24:23 -04:00
jack1142
57d5c0870a style(modlog): Phrase information about reason command better (#2777) 2019-06-19 08:40:25 -04:00
Neuro Assassin
9d008d587a [V3 Core] Add checks to [p]command (#2770)
* Add checks to [p]command

* Change to privilege level
2019-06-18 21:35:56 -04:00
DiscordLiz
804d6eecea [Core] Fix DictConverterer error handling format (#2776) 2019-06-18 21:25:49 -04:00
Toby Harradine
cc927248f0 Revert custom Bot.process_commands behaviour (#2768)
This still preserves the new event, which was a welcome change. However, context still needs to be invoked when a command isn't found, so `on_command_error` can still catch `commands.CommandNotFound`.

Fixes broken fuzzy help.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-06-12 18:27:47 -04:00
Toby Harradine
d133598d80 [Audio] Fix OSErrors on mixed-filesystem environments (#2765)
Resolves the issue outlined [here](https://github.com/Cog-Creators/Red-DiscordBot/issues/2682#issuecomment-500185495).

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-06-09 16:04:13 +10:00
Michael H
682ee1a459 [Docs] Fixes the docs for commands.Command.error (#2760)
* docfix

* inline code for sphinx, not a ref
2019-06-04 20:21:30 +02:00
El Laggron
61b5730c48 [V3 Core] More features for the bot invite URL (#1847)
* Add inviteset group command

* Fix errors

* Fix line break

* Remove user bot support

* Fix docstrings line breaks

* Remove embed specific formatting

* Remove invite redirect

* Add self argument to _can_get_invite_url

* Remove unused import

* fix errors related to classes + double help

* Removed self bot support
2019-06-03 11:46:13 -04:00
DevilXD
463d8d6306 [Commands] Added optional default_unit to the TimedeltaConverter (#2753)
* Added default_unit to the TimedeltaConverter

* Fixed a possible converter crash

* Updated get_timedelta_converter to incorporate the new kwarg
2019-06-03 07:46:55 -04:00
aikaterna
da40511306 [Audio] Remove blacklisted architectures (#2755) 2019-06-02 18:56:41 -04:00
aikaterna
c2195ec576 [Audio] Add bot permission checks (#2756) 2019-06-02 18:55:44 -04:00
Michael H
16443c8cc0 [CI] Improve automated checks (#2702)
* same stuff, but with some more spurious error supression

* fix issue in permissions found in this

* fix a few more spurious errors

* fix another issue

* semi-spurious error fixes

* .

* formatting

* move this to properly log

* distutils import + virtualenv

* more fixes
2019-06-02 19:42:57 +02:00
Bakersbakebread
9116cd02e6 [Core] Pass exceptions on Cog Load to user. (#2754) 2019-06-02 11:57:43 -04:00
Flame442
652d9fe950 Update version number to 3.1.2 🎉 (#2751) 2019-05-31 17:58:04 -04:00
Ryan
e956e6e320 [Streams] Ignore lack of rerun info where not available (#2748) 2019-05-31 16:41:23 -04:00
aikaterna
2e58922d01 [Audio] Lavalink jar bump (#2750) 2019-05-31 16:26:20 -04:00
Michael H
33b7652b62 [Help] Detatch menu usage into a task (#2725)
* [Help] Detatch menu usage into a task

  - This resolves #2712
  - This is a minor API change. Conceptually, the difference is minor in
  nature `bot.send_help_for` returns when help has been sent, however
  this can now be prior to when the help menu (if one is in use) is
  closed.

  - This should not be considered breaking as there is and has been a
  a warning about this file's APIs being still up for unannounced modifications
  No developers should be currently relying on this behavior.

* operator precendence
2019-05-31 21:41:04 +02:00
Michael H
0e9086ca1f [Core] Fix error handling in loading extensions. (#2688)
* fixes 2687

* raise the right exception
2019-05-31 21:38:44 +02:00
Michael H
3ca2a9af28 [Help] Fix long cog helps (#2730)
* [Help] Fix long cog helps

  - Why do people thing a category help of over 250 characters is more
  useful than putting the help in relevent commands?!

* toss an MD fix in here too I guess
2019-05-31 21:37:50 +02:00
DiscordLiz
e7b615d921 [Commands] Adds support for non interactive use (#2746)
Adds assume_yes to context
Changes cleanup's 100+ check
Changes cog update.
2019-05-31 05:54:27 -04:00
Matan Kushner
2cb6e98092 [Readme] Anilist → AniList (#2747) 2019-05-31 05:39:14 -04:00
DiscordLiz
1ccc441aab [Core] Make contact use configured destinations (#2743)
* Make contact use configured destinations
2019-05-31 05:32:26 -04:00
DiscordLiz
8ddc5aa63e [Core] Add commands to manage owner notification destinations. (#2745) 2019-05-31 05:13:36 -04:00
DevilXD
f894b62bfe [CustomCom] Fixed KeyError on specific message edge-case (#2739)
fixes #2679
2019-05-29 22:36:32 -04:00
DevilXD
aac9369f3f [Mod] Add [p]slowmode (#2734)
Makes use of new timedelta converter
2019-05-29 10:01:27 +10:00
DiscordLiz
1581604f71 Add a timedelta converter (#2736)
* Add a timedelta converter

This reuses a lot of logic from @mikeshardmind 's scheduler cog with permission

It adds a timedelta converter
It keeps it generalized as requested
It keeps the function available for non converter use as requested

* Handle feedback

* style fix
2019-05-28 12:43:55 -04:00
DiscordLiz
56161c0a88 Send to owners (#2738)
* Add bot.send_to_owner

resolves #2665

Adds some basic methods and config entries.

Does not add commands for modifying this yet.

* Use send_to_owners in events

* handle feedback
2019-05-28 12:37:02 -04:00
DiscordLiz
242df83785 [Image] Fix some issues in strings (#2737) 2019-05-28 02:47:44 -04:00
Stonedestroyer
2338ad8223 [Image] Fix giphy api (#2653)
* Remove hardcoded Giphy key.

Allows you to set your own Giphy API key.

* Run black

* Fix Giphy name

On their website it's spelled GIPHY.
2019-05-27 21:04:15 -04:00
PredaaA
b4f4e080af [core_commands] Using humanize_timedelta for [p]uptime command (#2735)
* Update core_commands.py
2019-05-27 20:39:36 -04:00
Flame442
132545e057 [Audio] Clarity changes for the API info commands (#2733)
* Clarity changes for the API info commands

* Remove unnecessary f-string
2019-05-27 20:27:56 -04:00
Michael H
68590dfdb8 [Core] Improve API token converter (#2692)
* improve api converter

* make usage more clear
2019-05-25 23:58:14 +02:00
Neuro Assassin
2e271d695b Add respectable aliases for consistency (#2731)
* Add respectable aliases for consistency

* General command name for alias.py

* Forgot one for alias

* General command for filter

* General command for warnings

* Whoops

Resolves #1749
2019-05-24 18:22:17 -04:00
Stonedestroyer
cd745d35c2 [Core] Add debug info command (#2728)
Shows useful debug information for debugging.
2019-05-24 17:55:48 -04:00
Flame442
6928e2aca2 Fixes some issues with API help commands (#2729)
* Fixes some issues with `[p]streamset youtubekey/twitchtoken`

Lots of general formatting bugs and clarity issues.

* General formatting bugs and clarity issues
2019-05-24 17:52:43 -04:00
Kowlin
49e86614c5 Adding support for GitHub Funding (#2732)
(I'm lazy, I know I should use a fork... sorry <3)
2019-05-24 20:10:55 +02:00
jack1142
51dcf65fd7 [Downloader] Fix problem with copying directory tree. (#2690)
* fix(downloader): clear paths in `distutils.dir_util._path_created` before copying tree

fix #2685

* style(downloader): add comment about PR
2019-05-23 03:08:14 -04:00
Michael H
c6c0165214 [Help] Special case fixing for empty docstring (#2722)
Resolves #2415
2019-05-22 18:22:31 +10:00
PredaaA
342935de49 [Trivia] Remove bold on a box (#2716) 2019-05-21 17:50:51 -04:00
jack1142
ced5bb4631 docs(install): remove information about voice extra (#2717) 2019-05-21 17:49:25 -04:00
DiscordLiz
0a832cee9c [Utils] Allow functools.partial use with menu (#2720) 2019-05-21 16:52:44 -04:00
Brenden Campbell
1cfce8b72c Fix minor typo (#2713) 2019-05-20 13:24:05 -04:00
jack1142
cdcde26dfc [Setup] Fix: wrong var used for instance data in remove_instance (#2709) 2019-05-19 10:13:01 -04:00
Fixator10
1ffb79f852 [events] send help on BadUnionArgument exception (#2707)
* [events] send help on BadUnionArgument exception

* Update redbot/core/events.py

Co-Authored-By: Michael H <michael@michaelhall.tech>
2019-05-19 06:14:12 -04:00
Michael H
644aaf0c0e [Help] Continuing work and bug-fixes (#2676)
* [Help] Add settings for various things

  - Fixes a small issue in a previously not-exposed logic path
  - Fixes an issue with denied commands help invocation
  - Adds some global usage settings

* remove outdated comment

* improve intent of strings

* added punctuation

* Add DM forbidden handling

* use a slightly different method for shortening embed width specifically
2019-05-18 06:54:02 -04:00
Michael H
cdea03792d [Streams] Fix NameError (#2699)
- fixes #2696
 - My fault for just looking at the github diff and seeing the logic fix
 on this one, without verifying the name validity in surrounding
 context. (see my review in #2679)
2019-05-18 00:59:26 -08:00
Flame442
b190e7417e [Downloader] Adds ctx.typing() to [p]pipinstall (#2700) 2019-05-17 21:40:42 -04:00
zephyrkul
7dd3ff7c8d [Core] Strip commas in user input for load, reload, unload (#2693)
rstrip commas, closes #2695
2019-05-16 23:54:17 -04:00
palmtree5
21a253103e [V3 Streams] fix an issue with stream commands not dealing with reruns (#2679) 2019-05-16 22:28:26 -04:00
El Laggron
db3fb29b30 [docs] Fix typo (#2691) 2019-05-16 17:03:09 -04:00
Neuro Assassin
c5d2ae5831 Mention voice channel in [p]userinfo (#2680)
* Mention voice channels, due to new discord update

* Add ID part back in, as Discord doesn't have copy ID for it yet
2019-05-16 15:12:09 +02:00
jack1142
9d0ca00f89 [General]: shorten descriptions properly with disabled embeds in urban (#2684)
fix #2683
2019-05-16 02:06:46 -04:00
DevilXD
79e5d2c9d7 Fixed command doc formatting in code blocks (#2678) 2019-05-15 20:01:02 -04:00
Fixator10
3a62d392b4 [Mod] [p]names utilize consume-rest (#2675)
Currently, `[p]names` requires quotes, if "user" arg contains spaces
2019-05-15 10:33:10 -04:00
Michael H
f2858ea48c [Core] Fix update notification (#2677)
removes a problematic await
2019-05-15 16:31:00 +02:00
Michael H
3c78fb420b [Help] Fixes some issues with fuzzy help (#2674)
* Fixes some issues with fuzzy help

 - also cleans up some name shadowing which wasn't causing issues
 (curently)

* ver

* style
2019-05-14 23:52:06 -07:00
Michael H
2d22ee7ccc 🎉 (#2673) 2019-05-14 21:30:52 -08:00
Michael H
9a243a1454 [Utils] Tools for marking things unsafe for general use (#2326)
* Tools for marking things unsafe for general use

* I'm facepalming so much...

Actually, make the two do something different 
instead of getting distracted writing different docs for both based on intended usage.

* local scopes mmkay + tests

* Move file to adress feedback

* typo fix

* Update __init__.py

* Fix issue with exported names in __init__

* changelog
2019-05-14 20:56:41 -07:00
Will
165e40c0db [Mongo] Unescape dict keys when rebuild (#2671)
* Unescape dict keys when rebuilding

* update pipfile

* Really update pipfile now
2019-05-14 23:50:51 -04:00
Michael H
7f1c2b475b [Core] Help Redesign (#2628)
* [Bot] Support new design

* [Context] use the new help in `ctx.send_help`

* [Commands] Update Cog and Group for help compat

- Removes a trap with all_commands, this isn't a good way to check this
- Adds a help property
- Fixes command parsing in invoke

* Redesigns red's help

* handle fuzzy help

* style

* handle a specific ugly hidden interaction

* fix bot-wide help grouping

* changelog

* remove no longer needed -
2019-05-14 20:49:51 -07:00
palmtree5
a5f38fa6e6 Add my 3.1 contributions (#2670) 2019-05-14 19:38:18 -08:00
Michael H
598968bf74 [Audio] Lavalink jar bump (#2669) 2019-05-14 20:35:09 -07:00
Will
ee661b0a9f [Docs] Add release notes for major functionality changes and instructions (#2668)
* Add release notes for major functionality changes and instructions

* Update docs/changelog_3_1_0.rst

Co-Authored-By: Michael H <michael@michaelhall.tech>
2019-05-14 20:30:17 -07:00
Michael H
7d7b3413bc Add contributions to changelog (#2666)
* Put some stuff in the changelog

* explicit note on d.py ver
2019-05-14 23:07:22 -04:00
Flame442
7400008384 Adds [p]datapath to print the bot's data path (#2652)
* Add `[p]datapath` to print the bot's datapath

* Adds 2652
2019-05-14 01:05:52 -04:00
TrustyJAID
4e564e8ce4 [V3 Economy] lookup users from the guild instead of using stored names (#2637)
* [V3 Economy] lookup users from the guild instead of using stored names

* Make user ID only appear when owner calls the leaderboard and the user is not in the guild also black formatting

* Slight optimizations in formatting and fix error when no banks exist
2019-05-14 00:52:08 -04:00
aikaterna
8691fdc533 [Docs] Update Mac install instructions for Java (#2663) 2019-05-14 06:46:30 +02:00
Flame442
7d103f1d32 [Docs] Typo fix (#2658) 2019-05-14 00:34:19 -04:00
Kowlin
3de1a265ea [Core] Added co-owners to outdated message warnings (#2664)
* Added co-owners to potentially DMd users

* Fetch the cached of every guild, see comments of #2664

* Ensure owners can be DM'd.

* Refactoring try block.
2019-05-14 00:33:05 -04:00
entchen66
3b6d4d9df6 [Cleanup] Fix for 3.1 (#2661)
cleanup before use get_message wich isn't possible anymore in dp 1.0.1. so I changed it to fetch_message
2019-05-13 05:39:28 -04:00
Michael H
e96e5374b4 Update intershpinx refs (#2660) 2019-05-13 12:02:57 +10:00
Toby Harradine
5c91709ac8 Remove vendoring note in README 2019-05-10 10:34:17 +10:00
NIXC
96a91b9d0e [Audio] Add ability to skip to a specified track by number (#2584)
* add skip to track functionality

* formatting

* Change some strings

* missing return, variable naming

* add variable names for translations

* change handling of skipping 1 track

* minor semantic adjustments

skiptotrack -> skip_to_track
2019-05-08 01:34:37 -04:00
aikaterna
65b88c09fb [Audio] Update for Red-Lavalink 0.3.x (#2547)
* [Audio] Update for Red-Lavalink #55

* Update setup.cfg

* Catch all the exceptions

* Update version range on Red-Lavalink

* Catch excepts on Spotify tracks/playlist upload

* No prefix needed
2019-05-08 00:56:40 -04:00
Flame442
80ff07f53d [Core] Fix two typos in API Token Converter (#2650) 2019-05-07 16:12:08 -04:00
Flame442
4f6485d1f9 [i18n] Changes default locale value from en to en-US (#2642)
* Changes default locale value to `en-US`

* Added this PR

Also fixed slight inconsistency in what is in a code block (if this is merged)
2019-05-06 12:19:57 -04:00
Flame442
d1c903f36f Fix grammar mistake by changing "to large" to "too large" (#2646) 2019-05-06 12:18:57 -04:00
Kowlin
516ebcfa2b Fixed missing imports. (#2643)
* Added changelog

* Fixed missing imports.
2019-05-03 10:22:06 -04:00
Kowlin
9414de24d4 [Mod] Added voice kicking. (#2639)
* Added voice kicking.

* Reversed exceptions.

* Lets use a check that works for this task 👀

* Update abc.py

* Black formatting
2019-05-03 10:08:25 -04:00
Michael H
16990071cb [V3 core] on_message_without_command dispatch (#2338)
* conveinience and performance addition with new dispatch

* I promise, I read the specs first.

* Really, I read the fucking specs.
2019-05-02 16:25:35 -04:00
James
52433d253f String format failure when set invoked without subcommand (#2638) 2019-05-02 15:44:33 -04:00
Will
bb6327d969 [Audio] Fix architecture blacklisting (#2634) 2019-04-30 12:32:16 -04:00
Toby Harradine
476f441c9b [Audio] Refactor internal Lavalink server management (#2495)
* Refactor internal Lavalink server management

Killing many birds with one stone here.
- Made server manager into class-based API with two public methods: `start()` and `shutdown()`. Must be re-instantiated each time it is restarted.
- Using V3 universal Lavalink.jar hosted on Cog-Creators/Lavalink-Jars repository.
- Uses output of `java -jar Lavalink.jar --version` to check if a new jar needs to be downloaded.
- `ServerManager.start()` won't return until server is ready, i.e. when "Started Launcher in X seconds" message is printed to STDOUT.
- `shlex.quote()` is used so spaces in path to Lavalink.jar don't cause issues.
- Enabling external Lavalink will cause internal server to be terminated.
- Disabling internal Lavalink will no longer reset settings in config - instead, hard-coded values will be used when connecting to an internal server.
- Internal server will now run both WS and REST servers on port 2333, meaning one less port will need to be taken up.
- Now using `asyncio.subprocess` module so waiting on and reading from subprocesses can be done asynchronously.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Don't use shlex.quote on Windows

Signed-off-by: Toby <tobyharradine@gmail.com>

* Don't use shlex.quote at all

I misread a note in the python docs and assumed it was best to use it. Turns out the note only applies to `asyncio.create_subprocess_shell`.

Signed-off-by: Toby <tobyharradine@gmail.com>

* Missed the port on the rebase

* Ignore invalid architectures and inform users when commands are used.

* Style fix
2019-04-29 21:31:28 -04:00
Neuro Assassin
c79b5e6179 [Core Commands] Add patch for invalid path with [p]backup (#2626)
* Add patch
2019-04-29 19:38:36 -04:00
aikaterna
c1bee3fee5 [V3 Audio] Add settable path for external Lavalink (#2480) 2019-04-29 18:34:09 -04:00
aikaterna
d786103d8d [Audio] Set cwd for localtracks on playlist start (#2534) 2019-04-29 18:28:44 -04:00
Neuro Assassin
b3850f6bb7 [Cleanup] Add [p]cleanup between (#2617)
* Add `[p]cleanup between`

At the moment, only deletes the messages in between, does not delete the messages specified when running the command.

* Create converter for message IDs; remove f-strings; use converters in a few extra commands

* Sacrifice to the style gods
2019-04-29 15:55:23 -04:00
PredaaA
e3db3c0341 [Core_commands] Fix some missing i18n strings (#2631)
* Update core_commands.py

* Update core_commands.py
2019-04-29 15:21:58 -04:00
jack1142
1ce3bc2870 [Downloader] Suppress commands.ExtensionNotLoaded for bot.unload_extension() call (#2625)
fix(downloader): suppress `commands.ExtensionNotLoaded` for `bot.unload_extension()` call (#2625)
2019-04-29 12:42:36 -04:00
jack1142
24ac111782 [V3 Downloader] Allow to specify minimum and maximum bot version in info.json (#2605)
* feat(downloader): add `min_bot_version` and `max_bot_version`

Adds actually working way of specifying minimum and maximum bot version and removes not working
`bot_version`

BREAKING CHANGE: - removal of `bot_version` attribute in `Installable`

* test(downloader): `Installable` tests fix for new bot version attributes

* docs(changelog): added changelog entries for this PR
2019-04-29 12:33:49 -04:00
Flame442
07f127ffe4 [Docs] Changelog entries for contributions by Flame (#2627) 2019-04-29 12:06:02 -04:00
Will
c58f566047 [CustomCom] Update command generator to work with dpy update (#2616)
* I think this works?

* Let's do it

Co-Authored-By: tekulvw <tekulvw@users.noreply.github.com>
2019-04-25 12:31:58 -04:00
Tyler Adam
f28d6dff32 [Streams] Add ability to exclude rerun streams from alerts (#2620)
* [Streams] Add ability to exclude rerun streams from alerts

* [Docs] Changelog entries for contributions by EgonSpengler

* Changelog entry for #2620 [Streams] Ignore Reruns In Alerts
2019-04-25 11:58:58 -04:00
Neuro Assassin
7e49ce9a7b [Mod] Remove error when unbanning an unknown user (#2619)
Fix for #2542
2019-04-25 11:57:26 -04:00
Will
59115cd1c7 [Commands] Fix built in check decorator order affecting permissions (#2621)
OOOoooooOOOoOOOooOoOOOOoooo
2019-04-25 11:51:02 -04:00
PredaaA
1d93fe4cf9 Update changelog_3_1_0.rst (#2615) 2019-04-25 05:44:34 +02:00
aikaterna
3f1f7640cb [Docs] Changelog entries for contributions by aikaterna (#2614) 2019-04-24 20:55:32 -04:00
TrustyJAID
83ee7c5e92 [V3 Dev] Fix repl command sanitize api keys (#2613) 2019-04-24 20:54:50 -04:00
jack1142
b95ddf18ba [Docs] Changelog entries for contributions by jack1142 (#2612)
* docs(changelog): [Mod] Allow admin to choose amount of repeats for "deleterepeats" #2437

* docs(changelog): Spelling correction of method name in Tunnel #2496

* docs(changelog): Tunnel fix - When tunnel closes, message should be sent to other end #2507

* docs(changelog): [V3 Downloader] Tell user how to load the cog after [p]cog install #2523

* docs(changelog): [V3 Audio] If bot has move members perm, it can join to user-limited channels #2525

* docs(changelog): [Trivia] Fix of dead image link (world flags) #2540

* docs(changelog): [V3 Test] Make sure that trivia test will use utf-8 encoding #2565

* docs(changelog): [V3 Core] Print actual version, when `--version` flag is used #2567

* docs(changelog): [V3 Downloader] Stop including subpackages in cog list #2590

* docs(changelog): [V3 Downloader] Uninstall multiple cogs #2592

* docs(changelog): [V3 Downloader] Always remove cog from installed in `[p]cog uninstall` #2595
2019-04-24 20:06:51 -04:00
Will
61d255726c [Docs] Add initial changelog document (#2611)
* Add initial changelog document

* add initial links

* oops
2019-04-24 17:08:55 -04:00
Will
05e2851c67 [Config] Migrate UUID for JSON backend (#2604)
* Migrate UUID for JSON backend

* Interesting...

* black

* Simplify UUID creation
2019-04-24 16:03:27 -04:00
Will
f20a174038 Fix the check to raise the correct message (#2603) 2019-04-24 21:24:31 +02:00
Michael H
ec108e7c02 [Alias] cleanup issues missed with #2587 (#2610) 2019-04-24 11:43:47 -04:00
Michael H
ad114295e7 Discord.py dep update 3.1 (#2587)
* Dependency update

discord.py==1.0.1
websockets<7

[style]
black==19.3b0

[Docs]
jinja==2.10.1
urllib3==1.24.2

Changes related to breaking changes from discord.py have also been made
to match

As of this commit, help formatter is back to discord.py's default
2019-04-23 21:40:38 -04:00
aikaterna
0ff7259bc3 [Audio] DJ role should ask for a role (#2606) 2019-04-23 18:41:46 -04:00
TrustyJAID
49af94334e Add Central API Key Documentation (#2574) 2019-04-23 23:51:37 +02:00
Flame442
22c318fda3 [Core] Adds a check to [p]set locale (#2553)
* Adds a check to [p]set locale

Fixes #2552
I would like a little bit of feedback on this change.
- Right now, `locale_name` is case sensitive. Should that remain case sensitive or should I allow it to accept it case insensitively?
- I made the invalid locale string an i18n string, however I don't know the process for how those are supposed to be made or if that will break anything. Should that remain an i18n string or should I make it a normal string?

* Case insensitivity and explicit en-US

-`[p]set locale` is now case insensitive
-`en-US` added to `[p]listlocales` instead of only existing in `[p]set locale`'s help text

* Remove spacing
2019-04-23 17:43:50 -04:00
jack1142
da5fd7699e [V3 Downloader] Always remove cog from installed when using cog uninstall (#2595) 2019-04-23 14:26:16 -04:00
Michael H
3d498a74ba [Docs] Update docs for redbot.core.humanize_list (#2598)
closes #2546
2019-04-23 14:16:15 -04:00
jack1142
460b4bb3f2 [Mod] Allow admins to choose amount of repeats for "deleterepeats" (#2437)
* feat(mod): configurable amount of repeats for "deleterepeats"

resolves #2267

* fix(mod): check user input instead of changing it if it's invalid

* fix(mod): only purge cache when argument is valid

* perf(mod): fetch repeats from config only when guild not in cache
2019-04-23 10:01:20 -04:00
Tyler Adam
47723cee33 [Mod] make [p]ban days parameter optional as per the doc (#2602) 2019-04-23 09:45:28 -04:00
Tyler Adam
a1b03be27e Add support for custom stream alert messages per guild (#2600) 2019-04-23 02:57:46 -08:00
Michael H
012d99c05c [Utils] Better error handling for humanize_list (#2597) 2019-04-22 22:34:38 -04:00
jack1142
2c8a425f87 [V3 Downloader] Uninstall multiple cogs (#2592)
* feat(downloader): Uninstall multiple cogs

* refactor(downloader): Put everything in one message
2019-04-22 20:17:30 -04:00
Flame442
8555f8c28c [Downloader] Pretties up the output when libraries fail to install (#2576)
* Pretties up the output when libraries fail to install

* Stupid double quote bullshit

* Added jack1142's suggestion

* I will never satisfy the eldritch being named black
2019-04-22 20:15:26 -04:00
jack1142
46413c2c52 [V3 Downloader] Stop including subpackages in cog list (#2590)
Before this change, `Repo.available_modules` would also contain subpackages, which is unintended
2019-04-22 20:07:52 -04:00
TrustyJAID
eaeaf9dd69 [V3 Streams] Change twitch and youtube top level commands (#2479) 2019-04-22 20:06:50 -04:00
zephyrkul
ee11d7da63 [V3 Audio] Cancel emptydisconnect when no longer alone (#2519)
* [audio] cancel disconnect when no longer alone

* [audio] fix modifying while iterating
2019-04-22 20:05:37 -04:00
NIXC
0ac93aacd5 [V3 Economy] Add default cooldown to slots (#2561)
* Add default cooldown to slots

To prevent abuse

* slight boost in time

1 second actually doesn't help, needs a bit more.
2019-04-22 19:44:05 -04:00
TrustyJAID
691d8af26d [V3 Warnings] Utilize modlog cases (#2471)
* [V3 Warnings] Utilize modlog cases

This update utilizes modlog cases for warnings and slightly improves usage of custom warnings if enabled.

* remove BadArgument error response

* Utilize Optional and consume-rest for points and reason

* black format

* Remove unnecessary imports, cleanup error handling, and improve docstrings
2019-04-22 19:34:36 -04:00
TrustyJAID
87c66b2423 [V3 Admin] Fix errors when hierarchy issues are raised (#2498)
* Fix addrole mentioning who we're trying to add the role to

* More things are broken, huh

* formatting...
2019-04-22 19:25:44 -04:00
aikaterna
005123a371 [Audio] Fix for playlist queue when not playing (#2586) 2019-04-22 19:17:44 -04:00
aikaterna
bb8ce43cc0 [Audio] Track search and append fixes (#2591)
* [Audio] Track search and append fixes

* Appeasing the style gods
2019-04-22 19:17:17 -04:00
palmtree5
13611e34d2 Fix extras in launcher (#2588)
Now non-existent voice extra was still hanging around in the launcher while the style extra was never added in
2019-04-22 14:46:07 -08:00
Neuro Assassin
b8190c44a8 [Dev] Sanitize API tokens in debug and eval (#2585)
* Sanitize API tokens in debug and eval

* Not sure what happened there
2019-04-22 18:43:02 -04:00
Will
95d5ec5f0e [Setup] Fix the mongo name to create instances using new driver (#2594)
* oops

* damn you
2019-04-22 18:33:52 -04:00
zephyrkul
874204bf18 [mongo setup] utilize getpass (#2593) 2019-04-21 07:04:08 -08:00
Will
6c296a9a17 [V3 Setup] Overhaul backend conversion process through setup scripts (#2579)
* swap to click for setup

* Initial changes

* expose some stuff to allow for per-driver optimizations

* overwrite base config

* add red log

* add one print juuuust in case

* fix this

* thanks kowlin

* damn

* oops

* fix thing

* partial commit

* Working mongo -> json conversion, it sucks tho

* remove unused line

* Wrote initial optimized json importer

* optimized json importer

* remove useless line

* update mongo to json converter

* lets try writing the correct entry

* oops

* style fix

* add some garbage data filters going from old mongo to json

* ignore garbage data in mongov2 conversions

* simplify code a bit and add a completion message

* missed one

* Update pipfile lock

* Lock click version
2019-04-20 20:10:44 -04:00
PredaaA
ad06b0e723 [Audio] Fix issue on audiostats command when more than 20 servers to display (#2533)
* Update audio.py

* Fix of pages counter.
2019-04-18 12:12:16 -04:00
Will
0652dd344b [V3 Mongo] Correct dictionary rebuilding process for global all case (#2581) 2019-04-13 15:51:49 -04:00
Will
8b3c3e89e9 [V3 Mongo] Fix all behavior (#2580) 2019-04-13 15:24:50 -04:00
Will
c82ac5ae68 Add some errors for backend conversions and only allow MongoV2 creation (#2570)
* Add some errors for conversions and only allow mongoV2 creation

* Add another message

* Fixed message to be more clear
2019-04-10 20:42:28 -04:00
jack1142
2776db0cf9 [V3 Core] Print actual version, when version flag is used (#2567) 2019-04-10 19:32:20 -04:00
Will
ba19179e4f [V3 Config] Record custom group information using cog_add event (#2550)
* Do things differently

* Uncomment critical lines

* Reduce, reuse, recycle

* Check groups on all new config objects after a cog loads

* I don't know why this is failing now or why we need the global keyword

* gotta fix this too
2019-04-09 22:02:50 -04:00
jack1142
e347ffa336 Bot can join voice channel with user limit if it has move members perm (#2525) 2019-04-09 20:33:19 -04:00
kennnyshiwa
c85af62401 Fix message when user hits max credits (#2563)
* Fix message when user hits max credits

Fixes the error message when a users issues the payday command when having max credits

* Update economy.py

Changed message when user hits max payday and bank is global to match message when bank is per server

* Update economy.py

made statements match
2019-04-09 18:54:44 -04:00
aikaterna
39b64b7570 [Audio] Fix for localtrack playing (#2557) 2019-04-09 17:13:57 -04:00
aikaterna
56b220b92e [Audio] Fix for prev command display (#2556) 2019-04-09 17:10:25 -04:00
jack1142
972fbecc94 [V3 Trivia] Make sure that test will use utf-8 encoding (#2565) 2019-04-09 17:03:34 -04:00
Michael H
136e781c7f Kill DataConverter (#2554)
* Kill DataConverter

* remove the tests
2019-04-09 17:01:04 -04:00
Will
0852d1be9f [V3 Config] Require custom group initialization before usage (#2545)
* Require custom group initialization before usage and write that data to disk

* Style

* add tests

* remove custom info update method from drivers

* clean up remnant

* Turn config objects into a singleton to deal with custom group identifiers

* Fix dumbassery

* Stupid stupid stupid
2019-04-04 21:47:08 -04:00
Will
fb722c79be [V3 ModLog] Change register_casetypes behavior (#2551)
* Ignore runtime error in register_casetypes

* Fix documentation
2019-04-04 18:59:14 -04:00
jack1142
c63d069f69 [Trivia] Fix of dead image link (world flags) (#2540)
* New image link for Sao Tome and Principe

Current link is dead

* Someone didn't pay attention on geography lessons
2019-04-03 11:40:20 -04:00
Will
1cd7e41f33 [V3 Config] Update Mongo document organization to bypass doc size restriction (#2536)
* modify config to use identifier data class and update json driver

* move identifier data attributes into read only properties

* Update mongo get and set methods

* Update get/set to use UUID separately, make clear work

* Remove not implemented and fix get_raw

* Update remaining untouched get/set/clear

* Fix get_raw

* Finally fix get_raw and set_raw

* style

* This is better

* Sorry guys

* Update get behavior to handle "all" calls as expected

* style again

* Why do you do this to me

* style once more

* Update mongo schema
2019-04-03 09:04:47 -04:00
zephyrkul
d6d6d14977 [V3 Alias] Customize Parameters (#2455)
* [alias] custom parameters

Signed-off-by: zephyrkul <zephyrkul@users.noreply.github.com>

* [alias] quoted words remain quoted

Signed-off-by: zephyrkul <zephyrkul@users.noreply.github.com>

* [alias] fix no-parameter aliases

Signed-off-by: zephyrkul <zephyrkul@users.noreply.github.com>

* [alias] remove unneeded error dispatch

it was expensive and did nothing anyway from my own testing
2019-04-02 23:08:28 -04:00
PredaaA
82cda4b57a Delete cooldown messages when expired (#2469) 2019-04-02 23:06:30 -04:00
Toby Harradine
301c800319 Logging enhancements and cleanup (#2502)
* Logging enhancements and cleanup

- Removed debug log messages every time `Config.get_conf` is used or a JSON file is read/saved. The basic configuration is now logged once with DEBUG when the bot starts up instead.
- Changed logging output format to reverse date order, include seconds, and use the logger's name instead of the module, function and line number.
- Log files are now kept in the `DATAPATH/core/logs` directory. Each time Red is restarted, a new log is created, and the old ones renamed in a rotating fashion. There can be a maximum of 9 logs in total.
- Each log file now has a smaller max size of 500KB before it will be split into multiple parts. There are also a maximum of 9 parts of each log.
- Discord.py logger now uses the same output formatter as red's loggers
- Moved logging setup code into `redbot.logging` module.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Reformat

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Implement discussed changes

- We maintain a red.log over multiple runtimes, alongside a latest.log and previous.log for individual runtimes.
- Naming convention changed a bit. E.g. when latest.log is just one part, it will be named latest.log. When it becomes two parts, they will both be named latest-part1.log and latest-part2.log.
- Rotation direction is reversed. This means as the files end up being named in chronological order.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-04-02 22:58:34 -04:00
DiscordLiz
30af83aa6a [Permissions] Allow for multiple IDs in permissions rule commands. (#2448)
Use `commands.Greedy` to apply multiple rules at once.

closes #2214
2019-04-02 22:53:07 -04:00
jack1142
0f9501f93a Tunnel - Send message after close (#2507) 2019-04-02 22:50:01 -04:00
Michael H
466b2b82d0 Fix localwhitelist/localblacklist add/remove (#2531) 2019-04-02 22:46:12 -04:00
Michael H
8ab39512d9 [Filter] Performance increases. (#2509)
* [Filter] Performance increases.

The filter was already using re to split words, this just does the entire search in re instead.

A further improvement to this would cache patterns used and update them if the wordlist changes.

* Add a pattern cache

* exit on no-words

* formatting pass

* keep the return type consistent, even though this doesnt break core since this is available to cogs

* ...

* Quit being an idiot

* Slight further improvements, a fix, and restructure

Moved actual set creation out of the inner portion.
Reduced config lookups in case of no filter.
Fixed channel wordlist fetching.

* I really should go back to using a pre-commit hook for the style stuff
2019-04-02 22:42:13 -04:00
jack1142
e08e95c04e [V3 Downloader] Tell user how to load the cog after [p]cog install (#2523)
* tell user how to load the cog after install

* use code block
2019-04-02 22:35:21 -04:00
FixedThink
e7b1fa5ab5 [V3 Trivia] Update "World" trivias to reflect legislative changes (#2526)
* Update worldmap.yaml

* Update worldflags.yaml

* Update worldcapitals.yaml
2019-04-02 22:33:40 -04:00
Flame442
14a2f98418 [Docs] Adds self recommendation to cog_data_path (#2539)
This change adds the help text of "If calling from a command or method of your cog, this should be self." from `bundled_data_path` to `cog_data_path`. This bit of text can help people who are unsure of what a "cog instance" is to understand how to use `cog_data_path`.
2019-04-02 22:24:20 -04:00
aikaterna
de7d08ee75 [Audio] Match v2 behavior for channel change (#2521)
* [Audio] Match v2 behavior for channel change

* Use move_to instead of connect
2019-04-02 22:22:57 -04:00
aikaterna
2a486cad66 [V3 Audio] Playlist info improvements (#2274)
* [V3 Audio] Playlist info improvements

* Add pagify import, reformat for Black

* Change from code block to embed with links
2019-04-02 21:48:21 -04:00
aikaterna
80fc639480 [V3 Audio] Queue clean and queue clear addition (#2476)
* [V3 Audio] Queue clean and queue clear addition

* Use DJ role and existing checks inst. of mod/admin

* Remove unneeded .format()
2019-04-02 21:12:55 -04:00
Michael H
c7608aeb17 [V3 Mod] Use a composite class for mod (#2501)
* [V3 Mod] Use a composite class for mod

This turns mod.py into acomposite class

I've split things in this up based on purpose, including `movetocore`

`movetocore` is a set of things which likely belong in the core bot and
not relying on mod being loaded.

This is part of #2500

Per discussion in discord, this should be the first thing in #2500
merged

* Move this back,
mod was importable,
and this was intended as non-breaking

* Prevent fix from being lost if merged before this.

see Cog-Creators/Red-DiscordBot#2510

* Move case creation to before sending

see #2515

* fix failed merge done in web
2019-04-01 03:34:27 -08:00
aikaterna
050300040c [V3 Audio] Add Spotify support (#2328)
* [V3 Audio] Add Spotify support

* [V3 Audio] Update LICENSE

* Appeasing the style gods

* Extra word removal on LICENSE

* Update for #2389

Thanks to TrustyJAID for the help.

* Playlist command support for Spotify URLs or codes

* Add exception for dc while loading Spotify tracks

* Allow Spotify urls by default in audioset restrict

Matches the behavior of Spotify codes already being allowed by default.

* Update audio.py

* .format() moving

* Added a character to try to make Travis behave
2019-03-28 13:41:17 -04:00
aikaterna
94c3a2fedd [Audio] Seek command can now seek to position (#2470)
- Seek can now seek to a specific position, formatted like 00:00:00 or 00:00. Using negative or positive ints still functions the same as previously and will seek ahead or behind by that value instead.
- This PR requires the `_time_convert` func added in #2465 and should be merged after that one.
2019-03-10 18:27:23 +11:00
aikaterna
421043d923 [Audio] Fix for audioset status (#2481)
Revert player.is_playing check added to the playing players list for audioset status in #2473. This addition would cause no status to be shown when a local track was played and skip was used.
2019-03-08 09:09:22 +11:00
aikaterna
1c22b212c2 [Audio] Add songs when search-queuing (#2513)
Searching for a song and pressing the reaction to queue a song would not add the song to the queue if `[p]audioset maxlength` was off. This was an omission from #2465.
2019-03-07 14:12:15 +11:00
Flame442
d52b3eaf21 Proper capitalization of [p]blacklist help text (#2511) 2019-03-07 08:57:06 +11:00
Flame442
30ca226e39 [Trivia] Fix typo in warcraft trivia (#2508)
teh -> the
2019-03-06 20:04:11 +11:00
aikaterna
15037013e7 [Audio] Add option for dc at queue end (#2472)
This addition adds a toggle for having the bot instantly disconnect when the queue ends. It takes precedence over the `[p]audioset emptydisconnect` setting as it disconnects immediately when the queue or single song is finished.
2019-03-04 14:16:26 +11:00
jack1142
30fa9303e8 Spelling correction of method name in Tunnel (#2496)
`Tunnel.files_from_attatch` was misspelled.

Kept old name as an alias for backwards compatibility.
2019-03-04 12:19:40 +11:00
Toby Harradine
b4753a02de Fix translations of multiline strings (#2504)
* Fix translations of multiline strings

Resolves #2408.

Also did a few little optimisations here and there, we're no longer just using copied code from another project.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Reformat

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-03-04 00:45:15 +01:00
Toby Harradine
628073cbe1 Update Translations (#2486)
Also included a Makefile recipe which makes use of the Crowdin CLI's `crowdin download` command. This requires whoever is using it to provide the project's API key in an environment variable, but we may automate this at some point.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-03-04 08:55:01 +11:00
aikaterna
2755592175 [Audio] Playlist download addition (#2482)
Bot owners can use `[p]playlist download playlistname` to download a playlist file that is compatible with the playlist upload command. Songs can also be exported for v2 use by using `[p]playlist download playlistname True`, which strips out tracks besides YouTube or Soundcloud URLs.
2019-03-03 14:29:42 +11:00
entchen66
6051ccb23c [Filter] Dispatch event on_filter_message_delete (#2483) 2019-02-27 16:27:10 +11:00
El Laggron
46f9cae0ef [Audio] Sort local files (#2358) 2019-02-27 16:22:10 +11:00
Seputaes
16614168a7 [Downloader] Install SHARED_LIBRARY requirements (#2384)
SHARED_LIBRARY Installable types did not have the requirements as
defined in info.json automatically installed. This change updates the
installation of libraries to also install their requirements.

Resolves #2381
2019-02-27 16:07:05 +11:00
El Laggron
5a15939f08 Bump aiohttp-json-rpc to version 0.12.1 (#2489) 2019-02-27 09:55:20 +11:00
Toby Harradine
bb5aab16c9 [Permissions] Exclude @everyone role when retrieving rules (#2484)
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-25 10:19:00 +11:00
Toby Harradine
b38ac1d025 Bump version to 3.0.2
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-25 08:54:50 +11:00
Toby Harradine
22cf8e940c [Permissions] Fix typo in cog_add event 2019-02-25 08:27:49 +11:00
aikaterna
b0ab6bd7e2 [Audio] Add track length restriction (#2465)
* Added `[p]audioset maxlength`, which takes seconds or 00:00-style of formatted input for restricting the player to songs that have a length under that threshold.
2019-02-24 11:44:58 +11:00
aikaterna
7b9d85c1b5 [Audio] Emptydisconnect and status refactor (#2473)
- Refactored disconnect_timer, the function behind audioset emptydisconnect, to be more appropriately responsive (thanks to TrustyJAID)
- Refactored status clearing/status changing when emptydisconnect or other Lavalink player statuses would have a TRACK_END event but no QUEUE_END event. This should clear or modify the bot's status event appropriately when [p]audioset status is on and the bot disconnects due to emptydisconnect and ideally play a little nicer with other cogs that set statuses.
2019-02-23 08:45:01 +11:00
DiscordLiz
3637804929 Fix Command.error decorator (#2478)
This shouldn't be a coroutine.
2019-02-23 07:13:22 +11:00
DiscordLiz
c70a44e0fe Make on_command_error recognise custom error handlers (#2458)
Adds detection of custom error handlers to the global error handler.

Adds documentation of the updated behaviour.

Closes #2276.
2019-02-22 20:12:00 +11:00
Toby Harradine
cf18b601e2 [Mod] Use consume-rest in [p]casesfor 2019-02-22 17:52:30 +11:00
Lionir
139cc07bda Resolve network issue due to certificate failure (#2442)
There seems to have been a recurring problem with certificates on Macs, this is how you solve it *apparently*. 😎
2019-02-22 06:24:39 +01:00
DiscordLiz
619c3f28f7 fix case generation for cases which were not logged to modlog channel (#2477)
Add documentation for failure cases
Prevent an expected failure case.
2019-02-22 03:33:45 +01:00
DiscordLiz
9966668307 adds function to modlg API to get cases by member (#2453)
adds command using this to view all of a member's cases demonstrating this

closes #2266
2019-02-22 03:31:37 +01:00
palmtree5
77a0a67029 [Streams] Remove communities support (#2223)
See [this blog post](https://blog.twitch.tv/introducing-tags-and-new-categories-33744ef7b04f), communities on Twitch have been discontinued.
2019-02-21 17:37:28 +11:00
ZeLarpMaster
b65466cebd [Trivia] Fix typo in cars.yaml (#2475) 2019-02-21 09:49:43 +11:00
Toby Harradine
f1873e32d6 [Docs] Use correct perms cmd for setting default rules 2019-02-20 16:08:25 +11:00
Michael H
b7b4e65d2d [Permissions] Remove p alias (#2467)
People can re-add it with the alias cog, but core red should not monopolize short aliases.

What about those servers that want `[p]play` even shorter?
2019-02-19 10:43:02 +11:00
aikaterna
16bb334fba [Audio] Add playlist copy (#2205)
Bot owners can now copy playlists from one server to another using server IDs.
2019-02-19 10:36:20 +11:00
TrustyJAID
3f1d416526 Allow central storage of API keys (#2389)
This creates a central location to store external API tokens that can be used between cogs without requiring each cog to be loaded for it to work.

A new set option for `[p]set api` is created to assist in forming bot readable API token locations.

This also updates the Streams cog to utilize the central database.

Tokens are moved from the old data locations in core cogs on load.
2019-02-19 10:22:44 +11:00
Michael H
722aaa225b Improve Cooldown UX (#2412)
This improves the feedback given on `command_on_cool_down`, as well as automatically handling cooldowns under 1 second for the user.
2019-02-19 10:19:49 +11:00
aikaterna
7e2e37ab3f [Audio] Play local folders via text command (#2457)
`[p]local folder` will now accept folder names in the command instead of having to navigate through the reaction menu. Also added an alias of `[p]local start` to help users coming from v2 audio.
2019-02-19 10:16:41 +11:00
aikaterna
83411d0fa4 [Audio] Change pause to a toggle (#2461) 2019-02-19 10:10:11 +11:00
aikaterna
d608dd953b [Audio] Remove aliases (#2462) 2019-02-19 10:08:59 +11:00
Flame442
e5e0a024f9 Remove unnecessary "or" from Config doc (#2464) 2019-02-17 14:14:40 -09:00
Caleb Johnson
8e6db0829c [Audio] Connect to lavalink in the background (#2460)
Also:
- restart and reconnect if connection settings change
  - shutdown and restart if not configured to use external
- show a message in [p]play et al. when the connection hasn't been made
- move the JAR download to manager so audio.py can access it
- only start if no process exists
- bump red-lavalink to 0.2.3

Resolves #2306
2019-02-17 09:22:55 +11:00
Toby Harradine
5359fec195 Bump version to 3.0.1
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-16 12:21:25 +11:00
Toby Harradine
f2daf0be9a Revert "[Audio] Connect to lavalink in the background (#2335)" (#2459)
This reverts commit b633a33137.
2019-02-16 11:52:03 +11:00
Caleb Johnson
b633a33137 [Audio] Connect to lavalink in the background (#2335)
Also:
- restart and reconnect if connection settings change
  - shutdown and restart if not configured to use external
- show a message in [p]play et al. when the connection hasn't been made
- move the JAR download to manager so audio.py can access it
- only start if no process exists

Resolves #2306
2019-02-16 11:35:21 +11:00
Michael H
d13bf37845 [Utils] Add filters for spoiler markdown (#2401)
This also wraps some fields of the modlog with the same sanitization, as well as the `[p]names` command.
2019-02-16 11:34:38 +11:00
Michael H
4b831a634a [Audio] Remove players which no longer have a guild. (#2414)
Cleanup players when the bot has one for a guild it leaves.

Bumps Red-Lavalink to v0.2.2
2019-02-16 11:15:33 +11:00
DiscordLiz
f91e0a6546 Prevent error when ctx.send_interactive prompt is deleted (#2447)
Supress excpetions which may occur when attempting to delete a prompt.

fixes #2380
2019-02-16 07:46:36 +11:00
ZeLarpMaster
2e2d669fdf [Trivia] Fix typo in cars.yaml (#2456) 2019-02-16 07:39:49 +11:00
Toby Harradine
7ecdf7a7be Remove asyncio.Event creation from module level in Audio (#2454)
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-15 14:27:01 +11:00
Twentysix
9b940de854 [Downloader] [p]pipinstall: Handle no args 2019-02-14 23:39:38 +01:00
zephyrkul
82807ffe69 [Downloader] Use shlex for subprocesses (#2421) 2019-02-14 23:32:11 +01:00
Toby Harradine
b1066ad58f Guard module-level creation of Config objects (#2449)
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-14 15:36:48 +11:00
Caleb Johnson
ac8b1fc108 [Filter] Filter based on words for non-phrases (#2262)
Filters based strictly on words (ignoring punctuation) if filter entry isn't a phrase.
2019-02-13 14:14:12 +11:00
zephyrkul
820be2a0ae [Core] Utilize consume rest, Union (#2407) 2019-02-13 14:11:22 +11:00
Toby Harradine
9869f95bd6 Update dependencies and copyright year (#2436)
- aiohttp 3.5
- websockets 7
- Rapptz/discord.py@700dbb5
- A few others

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-13 10:49:11 +11:00
zephyrkul
c87286d3c6 [README] Update support channel (#2445) 2019-02-12 21:24:14 +01:00
Twentysix
7028ca9df3 [Docs] Link bot account guide (#2440) 2019-02-11 20:17:39 +01:00
Toby Harradine
435fc141ae Default rules for subcommands precede supercommands (#2422)
This incorporates default rules into the same resolution techniques used by concrete rules.

Resolves #2313.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-11 14:14:29 +11:00
Twentysix
889fa63aff Sentry removal (#2439)
Resolves #2430.
2019-02-11 11:19:02 +11:00
Toby Harradine
dae75521d3 [Audio] Enable logging on Lavalink V3 (#2438)
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-10 18:36:02 +11:00
Toby Harradine
b9d440f2f7 Utilise setup.cfg, move version info to redbot package (#2411)
* Utilise setup.cfg, move version info to redbot package

- `redbot.__init__` now is safe to import without installing dependencies.
- Now deploying binary wheel distribution from travis
- Include locale files in sub-packages of cog packages
- python_requires now has no upper limit

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-09 12:08:22 +11:00
Toby Harradine
ec4c325efd Guard parsing of CLI args in launcher, setup scripts (#2432)
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-08 18:08:10 +11:00
Twentysix
b350ac38dc Allow [p]info customization (#2417)
* Allow [p]info customization

* Style

* Naming
2019-02-08 02:38:26 +01:00
PredaaA
e88c82e7e0 Update help_formatter.py (#2431) 2019-02-08 02:24:59 +01:00
Twentysix
99ad01ae0d [p]userinfo: Handle target w/ 'None' Member.joined_at (#2426) 2019-02-07 22:40:40 +01:00
Toby Harradine
8f8c52d8c4 [Docs] Add note about pyenv optimisation flag (#2428)
Signed-off-by: Toby <tobyharradine@gmail.com>
2019-02-07 21:54:14 +11:00
Toby Harradine
c56fa5a320 Minor changes to install docs (#2427)
- When creating a venv, use `python3.7` instead of `python3`
- Remove unnecessary dependency from pyenv pre-requirements on Debian
- Use curl over wget for get-pip on Xenial

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-07 10:51:17 +11:00
Toby Harradine
7d5bae5a50 Use V2 of RTD's configuration file (#2418)
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-07 10:30:01 +11:00
bobloy
7c404082f8 [Help] Group Fields respect page_char_limit (#2281)
It would groups the cogs until it is **greater** than the set `page_char_limit` in helpset. This leads to inconsistent page sizes when a large cog was appended to something barely under the limit.

I think this commit will reign in the weirdness by adjusting the secondary grouping to aim for **less than** `page_char_limit` grouping.
2019-02-06 18:59:54 +11:00
Toby Harradine
dc8e61cbe5 Always tick Voice requirements on startup screen (#2413)
Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-02-04 22:33:48 +11:00
zephyrkul
f2ebf52f6e Send help on empty [p]load/unload/reload (#2410)
Rather than attempting to load / reload / unload nothing, send command help on bare `[p]load`, etc. commands.
2019-02-04 17:39:03 +11:00
Redjumpman
fa223e22ed [Utils] Fix for MessagePredicate.lower_contained_in (#2399)
Added a missing str.lower() method when checking to see if the content is in the list.
2019-02-04 10:22:01 +11:00
PredaaA
6d22c8faa5 [Core cmds] [p]servers: handle message deletion (#2400) 2019-02-03 23:32:45 +01:00
Michael H
01ebf2835b Improve usability of warnings/unwarn\n resolves #2403 (#2404) 2019-02-03 02:37:01 -09:00
Michael H
3ef693a259 prevent traceback (#2406)
* prevent traceback related to  Rapptz/discord.py#1638

* formatting
2019-02-02 11:20:17 +01:00
Caleb Johnson
3a4d932d2b Use find_namespace_packages in setup.py (#2402) 2019-02-01 16:10:10 +11:00
Kowlin
571332ae18 Fixed our missing templates (#2398) 2019-01-31 10:36:14 +11:00
Toby Harradine
0607f5552a Use python-Levenshtein-wheels (#2393)
This removes the compiler detection logic in setup.py. python-Levenshtein-wheels includes pre-built wheels for virtually all operating systems and architectures we support.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2019-01-30 16:52:36 +11:00
Toby Harradine
016a6d3aa6 Bump minimum python version to 3.7.0 (#2394)
This is in anticipation of #2246, although I've written that PR to not break on 3.6, the feature itself is not usable on 3.6. So I think the best way forward is to simply require python 3.7. This also allows devs and cog creators to utilise all of the new features in 3.7, and it also updates the docs so all operating systems will have 3.7 installed.

Signed-off-by: Toby <tobyharradine@gmail.com>
2019-01-30 14:07:53 +11:00
Toby Harradine
c7d98f88e8 Update Travis badge in README to travis-ci.com (#2395)
Signed-off-by: Toby <tobyharradine@gmail.com>
2019-01-29 01:46:37 -09:00
Toby Harradine
b82756087a Merge V3/release/3.0.0 into V3/develop 2019-01-28 15:30:30 +11:00
El Laggron
3b62572c89 Graceful shutdown when SIGTERM is received (#2286)
Only works on Unix.
2019-01-23 10:28:30 +11:00
bobloy
abcf179042 [CogManager] Fix return type-hint (#2319) 2019-01-19 11:47:58 +11:00
Michael H
3dba09d19d [Docs] Chocolately/PowerShell install instructions for Windows (#2364) 2019-01-19 11:45:22 +11:00
Toby Harradine
e07408161a Merge branch 'V3/release/3.0.0' into V3/develop
# Conflicts:
#	redbot/cogs/mod/mod.py
2019-01-11 16:42:42 +11:00
Twentysix
937d2fe0f6 [Mod] Enhanced [p]hackban (#2164) 2019-01-05 03:29:05 +01:00
palmtree5
bcc50557a9 [V3 Readme] Update cog list links (#2347) 2018-12-23 00:17:20 -09:00
Toby Harradine
bdcb69ad37 Merge branch 'V3/release/3.0.0' into V3/develop
# Conflicts:
#	redbot/cogs/audio/audio.py
2018-12-21 13:37:32 +11:00
aikaterna
3b50ed8192 [V3 Audio] Restrict toggle for commercial sites (#2245)
* [V3 Audio] Restrict toggle for commercial sites

* Different url parsing

* Allow local tracks

* No self needed

* Change Twitch url
2018-12-13 18:31:24 +01:00
Michael H
30c3a4c7c1 [Docs] CentOS correct git version (#2309)
Resolves #2260.
2018-11-24 10:06:59 +11:00
FixedThink
6470bc1cda [Mod] [p]userinfo: Get avatar format with proper method (#2291) 2018-11-14 22:46:01 +01:00
Michael H
221b636f3f Prevent locking out owner from commands (#2257) 2018-11-06 11:32:40 +11:00
FixedThink
f7e41063bf [Trivia] Change Swaziland to its new name, eSwatini (#2275) 2018-11-06 09:52:25 +11:00
bobloy
d6cd959a2b [Docs] Update example cog to include base cog class (#2256) 2018-11-06 08:41:34 +11:00
aikaterna
57f078925e [V3] Update CODEOWNERS for audio (#2277) 2018-10-30 18:19:16 +01:00
Toby Harradine
8b4e12da81 Merge branch 'V3/release/3.0.0' into V3/develop
# Conflicts:
#	redbot/cogs/customcom/customcom.py
#	redbot/core/errors.py
2018-10-16 09:42:38 +11:00
Toby Harradine
5ed8be9998 Merge V3/release/3.0.0 into V3/develop 2018-10-12 08:59:14 +11:00
Michael H
4357fe1ba9 [Core] Fixes reload, and prompted reload on cog update (#2226)
Fix something missed when QAing #2207
2018-10-12 07:23:04 +11:00
El Laggron
a64db76b4d [Core] Specify an error message on package loading (#2207)
Allows cog creators to explain clearly why a cog cannot load by raising  `redbot.core.errors.CogLoadError`. Instead of having to check in the console what's wrong, the message will directly be sent in the context channel.
2018-10-11 11:57:11 +11:00
Twentysix
c464f5e7dc [CustomCommands] Add [p]cc show (#2204) 2018-10-10 10:27:25 +11:00
Toby Harradine
00bc3c86b1 Merge V3/release/3.0.0 into V3/develop (#2209) 2018-10-09 09:10:05 +11:00
Toby Harradine
ba605495ac [Dev] Use isawaitable over iscoroutine for [p]debug (#2202)
Allows for non-coroutine awaitables (such as config's `_ValueCtxManager`) to be awaited from debug.

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
2018-10-07 19:36:35 +11:00
Toby Harradine
748847d5bf Merge changes for RC1 into V3/develop 2018-10-07 12:06:28 +11:00
1937 changed files with 731939 additions and 63719 deletions

396
.bandit.yml Normal file
View File

@@ -0,0 +1,396 @@
### Bandit config file generated
### This config may optionally select a subset of tests to run or skip by
### filling out the 'tests' and 'skips' lists given below. If no tests are
### specified for inclusion then it is assumed all tests are desired. The skips
### set will remove specific tests from the include set. This can be controlled
### using the -t/-s CLI options. Note that the same test ID should not appear
### in both 'tests' and 'skips', this would be nonsensical and is detected by
### Bandit at runtime.
# Available tests:
# B101 : assert_used
# B102 : exec_used
# B103 : set_bad_file_permissions
# B104 : hardcoded_bind_all_interfaces
# B105 : hardcoded_password_string
# B106 : hardcoded_password_funcarg
# B107 : hardcoded_password_default
# B108 : hardcoded_tmp_directory
# B110 : try_except_pass
# B112 : try_except_continue
# B201 : flask_debug_true
# B301 : pickle
# B302 : marshal
# B303 : md5
# B304 : ciphers
# B305 : cipher_modes
# B306 : mktemp_q
# B307 : eval
# B308 : mark_safe
# B309 : httpsconnection
# B310 : urllib_urlopen
# B311 : random
# B312 : telnetlib
# B313 : xml_bad_cElementTree
# B314 : xml_bad_ElementTree
# B315 : xml_bad_expatreader
# B316 : xml_bad_expatbuilder
# B317 : xml_bad_sax
# B318 : xml_bad_minidom
# B319 : xml_bad_pulldom
# B320 : xml_bad_etree
# B321 : ftplib
# B322 : input
# B323 : unverified_context
# B324 : hashlib_new_insecure_functions
# B325 : tempnam
# B401 : import_telnetlib
# B402 : import_ftplib
# B403 : import_pickle
# B404 : import_subprocess
# B405 : import_xml_etree
# B406 : import_xml_sax
# B407 : import_xml_expat
# B408 : import_xml_minidom
# B409 : import_xml_pulldom
# B410 : import_lxml
# B411 : import_xmlrpclib
# B412 : import_httpoxy
# B413 : import_pycrypto
# B501 : request_with_no_cert_validation
# B502 : ssl_with_bad_version
# B503 : ssl_with_bad_defaults
# B504 : ssl_with_no_version
# B505 : weak_cryptographic_key
# B506 : yaml_load
# B507 : ssh_no_host_key_verification
# B601 : paramiko_calls
# B602 : subprocess_popen_with_shell_equals_true
# B603 : subprocess_without_shell_equals_true
# B604 : any_other_function_with_shell_equals_true
# B605 : start_process_with_a_shell
# B606 : start_process_with_no_shell
# B607 : start_process_with_partial_path
# B608 : hardcoded_sql_expressions
# B609 : linux_commands_wildcard_injection
# B610 : django_extra_used
# B611 : django_rawsql_used
# B701 : jinja2_autoescape_false
# B702 : use_of_mako_templates
# B703 : django_mark_safe
# (optional) list included test IDs here, eg '[B101, B406]':
tests:
# (optional) list skipped test IDs here, eg '[B101, B406]':
skips: ['B322']
### (optional) plugin settings - some test plugins require configuration data
### that may be given here, per-plugin. All bandit test plugins have a built in
### set of sensible defaults and these will be used if no configuration is
### provided. It is not necessary to provide settings for every (or any) plugin
### if the defaults are acceptable.
any_other_function_with_shell_equals_true:
no_shell:
- os.execl
- os.execle
- os.execlp
- os.execlpe
- os.execv
- os.execve
- os.execvp
- os.execvpe
- os.spawnl
- os.spawnle
- os.spawnlp
- os.spawnlpe
- os.spawnv
- os.spawnve
- os.spawnvp
- os.spawnvpe
- os.startfile
shell:
- os.system
- os.popen
- os.popen2
- os.popen3
- os.popen4
- popen2.popen2
- popen2.popen3
- popen2.popen4
- popen2.Popen3
- popen2.Popen4
- commands.getoutput
- commands.getstatusoutput
subprocess:
- subprocess.Popen
- subprocess.call
- subprocess.check_call
- subprocess.check_output
- subprocess.run
hardcoded_tmp_directory:
tmp_dirs:
- /tmp
- /var/tmp
- /dev/shm
linux_commands_wildcard_injection:
no_shell:
- os.execl
- os.execle
- os.execlp
- os.execlpe
- os.execv
- os.execve
- os.execvp
- os.execvpe
- os.spawnl
- os.spawnle
- os.spawnlp
- os.spawnlpe
- os.spawnv
- os.spawnve
- os.spawnvp
- os.spawnvpe
- os.startfile
shell:
- os.system
- os.popen
- os.popen2
- os.popen3
- os.popen4
- popen2.popen2
- popen2.popen3
- popen2.popen4
- popen2.Popen3
- popen2.Popen4
- commands.getoutput
- commands.getstatusoutput
subprocess:
- subprocess.Popen
- subprocess.call
- subprocess.check_call
- subprocess.check_output
- subprocess.run
ssl_with_bad_defaults:
bad_protocol_versions:
- PROTOCOL_SSLv2
- SSLv2_METHOD
- SSLv23_METHOD
- PROTOCOL_SSLv3
- PROTOCOL_TLSv1
- SSLv3_METHOD
- TLSv1_METHOD
ssl_with_bad_version:
bad_protocol_versions:
- PROTOCOL_SSLv2
- SSLv2_METHOD
- SSLv23_METHOD
- PROTOCOL_SSLv3
- PROTOCOL_TLSv1
- SSLv3_METHOD
- TLSv1_METHOD
start_process_with_a_shell:
no_shell:
- os.execl
- os.execle
- os.execlp
- os.execlpe
- os.execv
- os.execve
- os.execvp
- os.execvpe
- os.spawnl
- os.spawnle
- os.spawnlp
- os.spawnlpe
- os.spawnv
- os.spawnve
- os.spawnvp
- os.spawnvpe
- os.startfile
shell:
- os.system
- os.popen
- os.popen2
- os.popen3
- os.popen4
- popen2.popen2
- popen2.popen3
- popen2.popen4
- popen2.Popen3
- popen2.Popen4
- commands.getoutput
- commands.getstatusoutput
subprocess:
- subprocess.Popen
- subprocess.call
- subprocess.check_call
- subprocess.check_output
- subprocess.run
start_process_with_no_shell:
no_shell:
- os.execl
- os.execle
- os.execlp
- os.execlpe
- os.execv
- os.execve
- os.execvp
- os.execvpe
- os.spawnl
- os.spawnle
- os.spawnlp
- os.spawnlpe
- os.spawnv
- os.spawnve
- os.spawnvp
- os.spawnvpe
- os.startfile
shell:
- os.system
- os.popen
- os.popen2
- os.popen3
- os.popen4
- popen2.popen2
- popen2.popen3
- popen2.popen4
- popen2.Popen3
- popen2.Popen4
- commands.getoutput
- commands.getstatusoutput
subprocess:
- subprocess.Popen
- subprocess.call
- subprocess.check_call
- subprocess.check_output
- subprocess.run
start_process_with_partial_path:
no_shell:
- os.execl
- os.execle
- os.execlp
- os.execlpe
- os.execv
- os.execve
- os.execvp
- os.execvpe
- os.spawnl
- os.spawnle
- os.spawnlp
- os.spawnlpe
- os.spawnv
- os.spawnve
- os.spawnvp
- os.spawnvpe
- os.startfile
shell:
- os.system
- os.popen
- os.popen2
- os.popen3
- os.popen4
- popen2.popen2
- popen2.popen3
- popen2.popen4
- popen2.Popen3
- popen2.Popen4
- commands.getoutput
- commands.getstatusoutput
subprocess:
- subprocess.Popen
- subprocess.call
- subprocess.check_call
- subprocess.check_output
- subprocess.run
subprocess_popen_with_shell_equals_true:
no_shell:
- os.execl
- os.execle
- os.execlp
- os.execlpe
- os.execv
- os.execve
- os.execvp
- os.execvpe
- os.spawnl
- os.spawnle
- os.spawnlp
- os.spawnlpe
- os.spawnv
- os.spawnve
- os.spawnvp
- os.spawnvpe
- os.startfile
shell:
- os.system
- os.popen
- os.popen2
- os.popen3
- os.popen4
- popen2.popen2
- popen2.popen3
- popen2.popen4
- popen2.Popen3
- popen2.Popen4
- commands.getoutput
- commands.getstatusoutput
subprocess:
- subprocess.Popen
- subprocess.call
- subprocess.check_call
- subprocess.check_output
- subprocess.run
subprocess_without_shell_equals_true:
no_shell:
- os.execl
- os.execle
- os.execlp
- os.execlpe
- os.execv
- os.execve
- os.execvp
- os.execvpe
- os.spawnl
- os.spawnle
- os.spawnlp
- os.spawnlpe
- os.spawnv
- os.spawnve
- os.spawnvp
- os.spawnvpe
- os.startfile
shell:
- os.system
- os.popen
- os.popen2
- os.popen3
- os.popen4
- popen2.popen2
- popen2.popen3
- popen2.popen4
- popen2.Popen3
- popen2.Popen4
- commands.getoutput
- commands.getstatusoutput
subprocess:
- subprocess.Popen
- subprocess.call
- subprocess.check_call
- subprocess.check_output
- subprocess.run
try_except_continue:
check_typed_exception: false
try_except_pass:
check_typed_exception: false
weak_cryptographic_key:
weak_key_size_dsa_high: 1024
weak_key_size_dsa_medium: 2048
weak_key_size_ec_high: 160
weak_key_size_ec_medium: 224
weak_key_size_rsa_high: 1024
weak_key_size_rsa_medium: 2048

5
.cherry_picker.toml Normal file
View File

@@ -0,0 +1,5 @@
team = "Cog-Creators"
repo = "Red-DiscordBot"
check_sha = "6251c585e4ec0a53813a9993ede3ab5309024579"
fix_commit_msg = false
default_branch = "V3/develop"

52
.codeclimate.yml Normal file
View File

@@ -0,0 +1,52 @@
version: "2" # required to adjust maintainability checks
checks:
argument-count:
config:
threshold: 8 # work on this later
complex-logic:
enabled: false # Disabled in favor of using Radon for this
config:
threshold: 4
file-lines:
enabled: false # enable after audio stuff...
config:
threshold: 2000 # I would set this lower if not for cogs as command containers.
method-complexity:
enabled: false # Disabled in favor of using Radon for this
config:
threshold: 5
method-count:
enabled: false # I would set this lower if not for cogs as command containers.
config:
threshold: 20
method-lines:
enabled: false
config:
threshold: 25 # I'm fine with long methods, cautious about the complexity of a single method.
nested-control-flow:
config:
threshold: 6
return-statements:
config:
threshold: 6
similar-code:
enabled: false
config:
threshold: # language-specific defaults. an override will affect all languages.
identical-code:
enabled: false
config:
threshold: # language-specific defaults. an override will affect all languages.
plugins:
bandit:
enabled: false
radon:
enabled: false
config:
threshold: "D"
duplication:
enabled: false
config:
languages:
python:
python_version: 3

40
.git-blame-ignore-revs Normal file
View File

@@ -0,0 +1,40 @@
# Since version 2.23 (released in August 2019), git-blame has a feature
# to ignore or bypass certain commits.
#
# This file contains a list of commits that are not likely what you
# are looking for in a blame, such as mass reformatting or renaming.
# You can set this file as a default ignore file for blame by running
# the following command.
#
# $ git config blame.ignoreRevsFile .git-blame-ignore-revs
# [V3] Update code standards (black code format pass) (#1650)
b88b5a2601f56bda985729352d24842f087a8ade
# Black tests and setup.py (#1657)
e01cdbb0912387749d9459e1d934f9ed393a9b51
# Black formatting for generate_strings.py and docs/conf.py (#1658)
1ecaf6f8d5f2af731bec3eb6ad3a9721ab7a2812
# [V3 Travis] Update travis to not skip pipfile lock... (#1678)
# additional black formatting pass to conform to black 18.5b
d3f406a34a5cae6ea63664e76e8e74be43f9949f
# [V3] Update black version and reformat (#1745)
14cc701b25cea385fd0d537cdb6475d341c017c5
# [V3] Clean up some ugly auto-formatted strings (#1753)
622382f42588ac1d8a52bd3e39bf171c89ff0224
# [CI] Improve automated checks (#2702)
16443c8cc0c24cbc5b3dc7de858edb71b9ca6cd3
# Bump black to 20.8b1 (and reformat) (#4371)
85afe19455f91af21a0f603705eeb5d9599b45cc
# Reformat with Black 22.1.0 (#5633)
c69e8d31fdadbe10230ec0ea2ef35402e5c4cf43
# Reformat with Black 2023 formatting changes
226d8d734de43e1d5ea96a528a8e480641604db1

2
.git_archive_info.txt Normal file
View File

@@ -0,0 +1,2 @@
$Format:%h$
$Format:%(describe:tags=true)$

11
.gitattributes vendored Normal file
View File

@@ -0,0 +1,11 @@
* text eol=lf
# binary file excludsions
*.png binary
# include commit/tag information in `.git_archive_info.txt` when packing with git-archive
.git_archive_info.txt export-subst
# hide diffs for .po files by default
# https://docs.github.com/en/repositories/working-with-files/managing-files/customizing-how-changed-files-appear-on-github
*.po linguist-generated

84
.github/CODEOWNERS vendored
View File

@@ -1,62 +1,30 @@
# Default
* @Twentysix26
# Core
redbot/core/bank.py @palmtree5
redbot/core/checks.py @tekulvw
redbot/core/cli.py @tekulvw
redbot/core/config.py @tekulvw
redbot/core/cog_manager.py @tekulvw
redbot/core/core_commands.py @tekulvw
redbot/core/context.py @Tobotimus
redbot/core/data_manager.py @tekulvw
redbot/core/dev_commands.py @tekulvw
redbot/core/drivers/* @tekulvw
redbot/core/events.py @tekulvw
redbot/core/global_checks.py @tekulvw
redbot/core/i18n.py @tekulvw
redbot/core/json_io.py @tekulvw
redbot/core/modlog.py @palmtree5
redbot/core/rpc.py @tekulvw
redbot/core/sentry_setup.py @Kowlin @tekulvw
redbot/core/utils/chat_formatting.py @tekulvw
redbot/core/utils/mod.py @palmtree5
redbot/core/utils/data_converter.py @mikeshardmind
redbot/core/utils/antispam.py @mikeshardmind
redbot/core/utils/tunnel.py @mikeshardmind
redbot/core/utils/caching.py @mikeshardmind
redbot/core/utils/common_filters.py @mikeshardmind
# Cogs
redbot/cogs/admin/* @tekulvw
redbot/cogs/alias/* @tekulvw
redbot/cogs/audio/* @aikaterna @atiwiex
redbot/cogs/bank/* @tekulvw
redbot/cogs/cleanup/* @palmtree5
redbot/cogs/customcom/* @palmtree5
redbot/cogs/downloader/* @tekulvw
redbot/cogs/economy/* @palmtree5
redbot/cogs/filter/* @palmtree5
redbot/cogs/general/* @palmtree5
redbot/cogs/image/* @palmtree5
redbot/cogs/mod/* @palmtree5
redbot/cogs/modlog/* @palmtree5
redbot/cogs/streams/* @Twentysix26 @palmtree5
redbot/cogs/trivia/* @Tobotimus
redbot/cogs/dataconverter/* @mikeshardmind
redbot/cogs/reports/* @mikeshardmind
redbot/cogs/permissions/* @mikeshardmind
redbot/cogs/warnings/* @palmtree5
/redbot/cogs/audio/** @aikaterna @PredaaA
/redbot/cogs/downloader/* @Jackenmen
/redbot/cogs/streams/* @palmtree5
/redbot/cogs/mutes/* @TrustyJAID
# Docs
docs/* @tekulvw @palmtree5
# Docs - Install and update guides
/docs/install_guides/** @Jackenmen
/docs/update_red.rst @Jackenmen
# Setup, instance setup, and running the bot
setup.py @tekulvw
redbot/__init__.py @tekulvw
redbot/__main__.py @tekulvw
redbot/setup.py @tekulvw
# Docs - Version guarantees
/docs/version_guarantees.rst @Jackenmen
# Others
.travis.yml @Kowlin
crowdin.yml @Kowlin
# Trivia Lists
/redbot/cogs/trivia/data/lists/whosthatpokemon*.yaml @aikaterna
# Tests
/redbot/pytest/downloader* @Jackenmen
/tests/cogs/downloader/* @Jackenmen
# Schemas
/schema/* @Jackenmen
# CI
/.travis.yml @Kowlin
/crowdin.yml @Kowlin
/.github/workflows/* @Kowlin
# Excludes
**/locales/* @ghost

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
# These are supported funding model platforms
patreon: Red_Devs

5
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,5 @@
<!--
Please be sure to use the correct template,
if your report doesn't have the correct template please open an issue describing your issue in detail
For support regarding the bot itself please visit the discord server over at https://discord.gg/red
-->

View File

@@ -0,0 +1,86 @@
name: Bug reports for commands
description: For bugs that involve commands found within Red.
labels: 'Type: Bug'
body:
- type: markdown
attributes:
value: |
Thank you for taking the time to fill out an issue. This template is meant for any issues related to commands.
If you require help with installing Red we ask that you join our [Discord server](https://discord.gg/red)
- type: input
id: red-version
attributes:
label: "What Red version are you using?"
placeholder: 3.4.5
validations:
required: true
- type: dropdown
id: cog-name
attributes:
label: "Cog name"
description: "From which cog does the command come from?"
options:
- Admin
- Alias
- Audio
- Bank
- Cleanup
- CogManagerUI
- Core
- Customcom
- Dev
- Downloader
- Economy
- Filter
- General
- Image
- Mod
- Modlog
- Mutes
- Permissions
- Reports
- Streams
- Trivia
- Warnings
validations:
required: true
- type: input
id: command-name
attributes:
label: "Command name"
description: "What is the command that caused the error?"
placeholder: "play"
validations:
required: true
- type: textarea
id: weh
attributes:
label: "What did you expect to happen?"
validations:
required: true
- type: textarea
id: wah
attributes:
label: "What actually happened?"
description: |
A clear and concise description of what the bug is.
If the issue is visual in nature, consider posting a screenshot.
validations:
required: true
- type: textarea
id: reproduction-steps
attributes:
label: "How can we reproduce this error?"
description: "List of steps required to reproduce this error."
value: |
1.
2.
3.
...
validations:
required: true
- type: textarea
id: anything-else
attributes:
label: Anything else?
description: Let us know if you have anything else to share.

View File

@@ -0,0 +1,54 @@
name: Bug report
description: "For bugs that don't involve a command."
labels: 'Type: Bug'
body:
- type: markdown
attributes:
value: |
Thank you for taking the time to fill out an issue. This template is meant for any issues not related to any existing command.
If you require help with installing Red we ask that you join our [Discord server](https://discord.gg/red)
- type: input
id: red-version
attributes:
label: "What Red version are you using?"
placeholder: 3.4.5
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: "What were you trying to do?"
validations:
required: true
- type: textarea
id: weh
attributes:
label: "What did you expect to happen?"
validations:
required: true
- type: textarea
id: wah
attributes:
label: "What actually happened?"
description: |
If the issue is visual in nature, consider posting a screenshot.
validations:
required: true
- type: textarea
id: reproduction-steps
attributes:
label: "How can we reproduce this error?"
description: |
List of steps required to reproduce the error. If the bug is code related, a minimal code example that reproduces the problem would be a big help.
value: |
1.
2.
3.
...
validations:
required: true
- type: textarea
id: anything-else
attributes:
label: Anything else?
description: Let us know if you have anything else to share.

View File

@@ -0,0 +1,29 @@
name: Enhancement proposal
description: For feature requests and improvements related to already existing functionality.
labels: 'Type: Enhancement'
body:
- type: markdown
attributes:
value: |
Thank you for taking the time to fill out an issue. This template is meant for feature requests and improvements to already existing functionality.
If you require help with installing Red we ask that you join our [Discord server](https://discord.gg/red)
- type: input
id: component-name
attributes:
label: "What component of Red (cog, command, API) would you like to see improvements on?"
placeholder: Audio
validations:
required: true
- type: textarea
id: proposal
attributes:
label: "Describe the enhancement you're suggesting."
description: |
Feel free to describe in as much detail as you wish.
validations:
required: true
- type: textarea
id: anything-else
attributes:
label: Anything else?
description: Let us know if you have anything else to share.

View File

@@ -0,0 +1,52 @@
name: Feature request
description: For feature requests regarding Red itself.
labels: 'Type: Feature'
body:
- type: markdown
attributes:
value: |
Thank you for taking the time to fill out an issue, this template is meant for any feature suggestions.
If you require help with installing Red we ask that you join our [Discord server](https://discord.gg/red)
- type: dropdown
id: feature-name
attributes:
label: "Type of feature request"
description: "What type of feature would you like to request?"
multiple: true
options:
- API functionality
- Cog
- Command
- Other
validations:
required: true
- type: textarea
id: proposal
attributes:
label: "Description of the feature you're suggesting"
description: |
Feel free to describe in as much detail as you wish.
If you are requesting API functionality:
- Describe what it should do
- Note whether it is to extend existing functionality or introduce new functionality
If you are requesting a cog to be included in core:
- Describe the functionality in as much detail as possible
- Include the command structure, if possible
- Please note that unless it's something that should be core functionality,
we reserve the right to reject your suggestion and point you to our cog
board to request it for a third-party cog
If you are requesting a command:
- Include what cog it should be in and a name for the command
- Describe the intended functionality for the command
- Note any restrictions on who can use the command or where it can be used
validations:
required: true
- type: textarea
id: anything-else
attributes:
label: Anything else?
description: Let us know if you have anything else to share.

View File

@@ -1,20 +0,0 @@
Please be sure to read through other issues as well to make sure what you are suggesting/reporting has not already
been suggested/reported
### Type:
- [ ] Suggestion
- [ ] Bug
### Brief description of the problem
### Expected behavior
### Actual behavior
### Steps to reproduce
1.
2.
3.
4.

View File

@@ -1,25 +0,0 @@
# Command bugs
<!--
Did you find a bug with a command? Fill out the following:
-->
#### Command name
<!-- Replace this line with the name of the command -->
#### What cog is this command from?
<!-- Replace this line with the name of the cog -->
#### What were you expecting to happen?
<!-- Replace this line with a description of what you were expecting to happen -->
#### What actually happened?
<!-- Replace this line with a description of what actually happened. Include any error messages -->
#### How can we reproduce this issue?
<!-- Replace with numbered steps to reproduce the issue -->

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Support question
url: https://discord.gg/red
about: For any questions regarding on how to operate and run Red.

View File

@@ -1,35 +0,0 @@
# Feature request
<!-- This template is for feature requests. Please fill out the following: -->
#### Select the type of feature you are requesting:
<!-- To check a box, replace the space between the [] with a x -->
- [ ] Cog
- [ ] Command
- [ ] API functionality
#### Describe your requested feature
<!--
Feel free to describe in as much detail as you wish.
If you are requesting a cog to be included in core:
- Describe the functionality in as much detail as possible
- Include the command structure, if possible
- Please note that unless it's something that should be core functionality,
we reserve the right to reject your suggestion and point you to our cog
board to request it for a third-party cog
If you are requesting a command:
- Include what cog it should be in and a name for the command
- Describe the intended functionality for the command
- Note any restrictions on who can use the command or where it can be used
If you are requesting API functionality:
- Describe what it should do
- Note whether it is to extend existing functionality or introduce new functionality
-->

View File

@@ -1,21 +0,0 @@
# Other bugs
<!--
Did you find a bug with something other than a command? Fill out the following:
-->
#### What were you trying to do?
<!-- Replace this line with a description of what you were trying to do -->
#### What were you expecting to happen?
<!-- Replace this line with a description of what you were expecting to happen -->
#### What actually happened?
<!-- Replace this line with a description of what actually happened. Include any error messages -->
#### How can we reproduce this issue?
<!-- Replace with numbered steps to reproduce the issue -->

17
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,17 @@
### Description of the changes
### Have the changes in this PR been tested?
<!--
Choose one (remove the line that doesn't apply):
-->
Yes
No
<!--
If the question doesn't apply (for example, it's not a code change), choose Yes.
Please respond to this question truthfully. We do not delay nor reject PRs
based on the answer to this question but it allows to better review this PR.
-->

View File

@@ -1,7 +0,0 @@
### Type
- [ ] Bugfix
- [ ] Enhancement
- [ ] New feature
### Description of the changes

View File

@@ -1,6 +1,7 @@
# Bugfix request
<!--
THIS TEMPLATE IS CURRENTLY UNUSED DUE TO GITHUB LIMITATIONS!
To be used for pull requests that fix a bug
-->

View File

@@ -1,6 +1,7 @@
# Enhancement request
<!--
THIS TEMPLATE IS CURRENTLY UNUSED DUE TO GITHUB LIMITATIONS!
To be used for PRs which enhance existing features
-->
@@ -17,4 +18,4 @@ If adding commands, describe any restrictions on their usage.
<!-- To check a box, replace the space between the [] with a x -->
- [ ] Yes
- [ ] No
- [ ] No

View File

@@ -1,6 +1,7 @@
# New feature addition
<!--
THIS TEMPLATE IS CURRENTLY UNUSED DUE TO GITHUB LIMITATIONS!
To be used for PRs which add a new feature
Examples of this include new APIs, new core cogs, etc.
-->
@@ -18,4 +19,4 @@ Examples of this include new APIs, new core cogs, etc.
<!--
If you are adding a cog, describe its commands in detail (functionality, usage restrictions, etc).
If the new feature introduces new requirements, please try to explain why they are necessary.
-->
-->

View File

@@ -1,6 +1,7 @@
# New release
<!--
THIS TEMPLATE IS CURRENTLY UNUSED DUE TO GITHUB LIMITATIONS!
To be used by collaborators for doing releases.
Most contributors will not need to use this.
-->
@@ -13,4 +14,3 @@ Most contributors will not need to use this.
- [ ] Yes
- [ ] No

View File

@@ -1,5 +1,6 @@
# Translations update
<!--
THIS TEMPLATE IS CURRENTLY UNUSED DUE TO GITHUB LIMITATIONS!
Used for PRs updating translations from Crowdin
-->
-->

332
.github/labeler.yml vendored Normal file
View File

@@ -0,0 +1,332 @@
"Category: CI":
- .github/workflows/**/*
"Category: Cogs - Admin":
# Source
- redbot/cogs/admin/*
# Docs
- docs/cog_guides/admin.rst
- docs/.resources/admin/**/*
"Category: Cogs - Alias":
# Source
- redbot/cogs/alias/*
# Docs
- docs/cog_guides/alias.rst
# Tests
- redbot/pytest/alias.py
- tests/cogs/test_alias.py
- docs/.resources/alias/**/*
"Category: Cogs - Audio":
# Source
- any:
- redbot/cogs/audio/**/*
- "!redbot/cogs/audio/**/locales/*"
# Docs
- docs/cog_guides/audio.rst
# Tests
- tests/cogs/audio/**/*
"Category: Cogs - Bank": [] # historical label for a removed cog
"Category: Cogs - Cleanup":
# Source
- redbot/cogs/cleanup/*
# Docs
- docs/cog_guides/cleanup.rst
"Category: Cogs - CustomCommands":
# Source
- redbot/cogs/customcom/*
# Docs
- docs/cog_customcom.rst
- docs/cog_guides/customcommands.rst
"Category: Cogs - Dev":
# Source
- redbot/core/dev_commands.py
# Docs
- docs/cog_guides/dev.rst
# Tests
- tests/core/test_dev_commands.py
"Category: Cogs - Downloader":
# Source
- redbot/cogs/downloader/*
# Docs
- docs/cog_guides/downloader.rst
# Tests
- redbot/pytest/downloader.py
- redbot/pytest/downloader_testrepo.*
- tests/cogs/downloader/**/*
"Category: Cogs - Economy":
# Source
- redbot/cogs/economy/*
# Docs
- docs/cog_guides/economy.rst
# Tests
- redbot/pytest/economy.py
- tests/cogs/test_economy.py
"Category: Cogs - Filter":
# Source
- redbot/cogs/filter/*
# Docs
- docs/cog_guides/filter.rst
"Category: Cogs - General":
# Source
- redbot/cogs/general/*
# Docs
- docs/cog_guides/general.rst
"Category: Cogs - Image":
# Source
- redbot/cogs/image/*
# Docs
- docs/cog_guides/image.rst
"Category: Cogs - Mod":
# Source
- redbot/cogs/mod/*
# Docs
- docs/cog_guides/mod.rst
# Tests
- redbot/pytest/mod.py
- tests/cogs/test_mod.py
"Category: Cogs - Modlog":
# Source
- redbot/cogs/modlog/*
# Docs
- docs/cog_guides/modlog.rst
"Category: Cogs - Mutes":
# Source
- redbot/cogs/mutes/*
# Docs
- docs/cog_guides/mutes.rst
"Category: Cogs - Permissions":
# Source
- redbot/cogs/permissions/*
# Docs
- docs/cog_guides/permissions.rst
- docs/cog_permissions.rst
# Tests
- redbot/pytest/permissions.py
- tests/cogs/test_permissions.py
"Category: Cogs - Reports":
# Source
- redbot/cogs/reports/*
# Docs
- docs/cog_guides/reports.rst
"Category: Cogs - Streams":
# Source
- redbot/cogs/streams/*
# Docs
- docs/cog_guides/streams.rst
"Category: Cogs - Trivia":
# Source
- redbot/cogs/trivia/*
# Docs
- docs/cog_guides/trivia.rst
- docs/guide_trivia_list_creation.rst
- docs/.resources/trivia/**/*
# Tests
- tests/cogs/test_trivia.py
"Category: Cogs - Trivia - Lists":
- redbot/cogs/trivia/data/lists/*
"Category: Cogs - Warnings":
# Source
- redbot/cogs/warnings/*
# Docs
- docs/cog_guides/warnings.rst
"Category: Core - API - Audio": [] # potential future feature
"Category: Core - API - Bank":
# Source
- redbot/core/bank.py
# Docs
- docs/framework_bank.rst
"Category: Core - API - App Commands Package":
# Source
- redbot/core/app_commands/*
# Docs
- docs/framework_app_commands.rst
# Tests
- tests/core/test_app_commands.py
"Category: Core - API - Commands Package":
# Source
- any:
- redbot/core/commands/*
- "!redbot/core/commands/help.py"
# this isn't in commands package but it just re-exports things from it
- redbot/core/checks.py
# Docs
- docs/framework_checks.rst
- docs/framework_commands.rst
# Tests
- tests/core/test_commands.py
"Category: Core - API - Config":
# Source
- any:
- redbot/core/_drivers/**/*
- "!redbot/core/_drivers/**/locales/*"
- redbot/core/_config.py
- redbot/core/config.py
# Docs
- docs/framework_config.rst
# Tests
- tests/core/test_config.py
"Category: Core - API - Other":
# Source
- redbot/__init__.py
- redbot/core/__init__.py
- redbot/core/data_manager.py
- redbot/core/errors.py
- redbot/core/tree.py
# Docs
- docs/framework_datamanager.rst
- docs/framework_tree.rst
# Tests
- redbot/pytest/data_manager.py
- tests/core/test_cog_manager.py
- tests/core/test_data_manager.py
- tests/core/test_version.py
"Category: Core - API - Utils Package":
# Source
- any:
- redbot/core/utils/*
- "!redbot/core/utils/_internal_utils.py"
# Docs
- docs/framework_utils.rst
# Tests
- tests/core/test_utils.py
"Category: Core - Bot Class":
# Source
- redbot/core/bot.py
# Docs
- docs/framework_apikeys.rst
- docs/framework_bot.rst
"Category: Core - Bot Commands":
# Source
- redbot/core/core_commands.py
- redbot/core/_diagnoser.py
# Docs
- docs/.resources/cog_manager_ui/**/*
- docs/cog_guides/cog_manager_ui.rst
- docs/cog_guides/core.rst
"Category: Core - Command-line Interfaces":
- redbot/__main__.py
- redbot/logging.py
- redbot/core/_cli.py
- redbot/core/_debuginfo.py
- redbot/setup.py
"Category: Core - Help":
- redbot/core/commands/help.py
"Category: Core - i18n":
# Source
- redbot/core/_i18n.py
- redbot/core/i18n.py
# Locale files
- redbot/**/locales/*
# Docs
- docs/framework_i18n.rst
"Category: Core - Modlog":
# Source
- redbot/core/generic_casetypes.py
- redbot/core/modlog.py
# Docs
- docs/framework_modlog.rst
"Category: Core - Other Internals":
# Source
- redbot/core/_cog_manager.py
- redbot/core/_events.py
- redbot/core/_global_checks.py
- redbot/core/_settings_caches.py
- redbot/core/_sharedlibdeprecation.py
- redbot/core/utils/_internal_utils.py
# Tests
- redbot/pytest/__init__.py
- redbot/pytest/cog_manager.py
- redbot/pytest/core.py
- tests/core/test_installation.py
"Category: Core - RPC/ZMQ":
# Source
- redbot/core/_rpc.py
# Docs
- docs/framework_rpc.rst
# Tests
- redbot/pytest/rpc.py
- tests/core/test_rpc.py
- tests/rpc_test.html
"Category: Docker": [] # potential future feature
"Category: Docs - Changelogs":
- CHANGES.rst
- docs/changelog.rst
- docs/incompatible_changes/**/*
"Category: Docs - For Developers":
- docs/framework_events.rst
- docs/guide_cog_creation.rst
- docs/guide_cog_creators.rst
- docs/guide_migration.rst
- docs/guide_publish_cogs.rst
- docs/guide_slash_and_interactions.rst
"Category: Docs - Install Guides":
- docs/about_venv.rst
- docs/autostart_*.rst
- docs/.resources/bot-guide/**/*
- docs/bot_application_guide.rst
- docs/install_guides/**/*
- docs/update_red.rst
"Category: Docs - Other":
- docs/host-list.rst
- docs/index.rst
- docs/version_guarantees.rst
- README.md
"Category: Docs - User Guides":
- docs/getting_started.rst
- docs/intents.rst
- docs/red_core_data_statement.rst
# TODO: move these to `docs/.resources/getting_started` subfolder
- docs/.resources/red-console.png
- docs/.resources/code-grant.png
- docs/.resources/instances-ssh-button.png
- docs/.resources/ssh-output.png
"Category: Meta":
# top-level files
- any:
- '*'
- '!README.md'
- '!CHANGES.rst'
# .gitattributes files
- '**/.gitattributes'
# GitHub configuration files, with the exception of CI configuration
- .github/*
- .github/ISSUE_TEMPLATE/*
- .github/PULL_REQUEST_TEMPLATE/*
# documentation configuration, extensions, scripts, templates, etc.
- docs/conf.py
- docs/_ext/**/*
- docs/_html/**/*
- docs/make.bat
- docs/Makefile
- docs/prolog.txt
- docs/_templates/**/*
# empty file
- redbot/cogs/__init__.py
# py.typed file
- redbot/py.typed
# requirements files
- requirements/*
# schema files
- schema/*
# tests configuration, global fixtures, etc.
- tests/conftest.py
- tests/__init__.py
- tests/*/__init__.py
# repository tools
- tools/*
# "Category: RPC/ZMQ methods": [] # can't be matched by file patterns
"Category: Vendored Packages":
- redbot/vendored/**/*

View File

@@ -0,0 +1,28 @@
name: Auto Labeler - Issues
on:
issues:
types: [opened]
permissions:
issues: write
jobs:
apply_triage_label_to_issues:
runs-on: ubuntu-latest
steps:
- name: Apply Triage Label
uses: actions/github-script@v6
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const is_status_label = (label) => label.name.startsWith('Status: ');
if (context.payload.issue.labels.some(is_status_label)) {
console.log('Issue already has Status label, skipping...');
return;
}
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['Status: Needs Triage']
});

27
.github/workflows/auto_labeler_pr.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: Auto Labeler - PRs
on:
pull_request_target:
types:
- opened
- synchronize
- reopened
- labeled
- unlabeled
permissions:
pull-requests: write
jobs:
label_pull_requests:
runs-on: ubuntu-latest
steps:
- name: Apply Type Label
uses: actions/labeler@v4
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
sync-labels: true
- name: Label documentation-only changes.
uses: Jackenmen/label-doconly-changes@v1
env:
LDC_LABELS: Docs-only

View File

@@ -0,0 +1,23 @@
name: Check label pattern exhaustiveness
on:
pull_request:
push:
jobs:
check_label_pattern_exhaustiveness:
name: Check label pattern exhaustiveness
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.8"
- name: Install script's pre-requirements
run: |
python -m pip install -U pip
python -m pip install -U pathspec pyyaml rich
- name: Check label pattern exhaustiveness
run: |
python .github/workflows/scripts/check_label_pattern_exhaustiveness.py

57
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,57 @@
name: "CodeQL"
on:
push:
pull_request:
schedule:
- cron: '0 14 * * 4'
workflow_dispatch:
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.8"
- name: Install dependencies
run: |
python -m pip install -U pip wheel
python -m pip install -e .[all]
# Set the `CODEQL-PYTHON` environment variable to the Python executable
# that includes the dependencies
echo "CODEQL_PYTHON=$(which python)" >> $GITHUB_ENV
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: 'python'
# Override the default behavior so that the action doesn't attempt
# to auto-install Python dependencies
# Learn more...
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#analyzing-python-dependencies
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3

View File

@@ -0,0 +1,32 @@
name: Crowdin - Upload strings
on:
push:
branches:
- V3/develop
jobs:
deploy:
if: github.repository == 'Cog-Creators/Red-DiscordBot'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'
- name: Install dependencies
run: |
curl https://artifacts.crowdin.com/repo/GPG-KEY-crowdin | sudo apt-key add -
echo "deb https://artifacts.crowdin.com/repo/deb/ /" | sudo tee -a /etc/apt/sources.list
sudo apt-get update -qq
sudo apt-get install -y crowdin3
pip install redgettext==3.4.2
- name: Generate source files
run: |
make gettext
- name: Upload source files
run: |
make upload_translations
env:
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_IDENTIFIER }}

30
.github/workflows/lint_python.yaml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Lint Python
on:
pull_request:
push:
repository_dispatch:
types:
- dispatched_test
env:
ref: ${{ github.event.client_payload.ref || '' }}
jobs:
lint_python:
name: Lint Python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ env.ref }}
- uses: actions/setup-python@v4
with:
python-version: "3.8"
- run: >
python -m pip install
'pyflakes @ https://github.com/pycqa/pyflakes/tarball/1911c20'
'pycodestyle @ https://github.com/pycqa/pycodestyle/tarball/d219c68'
'flake8 @ https://github.com/pycqa/flake8/tarball/3.7.9'
name: Install Flake8
- run: "python -m flake8 . --count --select=E9,F7,F82 --show-source"
name: Flake8 Linting

130
.github/workflows/prepare_release.yml vendored Normal file
View File

@@ -0,0 +1,130 @@
name: Prepare Release
on:
workflow_dispatch:
inputs:
new_stable_version:
description: Version number for the new stable release (leave empty to just strip `.dev1`)
required: false
default: 'auto'
permissions:
contents: write
pull-requests: write
jobs:
crowdin_download_translations:
needs: pr_stable_bump
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'
- name: Install dependencies
run: |
curl https://artifacts.crowdin.com/repo/GPG-KEY-crowdin | sudo apt-key add -
echo "deb https://artifacts.crowdin.com/repo/deb/ /" | sudo tee -a /etc/apt/sources.list
sudo apt-get update -qq
sudo apt-get install -y crowdin3
pip install redgettext==3.4.2
- name: Generate source files
run: |
make gettext
- name: Download translations
run: |
make download_translations
env:
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_IDENTIFIER }}
- name: Create Pull Request
id: cpr_crowdin
uses: peter-evans/create-pull-request@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Automated Crowdin downstream
title: "Automated Crowdin downstream"
body: |
This is an automated PR that is part of Prepare Release automated workflow (2 out of 2).
Please ensure that there are no errors or invalid files are in the PR.
labels: "Automated PR, Changelog Entry: Skipped"
branch: "automated/i18n"
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
milestone: ${{ needs.pr_stable_bump.outputs.milestone_number }}
- name: Close and reopen the PR with different token to trigger CI
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ steps.cpr_crowdin.outputs.pull-request-number }}
PR_OPERATION: ${{ steps.cpr_crowdin.outputs.pull-request-operation }}
with:
github-token: ${{ secrets.cogcreators_bot_repo_scoped }}
script: |
const script = require(
`${process.env.GITHUB_WORKSPACE}/.github/workflows/scripts/close_and_reopen_pr.js`
);
console.log(script({github, context}));
pr_stable_bump:
runs-on: ubuntu-latest
outputs:
milestone_number: ${{ steps.get_milestone_number.outputs.result }}
steps:
# Checkout repository and install Python
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'
# Create PR for stable version bump
- name: Update Red version number from input
id: bump_version_stable
run: |
python .github/workflows/scripts/bump_version.py
env:
PYTHONPATH: ${{ github.workspace }}:${{ env.PYTHONPATH }}
NEW_STABLE_VERSION: ${{ github.event.inputs.new_stable_version }}
# Get milestone number of the milestone for the new stable version
- name: Get milestone number
id: get_milestone_number
uses: actions/github-script@v6
env:
MILESTONE_TITLE: ${{ steps.bump_version_stable.outputs.new_version }}
with:
script: |
const script = require(
`${process.env.GITHUB_WORKSPACE}/.github/workflows/scripts/get_milestone_number_by_exact_title.js`
);
return await script({github, context});
- name: Create Pull Request
id: cpr_bump_stable
uses: peter-evans/create-pull-request@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Version bump to ${{ steps.bump_version_stable.outputs.new_version }}
title: Version bump to ${{ steps.bump_version_stable.outputs.new_version }}
body: |
This is an automated PR that is part of Prepare Release automated workflow (1 out of 2).
Please ensure that there are no errors or invalid files are in the PR.
labels: "Automated PR, Changelog Entry: Skipped"
branch: "automated/pr_bumps/${{ steps.bump_version_stable.outputs.new_version }}"
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
milestone: ${{ steps.get_milestone_number.outputs.result }}
- name: Close and reopen the PR with different token to trigger CI
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ steps.cpr_bump_stable.outputs.pull-request-number }}
PR_OPERATION: ${{ steps.cpr_bump_stable.outputs.pull-request-operation }}
with:
github-token: ${{ secrets.cogcreators_bot_repo_scoped }}
script: |
const script = require(
`${process.env.GITHUB_WORKSPACE}/.github/workflows/scripts/close_and_reopen_pr.js`
);
console.log(await script({github, context}));

220
.github/workflows/publish_release.yml vendored Normal file
View File

@@ -0,0 +1,220 @@
name: Publish Release
on:
push:
tags:
- "3.[0-9]+.[0-9]+"
jobs:
release_information:
if: github.repository == 'Cog-Creators/Red-DiscordBot'
name: GO HERE BEFORE APPROVING
runs-on: ubuntu-latest
steps:
# Checkout repository and install Python
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'
# Get version to release
- name: Get version to release
id: version_to_release
run: |
python .github/workflows/scripts/bump_version.py
env:
PYTHONPATH: ${{ github.workspace }}:${{ env.PYTHONPATH }}
JUST_RETURN_VERSION: '1'
# Print release information
- name: REVIEW OUTPUT OF THIS STEP BEFORE APPROVING
env:
TAG_BASE_BRANCH: ${{ github.event.base_ref }}
TAG_REF_NAME: ${{ github.ref }}
RELEASE_VERSION: ${{ steps.version_to_release.outputs.version }}
run: |
echo 'Release information:'
echo "- Branch the tag was based off: ${TAG_BASE_BRANCH#'refs/heads/'}"
echo "- Tag name: ${TAG_REF_NAME#'refs/tags/'}"
echo "- Release version: $RELEASE_VERSION"
echo "TAG_NAME=${TAG_REF_NAME#'refs/tags/'}" >> $GITHUB_ENV
- name: Ensure the tag name corresponds to the released version
env:
RELEASE_VERSION: ${{ steps.version_to_release.outputs.version }}
run: |
if [[ "$TAG_NAME" != "$RELEASE_VERSION" ]]; then
echo -n "The tag name ($TAG_NAME) is not the same as"
echo " the release version ($RELEASE_VERSION)!"
exit 1
else
echo "The tag name and the release version are the same ($TAG_NAME)."
echo 'Continuing...'
fi
build:
name: Build package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade build twine
- name: Build
run: python -m build
- name: Check built distributions
run: python -m twine check dist/*
- name: Upload packaged distributions
uses: actions/upload-artifact@v4
with:
name: build-output
path: ./dist
generate_default_ll_server_config:
name: Generate default application.yml
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'
- name: Install script's dependencies
run: python -m pip install PyYAML
- name: Generate default application.yml
env:
APP_YML_FILE: "Red-DiscordBot-${{ github.ref_name }}-default-lavalink-application.yml"
run: |
mkdir -p release_assets
python .github/workflows/scripts/get_default_ll_server_config.py "release_assets/$APP_YML_FILE"
- name: Upload default application.yml
uses: actions/upload-artifact@v4
with:
name: ll-default-server-config
path: ./release_assets
release_to_pypi:
needs:
- release_information
- build
- generate_default_ll_server_config
environment: Release
name: Release to PyPI
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- name: Download packaged distributions
uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- name: Download default application.yml
uses: actions/download-artifact@v4
with:
name: ll-default-server-config
path: release_assets/
- name: Upload dists to GitHub Release
env:
GITHUB_TOKEN: "${{ github.token }}"
run: |
gh release upload "$GITHUB_REF_NAME" dist/* release_assets/* --repo "$GITHUB_REPOSITORY"
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
# This is already checked during the build.
verify-metadata: false
# Allow security-minded people to verify whether the files on PyPI
# were automatically uploaded by a CI script.
print-hash: true
pr_dev_bump:
permissions:
contents: write
pull-requests: write
needs: release_to_pypi
name: Update Red version number to dev
runs-on: ubuntu-latest
steps:
- name: Get base branch
env:
TAG_BASE_BRANCH: ${{ github.event.base_ref }}
run: |
echo "BASE_BRANCH=${TAG_BASE_BRANCH#'refs/heads/'}" >> $GITHUB_ENV
- uses: actions/checkout@v4
with:
ref: ${{ env.BASE_BRANCH }}
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'
# Version bump to development version
- name: Update Red version number to dev
id: bump_version_dev
run: |
python .github/workflows/scripts/bump_version.py
env:
PYTHONPATH: ${{ github.workspace }}:${{ env.PYTHONPATH }}
DEV_BUMP: '1'
# Get milestone number of the milestone for the old version
- name: Get milestone number
id: get_milestone_number
uses: actions/github-script@v6
env:
MILESTONE_TITLE: ${{ steps.bump_version_dev.outputs.old_version }}
with:
script: |
const script = require(
`${process.env.GITHUB_WORKSPACE}/.github/workflows/scripts/get_milestone_number_by_exact_title.js`
);
return await script({github, context});
- name: Create Pull Request
id: cpr_bump_dev
uses: peter-evans/create-pull-request@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Version bump to ${{ steps.bump_version_dev.outputs.new_version }}
title: Version bump to ${{ steps.bump_version_dev.outputs.new_version }}
body: |
This is an automated PR.
Please ensure that there are no errors or invalid files are in the PR.
labels: "Automated PR, Changelog Entry: Skipped"
branch: "automated/pr_bumps/${{ steps.bump_version_dev.outputs.new_version }}"
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
milestone: ${{ steps.get_milestone_number.outputs.result }}
base: ${{ env.BASE_BRANCH }}
- name: Close and reopen the PR with different token to trigger CI
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ steps.cpr_bump_dev.outputs.pull-request-number }}
PR_OPERATION: ${{ steps.cpr_bump_dev.outputs.pull-request-operation }}
with:
github-token: ${{ secrets.cogcreators_bot_repo_scoped }}
script: |
const script = require(
`${process.env.GITHUB_WORKSPACE}/.github/workflows/scripts/close_and_reopen_pr.js`
);
console.log(await script({github, context}));

99
.github/workflows/run_pip_compile.yaml vendored Normal file
View File

@@ -0,0 +1,99 @@
name: Generate requirements files with pip-compile.
on:
workflow_dispatch:
jobs:
generate_requirements:
name: Generate requirements files for ${{ matrix.os }} platform.
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
- windows-latest
- macos-latest
steps:
- name: Checkout the repository.
uses: actions/checkout@v4
- name: Set up Python 3.8.
uses: actions/setup-python@v4
with:
python-version: |
3.11
3.10
3.9
3.8
- name: Install dependencies on Linux/macOS
if: matrix.os != 'windows-latest'
run: |
python3.11 -m pip install -U pip pip-tools
python3.10 -m pip install -U pip pip-tools
python3.9 -m pip install -U pip pip-tools
python3.8 -m pip install -U pip pip-tools
- name: Install dependencies on Windows
if: matrix.os == 'windows-latest'
run: |
py -3.11 -m pip install -U pip pip-tools
py -3.10 -m pip install -U pip pip-tools
py -3.9 -m pip install -U pip pip-tools
py -3.8 -m pip install -U pip pip-tools
- name: Generate requirements files.
id: compile_requirements
run: |
python .github/workflows/scripts/compile_requirements.py
- name: Upload requirements files.
uses: actions/upload-artifact@v4
with:
name: ${{ steps.compile_requirements.outputs.sys_platform }}
path: requirements/${{ steps.compile_requirements.outputs.sys_platform }}-*.txt
merge_requirements:
name: Merge requirements files.
needs: generate_requirements
runs-on: ubuntu-latest
steps:
- name: Checkout the repository.
uses: actions/checkout@v4
- name: Set up Python 3.8.
uses: actions/setup-python@v4
with:
python-version: '3.8'
- name: Install dependencies
run: |
python -m pip install -U "packaging>=22.0"
- name: Download Windows requirements.
uses: actions/download-artifact@v4
with:
name: win32
path: requirements
- name: Download Linux requirements.
uses: actions/download-artifact@v4
with:
name: linux
path: requirements
- name: Download macOS requirements.
uses: actions/download-artifact@v4
with:
name: darwin
path: requirements
- name: Merge requirements files.
run: |
python .github/workflows/scripts/merge_requirements.py
- name: Upload merged requirements files.
uses: actions/upload-artifact@v4
with:
name: merged
path: |
requirements/base.txt
requirements/extra-*.txt

View File

@@ -0,0 +1,59 @@
import os
import re
import sys
from typing import Any, Match
import redbot
GITHUB_OUTPUT = os.environ["GITHUB_OUTPUT"]
def set_output(name: str, value: Any) -> None:
with open(GITHUB_OUTPUT, "a", encoding="utf-8") as fp:
fp.write(f"{name}={value}\n")
if int(os.environ.get("JUST_RETURN_VERSION", 0)):
set_output("version", redbot._VERSION)
sys.exit(0)
version_info = None
def repl(match: Match[str]) -> str:
global version_info
set_output("old_version", match.group("version"))
new_stable_version = os.environ.get("NEW_STABLE_VERSION", "auto")
if new_stable_version == "auto":
version_info = redbot.VersionInfo.from_str(match.group("version"))
version_info.dev_release = None
else:
version_info = redbot.VersionInfo.from_str(new_stable_version)
if int(os.environ.get("DEV_BUMP", 0)):
version_info.micro += 1
version_info.dev_release = 1
return f'_VERSION = "{version_info}"'
with open("redbot/__init__.py", encoding="utf-8") as fp:
new_contents, found = re.subn(
pattern=r'^_VERSION = "(?P<version>[^"]*)"$',
repl=repl,
string=fp.read(),
count=1,
flags=re.MULTILINE,
)
if not found:
print("Couldn't find `_VERSION` line!")
sys.exit(1)
with open("redbot/__init__.py", "w", encoding="utf-8", newline="\n") as fp:
fp.write(new_contents)
set_output("new_version", version_info)

View File

@@ -0,0 +1,215 @@
import itertools
import operator
import os
import subprocess
from pathlib import Path
from typing import Any, Dict, Iterable, List, Optional
from typing_extensions import Self
import rich
import yaml
from rich.console import Console, ConsoleOptions, RenderResult
from rich.tree import Tree
from pathspec import PathSpec
from pathspec.patterns.gitwildmatch import GitWildMatchPattern
ROOT_PATH = Path(__file__).resolve().parents[3]
class Matcher:
def __init__(self, *, any: Iterable[str] = (), all: Iterable[str] = ()) -> None:
self.any_patterns = tuple(any)
self.any_specs = self._get_pathspecs(self.any_patterns)
self.all_patterns = tuple(all)
self.all_specs = self._get_pathspecs(self.all_patterns)
def __repr__(self) -> str:
return f"Matcher(any={self.any_patterns!r}, all={self.all_patterns!r})"
def __eq__(self, other: Any) -> bool:
if isinstance(other, self.__class__):
return (
self.any_patterns == other.any_patterns and self.all_patterns == other.all_patterns
)
return NotImplemented
def __hash__(self) -> int:
return hash((self.any_patterns, self.all_patterns))
@classmethod
def _get_pathspecs(cls, patterns: Iterable[str]) -> List[PathSpec]:
return tuple(
PathSpec.from_lines(GitWildMatchPattern, cls._get_pattern_lines(pattern))
for pattern in patterns
)
@staticmethod
def _get_pattern_lines(pattern: str) -> List[str]:
# an approximation of actions/labeler's minimatch globs
if pattern.startswith("!"):
pattern_lines = ["*", f"!/{pattern[1:]}"]
else:
pattern_lines = [f"/{pattern}"]
if pattern.endswith("*") and "**" not in pattern:
pattern_lines.append(f"!/{pattern}/")
return pattern_lines
@classmethod
def get_label_matchers(cls) -> Dict[str, List[Self]]:
with open(ROOT_PATH / ".github/labeler.yml", encoding="utf-8") as fp:
label_definitions = yaml.safe_load(fp)
label_matchers: Dict[str, List[Matcher]] = {}
for label_name, matcher_definitions in label_definitions.items():
matchers = label_matchers[label_name] = []
for idx, matcher_data in enumerate(matcher_definitions):
if isinstance(matcher_data, str):
matchers.append(cls(any=[matcher_data]))
elif isinstance(matcher_data, dict):
matchers.append(
cls(any=matcher_data.pop("any", []), all=matcher_data.pop("all", []))
)
if matcher_data:
raise RuntimeError(
f"Unexpected keys at index {idx} for label {label_name!r}: "
+ ", ".join(map(repr, matcher_data))
)
elif matcher_data is not None:
raise RuntimeError(f"Unexpected type at index {idx} for label {label_name!r}")
return label_matchers
class PathNode:
def __init__(self, parent_tree: Tree, path: Path, *, label: Optional[str] = None) -> None:
self.parent_tree = parent_tree
self.path = path
self.label = label
def __rich__(self) -> str:
if self.label is not None:
return self.label
return self.path.name
class DirectoryTree:
def __init__(self, label: str) -> None:
self.root = Tree(PathNode(Tree(""), Path(), label=label))
self._previous = self.root
def __bool__(self) -> bool:
return bool(self.root.children)
def __rich_console__(self, console: Console, options: ConsoleOptions) -> RenderResult:
yield from self.root.__rich_console__(console, options)
def add(self, file: Path) -> Tree:
common_path = Path(os.path.commonpath([file.parent, self._previous.label.path]))
parent_tree = self._previous
while parent_tree != self.root and parent_tree.label.path != common_path:
parent_tree = parent_tree.label.parent_tree
for part in file.relative_to(common_path).parts:
if parent_tree.label.path.name == "locales":
if not parent_tree.children:
parent_tree.add(PathNode(parent_tree, parent_tree.label.path / "*.po"))
continue
parent_tree = parent_tree.add(PathNode(parent_tree, parent_tree.label.path / part))
self._previous = parent_tree
return parent_tree
class App:
def __init__(self) -> None:
self.exit_code = 0
self.label_matchers = Matcher.get_label_matchers()
self.tracked_files = [
Path(filename)
for filename in subprocess.check_output(
("git", "ls-tree", "-r", "HEAD", "--name-only"), encoding="utf-8", cwd=ROOT_PATH
).splitlines()
]
self.matches_per_label = {label_name: set() for label_name in self.label_matchers}
self.matches_per_file = []
self.used_matchers = set()
def run(self) -> int:
old_cwd = os.getcwd()
try:
os.chdir(ROOT_PATH)
self._run()
finally:
os.chdir(old_cwd)
return self.exit_code
def _run(self) -> None:
self._collect_match_information()
self._show_matches_per_label()
self._show_files_without_labels()
self._show_files_with_multiple_labels()
self._show_unused_matchers()
def _collect_match_information(self) -> None:
tmp_matches_per_file = {file: [] for file in self.tracked_files}
for file in self.tracked_files:
for label_name, matchers in self.label_matchers.items():
matched = False
for matcher in matchers:
if all(
path_spec.match_file(file)
for path_spec in itertools.chain(matcher.all_specs, matcher.any_specs)
):
self.matches_per_label[label_name].add(file)
matched = True
self.used_matchers.add(matcher)
if matched:
tmp_matches_per_file[file].append(label_name)
self.matches_per_file = sorted(tmp_matches_per_file.items(), key=operator.itemgetter(0))
def _show_matches_per_label(self) -> None:
for label_name, files in self.matches_per_label.items():
top_tree = DirectoryTree(f"{label_name}:")
for file in sorted(files):
top_tree.add(file)
rich.print(top_tree)
print()
def _show_files_without_labels(self) -> None:
top_tree = DirectoryTree("\n--- Not matched ---")
for file, labels in self.matches_per_file:
if not labels:
top_tree.add(file)
if top_tree:
self.exit_code = 1
rich.print(top_tree)
else:
print("--- All files match at least one label's patterns ---")
def _show_files_with_multiple_labels(self) -> None:
top_tree = DirectoryTree("\n--- Matched by more than one label ---")
for file, labels in self.matches_per_file:
if len(labels) > 1:
tree = top_tree.add(file)
for label_name in labels:
tree.add(label_name)
if top_tree:
rich.print(top_tree)
else:
print("--- None of the files are matched by more than one label's patterns ---")
def _show_unused_matchers(self) -> None:
for label_name, matchers in self.label_matchers.items():
for idx, matcher in enumerate(matchers):
if matcher not in self.used_matchers:
print(
f"--- Matcher {idx} for label {label_name!r} does not match any files! ---"
)
self.exit_code = 1
if __name__ == "__main__":
raise SystemExit(App().run())

View File

@@ -0,0 +1,25 @@
module.exports = (async function ({github, context}) {
const pr_number = process.env.PR_NUMBER;
const pr_operation = process.env.PR_OPERATION;
let sleep_time = 0;
if (!['created', 'updated'].includes(pr_operation)) {
console.log('PR was not created as there were no changes.')
return;
}
for (const new_state of ['closed', 'open']) {
// some sleep time needed to make sure API handles open after close
if (sleep_time)
await new Promise(r => setTimeout(r, sleep_time));
github.rest.issues.update({
issue_number: pr_number,
owner: context.repo.owner,
repo: context.repo.repo,
state: new_state
});
sleep_time = 2000;
}
})

View File

@@ -0,0 +1,52 @@
import os
import re
import shutil
import subprocess
import sys
from pathlib import Path
EXCLUDE_STEM_RE = re.compile(r".*-3\.(?!8-)(\d+)-extra-(doc|style)")
GITHUB_OUTPUT = os.environ["GITHUB_OUTPUT"]
REQUIREMENTS_FOLDER = Path(__file__).parents[3].absolute() / "requirements"
os.chdir(REQUIREMENTS_FOLDER)
def pip_compile(version: str, name: str) -> None:
stem = f"{sys.platform}-{version}-{name}"
if EXCLUDE_STEM_RE.fullmatch(stem):
return
constraint_flags = [
arg
for file in REQUIREMENTS_FOLDER.glob(f"{sys.platform}-3.8-*.txt")
for arg in ("-c", file.name)
]
executable = ("py", f"-{version}") if sys.platform == "win32" else (f"python{version}",)
subprocess.check_call(
(
*executable,
"-m",
"piptools",
"compile",
"--upgrade",
"--resolver=backtracking",
"--verbose",
f"{name}.in",
"--output-file",
f"{stem}.txt",
*constraint_flags,
)
)
for minor in range(8, 11 + 1):
version = f"3.{minor}"
pip_compile(version, "base")
shutil.copyfile(f"{sys.platform}-{version}-base.txt", "base.txt")
for file in REQUIREMENTS_FOLDER.glob("extra-*.in"):
pip_compile(version, file.stem)
with open(GITHUB_OUTPUT, "a", encoding="utf-8") as fp:
fp.write(f"sys_platform={sys.platform}\n")

View File

@@ -0,0 +1,31 @@
import sys
from pathlib import Path
import yaml
ROOT_FOLDER = Path(__file__).parents[3].absolute()
AUDIO_FOLDER = ROOT_FOLDER / "redbot/cogs/audio"
# We want to import `redbot.cogs.audio.managed_node` package as if it were top-level package
# so we have to the `redbot/cogs/audio` directory to Python's path.
sys.path.insert(0, str(AUDIO_FOLDER))
def main() -> int:
try:
output_file = sys.argv[1]
except IndexError:
print("Usage:", sys.argv[0], "<output_file>", file=sys.stderr)
return 2
import managed_node
server_config = managed_node.get_default_server_config()
with open(output_file, "w", encoding="utf-8") as fp:
yaml.safe_dump(server_config, fp)
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,49 @@
module.exports = (async function ({github, context}) {
const milestone_title = process.env.MILESTONE_TITLE;
const [repo_owner, repo_name] = process.env.GITHUB_REPOSITORY.split('/');
const {
repository: {
milestones: {
nodes: milestones,
pageInfo: {hasNextPage}
}
}
} = await github.graphql({
query: `
query getMilestoneNumberByTitle(
$repo_owner: String!
$repo_name: String!
$milestone_title: String!
) {
repository(owner:$repo_owner name:$repo_name) {
milestones(query:$milestone_title states:OPEN first:100) {
nodes {
number
title
}
pageInfo {
hasNextPage
}
}
}
}`,
repo_owner: repo_owner,
repo_name: repo_name,
milestone_title: milestone_title,
});
if (hasNextPage) {
// this should realistically never happen so let's just error
core.setFailed('Impossible happened! :)');
return;
}
for (const milestone of milestones)
if (milestone.title === milestone_title)
return milestone.number;
// if no exact match is found, assume the milestone doesn't exist
console.log('The milestone was not found. API returned the array: %o', milestones);
return null;
})

View File

@@ -0,0 +1,207 @@
from __future__ import annotations
import os
from pathlib import Path
from typing import Dict, Iterable, List, TextIO, Tuple
from packaging.markers import Marker
from packaging.requirements import Requirement
REQUIREMENTS_FOLDER = Path(__file__).parents[3].absolute() / "requirements"
os.chdir(REQUIREMENTS_FOLDER)
class RequirementData:
def __init__(self, requirement_string: str) -> None:
self.req = Requirement(requirement_string)
self.comments = set()
def __hash__(self) -> int:
return hash(self.req)
def __eq__(self, other: RequirementData) -> bool:
return self.req == other.req
@property
def name(self) -> str:
return self.req.name
@property
def marker(self) -> Marker:
return self.req.marker
@marker.setter
def marker(self, value: Marker) -> None:
self.req.marker = value
def get_requirements(fp: TextIO) -> List[RequirementData]:
requirements = []
current = None
for line in fp.read().splitlines():
annotation_prefix = " # "
if line.startswith(annotation_prefix) and current is not None:
source = line[len(annotation_prefix) :].strip()
if source == "via":
continue
via_prefix = "via "
if source.startswith(via_prefix):
source = source[len(via_prefix) :]
if source.startswith("-c ") and source != "-c base.txt":
continue
current.comments.add(source)
elif line and not line.startswith(("#", " ")):
current = RequirementData(line)
requirements.append(current)
return requirements
def iter_envs(envs: Iterable[str]) -> Iterable[Tuple[str, str]]:
for env_name in envs:
platform, python_version = env_name.split("-", maxsplit=1)
yield (platform, python_version)
names = ["base"]
names.extend(file.stem for file in REQUIREMENTS_FOLDER.glob("extra-*.in"))
base_requirements: List[RequirementData] = []
for name in names:
# {req_data: {sys_platform: RequirementData}
input_data: Dict[RequirementData, Dict[str, RequirementData]] = {}
all_envs = set()
all_platforms = set()
all_python_versions = set()
for file in REQUIREMENTS_FOLDER.glob(f"*-{name}.txt"):
platform_name, python_version, _ = file.stem.split("-", maxsplit=2)
env_name = f"{platform_name}-{python_version}"
all_envs.add(env_name)
all_platforms.add(platform_name)
all_python_versions.add(python_version)
with file.open(encoding="utf-8") as fp:
requirements = get_requirements(fp)
for req in requirements:
envs = input_data.setdefault(req, {})
envs[env_name] = req
output = base_requirements if name == "base" else []
for req, envs in input_data.items():
# {platform: [python_versions...]}
python_versions_per_platform: Dict[str, List[str]] = {}
# {python_version: [platforms...]}
platforms_per_python_version: Dict[str, List[str]] = {}
platforms = python_versions_per_platform.keys()
python_versions = platforms_per_python_version.keys()
for env_name, other_req in envs.items():
platform_name, python_version = env_name.split("-", maxsplit=1)
python_versions_per_platform.setdefault(platform_name, []).append(python_version)
platforms_per_python_version.setdefault(python_version, []).append(platform_name)
req.comments.update(other_req.comments)
base_req = next(
(base_req for base_req in base_requirements if base_req.name == req.name), None
)
if base_req is not None:
old_base_marker = base_req.marker
old_req_marker = req.marker
req.marker = base_req.marker = None
if base_req.req != req.req:
raise RuntimeError(f"Incompatible requirements for {req.name}.")
base_req.marker = old_base_marker
req.marker = old_req_marker
if base_req.marker is None or base_req.marker == req.marker:
continue
if len(envs) == len(all_envs):
output.append(req)
continue
# At this point I'm wondering why I didn't just go for
# a more generic boolean algebra simplification (sympy.simplify_logic())...
if (
len(set(map(frozenset, python_versions_per_platform.values()))) == 1
or len(set(map(frozenset, platforms_per_python_version.values()))) == 1
):
# Either all platforms have the same Python version set
# or all Python versions have the same platform set.
# We can generate markers for platform (platform_marker) and Python
# (python_version_marker) version sets separately and then simply require
# that both markers are fulfilled at the same time (env_marker).
python_version_marker = (
# Requirement present on less Python versions than not.
" or ".join(
f"python_version == '{python_version}'"
for python_version in sorted(python_versions)
)
if len(python_versions) < len(all_python_versions - python_versions)
# Requirement present on more Python versions than not
# This may generate an empty string when Python version is irrelevant.
else " and ".join(
f"python_version != '{python_version}'"
for python_version in sorted(all_python_versions - python_versions)
)
)
platform_marker = (
# Requirement present on less platforms than not.
" or ".join(f"sys_platform == '{platform}'" for platform in sorted(platforms))
if len(platforms) < len(all_platforms - platforms)
# Requirement present on more platforms than not
# This may generate an empty string when platform is irrelevant.
else " and ".join(
f"sys_platform != '{platform}'"
for platform in sorted(all_platforms - platforms)
)
)
if python_version_marker and platform_marker:
env_marker = f"({python_version_marker}) and ({platform_marker})"
else:
env_marker = python_version_marker or platform_marker
else:
# Fallback to generic case.
env_marker = (
# Requirement present on less envs than not.
" or ".join(
f"(sys_platform == '{platform}' and python_version == '{python_version}')"
for platform, python_version in iter_envs(sorted(envs))
)
if len(envs) < len(all_envs - envs.keys())
else " and ".join(
f"(sys_platform != '{platform}' and python_version != '{python_version}')"
for platform, python_version in iter_envs(sorted(all_envs - envs.keys()))
)
)
new_marker = f"({req.marker}) and ({env_marker})" if req.marker is not None else env_marker
req.marker = Marker(new_marker)
if base_req is not None and base_req.marker == req.marker:
continue
output.append(req)
output.sort(key=lambda req: (req.marker is not None, req.name))
with open(f"{name}.txt", "w+", encoding="utf-8") as fp:
for req in output:
fp.write(str(req.req))
fp.write("\n")
comments = sorted(req.comments)
if len(comments) == 1:
source = comments[0]
fp.write(" # via ")
fp.write(source)
fp.write("\n")
else:
fp.write(" # via\n")
for source in comments:
fp.write(" # ")
fp.write(source)
fp.write("\n")

107
.github/workflows/tests.yml vendored Normal file
View File

@@ -0,0 +1,107 @@
name: Tests
on:
pull_request:
push:
repository_dispatch:
types:
- dispatched_test
env:
ref: ${{ github.event.client_payload.ref || '' }}
jobs:
tox:
runs-on: ubuntu-latest
strategy:
matrix:
python_version:
- "3.8"
tox_env:
- style
- docs
include:
- tox_env: py38
python_version: "3.8"
friendly_name: Python 3.8 - Tests
- tox_env: py39
python_version: "3.9"
friendly_name: Python 3.9 - Tests
- tox_env: py310
python_version: "3.10"
friendly_name: Python 3.10 - Tests
- tox_env: py311
python_version: "3.11"
friendly_name: Python 3.11 - Tests
- tox_env: style
friendly_name: Style
- tox_env: docs
friendly_name: Docs
fail-fast: false
name: Tox - ${{ matrix.friendly_name }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ env.ref }}
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python_version }}
- name: Install tox
run: |
python -m pip install --upgrade pip
pip install tox
- name: Tox test
env:
TOXENV: ${{ matrix.tox_env }}
run: tox
tox-postgres:
runs-on: ubuntu-latest
strategy:
matrix:
python_version:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
fail-fast: false
name: Tox - Postgres
services:
postgresql:
image: postgres:10
ports:
- 5432:5432
env:
POSTGRES_DB: red_db
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
steps:
- uses: actions/checkout@v4
with:
ref: ${{ env.ref }}
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python_version }}
- name: Install tox
run: |
python -m pip install --upgrade pip
pip install tox
- name: Tox test
env:
TOXENV: postgres
PGDATABASE: red_db
PGUSER: postgres
PGPASSWORD: postgres
PGPORT: 5432
run: tox
- name: Verify no errors in PostgreSQL logs.
run: |
logs="$(docker logs "${{ job.services.postgresql.id }}" 2>&1)"
echo "---- PostgreSQL logs ----"
echo "$logs"
echo "---- PostgreSQL logs ----"
error_count="$(echo "$logs" | { grep -c 'ERROR: ' || true; })"
if [[ $error_count -gt 0 ]]; then
exit 1
fi

94
.gitignore vendored
View File

@@ -1,9 +1,11 @@
*.json
*.exe
*.dll
*.pot
.data
!/tests/cogs/dataconverter/data/**/*.json
Pipfile
Pipfile.lock
.directory
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
@@ -12,6 +14,9 @@
# User-specific stuff:
.idea/
*.iws
.vscode/
*.sublime-project
*.sublime-workspace
## Plugin-specific files:
@@ -55,6 +60,7 @@ parts/
sdist/
var/
wheels/
pip-wheel-metadata/
*.egg-info/
.installed.cfg
*.egg
@@ -134,3 +140,89 @@ ENV/
# pytest
.pytest_cache/
# Pre-commit hooks
/.pre-commit-config.yaml
### macOS template
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Windows template
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
### SublimeText template
# Cache files for Sublime Text
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
# Workspace files are user-specific
# SFTP configuration file
sftp-config.json
sftp-config-alt*.json
# Package control specific files
Package Control.last-run
Package Control.ca-list
Package Control.ca-bundle
Package Control.system-ca-bundle
Package Control.cache/
Package Control.ca-certs/
Package Control.merged-ca-bundle
Package Control.user-ca-bundle
oscrypto-ca-bundle.crt
bh_unicode_properties.cache
# Sublime-github package stores a github token in this file
# https://packagecontrol.io/packages/sublime-github
GitHub.sublime-settings

139
.pylintrc Normal file
View File

@@ -0,0 +1,139 @@
[MASTER]
# Specify a configuration file.
#rcfile=
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=pytest
# Pickle collected data for later comparisons.
persistent=no
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
# DO NOT CHANGE THIS VALUE # Use multiple processes to speed up Pylint.
jobs=1
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time. See also the "--disable" option for examples.
enable=all
disable=C, # black is enforcing this for us already, incompatibly
W, # unbroaden this to the below specifics later on.
W0107, # uneccessary pass is stylisitc in most places
W0212, # Should likely refactor around protected access warnings later
W1203, # fstrings are too fast to care about enforcing this.
W0612, # unused vars can sometimes indicate an issue, but ...
W1401, # Should probably fix the reason this is disabled (start up screen)
W0511, # Nope, todos are fine for future people to see things to do.
W0613, # Too many places where we need to take unused args do to d.py ... also menus
W0221, # Overriden converters.
W0223, # abstractmethod not defined in mixins is expected
I, # ...
R # While some of these have merit, It's too large a burden to enable this right now.
[REPORTS]
output-format=parseable
reports=no
[LOGGING]
# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging
[TYPECHECK]
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# TODO: Write a plyint plugin to allow this with these mixin classes
# To use the abstractmethod we know will be defined in the final class.
ignored-classes=redbot.cogs.mod.movetocore.MoveToCore,
redbot.cogs.mod.kickban.KickBanMixin,
redbot.cogs.mod.mutes.MuteMixin,
redbot.cogs.mod.names.ModInfo,
redbot.cogs.mod.settings.ModSettings,
redbot.cogs.mod.events.Events
ignored-modules=distutils # https://github.com/PyCQA/pylint/issues/73
[VARIABLES]
# Tells whether we should check for unused import in __init__ files.
init-import=no
# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=_$|dummy
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=4
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
[CLASSES]
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,__call__
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception,discord.DiscordException

View File

@@ -1,12 +1,19 @@
formats:
- pdf
version: 2
build:
image: latest
os: "ubuntu-22.04"
tools:
python: "3.8"
jobs:
install:
- pip install .[doc]
sphinx:
configuration: docs/conf.py
python:
version: 3.6
pip_install: true
extra_requirements:
- docs
- mongo
install:
- method: pip
path: .
extra_requirements:
- doc

View File

@@ -1,67 +0,0 @@
dist: xenial
language: python
cache: pip
notifications:
email: false
sudo: true
python:
- 3.6.6
- 3.7
env:
global:
PIPENV_IGNORE_VIRTUALENVS=1
matrix:
TOXENV=py
install:
- pip install --upgrade pip tox
script:
- tox
jobs:
include:
- python: 3.6.6
env: TOXENV=docs
- python: 3.6.6
env: TOXENV=style
# These jobs only occur on tag creation if the prior ones succeed
- stage: PyPi Deployment
if: tag IS present
python: 3.6.6
env:
- DEPLOYING=true
- TOXENV=py36
deploy:
- provider: pypi
user: Red-DiscordBot
password:
secure: Ty9vYnd/wCuQkVC/OsS4E2jT9LVDVfzsFrQc4U2hMYcTJnYbl/3omyObdCWCOBC40vUDkVHAQU8ULHzoCA+2KX9Ds/7/P5zCumAA0uJRR9Smw7OlRzSMxJI+/lGq4CwXKzxDZKuo5rsxXEbW5qmYjtO8Mk6KuLkvieb1vyr2DcqWEFzg/7TZNDfD1oP8et8ITQ26lLP1dtQx/jlAiIBzgK9wziuwj1Divb9A///VsGz43N8maZ+jfsDjYqrfUVWTy3ar7JPUplletenYCR1PmQ5C46XfV0kitKd1aITJ48YPAKyYgKy8AIT+Uz1JArTnqdzLSFRNELS57qS00lzgllbteCyWQ8Uzy0Zpxb/5DDH8/mL1n0MyJrF8qjZd2hLNAXg3z/k9bGXeiMLGwoxRlGXkL2XpiVgI93UKKyVyooGNMgPTc/QdSc7krjAWcOtX/HgLR34jxeLPFEdzJNAFIimfDD8N+XTFcNBw6EvOYm/n5MXkckNoX/G+ThNobHZ7VKSASltZ9zBRAJ2dDh35G3CYmVEk33U77RKbL9le/Za9QVBcAO8i6rqVGYkdO7thHHKHc/1CB1jNnjsFSDt0bURtNfAqfwKCurQC8487zbEzT+2fog3Wygv7g3cklaRg4guY8UjZuFWStYGqbroTsOCd9ATNqeO5B13pNhllSzU=
skip_cleanup: true
on:
repo: Cog-Creators/Red-DiscordBot
python: 3.6.6
tags: true
- stage: Crowdin Deployment
if: tag IS present
python: 3.6.6
env:
- DEPLOYING=true
- TOXENV=py36
before_deploy:
- curl https://artifacts.crowdin.com/repo/GPG-KEY-crowdin | sudo apt-key add -
- echo "deb https://artifacts.crowdin.com/repo/deb/ /" | sudo tee -a /etc/apt/sources.list
- sudo apt-get update -qq
- sudo apt-get install -y crowdin
- pip install redgettext==2.2
deploy:
- provider: script
script: make gettext
skip_cleanup: true
on:
repo: Cog-Creators/Red-DiscordBot
python: 3.6.6
tags: true

4470
CHANGES.rst Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -29,9 +29,8 @@ Red is an open source project. This means that each and every one of the develop
We love receiving contributions from our community. Any assistance you can provide with regards to bug fixes, feature enhancements, and documentation is more than welcome.
# 2. Ground Rules
We've made a point to use [ZenHub](https://www.zenhub.com/) (a plugin for GitHub) as our main source of collaboration and coordination. Your experience contributing to Red will be greatly improved if you go get that plugin.
1. Ensure cross compatibility for Windows, Mac OS and Linux.
2. Ensure all Python features used in contributions exist and work in Python 3.6 and above.
2. Ensure all Python features used in contributions exist and work in Python 3.8.1 and above.
3. Create new tests for code you add or bugs you fix. It helps us help you by making sure we don't accidentally break anything :grinning:
4. Create any issues for new features you'd like to implement and explain why this feature is useful to everyone and not just you personally.
5. Don't add new cogs unless specifically given approval in an issue discussing said cog idea.
@@ -43,7 +42,7 @@ Unsure of how to get started contributing to Red? Please take a look at the Issu
* beginner - issues that can normally be fixed in just a few lines of code and maybe a test or two.
* help-wanted - issues that are currently unassigned to anyone and may be a bit more involved/complex than issues tagged with beginner.
**Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)
**Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github)
At this point you're ready to start making changes. Feel free to ask for help; everyone was a beginner at some point!
@@ -53,35 +52,38 @@ Red's repository is configured to follow a particular development workflow, usin
### 4.1 Setting up your development environment
The following requirements must be installed prior to setting up:
- Python 3.6.2 or greater (3.6.6 or greater on Windows)
- Python 3.8.1 or greater
- git
- pip
- pipenv
If you're not on Windows, you can optionally install [pyenv](https://github.com/pyenv/pyenv), which will help you run tests for different python versions.
If you're not on Windows, you should also have GNU make installed, and you can optionally install [pyenv](https://github.com/pyenv/pyenv), which can help you run tests for different python versions.
1. Fork and clone the repository to a directory on your local machine.
2. Open a command line in that directory and execute the following commands:
2. Open a command line in that directory and execute the following command:
```bash
pip install pipenv
pipenv install --dev
make newenv
```
Red, its dependencies, and all required development tools, are now installed to a virtual environment. Red is installed in editable mode, meaning that edits you make to the source code in the repository will be reflected when you run Red.
3. Activate the new virtual environment with the command:
```bash
pipenv shell
```
From here onwards, we will assume you are executing commands from within this shell. Each time you open a new command line, you should execute this command first.
Red, its dependencies, and all required development tools, are now installed to a virtual environment located in the `.venv` subdirectory. Red is installed in editable mode, meaning that edits you make to the source code in the repository will be reflected when you run Red.
3. Activate the new virtual environment with one of the following commands:
- Posix:
```bash
source .venv/bin/activate
```
- Windows:
```powershell
.venv\Scripts\activate
```
Each time you open a new command line, you should execute this command first. From here onwards, we will assume you are executing commands from within this activated virtual environment.
Note: If you haven't used `pipenv` before but are comfortable with virtualenvs, just run `pip install pipenv` in the virtualenv you're already using and invoke the command above from the cloned Red repo. It will do the correct thing.
**Note:** If you're comfortable with setting up virtual environments yourself and would rather do it manually, just run `pip install -Ur tools/dev-requirements.txt` after setting it up.
### 4.2 Testing
We've recently started using [tox](https://github.com/tox-dev/tox) to run all of our tests. It's extremely simple to use, and if you followed the previous section correctly, it is already installed to your virtual environment.
We're using [tox](https://github.com/tox-dev/tox) to run all of our tests. It's extremely simple to use, and if you followed the previous section correctly, it is already installed to your virtual environment.
Currently, tox does the following, creating its own virtual environments for each stage:
- Runs all of our unit tests with [pytest](https://github.com/pytest-dev/pytest) on python 3.6 and 3.7 (test environments `py36` and `py37`)
- Runs all of our unit tests with [pytest](https://github.com/pytest-dev/pytest) on python 3.8 (test environment `py38`)
- Ensures documentation builds without warnings, and all hyperlinks have a valid destination (test environment `docs`)
- Ensures that the code meets our style guide with [black](https://github.com/ambv/black) (test environment `style`)
- Ensures that the code meets our style guide with [black](https://github.com/psf/black) (test environment `style`)
To run all of these tests, just run the command `tox` in the project directory.
@@ -90,17 +92,23 @@ To run a subset of these tests, use the command `tox -e <env>`, where `<env>` is
Your PR will not be merged until all of these tests pass.
### 4.3 Style
Our style checker of choice, [black](https://github.com/ambv/black), actually happens to be an auto-formatter. The checking functionality simply detects whether or not it would try to reformat something in your code, should you run the formatter on it. For this reason, we recommend using this tool as a formatter, regardless of any disagreements you might have with the style it enforces.
Our style checker of choice, [black](https://github.com/psf/black), actually happens to be an auto-formatter. The checking functionality simply detects whether or not it would try to reformat something in your code, should you run the formatter on it. For this reason, we recommend using this tool as a formatter, regardless of any disagreements you might have with the style it enforces.
Use the command `black --help` to see how to use this tool. The full style guide is explained in detail on [black's GitHub repository](https://github.com/ambv/black). **There is one exception to this**, however, which is that we set the line length to 99, instead of black's default 88. When using `black` on the command line, simply use it like so: `black -l 99 -N <src>`.
Use the command `black --help` to see how to use this tool. The full style guide is explained in detail on [black's GitHub repository](https://github.com/psf/black). **There is one exception to this**, however, which is that we set the line length to 99, instead of black's default 88. This is already set in `pyproject.toml` configuration file in the repo so you can simply format code with Black like so: `black <src>`.
### 4.4 Make
You may have noticed we have a `Makefile` and a `make.bat` in the top-level directory. For now, you can do two things with them:
You may have noticed we have a `Makefile` and a `make.bat` in the top-level directory. For now, you can do a few things with them:
1. `make reformat`: Reformat all python files in the project with Black
2. `make stylecheck`: Check if any `.py` files in the project need reformatting
3. `make newenv`: Set up a new virtual environment in the `.venv` subdirectory, and install Red and its dependencies. If one already exists, it is cleared out and replaced.
4. `make syncenv`: Sync your environment with Red's latest dependencies.
The other make recipes are most likely for project maintainers rather than contributors.
You can specify the Python executable used in the make recipes with the `PYTHON` environment variable, e.g. `make PYTHON=/usr/bin/python3.8 newenv`.
### 4.5 Keeping your dependencies up to date
Whenever you pull from upstream (V3/develop on the main repository) and you notice the file `Pipfile.lock` has been changed, it usually means one of the package dependencies have been updated, added or removed. To make sure you're testing and formatting with the most up-to-date versions of our dependencies, run `pipenv install --dev` again.
Whenever you pull from upstream (V3/develop on the main repository) and you notice either of the files `setup.cfg` or `tools/dev-requirements.txt` have been changed, it can often mean some package dependencies have been updated, added or removed. To make sure you're testing and formatting with the most up-to-date versions of our dependencies, run `make syncenv`. You could also simply do `make newenv` to install them to a clean new virtual environment.
### 4.6 To contribute changes
@@ -109,6 +117,10 @@ Whenever you pull from upstream (V3/develop on the main repository) and you noti
3. If you like the changes and think the main Red project could use it:
* Run tests with `tox` to ensure your code is up to scratch
* Create a Pull Request on GitHub with your changes
- If you are contributing a behavior change, please keep in mind that behavior changes
are conditional on them being appropriate for the project's current goals.
If you would like to reduce the risk of putting in effort for something we aren't
going to use, open an issue discussing it first.
### 4.7 How To Report A Bug
Please see our **ISSUES.MD** for more information.
@@ -132,7 +144,7 @@ Pull requests are evaluated by their quality and how effectively they solve thei
1. A pull request is submitted
2. Core team members will review and test the pull request (usually within a week)
3. After a majority of the core team approves your pull request:
3. After a member of the core team approves your pull request:
* If your pull request is considered an improvement or enhancement the project owner will have 1 day to veto or approve your pull request.
* If your pull request is considered a new feature the project owner will have 1 week to veto or approve your pull request.
4. If any feedback is given we expect a response within 1 week or we may decide to close the PR.

37
LICENSE
View File

@@ -632,7 +632,8 @@ state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Red - A fully customizable Discord bot
Copyright (C) 2015-2018 Twentysix
Copyright (C) 2017-present Cog Creators
Copyright (C) 2015-2017 Twentysix
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -652,7 +653,8 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Red-DiscordBot Copyright (C) 2015-2018 Twentysix
Red-DiscordBot Copyright (C) 2017-present Cog Creators
Red-DiscordBot Copyright (C) 2015-2017 Twentysix
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@@ -672,3 +674,34 @@ may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
The Red-DiscordBot project contains subcomponents in the Audio module that
have a separate copyright notice and license terms. Your use of the source
code for these subcomponents is subject to the terms and conditions of the
following licenses.
This product bundles methods from https://github.com/Just-Some-Bots/MusicBot/
blob/master/musicbot/spotify.py which are available under an MIT license.
Copyright (c) 2015-2018 Just-Some-Bots (https://github.com/Just-Some-Bots)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
This project vendors discord.ext.menus package (https://github.com/Rapptz/discord-ext-menus) made by Danny Y. (Rapptz) which is distributed under MIT License.
Copy of this license can be found in discord-ext-menus.LICENSE file in redbot/vendored folder of this repository.

33
MANIFEST.in Normal file
View File

@@ -0,0 +1,33 @@
# include license files
include LICENSE
recursive-include redbot *.LICENSE
# include requirements files
include requirements/base.in
include requirements/base.txt
include requirements/extra-*.in
include requirements/extra-*.txt
# include locale files
recursive-include redbot locales/*.po
# include data folders for cogs
recursive-include redbot/**/data *
# include *.export files from the test fixtures
recursive-include redbot *.export
# include the py.typed file informing about Red being typed
recursive-include redbot py.typed
# include *.sql files from postgres driver
recursive-include redbot/core/_drivers/postgres *.sql
# include tests
graft tests
# include tox configuration
include tox.ini
# exclude files containing byte-code and compiled libs
global-exclude *.py[cod]

View File

@@ -1,13 +1,62 @@
reformat:
black -l 99 -N `git ls-files "*.py"`
stylecheck:
black --check -l 99 -N `git ls-files "*.py"`
gettext:
redgettext --command-docstrings --verbose --recursive redbot --exclude-files "redbot/pytest/**/*"
crowdin upload
.DEFAULT_GOAL := help
REF?=rewrite
update_vendor:
pip install --upgrade --no-deps -t . https://github.com/Rapptz/discord.py/archive/$(REF).tar.gz#egg=discord.py
rm -r discord.py*.egg-info
$(MAKE) reformat
PYTHON ?= python3.8
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
ifneq ($(wildcard $(ROOT_DIR)/.venv/.),)
VENV_PYTHON = $(ROOT_DIR)/.venv/bin/python
else
VENV_PYTHON = $(PYTHON)
endif
define HELP_BODY
Usage:
make <command>
Commands:
reformat Reformat all .py files being tracked by git.
stylecheck Check which tracked .py files need reformatting.
stylediff Show the post-reformat diff of the tracked .py files
without modifying them.
gettext Generate pot files.
upload_translations Upload pot files to Crowdin.
download_translations Download translations from Crowdin.
bumpdeps Run script bumping dependencies.
newenv Create or replace this project's virtual environment.
syncenv Sync this project's virtual environment to Red's latest
dependencies.
endef
export HELP_BODY
# Python Code Style
reformat:
$(VENV_PYTHON) -m black $(ROOT_DIR)
stylecheck:
$(VENV_PYTHON) -m black --check $(ROOT_DIR)
stylediff:
$(VENV_PYTHON) -m black --check --diff $(ROOT_DIR)
# Translations
gettext:
$(PYTHON) -m redgettext --command-docstrings --verbose --recursive redbot --exclude-files "redbot/pytest/**/*"
upload_translations:
crowdin upload sources
download_translations:
crowdin download
# Dependencies
bumpdeps:
$(PYTHON) tools/bumpdeps.py
# Development environment
newenv:
$(PYTHON) -m venv --clear .venv
.venv/bin/pip install -U pip wheel
$(MAKE) syncenv
syncenv:
.venv/bin/pip install -Ur ./tools/dev-requirements.txt
# Help
help:
@echo "$$HELP_BODY"

11
Pipfile
View File

@@ -1,11 +0,0 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
"e1839a8" = { path = ".", editable = true, extras = ['mongo', 'voice'] }
[dev-packages]
tox = "*"
"e1839a9" = { path = ".", editable = true, extras = ['docs', 'test', 'style'] }

771
Pipfile.lock generated
View File

@@ -1,771 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "57184ef83392116db24a1966022ad358f54048bb43d428d47a6e31f1a88fc434"
},
"pipfile-spec": 6,
"requires": {},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"aiohttp": {
"hashes": [
"sha256:0419705a36b43c0ac6f15469f9c2a08cad5c939d78bd12a5c23ea167c8253b2b",
"sha256:1812fc4bc6ac1bde007daa05d2d0f61199324e0cc893b11523e646595047ca08",
"sha256:2214b5c0153f45256d5d52d1e0cafe53f9905ed035a142191727a5fb620c03dd",
"sha256:275909137f0c92c61ba6bb1af856a522d5546f1de8ea01e4e726321c697754ac",
"sha256:3983611922b561868428ea1e7269e757803713f55b53502423decc509fef1650",
"sha256:51afec6ffa50a9da4cdef188971a802beb1ca8e8edb40fa429e5e529db3475fa",
"sha256:589f2ec8a101a0f340453ee6945bdfea8e1cd84c8d88e5be08716c34c0799d95",
"sha256:789820ddc65e1f5e71516adaca2e9022498fa5a837c79ba9c692a9f8f916c330",
"sha256:7a968a0bdaaf9abacc260911775611c9a602214a23aeb846f2eb2eeaa350c4dc",
"sha256:7aeefbed253f59ea39e70c5848de42ed85cb941165357fc7e87ab5d8f1f9592b",
"sha256:7b2eb55c66512405103485bd7d285a839d53e7fdc261ab20e5bcc51d7aaff5de",
"sha256:87bc95d3d333bb689c8d755b4a9d7095a2356108002149523dfc8e607d5d32a4",
"sha256:9d80e40db208e29168d3723d1440ecbb06054d349c5ece6a2c5a611490830dd7",
"sha256:a1b442195c2a77d33e4dbee67c9877ccbdd3a1f686f91eb479a9577ed8cc326b",
"sha256:ab3d769413b322d6092f169f316f7b21cd261a7589f7e31db779d5731b0480d8",
"sha256:b066d3dec5d0f5aee6e34e5765095dc3d6d78ef9839640141a2b20816a0642bd",
"sha256:b24e7845ae8de3e388ef4bcfcf7f96b05f52c8e633b33cf8003a6b1d726fc7c2",
"sha256:c59a953c3f8524a7c86eaeaef5bf702555be12f5668f6384149fe4bb75c52698",
"sha256:cf2cc6c2c10d242790412bea7ccf73726a9a44b4c4b073d2699ef3b48971fd95",
"sha256:e0c9c8d4150ae904f308ff27b35446990d2b1dfc944702a21925937e937394c6",
"sha256:f1839db4c2b08a9c8f9788112644f8a8557e8e0ecc77b07091afabb941dc55d0",
"sha256:f3df52362be39908f9c028a65490fae0475e4898b43a03d8aa29d1e765b45e07"
],
"version": "==3.4.4"
},
"aiohttp-json-rpc": {
"hashes": [
"sha256:00d72f40edfc7271578d545a8c47874c0e23cc5d3201ed8128481f6a4af47e32",
"sha256:02d83b6998f8a0b7e59b46f0cb8a96b475bbf82600b1f9527df47135353f1ca8"
],
"version": "==0.11.2"
},
"appdirs": {
"hashes": [
"sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
"sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"
],
"version": "==1.4.3"
},
"async-timeout": {
"hashes": [
"sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f",
"sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"
],
"version": "==3.0.1"
},
"attrs": {
"hashes": [
"sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
"sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
],
"version": "==18.2.0"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"colorama": {
"hashes": [
"sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d",
"sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"
],
"version": "==0.4.1"
},
"distro": {
"hashes": [
"sha256:224041cef9600e72d19ae41ba006e71c05c4dc802516da715d7fda55ba3d8742",
"sha256:6ec8e539cf412830e5ccf521aecf879f2c7fcf60ce446e33cd16eef1ed8a0158"
],
"version": "==1.3.0"
},
"dnspython": {
"hashes": [
"sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01",
"sha256:f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d"
],
"version": "==1.16.0"
},
"e1839a8": {
"editable": true,
"extras": [
"mongo",
"voice"
],
"path": "."
},
"fuzzywuzzy": {
"hashes": [
"sha256:5ac7c0b3f4658d2743aa17da53a55598144edbc5bee3c6863840636e6926f254",
"sha256:6f49de47db00e1c71d40ad16da42284ac357936fa9b66bea1df63fed07122d62"
],
"version": "==0.17.0"
},
"idna": {
"hashes": [
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
],
"version": "==2.8"
},
"idna-ssl": {
"hashes": [
"sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c"
],
"version": "==1.1.0"
},
"motor": {
"hashes": [
"sha256:462fbb824f4289481c158227a2579d6adaf1ec7c70cf7ebe60ed6ceb321e5869",
"sha256:d035c09ab422bc50bf3efb134f7405694cae76268545bd21e14fb22e2638f84e"
],
"version": "==2.0.0"
},
"multidict": {
"hashes": [
"sha256:024b8129695a952ebd93373e45b5d341dbb87c17ce49637b34000093f243dd4f",
"sha256:041e9442b11409be5e4fc8b6a97e4bcead758ab1e11768d1e69160bdde18acc3",
"sha256:045b4dd0e5f6121e6f314d81759abd2c257db4634260abcfe0d3f7083c4908ef",
"sha256:047c0a04e382ef8bd74b0de01407e8d8632d7d1b4db6f2561106af812a68741b",
"sha256:068167c2d7bbeebd359665ac4fff756be5ffac9cda02375b5c5a7c4777038e73",
"sha256:148ff60e0fffa2f5fad2eb25aae7bef23d8f3b8bdaf947a65cdbe84a978092bc",
"sha256:1d1c77013a259971a72ddaa83b9f42c80a93ff12df6a4723be99d858fa30bee3",
"sha256:1d48bc124a6b7a55006d97917f695effa9725d05abe8ee78fd60d6588b8344cd",
"sha256:31dfa2fc323097f8ad7acd41aa38d7c614dd1960ac6681745b6da124093dc351",
"sha256:34f82db7f80c49f38b032c5abb605c458bac997a6c3142e0d6c130be6fb2b941",
"sha256:3d5dd8e5998fb4ace04789d1d008e2bb532de501218519d70bb672c4c5a2fc5d",
"sha256:4a6ae52bd3ee41ee0f3acf4c60ceb3f44e0e3bc52ab7da1c2b2aa6703363a3d1",
"sha256:4b02a3b2a2f01d0490dd39321c74273fed0568568ea0e7ea23e02bd1fb10a10b",
"sha256:4b843f8e1dd6a3195679d9838eb4670222e8b8d01bc36c9894d6c3538316fa0a",
"sha256:5de53a28f40ef3c4fd57aeab6b590c2c663de87a5af76136ced519923d3efbb3",
"sha256:61b2b33ede821b94fa99ce0b09c9ece049c7067a33b279f343adfe35108a4ea7",
"sha256:6a3a9b0f45fd75dc05d8e93dc21b18fc1670135ec9544d1ad4acbcf6b86781d0",
"sha256:76ad8e4c69dadbb31bad17c16baee61c0d1a4a73bed2590b741b2e1a46d3edd0",
"sha256:7ba19b777dc00194d1b473180d4ca89a054dd18de27d0ee2e42a103ec9b7d014",
"sha256:7c1b7eab7a49aa96f3db1f716f0113a8a2e93c7375dd3d5d21c4941f1405c9c5",
"sha256:7fc0eee3046041387cbace9314926aa48b681202f8897f8bff3809967a049036",
"sha256:8ccd1c5fff1aa1427100ce188557fc31f1e0a383ad8ec42c559aabd4ff08802d",
"sha256:8e08dd76de80539d613654915a2f5196dbccc67448df291e69a88712ea21e24a",
"sha256:c18498c50c59263841862ea0501da9f2b3659c00db54abfbf823a80787fde8ce",
"sha256:c49db89d602c24928e68c0d510f4fcf8989d77defd01c973d6cbe27e684833b1",
"sha256:ce20044d0317649ddbb4e54dab3c1bcc7483c78c27d3f58ab3d0c7e6bc60d26a",
"sha256:d1071414dd06ca2eafa90c85a079169bfeb0e5f57fd0b45d44c092546fcd6fd9",
"sha256:d3be11ac43ab1a3e979dac80843b42226d5d3cccd3986f2e03152720a4297cd7",
"sha256:db603a1c235d110c860d5f39988ebc8218ee028f07a7cbc056ba6424372ca31b"
],
"version": "==4.5.2"
},
"pymongo": {
"hashes": [
"sha256:025f94fc1e1364f00e50badc88c47f98af20012f23317234e51a11333ef986e6",
"sha256:02aa7fb282606331aefbc0586e2cf540e9dbe5e343493295e7f390936ad2738e",
"sha256:057210e831573e932702cf332012ed39da78edf0f02d24a3f0b213264a87a397",
"sha256:0d946b79c56187fe139276d4c8ed612a27a616966c8b9779d6b79e2053587c8b",
"sha256:104790893b928d310aae8a955e0bdbaa442fb0ac0a33d1bbb0741c791a407778",
"sha256:15527ef218d95a8717486106553b0d54ff2641e795b65668754e17ab9ca6e381",
"sha256:1826527a0b032f6e20e7ac7f72d7c26dd476a5e5aa82c04aa1c7088a59fded7d",
"sha256:22e3aa4ce1c3eebc7f70f9ca7fd4ce1ea33e8bdb7b61996806cd312f08f84a3a",
"sha256:244e1101e9a48615b9a16cbd194f73c115fdfefc96894803158608115f703b26",
"sha256:24b8c04fdb633a84829d03909752c385faef249c06114cc8d8e1700b95aae5c8",
"sha256:2c276696350785d3104412cbe3ac70ab1e3a10c408e7b20599ee41403a3ed630",
"sha256:2d8474dc833b1182b651b184ace997a7bd83de0f51244de988d3c30e49f07de3",
"sha256:3119b57fe1d964781e91a53e81532c85ed1701baaddec592e22f6b77a9fdf3df",
"sha256:3bee8e7e0709b0fcdaa498a3e513bde9ffc7cd09dbceb11e425bd91c89dbd5b6",
"sha256:436c071e01a464753d30dbfc8768dd93aecf2a8e378e5314d130b95e77b4d612",
"sha256:46635e3f19ad04d5a7d7cf23d232388ddbfccf46d9a3b7436b6abadda4e84813",
"sha256:4772e0b679717e7ac4608d996f57b6f380748a919b457cb05bb941467b888b22",
"sha256:4e2cd80e16f481a62c3175b607373200e714ed29025f21559ebf7524f295689f",
"sha256:52732960efa0e003ca1c092dc0a3c65276e897681287a788a01ca78dda3b41f0",
"sha256:55a7de51ec7d1731b2431886d0349146645f2816e5b8eb982d7c49f89472c9f3",
"sha256:5f8ed5934197a2d4b2087646e98de3e099a237099dcf498b9e38dd3465f74ef4",
"sha256:64b064124fcbc8eb04a155117dc4d9a336e3cda3f069958fbc44fe70c3c3d1e9",
"sha256:65958b8e4319f992e85dad59d8081888b97fcdbde5f0d14bc28f2848b92d3ef1",
"sha256:7683428862e20c6a790c19e64f8ccf487f613fbc83d47e3d532df9c81668d451",
"sha256:78566d5570c75a127c2491e343dc006798a384f06be588fe9b0cbe5595711559",
"sha256:7d1cb00c093dbf1d0b16ccf123e79dee3b82608e4a2a88947695f0460eef13ff",
"sha256:8c74e2a9b594f7962c62cef7680a4cb92a96b4e6e3c2f970790da67cc0213a7e",
"sha256:8e60aa7699170f55f4b0f56ee6f8415229777ac7e4b4b1aa41fc61eec08c1f1d",
"sha256:9447b561529576d89d3bf973e5241a88cf76e45bd101963f5236888713dea774",
"sha256:970055bfeb0be373f2f5299a3db8432444bad3bc2f198753ee6c2a3a781e0959",
"sha256:a6344b8542e584e140dc3c651d68bde51270e79490aa9320f9e708f9b2c39bd5",
"sha256:ce309ca470d747b02ba6069d286a17b7df8e9c94d10d727d9cf3a64e51d85184",
"sha256:cfbd86ed4c2b2ac71bbdbcea6669bf295def7152e3722ddd9dda94ac7981f33d",
"sha256:d7929c513732dff093481f4a0954ed5ff16816365842136b17caa0b4992e49d3"
],
"version": "==3.7.2"
},
"python-levenshtein": {
"hashes": [
"sha256:033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1"
],
"version": "==0.12.0"
},
"pyyaml": {
"hashes": [
"sha256:3d7da3009c0f3e783b2c873687652d83b1bbfd5c88e9813fb7e5b03c0dd3108b",
"sha256:3ef3092145e9b70e3ddd2c7ad59bdd0252a94dfe3949721633e41344de00a6bf",
"sha256:40c71b8e076d0550b2e6380bada1f1cd1017b882f7e16f09a65be98e017f211a",
"sha256:558dd60b890ba8fd982e05941927a3911dc409a63dcb8b634feaa0cda69330d3",
"sha256:a7c28b45d9f99102fa092bb213aa12e0aaf9a6a1f5e395d36166639c1f96c3a1",
"sha256:aa7dd4a6a427aed7df6fb7f08a580d68d9b118d90310374716ae90b710280af1",
"sha256:bc558586e6045763782014934bfaf39d48b8ae85a2713117d16c39864085c613",
"sha256:d46d7982b62e0729ad0175a9bc7e10a566fc07b224d2c79fafb5e032727eaa04",
"sha256:d5eef459e30b09f5a098b9cea68bebfeb268697f78d647bd255a085371ac7f3f",
"sha256:e01d3203230e1786cd91ccfdc8f8454c8069c91bee3962ad93b87a4b2860f537",
"sha256:e170a9e6fcfd19021dd29845af83bb79236068bf5fd4df3327c1be18182b2531"
],
"version": "==3.13"
},
"raven": {
"hashes": [
"sha256:3fa6de6efa2493a7c827472e984ce9b020797d0da16f1db67197bcc23c8fae54",
"sha256:44a13f87670836e153951af9a3c80405d36b43097db869a36e92809673692ce4"
],
"version": "==6.10.0"
},
"raven-aiohttp": {
"hashes": [
"sha256:1444a49c93a85b8bb57c6ee649e512368dce7a26ad64ac3a01d86aa5669d77f3",
"sha256:6a34b6a9841ad0fd827eeb158edb5826c5c5bd7babe2cde2a3f23eb85313af04"
],
"version": "==0.7.0"
},
"red-lavalink": {
"hashes": [
"sha256:6a1a34471ccf4630eee537049568dd87e8e93614f1d1ce355dd74e5b10079782"
],
"version": "==0.1.2"
},
"schema": {
"hashes": [
"sha256:d994b0dc4966000037b26898df638e3e2a694cc73636cb2050e652614a350687",
"sha256:fa1a53fe5f3b6929725a4e81688c250f46838e25d8c1885a10a590c8c01a7b74"
],
"version": "==0.6.8"
},
"websockets": {
"hashes": [
"sha256:0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136",
"sha256:2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6",
"sha256:5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1",
"sha256:5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538",
"sha256:669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4",
"sha256:695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908",
"sha256:6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0",
"sha256:79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d",
"sha256:7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c",
"sha256:82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d",
"sha256:8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c",
"sha256:91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb",
"sha256:952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf",
"sha256:99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e",
"sha256:9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96",
"sha256:a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584",
"sha256:cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484",
"sha256:e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d",
"sha256:e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559",
"sha256:ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff",
"sha256:f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454"
],
"version": "==6.0"
},
"yarl": {
"hashes": [
"sha256:024ecdc12bc02b321bc66b41327f930d1c2c543fa9a561b39861da9388ba7aa9",
"sha256:2f3010703295fbe1aec51023740871e64bb9664c789cba5a6bdf404e93f7568f",
"sha256:3890ab952d508523ef4881457c4099056546593fa05e93da84c7250516e632eb",
"sha256:3e2724eb9af5dc41648e5bb304fcf4891adc33258c6e14e2a7414ea32541e320",
"sha256:5badb97dd0abf26623a9982cd448ff12cb39b8e4c94032ccdedf22ce01a64842",
"sha256:73f447d11b530d860ca1e6b582f947688286ad16ca42256413083d13f260b7a0",
"sha256:7ab825726f2940c16d92aaec7d204cfc34ac26c0040da727cf8ba87255a33829",
"sha256:b25de84a8c20540531526dfbb0e2d2b648c13fd5dd126728c496d7c3fea33310",
"sha256:c6e341f5a6562af74ba55205dbd56d248daf1b5748ec48a0200ba227bb9e33f4",
"sha256:c9bb7c249c4432cd47e75af3864bc02d26c9594f49c82e2a28624417f0ae63b8",
"sha256:e060906c0c585565c718d1c3841747b61c5439af2211e185f6739a9412dfbde1"
],
"version": "==1.3.0"
}
},
"develop": {
"aiohttp": {
"hashes": [
"sha256:0419705a36b43c0ac6f15469f9c2a08cad5c939d78bd12a5c23ea167c8253b2b",
"sha256:1812fc4bc6ac1bde007daa05d2d0f61199324e0cc893b11523e646595047ca08",
"sha256:2214b5c0153f45256d5d52d1e0cafe53f9905ed035a142191727a5fb620c03dd",
"sha256:275909137f0c92c61ba6bb1af856a522d5546f1de8ea01e4e726321c697754ac",
"sha256:3983611922b561868428ea1e7269e757803713f55b53502423decc509fef1650",
"sha256:51afec6ffa50a9da4cdef188971a802beb1ca8e8edb40fa429e5e529db3475fa",
"sha256:589f2ec8a101a0f340453ee6945bdfea8e1cd84c8d88e5be08716c34c0799d95",
"sha256:789820ddc65e1f5e71516adaca2e9022498fa5a837c79ba9c692a9f8f916c330",
"sha256:7a968a0bdaaf9abacc260911775611c9a602214a23aeb846f2eb2eeaa350c4dc",
"sha256:7aeefbed253f59ea39e70c5848de42ed85cb941165357fc7e87ab5d8f1f9592b",
"sha256:7b2eb55c66512405103485bd7d285a839d53e7fdc261ab20e5bcc51d7aaff5de",
"sha256:87bc95d3d333bb689c8d755b4a9d7095a2356108002149523dfc8e607d5d32a4",
"sha256:9d80e40db208e29168d3723d1440ecbb06054d349c5ece6a2c5a611490830dd7",
"sha256:a1b442195c2a77d33e4dbee67c9877ccbdd3a1f686f91eb479a9577ed8cc326b",
"sha256:ab3d769413b322d6092f169f316f7b21cd261a7589f7e31db779d5731b0480d8",
"sha256:b066d3dec5d0f5aee6e34e5765095dc3d6d78ef9839640141a2b20816a0642bd",
"sha256:b24e7845ae8de3e388ef4bcfcf7f96b05f52c8e633b33cf8003a6b1d726fc7c2",
"sha256:c59a953c3f8524a7c86eaeaef5bf702555be12f5668f6384149fe4bb75c52698",
"sha256:cf2cc6c2c10d242790412bea7ccf73726a9a44b4c4b073d2699ef3b48971fd95",
"sha256:e0c9c8d4150ae904f308ff27b35446990d2b1dfc944702a21925937e937394c6",
"sha256:f1839db4c2b08a9c8f9788112644f8a8557e8e0ecc77b07091afabb941dc55d0",
"sha256:f3df52362be39908f9c028a65490fae0475e4898b43a03d8aa29d1e765b45e07"
],
"version": "==3.4.4"
},
"aiohttp-json-rpc": {
"hashes": [
"sha256:00d72f40edfc7271578d545a8c47874c0e23cc5d3201ed8128481f6a4af47e32",
"sha256:02d83b6998f8a0b7e59b46f0cb8a96b475bbf82600b1f9527df47135353f1ca8"
],
"version": "==0.11.2"
},
"alabaster": {
"hashes": [
"sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359",
"sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"
],
"version": "==0.7.12"
},
"appdirs": {
"hashes": [
"sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
"sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"
],
"version": "==1.4.3"
},
"async-timeout": {
"hashes": [
"sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f",
"sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"
],
"version": "==3.0.1"
},
"atomicwrites": {
"hashes": [
"sha256:0312ad34fcad8fac3704d441f7b317e50af620823353ec657a53e981f92920c0",
"sha256:ec9ae8adaae229e4f8446952d204a3e4b5fdd2d099f9be3aaf556120135fb3ee"
],
"version": "==1.2.1"
},
"attrs": {
"hashes": [
"sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
"sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
],
"version": "==18.2.0"
},
"babel": {
"hashes": [
"sha256:6778d85147d5d85345c14a26aada5e478ab04e39b078b0745ee6870c2b5cf669",
"sha256:8cba50f48c529ca3fa18cf81fa9403be176d374ac4d60738b839122dfaaa3d23"
],
"version": "==2.6.0"
},
"black": {
"hashes": [
"sha256:817243426042db1d36617910df579a54f1afd659adb96fc5032fcf4b36209739",
"sha256:e030a9a28f542debc08acceb273f228ac422798e5215ba2a791a6ddeaaca22a5"
],
"version": "==18.9b0"
},
"certifi": {
"hashes": [
"sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7",
"sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033"
],
"version": "==2018.11.29"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"click": {
"hashes": [
"sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
"sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
],
"version": "==7.0"
},
"colorama": {
"hashes": [
"sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d",
"sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"
],
"version": "==0.4.1"
},
"distro": {
"hashes": [
"sha256:224041cef9600e72d19ae41ba006e71c05c4dc802516da715d7fda55ba3d8742",
"sha256:6ec8e539cf412830e5ccf521aecf879f2c7fcf60ce446e33cd16eef1ed8a0158"
],
"version": "==1.3.0"
},
"docutils": {
"hashes": [
"sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
"sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274",
"sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"
],
"version": "==0.14"
},
"e1839a9": {
"editable": true,
"extras": [
"docs",
"test",
"style"
],
"path": "."
},
"filelock": {
"hashes": [
"sha256:b8d5ca5ca1c815e1574aee746650ea7301de63d87935b3463d26368b76e31633",
"sha256:d610c1bb404daf85976d7a82eb2ada120f04671007266b708606565dd03b5be6"
],
"version": "==3.0.10"
},
"fuzzywuzzy": {
"hashes": [
"sha256:5ac7c0b3f4658d2743aa17da53a55598144edbc5bee3c6863840636e6926f254",
"sha256:6f49de47db00e1c71d40ad16da42284ac357936fa9b66bea1df63fed07122d62"
],
"version": "==0.17.0"
},
"idna": {
"hashes": [
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
],
"version": "==2.8"
},
"idna-ssl": {
"hashes": [
"sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c"
],
"version": "==1.1.0"
},
"imagesize": {
"hashes": [
"sha256:3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8",
"sha256:f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"
],
"version": "==1.1.0"
},
"jinja2": {
"hashes": [
"sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
"sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
],
"version": "==2.10"
},
"markupsafe": {
"hashes": [
"sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432",
"sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b",
"sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9",
"sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af",
"sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834",
"sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd",
"sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d",
"sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7",
"sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b",
"sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3",
"sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c",
"sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2",
"sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7",
"sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36",
"sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1",
"sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e",
"sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1",
"sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c",
"sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856",
"sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550",
"sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492",
"sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672",
"sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401",
"sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6",
"sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6",
"sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c",
"sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd",
"sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1"
],
"version": "==1.1.0"
},
"more-itertools": {
"hashes": [
"sha256:38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4",
"sha256:c0a5785b1109a6bd7fac76d6837fd1feca158e54e521ccd2ae8bfe393cc9d4fc",
"sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9"
],
"version": "==5.0.0"
},
"multidict": {
"hashes": [
"sha256:024b8129695a952ebd93373e45b5d341dbb87c17ce49637b34000093f243dd4f",
"sha256:041e9442b11409be5e4fc8b6a97e4bcead758ab1e11768d1e69160bdde18acc3",
"sha256:045b4dd0e5f6121e6f314d81759abd2c257db4634260abcfe0d3f7083c4908ef",
"sha256:047c0a04e382ef8bd74b0de01407e8d8632d7d1b4db6f2561106af812a68741b",
"sha256:068167c2d7bbeebd359665ac4fff756be5ffac9cda02375b5c5a7c4777038e73",
"sha256:148ff60e0fffa2f5fad2eb25aae7bef23d8f3b8bdaf947a65cdbe84a978092bc",
"sha256:1d1c77013a259971a72ddaa83b9f42c80a93ff12df6a4723be99d858fa30bee3",
"sha256:1d48bc124a6b7a55006d97917f695effa9725d05abe8ee78fd60d6588b8344cd",
"sha256:31dfa2fc323097f8ad7acd41aa38d7c614dd1960ac6681745b6da124093dc351",
"sha256:34f82db7f80c49f38b032c5abb605c458bac997a6c3142e0d6c130be6fb2b941",
"sha256:3d5dd8e5998fb4ace04789d1d008e2bb532de501218519d70bb672c4c5a2fc5d",
"sha256:4a6ae52bd3ee41ee0f3acf4c60ceb3f44e0e3bc52ab7da1c2b2aa6703363a3d1",
"sha256:4b02a3b2a2f01d0490dd39321c74273fed0568568ea0e7ea23e02bd1fb10a10b",
"sha256:4b843f8e1dd6a3195679d9838eb4670222e8b8d01bc36c9894d6c3538316fa0a",
"sha256:5de53a28f40ef3c4fd57aeab6b590c2c663de87a5af76136ced519923d3efbb3",
"sha256:61b2b33ede821b94fa99ce0b09c9ece049c7067a33b279f343adfe35108a4ea7",
"sha256:6a3a9b0f45fd75dc05d8e93dc21b18fc1670135ec9544d1ad4acbcf6b86781d0",
"sha256:76ad8e4c69dadbb31bad17c16baee61c0d1a4a73bed2590b741b2e1a46d3edd0",
"sha256:7ba19b777dc00194d1b473180d4ca89a054dd18de27d0ee2e42a103ec9b7d014",
"sha256:7c1b7eab7a49aa96f3db1f716f0113a8a2e93c7375dd3d5d21c4941f1405c9c5",
"sha256:7fc0eee3046041387cbace9314926aa48b681202f8897f8bff3809967a049036",
"sha256:8ccd1c5fff1aa1427100ce188557fc31f1e0a383ad8ec42c559aabd4ff08802d",
"sha256:8e08dd76de80539d613654915a2f5196dbccc67448df291e69a88712ea21e24a",
"sha256:c18498c50c59263841862ea0501da9f2b3659c00db54abfbf823a80787fde8ce",
"sha256:c49db89d602c24928e68c0d510f4fcf8989d77defd01c973d6cbe27e684833b1",
"sha256:ce20044d0317649ddbb4e54dab3c1bcc7483c78c27d3f58ab3d0c7e6bc60d26a",
"sha256:d1071414dd06ca2eafa90c85a079169bfeb0e5f57fd0b45d44c092546fcd6fd9",
"sha256:d3be11ac43ab1a3e979dac80843b42226d5d3cccd3986f2e03152720a4297cd7",
"sha256:db603a1c235d110c860d5f39988ebc8218ee028f07a7cbc056ba6424372ca31b"
],
"version": "==4.5.2"
},
"packaging": {
"hashes": [
"sha256:0886227f54515e592aaa2e5a553332c73962917f2831f1b0f9b9f4380a4b9807",
"sha256:f95a1e147590f204328170981833854229bb2912ac3d5f89e2a8ccd2834800c9"
],
"version": "==18.0"
},
"pluggy": {
"hashes": [
"sha256:8ddc32f03971bfdf900a81961a48ccf2fb677cf7715108f85295c67405798616",
"sha256:980710797ff6a041e9a73a5787804f848996ecaa6f8a1b1e08224a5894f2074a"
],
"version": "==0.8.1"
},
"py": {
"hashes": [
"sha256:bf92637198836372b520efcba9e020c330123be8ce527e535d185ed4b6f45694",
"sha256:e76826342cefe3c3d5f7e8ee4316b80d1dd8a300781612ddbc765c17ba25a6c6"
],
"version": "==1.7.0"
},
"pygments": {
"hashes": [
"sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a",
"sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d"
],
"version": "==2.3.1"
},
"pyparsing": {
"hashes": [
"sha256:40856e74d4987de5d01761a22d1621ae1c7f8774585acae358aa5c5936c6c90b",
"sha256:f353aab21fd474459d97b709e527b5571314ee5f067441dc9f88e33eecd96592"
],
"version": "==2.3.0"
},
"pytest": {
"hashes": [
"sha256:3e65a22eb0d4f1bdbc1eacccf4a3198bf8d4049dea5112d70a0c61b00e748d02",
"sha256:5924060b374f62608a078494b909d341720a050b5224ff87e17e12377486a71d"
],
"version": "==4.1.0"
},
"pytest-asyncio": {
"hashes": [
"sha256:9fac5100fd716cbecf6ef89233e8590a4ad61d729d1732e0a96b84182df1daaf",
"sha256:d734718e25cfc32d2bf78d346e99d33724deeba774cc4afdf491530c6184b63b"
],
"version": "==0.10.0"
},
"python-levenshtein": {
"hashes": [
"sha256:033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1"
],
"version": "==0.12.0"
},
"pytz": {
"hashes": [
"sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9",
"sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c"
],
"version": "==2018.9"
},
"pyyaml": {
"hashes": [
"sha256:3d7da3009c0f3e783b2c873687652d83b1bbfd5c88e9813fb7e5b03c0dd3108b",
"sha256:3ef3092145e9b70e3ddd2c7ad59bdd0252a94dfe3949721633e41344de00a6bf",
"sha256:40c71b8e076d0550b2e6380bada1f1cd1017b882f7e16f09a65be98e017f211a",
"sha256:558dd60b890ba8fd982e05941927a3911dc409a63dcb8b634feaa0cda69330d3",
"sha256:a7c28b45d9f99102fa092bb213aa12e0aaf9a6a1f5e395d36166639c1f96c3a1",
"sha256:aa7dd4a6a427aed7df6fb7f08a580d68d9b118d90310374716ae90b710280af1",
"sha256:bc558586e6045763782014934bfaf39d48b8ae85a2713117d16c39864085c613",
"sha256:d46d7982b62e0729ad0175a9bc7e10a566fc07b224d2c79fafb5e032727eaa04",
"sha256:d5eef459e30b09f5a098b9cea68bebfeb268697f78d647bd255a085371ac7f3f",
"sha256:e01d3203230e1786cd91ccfdc8f8454c8069c91bee3962ad93b87a4b2860f537",
"sha256:e170a9e6fcfd19021dd29845af83bb79236068bf5fd4df3327c1be18182b2531"
],
"version": "==3.13"
},
"raven": {
"hashes": [
"sha256:3fa6de6efa2493a7c827472e984ce9b020797d0da16f1db67197bcc23c8fae54",
"sha256:44a13f87670836e153951af9a3c80405d36b43097db869a36e92809673692ce4"
],
"version": "==6.10.0"
},
"raven-aiohttp": {
"hashes": [
"sha256:1444a49c93a85b8bb57c6ee649e512368dce7a26ad64ac3a01d86aa5669d77f3",
"sha256:6a34b6a9841ad0fd827eeb158edb5826c5c5bd7babe2cde2a3f23eb85313af04"
],
"version": "==0.7.0"
},
"requests": {
"hashes": [
"sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
"sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"
],
"version": "==2.21.0"
},
"schema": {
"hashes": [
"sha256:d994b0dc4966000037b26898df638e3e2a694cc73636cb2050e652614a350687",
"sha256:fa1a53fe5f3b6929725a4e81688c250f46838e25d8c1885a10a590c8c01a7b74"
],
"version": "==0.6.8"
},
"six": {
"hashes": [
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
],
"version": "==1.12.0"
},
"snowballstemmer": {
"hashes": [
"sha256:919f26a68b2c17a7634da993d91339e288964f93c274f1343e3bbbe2096e1128",
"sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89"
],
"version": "==1.2.1"
},
"sphinx": {
"hashes": [
"sha256:429e3172466df289f0f742471d7e30ba3ee11f3b5aecd9a840480d03f14bcfe5",
"sha256:c4cb17ba44acffae3d3209646b6baec1e215cad3065e852c68cc569d4df1b9f8"
],
"version": "==1.8.3"
},
"sphinx-rtd-theme": {
"hashes": [
"sha256:02f02a676d6baabb758a20c7a479d58648e0f64f13e07d1b388e9bb2afe86a09",
"sha256:d0f6bc70f98961145c5b0e26a992829363a197321ba571b31b24ea91879e0c96"
],
"version": "==0.4.2"
},
"sphinxcontrib-asyncio": {
"hashes": [
"sha256:96627b1ec4eba08d09ad577ff9416c131910333ef37a2c82a2716e59646739f0"
],
"version": "==0.2.0"
},
"sphinxcontrib-websupport": {
"hashes": [
"sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd",
"sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9"
],
"version": "==1.1.0"
},
"toml": {
"hashes": [
"sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c",
"sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"
],
"version": "==0.10.0"
},
"tox": {
"hashes": [
"sha256:04f8f1aa05de8e76d7a266ccd14e0d665d429977cd42123bc38efa9b59964e9e",
"sha256:25ef928babe88c71e3ed3af0c464d1160b01fca2dd1870a5bb26c2dea61a17fc"
],
"index": "pypi",
"version": "==3.7.0"
},
"urllib3": {
"hashes": [
"sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39",
"sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22"
],
"version": "==1.24.1"
},
"virtualenv": {
"hashes": [
"sha256:34b9ae3742abed2f95d3970acf4d80533261d6061b51160b197f84e5b4c98b4c",
"sha256:fa736831a7b18bd2bfeef746beb622a92509e9733d645952da136b0639cd40cd"
],
"version": "==16.2.0"
},
"websockets": {
"hashes": [
"sha256:0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136",
"sha256:2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6",
"sha256:5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1",
"sha256:5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538",
"sha256:669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4",
"sha256:695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908",
"sha256:6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0",
"sha256:79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d",
"sha256:7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c",
"sha256:82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d",
"sha256:8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c",
"sha256:91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb",
"sha256:952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf",
"sha256:99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e",
"sha256:9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96",
"sha256:a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584",
"sha256:cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484",
"sha256:e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d",
"sha256:e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559",
"sha256:ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff",
"sha256:f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454"
],
"version": "==6.0"
},
"yarl": {
"hashes": [
"sha256:024ecdc12bc02b321bc66b41327f930d1c2c543fa9a561b39861da9388ba7aa9",
"sha256:2f3010703295fbe1aec51023740871e64bb9664c789cba5a6bdf404e93f7568f",
"sha256:3890ab952d508523ef4881457c4099056546593fa05e93da84c7250516e632eb",
"sha256:3e2724eb9af5dc41648e5bb304fcf4891adc33258c6e14e2a7414ea32541e320",
"sha256:5badb97dd0abf26623a9982cd448ff12cb39b8e4c94032ccdedf22ce01a64842",
"sha256:73f447d11b530d860ca1e6b582f947688286ad16ca42256413083d13f260b7a0",
"sha256:7ab825726f2940c16d92aaec7d204cfc34ac26c0040da727cf8ba87255a33829",
"sha256:b25de84a8c20540531526dfbb0e2d2b648c13fd5dd126728c496d7c3fea33310",
"sha256:c6e341f5a6562af74ba55205dbd56d248daf1b5748ec48a0200ba227bb9e33f4",
"sha256:c9bb7c249c4432cd47e75af3864bc02d26c9594f49c82e2a28624417f0ae63b8",
"sha256:e060906c0c585565c718d1c3841747b61c5439af2211e185f6739a9412dfbde1"
],
"version": "==1.3.0"
}
}
}

View File

@@ -12,32 +12,35 @@
<a href="https://discord.gg/red">
<img src="https://discordapp.com/api/guilds/133049272517001216/widget.png?style=shield" alt="Discord Server">
</a>
<a href="https://www.patreon.com/Red_Devs">
<img src="https://img.shields.io/badge/Support-Red!-yellow.svg" alt="Support Red on Patreon!">
<a href="https://pypi.org/project/Red-DiscordBot/">
<img alt="PyPI" src="https://img.shields.io/pypi/v/Red-Discordbot">
</a>
<a href="https://www.python.org/downloads/">
<img src="https://img.shields.io/badge/Made%20With-Python%203-blue.svg?style=for-the-badge" alt="Made with Python 3">
<img alt="PyPI - Python Version" src="https://img.shields.io/pypi/pyversions/Red-Discordbot">
</a>
<a href="https://crowdin.com/project/red-discordbot">
<img src="https://d322cqt584bo4o.cloudfront.net/red-discordbot/localized.svg" alt="Localized with Crowdin">
<a href="https://github.com/Rapptz/discord.py/">
<img src="https://img.shields.io/badge/discord-py-blue.svg" alt="discord.py">
</a>
<a href="https://github.com/Rapptz/discord.py/tree/rewrite">
<img src="https://img.shields.io/badge/discord-py-blue.svg" alt="discord.py">
<a href="https://www.patreon.com/Red_Devs">
<img src="https://img.shields.io/badge/Support-Red!-red.svg" alt="Support Red on Patreon!">
</a>
</p>
<p align="center">
<a href="https://travis-ci.org/Cog-Creators/Red-DiscordBot">
<img src="https://api.travis-ci.org/Cog-Creators/Red-DiscordBot.svg?branch=V3/develop" alt="Travis CI">
<a href="https://github.com/Cog-Creators/Red-DiscordBot/actions">
<img src="https://img.shields.io/github/actions/workflow/status/Cog-Creators/Red-Discordbot/tests.yml?label=tests" alt="GitHub Actions">
</a>
<a href="http://red-discordbot.readthedocs.io/en/v3-develop/?badge=v3-develop">
<img src="https://readthedocs.org/projects/red-discordbot/badge/?version=v3-develop" alt="Red on readthedocs.org">
<a href="http://docs.discord.red/en/stable/?badge=stable">
<img src="https://readthedocs.org/projects/red-discordbot/badge/?version=stable" alt="Red on readthedocs.org">
</a>
<a href="https://github.com/ambv/black">
<a href="https://github.com/psf/black">
<img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code Style: Black">
</a>
<a href="http://makeapullrequest.com">
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
</a>
<a href="https://crowdin.com/project/red-discordbot">
<img src="https://d322cqt584bo4o.cloudfront.net/red-discordbot/localized.svg" alt="Localized with Crowdin">
</a>
</p>
<p align="center">
@@ -45,7 +48,7 @@
<a href="#installation">Installation</a>
<a href="http://red-discordbot.readthedocs.io/en/v3-develop/index.html">Documentation</a>
<a href="http://docs.discord.red/en/stable/index.html">Documentation</a>
<a href="#plugins">Plugins</a>
@@ -57,19 +60,19 @@
# Overview
Red is a fully modular bot meaning all features and commands can be enabled/disabled to your
liking, making it completely customizable. This is also a *self-hosted bot* meaning you will need
liking, making it completely customizable. This is a *self-hosted bot* meaning you will need
to host and maintain your own instance. You can turn Red into an admin bot, music bot, trivia bot,
new best friend or all of these together!
[Installation](#installation) is easy, and you do **NOT** need to know anything about coding! Aside
from installation and updating, every part of the bot can be controlled from within Discord.
from installing and updating, every part of the bot can be controlled from within Discord.
**The default set of modules includes and is not limited to:**
- Moderation features (kick/ban/softban/hackban, mod-log, filter, chat cleanup)
- Trivia (lists are included and can be easily added)
- Music features (YouTube, SoundCloud, local files, playlists, queues)
- Stream alerts (Twitch, Youtube, Mixer, Hitbox, Picarto)
- Stream alerts (Twitch, Youtube, Picarto)
- Bank (slot machine, user credits)
- Custom commands
- Imgur/gif search
@@ -83,19 +86,12 @@ community of cog repositories.**
**The following platforms are officially supported:**
- [Windows](https://red-discordbot.readthedocs.io/en/v3-develop/install_windows.html)
- [MacOS](https://red-discordbot.readthedocs.io/en/v3-develop/install_linux_mac.html)
- [Ubuntu](https://red-discordbot.readthedocs.io/en/v3-develop/install_linux_mac.html)
- [Debian Stretch](https://red-discordbot.readthedocs.io/en/v3-develop/install_linux_mac.html)
- [CentOS 7](https://red-discordbot.readthedocs.io/en/v3-develop/install_linux_mac.html)
- [Arch Linux](https://red-discordbot.readthedocs.io/en/v3-develop/install_linux_mac.html)
- [Raspbian Stretch](https://red-discordbot.readthedocs.io/en/v3-develop/install_linux_mac.html)
Already using **Red** V2? Take a look at the [Data Converter](https://red-discordbot.readthedocs.io/en/v3-develop/cog_dataconverter.html)
to import your data to V3.
- [Windows](https://docs.discord.red/en/stable/install_guides/windows.html)
- [MacOS](https://docs.discord.red/en/stable/install_guides/mac.html)
- [Most major linux distributions](https://docs.discord.red/en/stable/install_guides/index.html)
If after reading the guide you are still experiencing issues, feel free to join the
[Official Discord Server](https://discord.gg/red) and ask in the **#v3-support** channel for help.
[Official Discord Server](https://discord.gg/red) and ask in the **#support** channel for help.
# Plugins
@@ -108,18 +104,18 @@ plugins directly from Discord! A few examples are:
- Casino
- Reaction roles
- Slow Mode
- Anilist
- AniList
- And much, much more!
Feel free to take a [peek](https://github.com/Cog-Creators/Red-DiscordBot/issues/1398) at a list of
Feel free to take a [peek](https://index.discord.red) at a list of
available 3rd party cogs!
# Join the community!
**Red** is in continuous development, and its supported by an active community which produces new
content (cogs/plugins) for everyone to enjoy. New features are constantly added. If you cant
[find](https://github.com/Cog-Creators/Red-DiscordBot/issues/1398) the cog youre looking for,
consult our [guide](https://red-discordbot.readthedocs.io/en/v3-develop/guide_cog_creation.html) on
[find](https://index.discord.red) the cog youre looking for,
consult our [guide](https://docs.discord.red/en/stable/guide_cog_creation.html) on
building your own cogs!
Join us on our [Official Discord Server](https://discord.gg/red)!
@@ -128,13 +124,11 @@ Join us on our [Official Discord Server](https://discord.gg/red)!
Released under the [GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.en.html) license.
This project vendors the
[discord.py library by Rapptz](https://github.com/Rapptz/discord.py/tree/rewrite), which is
licensed under the [MIT License](https://opensource.org/licenses/MIT). This amounts to everything
within the *discord* folder of this repository.
Red is named after the main character of "Transistor", a video game by
[Super Giant Games](https://www.supergiantgames.com/games/transistor/).
Artwork created by [Sinlaire](https://sinlaire.deviantart.com/) on Deviant Art for the Red Discord
Bot Project.
This project vendors [discord.ext.menus](https://github.com/Rapptz/discord-ext-menus) package made by Danny Y. (Rapptz) which is distributed under MIT License.
A copy of this license can be found in the [discord-ext-menus.LICENSE](redbot/vendored/discord-ext-menus.LICENSE) file in the [redbot/vendored](redbot/vendored) folder of this repository.

38
SECURITY.md Normal file
View File

@@ -0,0 +1,38 @@
# Security Policy
## Supported Versions
The table below explains the current state of our versions. Currently, only version
3.5 and higher are supported and receive security updates. Versions lower than 3.5
are considered End of Life and will not receive any security updates.
| Version | Branch | Security Updates | End of Life |
|---------------|------------|--------------------|--------------------|
| < 2.0 | master | :x: | :white_check_mark: |
| >= 2.0, < 3.0 | develop | :x: | :white_check_mark: |
| >= 3.0, < 3.5 | V3/develop | :x: | :white_check_mark: |
| >= 3.5 | V3/develop | :white_check_mark: | :x: |
## Reporting a Vulnerability
For reporting vulnerabilities within Red-DiscordBot we make use of GitHub's
private vulnerability reporting feature (More information can be found
[here](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability)).
This ensures that all maintainers and key members have access to the reported
vulnerability.
### Opening a Vulnerability Report
To open a vulnerability report please fill out [this form](https://github.com/Cog-Creators/Red-DiscordBot/security/advisories/new)
You will be asked to provide a summary, details and proof of concept for your vulnerability report.
We ask that you fill out this form to the best of your ability, with as many details as possible.
Furthermore, you'll be asked to provide affected products and severity.
These fields are optional and will be filled appropriately by the maintainers if not provided.
### Timeline
We will try to answer your report within 7 days. If you haven't received an answer by then, we suggest you reach
out to us privately. This can best be done via our [Discord server](https://discord.gg/red), and contacting
a member who has the Staff role.

View File

@@ -1,5 +1,9 @@
api_key_env: CROWDIN_API_KEY
project_identifier_env: CROWDIN_PROJECT_ID
project_id_env: CROWDIN_PROJECT_ID
api_token_env: CROWDIN_PERSONAL_TOKEN
base_path: ./redbot/
preserve_hierarchy: true
files:
- source: /redbot/**/*.pot
- source: cogs/**/messages.pot
translation: /%original_path%/%locale%.po
- source: core/**/messages.pot
translation: /%original_path%/%locale%.po

View File

@@ -1,64 +0,0 @@
# -*- coding: utf-8 -*-
"""
Discord API Wrapper
~~~~~~~~~~~~~~~~~~~
A basic wrapper for the Discord API.
:copyright: (c) 2015-2017 Rapptz
:license: MIT, see LICENSE for more details.
"""
__title__ = "discord"
__author__ = "Rapptz"
__license__ = "MIT"
__copyright__ = "Copyright 2015-2017 Rapptz"
__version__ = "1.0.0a"
from collections import namedtuple
import logging
from .client import Client, AppInfo
from .user import User, ClientUser, Profile
from .emoji import Emoji, PartialEmoji
from .activity import *
from .channel import *
from .guild import Guild
from .relationship import Relationship
from .member import Member, VoiceState
from .message import Message, Attachment
from .errors import *
from .calls import CallMessage, GroupCall
from .permissions import Permissions, PermissionOverwrite
from .role import Role
from .file import File
from .colour import Color, Colour
from .invite import Invite
from .object import Object
from .reaction import Reaction
from . import utils, opus, abc
from .enums import *
from .embeds import Embed
from .shard import AutoShardedClient
from .player import *
from .webhook import *
from .voice_client import VoiceClient
from .audit_logs import AuditLogChanges, AuditLogEntry, AuditLogDiff
from .raw_models import *
VersionInfo = namedtuple("VersionInfo", "major minor micro releaselevel serial")
version_info = VersionInfo(major=1, minor=0, micro=0, releaselevel="alpha", serial=0)
try:
from logging import NullHandler
except ImportError:
class NullHandler(logging.Handler):
def emit(self, record):
pass
logging.getLogger(__name__).addHandler(NullHandler())

View File

@@ -1,337 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import argparse
import sys
from pathlib import Path
import discord
def core(parser, args):
pass
bot_template = """#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from discord.ext import commands
import discord
import config
class Bot(commands.{base}):
def __init__(self, **kwargs):
super().__init__(command_prefix=commands.when_mentioned_or('{prefix}'), **kwargs)
for cog in config.cogs:
try:
self.load_extension(cog)
except Exception as exc:
print('Could not load extension {{0}} due to {{1.__class__.__name__}}: {{1}}'.format(cog, exc))
async def on_ready(self):
print('Logged on as {{0}} (ID: {{0.id}})'.format(self.user))
bot = Bot()
# write general commands here
bot.run(config.token)
"""
gitignore_template = """# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# Our configuration files
config.py
"""
cog_template = '''# -*- coding: utf-8 -*-
from discord.ext import commands
import discord
class {name}:
"""The description for {name} goes here."""
def __init__(self, bot):
self.bot = bot
{extra}
def setup(bot):
bot.add_cog({name}(bot))
'''
cog_extras = """
def __unload(self):
# clean up logic goes here
pass
async def __local_check(self, ctx):
# checks that apply to every command in here
return True
async def __global_check(self, ctx):
# checks that apply to every command to the bot
return True
async def __global_check_once(self, ctx):
# check that apply to every command but is guaranteed to be called only once
return True
async def __error(self, ctx, error):
# error handling to every command in here
pass
async def __before_invoke(self, ctx):
# called before a command is called here
pass
async def __after_invoke(self, ctx):
# called after a command is called here
pass
"""
# certain file names and directory names are forbidden
# see: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
# although some of this doesn't apply to Linux, we might as well be consistent
_base_table = {
"<": "-",
">": "-",
":": "-",
'"': "-",
# '/': '-', these are fine
# '\\': '-',
"|": "-",
"?": "-",
"*": "-",
}
#
_base_table.update((chr(i), None) for i in range(32))
translation_table = str.maketrans(_base_table)
def to_path(parser, name, *, replace_spaces=False):
if isinstance(name, Path):
return name
if sys.platform == "win32":
forbidden = (
"CON",
"PRN",
"AUX",
"NUL",
"COM1",
"COM2",
"COM3",
"COM4",
"COM5",
"COM6",
"COM7",
"COM8",
"COM9",
"LPT1",
"LPT2",
"LPT3",
"LPT4",
"LPT5",
"LPT6",
"LPT7",
"LPT8",
"LPT9",
)
if len(name) <= 4 and name.upper() in forbidden:
parser.error("invalid directory name given, use a different one")
name = name.translate(translation_table)
if replace_spaces:
name = name.replace(" ", "-")
return Path(name)
def newbot(parser, args):
if sys.version_info < (3, 5):
parser.error("python version is older than 3.5, consider upgrading.")
new_directory = to_path(parser, args.directory) / to_path(parser, args.name)
# as a note exist_ok for Path is a 3.5+ only feature
# since we already checked above that we're >3.5
try:
new_directory.mkdir(exist_ok=True, parents=True)
except OSError as exc:
parser.error("could not create our bot directory ({})".format(exc))
cogs = new_directory / "cogs"
try:
cogs.mkdir(exist_ok=True)
init = cogs / "__init__.py"
init.touch()
except OSError as exc:
print("warning: could not create cogs directory ({})".format(exc))
try:
with open(str(new_directory / "config.py"), "w", encoding="utf-8") as fp:
fp.write('token = "place your token here"\ncogs = []\n')
except OSError as exc:
parser.error("could not create config file ({})".format(exc))
try:
with open(str(new_directory / "bot.py"), "w", encoding="utf-8") as fp:
base = "Bot" if not args.sharded else "AutoShardedBot"
fp.write(bot_template.format(base=base, prefix=args.prefix))
except OSError as exc:
parser.error("could not create bot file ({})".format(exc))
if not args.no_git:
try:
with open(str(new_directory / ".gitignore"), "w", encoding="utf-8") as fp:
fp.write(gitignore_template)
except OSError as exc:
print("warning: could not create .gitignore file ({})".format(exc))
print("successfully made bot at", new_directory)
def newcog(parser, args):
if sys.version_info < (3, 5):
parser.error("python version is older than 3.5, consider upgrading.")
cog_dir = to_path(parser, args.directory)
try:
cog_dir.mkdir(exist_ok=True)
except OSError as exc:
print("warning: could not create cogs directory ({})".format(exc))
directory = cog_dir / to_path(parser, args.name)
directory = directory.with_suffix(".py")
try:
with open(str(directory), "w", encoding="utf-8") as fp:
extra = cog_extras if args.full else ""
if args.class_name:
name = args.class_name
else:
name = str(directory.stem)
if "-" in name:
name = name.replace("-", " ").title().replace(" ", "")
else:
name = name.title()
fp.write(cog_template.format(name=name, extra=extra))
except OSError as exc:
parser.error("could not create cog file ({})".format(exc))
else:
print("successfully made cog at", directory)
def add_newbot_args(subparser):
parser = subparser.add_parser("newbot", help="creates a command bot project quickly")
parser.set_defaults(func=newbot)
parser.add_argument("name", help="the bot project name")
parser.add_argument(
"directory",
help="the directory to place it in (default: .)",
nargs="?",
default=Path.cwd(),
)
parser.add_argument(
"--prefix", help="the bot prefix (default: $)", default="$", metavar="<prefix>"
)
parser.add_argument("--sharded", help="whether to use AutoShardedBot", action="store_true")
parser.add_argument(
"--no-git", help="do not create a .gitignore file", action="store_true", dest="no_git"
)
def add_newcog_args(subparser):
parser = subparser.add_parser("newcog", help="creates a new cog template quickly")
parser.set_defaults(func=newcog)
parser.add_argument("name", help="the cog name")
parser.add_argument(
"directory",
help="the directory to place it in (default: cogs)",
nargs="?",
default=Path("cogs"),
)
parser.add_argument(
"--class-name", help="the class name of the cog (default: <name>)", dest="class_name"
)
parser.add_argument("--full", help="add all special methods as well", action="store_true")
def parse_args():
parser = argparse.ArgumentParser(
prog="discord", description="Tools for helping with discord.py"
)
version = "discord.py v{0.__version__} for Python {1[0]}.{1[1]}.{1[2]}".format(
discord, sys.version_info
)
parser.add_argument(
"-v", "--version", action="version", version=version, help="shows the library version"
)
parser.set_defaults(func=core)
subparser = parser.add_subparsers(dest="subcommand", title="subcommands")
add_newbot_args(subparser)
add_newcog_args(subparser)
return parser, parser.parse_args()
def main():
parser, args = parse_args()
args.func(parser, args)
main()

File diff suppressed because it is too large Load Diff

View File

@@ -1,613 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import datetime
from .enums import ActivityType, try_enum
from .colour import Colour
__all__ = ["Activity", "Streaming", "Game", "Spotify"]
"""If curious, this is the current schema for an activity.
It's fairly long so I will document it here:
All keys are optional.
state: str (max: 128),
details: str (max: 128)
timestamps: dict
start: int (min: 1)
end: int (min: 1)
assets: dict
large_image: str (max: 32)
large_text: str (max: 128)
small_image: str (max: 32)
small_text: str (max: 128)
party: dict
id: str (max: 128),
size: List[int] (max-length: 2)
elem: int (min: 1)
secrets: dict
match: str (max: 128)
join: str (max: 128)
spectate: str (max: 128)
instance: bool
application_id: str
name: str (max: 128)
url: str
type: int
sync_id: str
session_id: str
flags: int
There are also activity flags which are mostly uninteresting for the library atm.
t.ActivityFlags = {
INSTANCE: 1,
JOIN: 2,
SPECTATE: 4,
JOIN_REQUEST: 8,
SYNC: 16,
PLAY: 32
}
"""
class _ActivityTag:
__slots__ = ()
class Activity(_ActivityTag):
"""Represents an activity in Discord.
This could be an activity such as streaming, playing, listening
or watching.
For memory optimisation purposes, some activities are offered in slimmed
down versions:
- :class:`Game`
- :class:`Streaming`
Attributes
------------
application_id: :class:`str`
The application ID of the game.
name: :class:`str`
The name of the activity.
url: :class:`str`
A stream URL that the activity could be doing.
type: :class:`ActivityType`
The type of activity currently being done.
state: :class:`str`
The user's current state. For example, "In Game".
details: :class:`str`
The detail of the user's current activity.
timestamps: :class:`dict`
A dictionary of timestamps. It contains the following optional keys:
- ``start``: Corresponds to when the user started doing the
activity in milliseconds since Unix epoch.
- ``end``: Corresponds to when the user will finish doing the
activity in milliseconds since Unix epoch.
assets: :class:`dict`
A dictionary representing the images and their hover text of an activity.
It contains the following optional keys:
- ``large_image``: A string representing the ID for the large image asset.
- ``large_text``: A string representing the text when hovering over the large image asset.
- ``small_image``: A string representing the ID for the small image asset.
- ``small_text``: A string representing the text when hovering over the small image asset.
party: :class:`dict`
A dictionary representing the activity party. It contains the following optional keys:
- ``id``: A string representing the party ID.
- ``size``: A list of up to two integer elements denoting (current_size, maximum_size).
"""
__slots__ = (
"state",
"details",
"timestamps",
"assets",
"party",
"flags",
"sync_id",
"session_id",
"type",
"name",
"url",
"application_id",
)
def __init__(self, **kwargs):
self.state = kwargs.pop("state", None)
self.details = kwargs.pop("details", None)
self.timestamps = kwargs.pop("timestamps", {})
self.assets = kwargs.pop("assets", {})
self.party = kwargs.pop("party", {})
self.application_id = kwargs.pop("application_id", None)
self.name = kwargs.pop("name", None)
self.url = kwargs.pop("url", None)
self.flags = kwargs.pop("flags", 0)
self.sync_id = kwargs.pop("sync_id", None)
self.session_id = kwargs.pop("session_id", None)
self.type = try_enum(ActivityType, kwargs.pop("type", -1))
def to_dict(self):
ret = {}
for attr in self.__slots__:
value = getattr(self, attr, None)
if value is None:
continue
if isinstance(value, dict) and len(value) == 0:
continue
ret[attr] = value
ret["type"] = int(self.type)
return ret
@property
def start(self):
"""Optional[:class:`datetime.datetime`]: When the user started doing this activity in UTC, if applicable."""
try:
return datetime.datetime.utcfromtimestamp(self.timestamps["start"] / 1000)
except KeyError:
return None
@property
def end(self):
"""Optional[:class:`datetime.datetime`]: When the user will stop doing this activity in UTC, if applicable."""
try:
return datetime.datetime.utcfromtimestamp(self.timestamps["end"] / 1000)
except KeyError:
return None
@property
def large_image_url(self):
"""Optional[:class:`str`]: Returns a URL pointing to the large image asset of this activity if applicable."""
if self.application_id is None:
return None
try:
large_image = self.assets["large_image"]
except KeyError:
return None
else:
return "https://cdn.discordapp.com/app-assets/{0}/{1}.png".format(
self.application_id, large_image
)
@property
def small_image_url(self):
"""Optional[:class:`str`]: Returns a URL pointing to the small image asset of this activity if applicable."""
if self.application_id is None:
return None
try:
small_image = self.assets["small_image"]
except KeyError:
return None
else:
return "https://cdn.discordapp.com/app-assets/{0}/{1}.png".format(
self.application_id, small_image
)
@property
def large_image_text(self):
"""Optional[:class:`str`]: Returns the large image asset hover text of this activity if applicable."""
return self.assets.get("large_text", None)
@property
def small_image_text(self):
"""Optional[:class:`str`]: Returns the small image asset hover text of this activity if applicable."""
return self.assets.get("small_text", None)
class Game(_ActivityTag):
"""A slimmed down version of :class:`Activity` that represents a Discord game.
This is typically displayed via **Playing** on the official Discord client.
.. container:: operations
.. describe:: x == y
Checks if two games are equal.
.. describe:: x != y
Checks if two games are not equal.
.. describe:: hash(x)
Returns the game's hash.
.. describe:: str(x)
Returns the game's name.
Parameters
-----------
name: :class:`str`
The game's name.
start: Optional[:class:`datetime.datetime`]
A naive UTC timestamp representing when the game started. Keyword-only parameter. Ignored for bots.
end: Optional[:class:`datetime.datetime`]
A naive UTC timestamp representing when the game ends. Keyword-only parameter. Ignored for bots.
Attributes
-----------
name: :class:`str`
The game's name.
"""
__slots__ = ("name", "_end", "_start")
def __init__(self, name, **extra):
self.name = name
try:
timestamps = extra["timestamps"]
except KeyError:
self._extract_timestamp(extra, "start")
self._extract_timestamp(extra, "end")
else:
self._start = timestamps.get("start", 0)
self._end = timestamps.get("end", 0)
def _extract_timestamp(self, data, key):
try:
dt = data[key]
except KeyError:
setattr(self, "_" + key, 0)
else:
setattr(self, "_" + key, dt.timestamp() * 1000.0)
@property
def type(self):
"""Returns the game's type. This is for compatibility with :class:`Activity`.
It always returns :attr:`ActivityType.playing`.
"""
return ActivityType.playing
@property
def start(self):
"""Optional[:class:`datetime.datetime`]: When the user started playing this game in UTC, if applicable."""
if self._start:
return datetime.datetime.utcfromtimestamp(self._start / 1000)
return None
@property
def end(self):
"""Optional[:class:`datetime.datetime`]: When the user will stop playing this game in UTC, if applicable."""
if self._end:
return datetime.datetime.utcfromtimestamp(self._end / 1000)
return None
def __str__(self):
return str(self.name)
def __repr__(self):
return "<Game name={0.name!r}>".format(self)
def to_dict(self):
timestamps = {}
if self._start:
timestamps["start"] = self._start
if self._end:
timestamps["end"] = self._end
return {
"type": ActivityType.playing.value,
"name": str(self.name),
"timestamps": timestamps,
}
def __eq__(self, other):
return isinstance(other, Game) and other.name == self.name
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self.name)
class Streaming(_ActivityTag):
"""A slimmed down version of :class:`Activity` that represents a Discord streaming status.
This is typically displayed via **Streaming** on the official Discord client.
.. container:: operations
.. describe:: x == y
Checks if two streams are equal.
.. describe:: x != y
Checks if two streams are not equal.
.. describe:: hash(x)
Returns the stream's hash.
.. describe:: str(x)
Returns the stream's name.
Attributes
-----------
name: :class:`str`
The stream's name.
url: :class:`str`
The stream's URL. Currently only twitch.tv URLs are supported. Anything else is silently
discarded.
details: Optional[:class:`str`]
If provided, typically the game the streamer is playing.
assets: :class:`dict`
A dictionary comprising of similar keys than those in :attr:`Activity.assets`.
"""
__slots__ = ("name", "url", "details", "assets")
def __init__(self, *, name, url, **extra):
self.name = name
self.url = url
self.details = extra.pop("details", None)
self.assets = extra.pop("assets", {})
@property
def type(self):
"""Returns the game's type. This is for compatibility with :class:`Activity`.
It always returns :attr:`ActivityType.streaming`.
"""
return ActivityType.streaming
def __str__(self):
return str(self.name)
def __repr__(self):
return "<Streaming name={0.name!r}>".format(self)
@property
def twitch_name(self):
"""Optional[:class:`str`]: If provided, the twitch name of the user streaming.
This corresponds to the ``large_image`` key of the :attr:`Streaming.assets`
dictionary if it starts with ``twitch:``. Typically set by the Discord client.
"""
try:
name = self.assets["large_image"]
except KeyError:
return None
else:
return name[7:] if name[:7] == "twitch:" else None
def to_dict(self):
ret = {
"type": ActivityType.streaming.value,
"name": str(self.name),
"url": str(self.url),
"assets": self.assets,
}
if self.details:
ret["details"] = self.details
return ret
def __eq__(self, other):
return isinstance(other, Streaming) and other.name == self.name and other.url == self.url
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self.name)
class Spotify:
"""Represents a Spotify listening activity from Discord. This is a special case of
:class:`Activity` that makes it easier to work with the Spotify integration.
.. container:: operations
.. describe:: x == y
Checks if two activities are equal.
.. describe:: x != y
Checks if two activities are not equal.
.. describe:: hash(x)
Returns the activity's hash.
.. describe:: str(x)
Returns the string 'Spotify'.
"""
__slots__ = (
"_state",
"_details",
"_timestamps",
"_assets",
"_party",
"_sync_id",
"_session_id",
)
def __init__(self, **data):
self._state = data.pop("state", None)
self._details = data.pop("details", None)
self._timestamps = data.pop("timestamps", {})
self._assets = data.pop("assets", {})
self._party = data.pop("party", {})
self._sync_id = data.pop("sync_id")
self._session_id = data.pop("session_id")
@property
def type(self):
"""Returns the activity's type. This is for compatibility with :class:`Activity`.
It always returns :attr:`ActivityType.listening`.
"""
return ActivityType.listening
@property
def colour(self):
"""Returns the Spotify integration colour, as a :class:`Colour`.
There is an alias for this named :meth:`color`"""
return Colour(0x1DB954)
@property
def color(self):
"""Returns the Spotify integration colour, as a :class:`Colour`.
There is an alias for this named :meth:`colour`"""
return self.colour
def to_dict(self):
return {
"flags": 48, # SYNC | PLAY
"name": "Spotify",
"assets": self._assets,
"party": self._party,
"sync_id": self._sync_id,
"session_id": self._session_id,
"timestamps": self._timestamps,
"details": self._details,
"state": self._state,
}
@property
def name(self):
""":class:`str`: The activity's name. This will always return "Spotify"."""
return "Spotify"
def __eq__(self, other):
return isinstance(other, Spotify) and other._session_id == self._session_id
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self._session_id)
def __str__(self):
return "Spotify"
def __repr__(self):
return "<Spotify title={0.title!r} artist={0.artist!r} track_id={0.track_id!r}>".format(
self
)
@property
def title(self):
""":class:`str`: The title of the song being played."""
return self._details
@property
def artists(self):
"""List[:class:`str`]: The artists of the song being played."""
return self._state.split("; ")
@property
def artist(self):
""":class:`str`: The artist of the song being played.
This does not attempt to split the artist information into
multiple artists. Useful if there's only a single artist.
"""
return self._state
@property
def album(self):
""":class:`str`: The album that the song being played belongs to."""
return self._assets.get("large_text", "")
@property
def album_cover_url(self):
""":class:`str`: The album cover image URL from Spotify's CDN."""
large_image = self._assets.get("large_image", "")
if large_image[:8] != "spotify:":
return ""
album_image_id = large_image[8:]
return "https://i.scdn.co/image/" + album_image_id
@property
def track_id(self):
""":class:`str`: The track ID used by Spotify to identify this song."""
return self._sync_id
@property
def start(self):
""":class:`datetime.datetime`: When the user started playing this song in UTC."""
return datetime.datetime.utcfromtimestamp(self._timestamps["start"] / 1000)
@property
def end(self):
""":class:`datetime.datetime`: When the user will stop playing this song in UTC."""
return datetime.datetime.utcfromtimestamp(self._timestamps["end"] / 1000)
@property
def duration(self):
""":class:`datetime.timedelta`: The duration of the song being played."""
return self.end - self.start
@property
def party_id(self):
""":class:`str`: The party ID of the listening party."""
return self._party.get("id", "")
def create_activity(data):
if not data:
return None
game_type = try_enum(ActivityType, data.get("type", -1))
if game_type is ActivityType.playing:
if "application_id" in data or "session_id" in data:
return Activity(**data)
return Game(**data)
elif game_type is ActivityType.streaming:
if "url" in data:
return Streaming(**data)
return Activity(**data)
elif game_type is ActivityType.listening and "sync_id" in data and "session_id" in data:
return Spotify(**data)
return Activity(**data)

View File

@@ -1,366 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from . import utils, enums
from .object import Object
from .permissions import PermissionOverwrite, Permissions
from .colour import Colour
from .invite import Invite
def _transform_verification_level(entry, data):
return enums.try_enum(enums.VerificationLevel, data)
def _transform_default_notifications(entry, data):
return enums.try_enum(enums.NotificationLevel, data)
def _transform_explicit_content_filter(entry, data):
return enums.try_enum(enums.ContentFilter, data)
def _transform_permissions(entry, data):
return Permissions(data)
def _transform_color(entry, data):
return Colour(data)
def _transform_snowflake(entry, data):
return int(data)
def _transform_channel(entry, data):
if data is None:
return None
channel = entry.guild.get_channel(int(data)) or Object(id=data)
return channel
def _transform_owner_id(entry, data):
if data is None:
return None
return entry._get_member(int(data))
def _transform_inviter_id(entry, data):
if data is None:
return None
return entry._get_member(int(data))
def _transform_overwrites(entry, data):
overwrites = []
for elem in data:
allow = Permissions(elem["allow"])
deny = Permissions(elem["deny"])
ow = PermissionOverwrite.from_pair(allow, deny)
ow_type = elem["type"]
ow_id = int(elem["id"])
if ow_type == "role":
target = entry.guild.get_role(ow_id)
else:
target = entry._get_member(ow_id)
if target is None:
target = Object(id=ow_id)
overwrites.append((target, ow))
return overwrites
class AuditLogDiff:
def __len__(self):
return len(self.__dict__)
def __iter__(self):
return iter(self.__dict__.items())
def __repr__(self):
return "<AuditLogDiff attrs={0!r}>".format(tuple(self.__dict__))
class AuditLogChanges:
TRANSFORMERS = {
"verification_level": (None, _transform_verification_level),
"explicit_content_filter": (None, _transform_explicit_content_filter),
"allow": (None, _transform_permissions),
"deny": (None, _transform_permissions),
"permissions": (None, _transform_permissions),
"id": (None, _transform_snowflake),
"color": ("colour", _transform_color),
"owner_id": ("owner", _transform_owner_id),
"inviter_id": ("inviter", _transform_inviter_id),
"channel_id": ("channel", _transform_channel),
"afk_channel_id": ("afk_channel", _transform_channel),
"system_channel_id": ("system_channel", _transform_channel),
"widget_channel_id": ("widget_channel", _transform_channel),
"permission_overwrites": ("overwrites", _transform_overwrites),
"splash_hash": ("splash", None),
"icon_hash": ("icon", None),
"avatar_hash": ("avatar", None),
"rate_limit_per_user": ("slowmode_delay", None),
"default_message_notifications": (
"default_notifications",
_transform_default_notifications,
),
}
def __init__(self, entry, data):
self.before = AuditLogDiff()
self.after = AuditLogDiff()
for elem in data:
attr = elem["key"]
# special cases for role add/remove
if attr == "$add":
self._handle_role(self.before, self.after, entry, elem["new_value"])
continue
elif attr == "$remove":
self._handle_role(self.after, self.before, entry, elem["new_value"])
continue
transformer = self.TRANSFORMERS.get(attr)
if transformer:
key, transformer = transformer
if key:
attr = key
try:
before = elem["old_value"]
except KeyError:
before = None
else:
if transformer:
before = transformer(entry, before)
setattr(self.before, attr, before)
try:
after = elem["new_value"]
except KeyError:
after = None
else:
if transformer:
after = transformer(entry, after)
setattr(self.after, attr, after)
# add an alias
if hasattr(self.after, "colour"):
self.after.color = self.after.colour
self.before.color = self.before.colour
def _handle_role(self, first, second, entry, elem):
if not hasattr(first, "roles"):
setattr(first, "roles", [])
data = []
g = entry.guild
for e in elem:
role_id = int(e["id"])
role = g.get_role(role_id)
if role is None:
role = Object(id=role_id)
role.name = e["name"]
data.append(role)
setattr(second, "roles", data)
class AuditLogEntry:
r"""Represents an Audit Log entry.
You retrieve these via :meth:`Guild.audit_logs`.
Attributes
-----------
action: :class:`AuditLogAction`
The action that was done.
user: :class:`abc.User`
The user who initiated this action. Usually a :class:`Member`\, unless gone
then it's a :class:`User`.
id: :class:`int`
The entry ID.
target: Any
The target that got changed. The exact type of this depends on
the action being done.
reason: Optional[:class:`str`]
The reason this action was done.
extra: Any
Extra information that this entry has that might be useful.
For most actions, this is ``None``. However in some cases it
contains extra information. See :class:`AuditLogAction` for
which actions have this field filled out.
"""
def __init__(self, *, users, data, guild):
self._state = guild._state
self.guild = guild
self._users = users
self._from_data(data)
def _from_data(self, data):
self.action = enums.AuditLogAction(data["action_type"])
self.id = int(data["id"])
# this key is technically not usually present
self.reason = data.get("reason")
self.extra = data.get("options")
if self.extra:
if self.action is enums.AuditLogAction.member_prune:
# member prune has two keys with useful information
self.extra = type(
"_AuditLogProxy", (), {k: int(v) for k, v in self.extra.items()}
)()
elif self.action is enums.AuditLogAction.message_delete:
channel_id = int(self.extra["channel_id"])
elems = {
"count": int(self.extra["count"]),
"channel": self.guild.get_channel(channel_id) or Object(id=channel_id),
}
self.extra = type("_AuditLogProxy", (), elems)()
elif self.action.name.startswith("overwrite_"):
# the overwrite_ actions have a dict with some information
instance_id = int(self.extra["id"])
the_type = self.extra.get("type")
if the_type == "member":
self.extra = self._get_member(instance_id)
else:
role = self.guild.get_role(instance_id)
if role is None:
role = Object(id=instance_id)
role.name = self.extra.get("role_name")
self.extra = role
# this key is not present when the above is present, typically.
# It's a list of { new_value: a, old_value: b, key: c }
# where new_value and old_value are not guaranteed to be there depending
# on the action type, so let's just fetch it for now and only turn it
# into meaningful data when requested
self._changes = data.get("changes", [])
self.user = self._get_member(utils._get_as_snowflake(data, "user_id"))
self._target_id = utils._get_as_snowflake(data, "target_id")
def _get_member(self, user_id):
return self.guild.get_member(user_id) or self._users.get(user_id)
def __repr__(self):
return "<AuditLogEntry id={0.id} action={0.action} user={0.user!r}>".format(self)
@utils.cached_property
def created_at(self):
"""Returns the entry's creation time in UTC."""
return utils.snowflake_time(self.id)
@utils.cached_property
def target(self):
try:
converter = getattr(self, "_convert_target_" + self.action.target_type)
except AttributeError:
return Object(id=self._target_id)
else:
return converter(self._target_id)
@utils.cached_property
def category(self):
"""Optional[:class:`AuditLogActionCategory`]: The category of the action, if applicable."""
return self.action.category
@utils.cached_property
def changes(self):
""":class:`AuditLogChanges`: The list of changes this entry has."""
obj = AuditLogChanges(self, self._changes)
del self._changes
return obj
@utils.cached_property
def before(self):
""":class:`AuditLogDiff`: The target's prior state."""
return self.changes.before
@utils.cached_property
def after(self):
""":class:`AuditLogDiff`: The target's subsequent state."""
return self.changes.after
def _convert_target_guild(self, target_id):
return self.guild
def _convert_target_channel(self, target_id):
ch = self.guild.get_channel(target_id)
if ch is None:
return Object(id=target_id)
return ch
def _convert_target_user(self, target_id):
return self._get_member(target_id)
def _convert_target_role(self, target_id):
role = self.guild.get_role(target_id)
if role is None:
return Object(id=target_id)
return role
def _convert_target_invite(self, target_id):
# invites have target_id set to null
# so figure out which change has the full invite data
changeset = (
self.before if self.action is enums.AuditLogAction.invite_delete else self.after
)
fake_payload = {
"max_age": changeset.max_age,
"max_uses": changeset.max_uses,
"code": changeset.code,
"temporary": changeset.temporary,
"channel": changeset.channel,
"uses": changeset.uses,
"guild": self.guild,
}
obj = Invite(state=self._state, data=fake_payload)
try:
obj.inviter = changeset.inviter
except AttributeError:
pass
return obj
def _convert_target_emoji(self, target_id):
return self._state.get_emoji(target_id) or Object(id=target_id)
def _convert_target_message(self, target_id):
return self._get_member(target_id)

View File

@@ -1,86 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import time
import random
class ExponentialBackoff:
"""An implementation of the exponential backoff algorithm
Provides a convenient interface to implement an exponential backoff
for reconnecting or retrying transmissions in a distributed network.
Once instantiated, the delay method will return the next interval to
wait for when retrying a connection or transmission. The maximum
delay increases exponentially with each retry up to a maximum of
2^10 * base, and is reset if no more attempts are needed in a period
of 2^11 * base seconds.
Parameters
----------
base: int
The base delay in seconds. The first retry-delay will be up to
this many seconds.
integral: bool
Set to True if whole periods of base is desirable, otherwise any
number in between may be returned.
"""
def __init__(self, base=1, *, integral=False):
self._base = base
self._exp = 0
self._max = 10
self._reset_time = base * 2 ** 11
self._last_invocation = time.monotonic()
# Use our own random instance to avoid messing with global one
rand = random.Random()
rand.seed()
self._randfunc = rand.randrange if integral else rand.uniform
def delay(self):
"""Compute the next delay
Returns the next delay to wait according to the exponential
backoff algorithm. This is a value between 0 and base * 2^exp
where exponent starts off at 1 and is incremented at every
invocation of this method up to a maximum of 10.
If a period of more than base * 2^11 has passed since the last
retry, the exponent is reset to 1.
"""
invocation = time.monotonic()
interval = invocation - self._last_invocation
self._last_invocation = invocation
if interval > self._reset_time:
self._exp = 0
self._exp = min(self._exp + 1, self._max)
return self._randfunc(0, self._base * 2 ** self._exp)

View File

@@ -1,157 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import datetime
from . import utils
from .enums import VoiceRegion, try_enum
from .member import VoiceState
class CallMessage:
"""Represents a group call message from Discord.
This is only received in cases where the message type is equivalent to
:attr:`MessageType.call`.
Attributes
-----------
ended_timestamp: Optional[datetime.datetime]
A naive UTC datetime object that represents the time that the call has ended.
participants: List[:class:`User`]
The list of users that are participating in this call.
message: :class:`Message`
The message associated with this call message.
"""
def __init__(self, message, **kwargs):
self.message = message
self.ended_timestamp = utils.parse_time(kwargs.get("ended_timestamp"))
self.participants = kwargs.get("participants")
@property
def call_ended(self):
""":obj:`bool`: Indicates if the call has ended."""
return self.ended_timestamp is not None
@property
def channel(self):
r""":class:`GroupChannel`\: The private channel associated with this message."""
return self.message.channel
@property
def duration(self):
"""Queries the duration of the call.
If the call has not ended then the current duration will
be returned.
Returns
---------
datetime.timedelta
The timedelta object representing the duration.
"""
if self.ended_timestamp is None:
return datetime.datetime.utcnow() - self.message.created_at
else:
return self.ended_timestamp - self.message.created_at
class GroupCall:
"""Represents the actual group call from Discord.
This is accompanied with a :class:`CallMessage` denoting the information.
Attributes
-----------
call: :class:`CallMessage`
The call message associated with this group call.
unavailable: :obj:`bool`
Denotes if this group call is unavailable.
ringing: List[:class:`User`]
A list of users that are currently being rung to join the call.
region: :class:`VoiceRegion`
The guild region the group call is being hosted on.
"""
def __init__(self, **kwargs):
self.call = kwargs.get("call")
self.unavailable = kwargs.get("unavailable")
self._voice_states = {}
for state in kwargs.get("voice_states", []):
self._update_voice_state(state)
self._update(**kwargs)
def _update(self, **kwargs):
self.region = try_enum(VoiceRegion, kwargs.get("region"))
lookup = {u.id: u for u in self.call.channel.recipients}
me = self.call.channel.me
lookup[me.id] = me
self.ringing = list(filter(None, map(lookup.get, kwargs.get("ringing", []))))
def _update_voice_state(self, data):
user_id = int(data["user_id"])
# left the voice channel?
if data["channel_id"] is None:
self._voice_states.pop(user_id, None)
else:
self._voice_states[user_id] = VoiceState(data=data, channel=self.channel)
@property
def connected(self):
"""A property that returns the :obj:`list` of :class:`User` that are currently in this call."""
ret = [u for u in self.channel.recipients if self.voice_state_for(u) is not None]
me = self.channel.me
if self.voice_state_for(me) is not None:
ret.append(me)
return ret
@property
def channel(self):
r""":class:`GroupChannel`\: Returns the channel the group call is in."""
return self.call.channel
def voice_state_for(self, user):
"""Retrieves the :class:`VoiceState` for a specified :class:`User`.
If the :class:`User` has no voice state then this function returns
``None``.
Parameters
------------
user: :class:`User`
The user to retrieve the voice state for.
Returns
--------
Optional[:class:`VoiceState`]
The voice state associated with this user.
"""
return self._voice_states.get(user.id)

View File

@@ -1,986 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import time
import asyncio
import discord.abc
from .permissions import Permissions
from .enums import ChannelType, try_enum
from .mixins import Hashable
from . import utils
from .errors import ClientException, NoMoreItems
from .webhook import Webhook
__all__ = [
"TextChannel",
"VoiceChannel",
"DMChannel",
"CategoryChannel",
"GroupChannel",
"_channel_factory",
]
async def _single_delete_strategy(messages):
for m in messages:
await m.delete()
class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
"""Represents a Discord guild text channel.
.. container:: operations
.. describe:: x == y
Checks if two channels are equal.
.. describe:: x != y
Checks if two channels are not equal.
.. describe:: hash(x)
Returns the channel's hash.
.. describe:: str(x)
Returns the channel's name.
Attributes
-----------
name: :class:`str`
The channel name.
guild: :class:`Guild`
The guild the channel belongs to.
id: :class:`int`
The channel ID.
category_id: :class:`int`
The category channel ID this channel belongs to.
topic: Optional[:class:`str`]
The channel's topic. None if it doesn't exist.
position: :class:`int`
The position in the channel list. This is a number that starts at 0. e.g. the
top channel is position 0.
slowmode_delay: :class:`int`
The number of seconds a member must wait between sending messages
in this channel. A value of `0` denotes that it is disabled.
Bots and users with :attr:`~Permissions.manage_channels` or
:attr:`~Permissions.manage_messages` bypass slowmode.
"""
__slots__ = (
"name",
"id",
"guild",
"topic",
"_state",
"nsfw",
"category_id",
"position",
"slowmode_delay",
"_overwrites",
)
def __init__(self, *, state, guild, data):
self._state = state
self.id = int(data["id"])
self._update(guild, data)
def __repr__(self):
return "<TextChannel id={0.id} name={0.name!r} position={0.position}>".format(self)
def _update(self, guild, data):
self.guild = guild
self.name = data["name"]
self.category_id = utils._get_as_snowflake(data, "parent_id")
self.topic = data.get("topic")
self.position = data["position"]
self.nsfw = data.get("nsfw", False)
# Does this need coercion into `int`? No idea yet.
self.slowmode_delay = data.get("rate_limit_per_user", 0)
self._fill_overwrites(data)
async def _get_channel(self):
return self
def permissions_for(self, member):
base = super().permissions_for(member)
# text channels do not have voice related permissions
denied = Permissions.voice()
base.value &= ~denied.value
return base
permissions_for.__doc__ = discord.abc.GuildChannel.permissions_for.__doc__
@property
def members(self):
"""Returns a :class:`list` of :class:`Member` that can see this channel."""
return [m for m in self.guild.members if self.permissions_for(m).read_messages]
def is_nsfw(self):
"""Checks if the channel is NSFW."""
n = self.name
return self.nsfw or n == "nsfw" or n[:5] == "nsfw-"
async def edit(self, *, reason=None, **options):
"""|coro|
Edits the channel.
You must have the :attr:`~Permissions.manage_channels` permission to
use this.
Parameters
----------
name: :class:`str`
The new channel name.
topic: :class:`str`
The new channel's topic.
position: :class:`int`
The new channel's position.
nsfw: :class:`bool`
To mark the channel as NSFW or not.
sync_permissions: :class:`bool`
Whether to sync permissions with the channel's new or pre-existing
category. Defaults to ``False``.
category: Optional[:class:`CategoryChannel`]
The new category for this channel. Can be ``None`` to remove the
category.
slowmode_delay: :class:`int`
Specifies the slowmode rate limit for user in this channel. A value of
`0` disables slowmode. The maximum value possible is `120`.
reason: Optional[:class:`str`]
The reason for editing this channel. Shows up on the audit log.
Raises
------
InvalidArgument
If position is less than 0 or greater than the number of channels.
Forbidden
You do not have permissions to edit the channel.
HTTPException
Editing the channel failed.
"""
await self._edit(options, reason=reason)
async def delete_messages(self, messages):
"""|coro|
Deletes a list of messages. This is similar to :meth:`Message.delete`
except it bulk deletes multiple messages.
As a special case, if the number of messages is 0, then nothing
is done. If the number of messages is 1 then single message
delete is done. If it's more than two, then bulk delete is used.
You cannot bulk delete more than 100 messages or messages that
are older than 14 days old.
You must have the :attr:`~Permissions.manage_messages` permission to
use this.
Usable only by bot accounts.
Parameters
-----------
messages: Iterable[:class:`abc.Snowflake`]
An iterable of messages denoting which ones to bulk delete.
Raises
------
ClientException
The number of messages to delete was more than 100.
Forbidden
You do not have proper permissions to delete the messages or
you're not using a bot account.
HTTPException
Deleting the messages failed.
"""
if not isinstance(messages, (list, tuple)):
messages = list(messages)
if len(messages) == 0:
return # do nothing
if len(messages) == 1:
message_id = messages[0].id
await self._state.http.delete_message(self.id, message_id)
return
if len(messages) > 100:
raise ClientException("Can only bulk delete messages up to 100 messages")
message_ids = [m.id for m in messages]
await self._state.http.delete_messages(self.id, message_ids)
async def purge(
self,
*,
limit=100,
check=None,
before=None,
after=None,
around=None,
reverse=False,
bulk=True
):
"""|coro|
Purges a list of messages that meet the criteria given by the predicate
``check``. If a ``check`` is not provided then all messages are deleted
without discrimination.
You must have the :attr:`~Permissions.manage_messages` permission to
delete messages even if they are your own (unless you are a user
account). The :attr:`~Permissions.read_message_history` permission is
also needed to retrieve message history.
Internally, this employs a different number of strategies depending
on the conditions met such as if a bulk delete is possible or if
the account is a user bot or not.
Parameters
-----------
limit: int
The number of messages to search through. This is not the number
of messages that will be deleted, though it can be.
check: predicate
The function used to check if a message should be deleted.
It must take a :class:`Message` as its sole parameter.
before
Same as ``before`` in :meth:`history`.
after
Same as ``after`` in :meth:`history`.
around
Same as ``around`` in :meth:`history`.
reverse
Same as ``reverse`` in :meth:`history`.
bulk: bool
If True, use bulk delete. bulk=False is useful for mass-deleting
a bot's own messages without manage_messages. When True, will fall
back to single delete if current account is a user bot, or if
messages are older than two weeks.
Raises
-------
Forbidden
You do not have proper permissions to do the actions required.
HTTPException
Purging the messages failed.
Examples
---------
Deleting bot's messages ::
def is_me(m):
return m.author == client.user
deleted = await channel.purge(limit=100, check=is_me)
await channel.send('Deleted {} message(s)'.format(len(deleted)))
Returns
--------
list
The list of messages that were deleted.
"""
if check is None:
check = lambda m: True
iterator = self.history(
limit=limit, before=before, after=after, reverse=reverse, around=around
)
ret = []
count = 0
minimum_time = int((time.time() - 14 * 24 * 60 * 60) * 1000.0 - 1420070400000) << 22
strategy = self.delete_messages if self._state.is_bot and bulk else _single_delete_strategy
while True:
try:
msg = await iterator.next()
except NoMoreItems:
# no more messages to poll
if count >= 2:
# more than 2 messages -> bulk delete
to_delete = ret[-count:]
await strategy(to_delete)
elif count == 1:
# delete a single message
await ret[-1].delete()
return ret
else:
if count == 100:
# we've reached a full 'queue'
to_delete = ret[-100:]
await strategy(to_delete)
count = 0
await asyncio.sleep(1)
if check(msg):
if msg.id < minimum_time:
# older than 14 days old
if count == 1:
await ret[-1].delete()
elif count >= 2:
to_delete = ret[-count:]
await strategy(to_delete)
count = 0
strategy = _single_delete_strategy
count += 1
ret.append(msg)
async def webhooks(self):
"""|coro|
Gets the list of webhooks from this channel.
Requires :attr:`~.Permissions.manage_webhooks` permissions.
Raises
-------
Forbidden
You don't have permissions to get the webhooks.
Returns
--------
List[:class:`Webhook`]
The webhooks for this channel.
"""
data = await self._state.http.channel_webhooks(self.id)
return [Webhook.from_state(d, state=self._state) for d in data]
async def create_webhook(self, *, name, avatar=None):
"""|coro|
Creates a webhook for this channel.
Requires :attr:`~.Permissions.manage_webhooks` permissions.
Parameters
-------------
name: str
The webhook's name.
avatar: Optional[bytes]
A :term:`py:bytes-like object` representing the webhook's default avatar.
This operates similarly to :meth:`~ClientUser.edit`.
Raises
-------
HTTPException
Creating the webhook failed.
Forbidden
You do not have permissions to create a webhook.
Returns
--------
:class:`Webhook`
The created webhook.
"""
if avatar is not None:
avatar = utils._bytes_to_base64_data(avatar)
data = await self._state.http.create_webhook(self.id, name=str(name), avatar=avatar)
return Webhook.from_state(data, state=self._state)
class VoiceChannel(discord.abc.Connectable, discord.abc.GuildChannel, Hashable):
"""Represents a Discord guild voice channel.
.. container:: operations
.. describe:: x == y
Checks if two channels are equal.
.. describe:: x != y
Checks if two channels are not equal.
.. describe:: hash(x)
Returns the channel's hash.
.. describe:: str(x)
Returns the channel's name.
Attributes
-----------
name: :class:`str`
The channel name.
guild: :class:`Guild`
The guild the channel belongs to.
id: :class:`int`
The channel ID.
category_id: :class:`int`
The category channel ID this channel belongs to.
position: :class:`int`
The position in the channel list. This is a number that starts at 0. e.g. the
top channel is position 0.
bitrate: :class:`int`
The channel's preferred audio bitrate in bits per second.
user_limit: :class:`int`
The channel's limit for number of members that can be in a voice channel.
"""
__slots__ = (
"name",
"id",
"guild",
"bitrate",
"user_limit",
"_state",
"position",
"_overwrites",
"category_id",
)
def __init__(self, *, state, guild, data):
self._state = state
self.id = int(data["id"])
self._update(guild, data)
def __repr__(self):
return "<VoiceChannel id={0.id} name={0.name!r} position={0.position}>".format(self)
def _get_voice_client_key(self):
return self.guild.id, "guild_id"
def _get_voice_state_pair(self):
return self.guild.id, self.id
def _update(self, guild, data):
self.guild = guild
self.name = data["name"]
self.category_id = utils._get_as_snowflake(data, "parent_id")
self.position = data["position"]
self.bitrate = data.get("bitrate")
self.user_limit = data.get("user_limit")
self._fill_overwrites(data)
@property
def members(self):
"""Returns a list of :class:`Member` that are currently inside this voice channel."""
ret = []
for user_id, state in self.guild._voice_states.items():
if state.channel.id == self.id:
member = self.guild.get_member(user_id)
if member is not None:
ret.append(member)
return ret
def permissions_for(self, member):
base = super().permissions_for(member)
# voice channels cannot be edited by people who can't connect to them
# It also implicitly denies all other voice perms
if not base.connect:
denied = Permissions.voice()
denied.update(manage_channels=True, manage_roles=True)
base.value &= ~denied.value
return base
permissions_for.__doc__ = discord.abc.GuildChannel.permissions_for.__doc__
async def edit(self, *, reason=None, **options):
"""|coro|
Edits the channel.
You must have the :attr:`~Permissions.manage_channels` permission to
use this.
Parameters
----------
name: str
The new channel's name.
bitrate: int
The new channel's bitrate.
user_limit: int
The new channel's user limit.
position: int
The new channel's position.
sync_permissions: bool
Whether to sync permissions with the channel's new or pre-existing
category. Defaults to ``False``.
category: Optional[:class:`CategoryChannel`]
The new category for this channel. Can be ``None`` to remove the
category.
reason: Optional[str]
The reason for editing this channel. Shows up on the audit log.
Raises
------
Forbidden
You do not have permissions to edit the channel.
HTTPException
Editing the channel failed.
"""
await self._edit(options, reason=reason)
class CategoryChannel(discord.abc.GuildChannel, Hashable):
"""Represents a Discord channel category.
These are useful to group channels to logical compartments.
.. container:: operations
.. describe:: x == y
Checks if two channels are equal.
.. describe:: x != y
Checks if two channels are not equal.
.. describe:: hash(x)
Returns the category's hash.
.. describe:: str(x)
Returns the category's name.
Attributes
-----------
name: :class:`str`
The category name.
guild: :class:`Guild`
The guild the category belongs to.
id: :class:`int`
The category channel ID.
position: :class:`int`
The position in the category list. This is a number that starts at 0. e.g. the
top category is position 0.
"""
__slots__ = ("name", "id", "guild", "nsfw", "_state", "position", "_overwrites", "category_id")
def __init__(self, *, state, guild, data):
self._state = state
self.id = int(data["id"])
self._update(guild, data)
def __repr__(self):
return "<CategoryChannel id={0.id} name={0.name!r} position={0.position}>".format(self)
def _update(self, guild, data):
self.guild = guild
self.name = data["name"]
self.category_id = utils._get_as_snowflake(data, "parent_id")
self.nsfw = data.get("nsfw", False)
self.position = data["position"]
self._fill_overwrites(data)
def is_nsfw(self):
"""Checks if the category is NSFW."""
n = self.name
return self.nsfw or n == "nsfw" or n[:5] == "nsfw-"
async def edit(self, *, reason=None, **options):
"""|coro|
Edits the channel.
You must have the :attr:`~Permissions.manage_channels` permission to
use this.
Parameters
----------
name: str
The new category's name.
position: int
The new category's position.
nsfw: bool
To mark the category as NSFW or not.
reason: Optional[str]
The reason for editing this category. Shows up on the audit log.
Raises
------
InvalidArgument
If position is less than 0 or greater than the number of categories.
Forbidden
You do not have permissions to edit the category.
HTTPException
Editing the category failed.
"""
try:
position = options.pop("position")
except KeyError:
pass
else:
await self._move(position, reason=reason)
self.position = position
if options:
data = await self._state.http.edit_channel(self.id, reason=reason, **options)
self._update(self.guild, data)
@property
def channels(self):
"""List[:class:`abc.GuildChannel`]: Returns the channels that are under this category.
These are sorted by the official Discord UI, which places voice channels below the text channels.
"""
def comparator(channel):
return (not isinstance(channel, TextChannel), channel.position)
ret = [c for c in self.guild.channels if c.category_id == self.id]
ret.sort(key=comparator)
return ret
class DMChannel(discord.abc.Messageable, Hashable):
"""Represents a Discord direct message channel.
.. container:: operations
.. describe:: x == y
Checks if two channels are equal.
.. describe:: x != y
Checks if two channels are not equal.
.. describe:: hash(x)
Returns the channel's hash.
.. describe:: str(x)
Returns a string representation of the channel
Attributes
----------
recipient: :class:`User`
The user you are participating with in the direct message channel.
me: :class:`ClientUser`
The user presenting yourself.
id: :class:`int`
The direct message channel ID.
"""
__slots__ = ("id", "recipient", "me", "_state")
def __init__(self, *, me, state, data):
self._state = state
self.recipient = state.store_user(data["recipients"][0])
self.me = me
self.id = int(data["id"])
async def _get_channel(self):
return self
def __str__(self):
return "Direct Message with %s" % self.recipient
def __repr__(self):
return "<DMChannel id={0.id} recipient={0.recipient!r}>".format(self)
@property
def created_at(self):
"""Returns the direct message channel's creation time in UTC."""
return utils.snowflake_time(self.id)
def permissions_for(self, user=None):
"""Handles permission resolution for a :class:`User`.
This function is there for compatibility with other channel types.
Actual direct messages do not really have the concept of permissions.
This returns all the Text related permissions set to true except:
- send_tts_messages: You cannot send TTS messages in a DM.
- manage_messages: You cannot delete others messages in a DM.
Parameters
-----------
user: :class:`User`
The user to check permissions for. This parameter is ignored
but kept for compatibility.
Returns
--------
:class:`Permissions`
The resolved permissions.
"""
base = Permissions.text()
base.send_tts_messages = False
base.manage_messages = False
return base
class GroupChannel(discord.abc.Messageable, Hashable):
"""Represents a Discord group channel.
.. container:: operations
.. describe:: x == y
Checks if two channels are equal.
.. describe:: x != y
Checks if two channels are not equal.
.. describe:: hash(x)
Returns the channel's hash.
.. describe:: str(x)
Returns a string representation of the channel
Attributes
----------
recipients: :class:`list` of :class:`User`
The users you are participating with in the group channel.
me: :class:`ClientUser`
The user presenting yourself.
id: :class:`int`
The group channel ID.
owner: :class:`User`
The user that owns the group channel.
icon: Optional[:class:`str`]
The group channel's icon hash if provided.
name: Optional[:class:`str`]
The group channel's name if provided.
"""
__slots__ = ("id", "recipients", "owner", "icon", "name", "me", "_state")
def __init__(self, *, me, state, data):
self._state = state
self.id = int(data["id"])
self.me = me
self._update_group(data)
def _update_group(self, data):
owner_id = utils._get_as_snowflake(data, "owner_id")
self.icon = data.get("icon")
self.name = data.get("name")
try:
self.recipients = [self._state.store_user(u) for u in data["recipients"]]
except KeyError:
pass
if owner_id == self.me.id:
self.owner = self.me
else:
self.owner = utils.find(lambda u: u.id == owner_id, self.recipients)
async def _get_channel(self):
return self
def __str__(self):
if self.name:
return self.name
if len(self.recipients) == 0:
return "Unnamed"
return ", ".join(map(lambda x: x.name, self.recipients))
def __repr__(self):
return "<GroupChannel id={0.id} name={0.name!r}>".format(self)
@property
def icon_url(self):
"""Returns the channel's icon URL if available or an empty string otherwise."""
if self.icon is None:
return ""
return "https://cdn.discordapp.com/channel-icons/{0.id}/{0.icon}.jpg".format(self)
@property
def created_at(self):
"""Returns the channel's creation time in UTC."""
return utils.snowflake_time(self.id)
def permissions_for(self, user):
"""Handles permission resolution for a :class:`User`.
This function is there for compatibility with other channel types.
Actual direct messages do not really have the concept of permissions.
This returns all the Text related permissions set to true except:
- send_tts_messages: You cannot send TTS messages in a DM.
- manage_messages: You cannot delete others messages in a DM.
This also checks the kick_members permission if the user is the owner.
Parameters
-----------
user: :class:`User`
The user to check permissions for.
Returns
--------
:class:`Permissions`
The resolved permissions for the user.
"""
base = Permissions.text()
base.send_tts_messages = False
base.manage_messages = False
base.mention_everyone = True
if user.id == self.owner.id:
base.kick_members = True
return base
async def add_recipients(self, *recipients):
r"""|coro|
Adds recipients to this group.
A group can only have a maximum of 10 members.
Attempting to add more ends up in an exception. To
add a recipient to the group, you must have a relationship
with the user of type :attr:`RelationshipType.friend`.
Parameters
-----------
\*recipients: :class:`User`
An argument list of users to add to this group.
Raises
-------
HTTPException
Adding a recipient to this group failed.
"""
# TODO: wait for the corresponding WS event
req = self._state.http.add_group_recipient
for recipient in recipients:
await req(self.id, recipient.id)
async def remove_recipients(self, *recipients):
r"""|coro|
Removes recipients from this group.
Parameters
-----------
\*recipients: :class:`User`
An argument list of users to remove from this group.
Raises
-------
HTTPException
Removing a recipient from this group failed.
"""
# TODO: wait for the corresponding WS event
req = self._state.http.remove_group_recipient
for recipient in recipients:
await req(self.id, recipient.id)
async def edit(self, **fields):
"""|coro|
Edits the group.
Parameters
-----------
name: Optional[str]
The new name to change the group to.
Could be ``None`` to remove the name.
icon: Optional[bytes]
A :term:`py:bytes-like object` representing the new icon.
Could be ``None`` to remove the icon.
Raises
-------
HTTPException
Editing the group failed.
"""
try:
icon_bytes = fields["icon"]
except KeyError:
pass
else:
if icon_bytes is not None:
fields["icon"] = utils._bytes_to_base64_data(icon_bytes)
data = await self._state.http.edit_group(self.id, **fields)
self._update_group(data)
async def leave(self):
"""|coro|
Leave the group.
If you are the only one in the group, this deletes it as well.
Raises
-------
HTTPException
Leaving the group failed.
"""
await self._state.http.leave_group(self.id)
def _channel_factory(channel_type):
value = try_enum(ChannelType, channel_type)
if value is ChannelType.text:
return TextChannel, value
elif value is ChannelType.voice:
return VoiceChannel, value
elif value is ChannelType.private:
return DMChannel, value
elif value is ChannelType.category:
return CategoryChannel, value
elif value is ChannelType.group:
return GroupChannel, value
else:
return None, value

File diff suppressed because it is too large Load Diff

View File

@@ -1,234 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import colorsys
class Colour:
"""Represents a Discord role colour. This class is similar
to an (red, green, blue) :class:`tuple`.
There is an alias for this called Color.
.. container:: operations
.. describe:: x == y
Checks if two colours are equal.
.. describe:: x != y
Checks if two colours are not equal.
.. describe:: hash(x)
Return the colour's hash.
.. describe:: str(x)
Returns the hex format for the colour.
Attributes
------------
value: :class:`int`
The raw integer colour value.
"""
__slots__ = ("value",)
def __init__(self, value):
if not isinstance(value, int):
raise TypeError(
"Expected int parameter, received %s instead." % value.__class__.__name__
)
self.value = value
def _get_byte(self, byte):
return (self.value >> (8 * byte)) & 0xFF
def __eq__(self, other):
return isinstance(other, Colour) and self.value == other.value
def __ne__(self, other):
return not self.__eq__(other)
def __str__(self):
return "#{:0>6x}".format(self.value)
def __repr__(self):
return "<Colour value=%s>" % self.value
def __hash__(self):
return hash(self.value)
@property
def r(self):
"""Returns the red component of the colour."""
return self._get_byte(2)
@property
def g(self):
"""Returns the green component of the colour."""
return self._get_byte(1)
@property
def b(self):
"""Returns the blue component of the colour."""
return self._get_byte(0)
def to_rgb(self):
"""Returns an (r, g, b) tuple representing the colour."""
return (self.r, self.g, self.b)
@classmethod
def from_rgb(cls, r, g, b):
"""Constructs a :class:`Colour` from an RGB tuple."""
return cls((r << 16) + (g << 8) + b)
@classmethod
def from_hsv(cls, h, s, v):
"""Constructs a :class:`Colour` from an HSV tuple."""
rgb = colorsys.hsv_to_rgb(h, s, v)
return cls.from_rgb(*(int(x * 255) for x in rgb))
@classmethod
def default(cls):
"""A factory method that returns a :class:`Colour` with a value of 0."""
return cls(0)
@classmethod
def teal(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x1abc9c``."""
return cls(0x1ABC9C)
@classmethod
def dark_teal(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x11806a``."""
return cls(0x11806A)
@classmethod
def green(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x2ecc71``."""
return cls(0x2ECC71)
@classmethod
def dark_green(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x1f8b4c``."""
return cls(0x1F8B4C)
@classmethod
def blue(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x3498db``."""
return cls(0x3498DB)
@classmethod
def dark_blue(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x206694``."""
return cls(0x206694)
@classmethod
def purple(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x9b59b6``."""
return cls(0x9B59B6)
@classmethod
def dark_purple(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x71368a``."""
return cls(0x71368A)
@classmethod
def magenta(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0xe91e63``."""
return cls(0xE91E63)
@classmethod
def dark_magenta(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0xad1457``."""
return cls(0xAD1457)
@classmethod
def gold(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0xf1c40f``."""
return cls(0xF1C40F)
@classmethod
def dark_gold(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0xc27c0e``."""
return cls(0xC27C0E)
@classmethod
def orange(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0xe67e22``."""
return cls(0xE67E22)
@classmethod
def dark_orange(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0xa84300``."""
return cls(0xA84300)
@classmethod
def red(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0xe74c3c``."""
return cls(0xE74C3C)
@classmethod
def dark_red(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x992d22``."""
return cls(0x992D22)
@classmethod
def lighter_grey(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x95a5a6``."""
return cls(0x95A5A6)
@classmethod
def dark_grey(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x607d8b``."""
return cls(0x607D8B)
@classmethod
def light_grey(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x979c9f``."""
return cls(0x979C9F)
@classmethod
def darker_grey(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x546e7a``."""
return cls(0x546E7A)
@classmethod
def blurple(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x7289da``."""
return cls(0x7289DA)
@classmethod
def greyple(cls):
"""A factory method that returns a :class:`Colour` with a value of ``0x99aab5``."""
return cls(0x99AAB5)
Color = Colour

View File

@@ -1,69 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import asyncio
def _typing_done_callback(fut):
# just retrieve any exception and call it a day
try:
fut.exception()
except Exception:
pass
class Typing:
def __init__(self, messageable):
self.loop = messageable._state.loop
self.messageable = messageable
async def do_typing(self):
try:
channel = self._channel
except AttributeError:
channel = await self.messageable._get_channel()
typing = channel._state.http.send_typing
while True:
await typing(channel.id)
await asyncio.sleep(5)
def __enter__(self):
self.task = asyncio.ensure_future(self.do_typing(), loop=self.loop)
self.task.add_done_callback(_typing_done_callback)
return self
def __exit__(self, exc_type, exc, tb):
self.task.cancel()
async def __aenter__(self):
self._channel = channel = await self.messageable._get_channel()
await channel._state.http.send_typing(channel.id)
return self.__enter__()
async def __aexit__(self, exc_type, exc, tb):
self.task.cancel()

View File

@@ -1,492 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import datetime
from . import utils
from .colour import Colour
class _EmptyEmbed:
def __bool__(self):
return False
def __repr__(self):
return "Embed.Empty"
EmptyEmbed = _EmptyEmbed()
class EmbedProxy:
def __init__(self, layer):
self.__dict__.update(layer)
def __len__(self):
return len(self.__dict__)
def __repr__(self):
return "EmbedProxy(%s)" % ", ".join(
("%s=%r" % (k, v) for k, v in self.__dict__.items() if not k.startswith("_"))
)
def __getattr__(self, attr):
return EmptyEmbed
class Embed:
"""Represents a Discord embed.
The following attributes can be set during creation
of the object:
Certain properties return an ``EmbedProxy``. Which is a type
that acts similar to a regular :class:`dict` except access the attributes
via dotted access, e.g. ``embed.author.icon_url``. If the attribute
is invalid or empty, then a special sentinel value is returned,
:attr:`Embed.Empty`.
For ease of use, all parameters that expect a :class:`str` are implicitly
casted to :class:`str` for you.
Attributes
-----------
title: :class:`str`
The title of the embed.
type: :class:`str`
The type of embed. Usually "rich".
description: :class:`str`
The description of the embed.
url: :class:`str`
The URL of the embed.
timestamp: `datetime.datetime`
The timestamp of the embed content. This could be a naive or aware datetime.
colour: :class:`Colour` or :class:`int`
The colour code of the embed. Aliased to ``color`` as well.
Empty
A special sentinel value used by ``EmbedProxy`` and this class
to denote that the value or attribute is empty.
"""
__slots__ = (
"title",
"url",
"type",
"_timestamp",
"_colour",
"_footer",
"_image",
"_thumbnail",
"_video",
"_provider",
"_author",
"_fields",
"description",
)
Empty = EmptyEmbed
def __init__(self, **kwargs):
# swap the colour/color aliases
try:
colour = kwargs["colour"]
except KeyError:
colour = kwargs.get("color", EmptyEmbed)
self.colour = colour
self.title = kwargs.get("title", EmptyEmbed)
self.type = kwargs.get("type", "rich")
self.url = kwargs.get("url", EmptyEmbed)
self.description = kwargs.get("description", EmptyEmbed)
try:
timestamp = kwargs["timestamp"]
except KeyError:
pass
else:
self.timestamp = timestamp
@classmethod
def from_data(cls, data):
# we are bypassing __init__ here since it doesn't apply here
self = cls.__new__(cls)
# fill in the basic fields
self.title = data.get("title", EmptyEmbed)
self.type = data.get("type", EmptyEmbed)
self.description = data.get("description", EmptyEmbed)
self.url = data.get("url", EmptyEmbed)
# try to fill in the more rich fields
try:
self._colour = Colour(value=data["color"])
except KeyError:
pass
try:
self._timestamp = utils.parse_time(data["timestamp"])
except KeyError:
pass
for attr in ("thumbnail", "video", "provider", "author", "fields", "image", "footer"):
try:
value = data[attr]
except KeyError:
continue
else:
setattr(self, "_" + attr, value)
return self
@property
def colour(self):
return getattr(self, "_colour", EmptyEmbed)
@colour.setter
def colour(self, value):
if isinstance(value, (Colour, _EmptyEmbed)):
self._colour = value
elif isinstance(value, int):
self._colour = Colour(value=value)
else:
raise TypeError(
"Expected discord.Colour, int, or Embed.Empty but received %s instead."
% value.__class__.__name__
)
color = colour
@property
def timestamp(self):
return getattr(self, "_timestamp", EmptyEmbed)
@timestamp.setter
def timestamp(self, value):
if isinstance(value, (datetime.datetime, _EmptyEmbed)):
self._timestamp = value
else:
raise TypeError(
"Expected datetime.datetime or Embed.Empty received %s instead"
% value.__class__.__name__
)
@property
def footer(self):
"""Returns an ``EmbedProxy`` denoting the footer contents.
See :meth:`set_footer` for possible values you can access.
If the attribute has no value then :attr:`Empty` is returned.
"""
return EmbedProxy(getattr(self, "_footer", {}))
def set_footer(self, *, text=EmptyEmbed, icon_url=EmptyEmbed):
"""Sets the footer for the embed content.
This function returns the class instance to allow for fluent-style
chaining.
Parameters
-----------
text: str
The footer text.
icon_url: str
The URL of the footer icon. Only HTTP(S) is supported.
"""
self._footer = {}
if text is not EmptyEmbed:
self._footer["text"] = str(text)
if icon_url is not EmptyEmbed:
self._footer["icon_url"] = str(icon_url)
return self
@property
def image(self):
"""Returns an ``EmbedProxy`` denoting the image contents.
Possible attributes you can access are:
- ``url``
- ``proxy_url``
- ``width``
- ``height``
If the attribute has no value then :attr:`Empty` is returned.
"""
return EmbedProxy(getattr(self, "_image", {}))
def set_image(self, *, url):
"""Sets the image for the embed content.
This function returns the class instance to allow for fluent-style
chaining.
Parameters
-----------
url: str
The source URL for the image. Only HTTP(S) is supported.
"""
self._image = {"url": str(url)}
return self
@property
def thumbnail(self):
"""Returns an ``EmbedProxy`` denoting the thumbnail contents.
Possible attributes you can access are:
- ``url``
- ``proxy_url``
- ``width``
- ``height``
If the attribute has no value then :attr:`Empty` is returned.
"""
return EmbedProxy(getattr(self, "_thumbnail", {}))
def set_thumbnail(self, *, url):
"""Sets the thumbnail for the embed content.
This function returns the class instance to allow for fluent-style
chaining.
Parameters
-----------
url: str
The source URL for the thumbnail. Only HTTP(S) is supported.
"""
self._thumbnail = {"url": str(url)}
return self
@property
def video(self):
"""Returns an ``EmbedProxy`` denoting the video contents.
Possible attributes include:
- ``url`` for the video URL.
- ``height`` for the video height.
- ``width`` for the video width.
If the attribute has no value then :attr:`Empty` is returned.
"""
return EmbedProxy(getattr(self, "_video", {}))
@property
def provider(self):
"""Returns an ``EmbedProxy`` denoting the provider contents.
The only attributes that might be accessed are ``name`` and ``url``.
If the attribute has no value then :attr:`Empty` is returned.
"""
return EmbedProxy(getattr(self, "_provider", {}))
@property
def author(self):
"""Returns an ``EmbedProxy`` denoting the author contents.
See :meth:`set_author` for possible values you can access.
If the attribute has no value then :attr:`Empty` is returned.
"""
return EmbedProxy(getattr(self, "_author", {}))
def set_author(self, *, name, url=EmptyEmbed, icon_url=EmptyEmbed):
"""Sets the author for the embed content.
This function returns the class instance to allow for fluent-style
chaining.
Parameters
-----------
name: str
The name of the author.
url: str
The URL for the author.
icon_url: str
The URL of the author icon. Only HTTP(S) is supported.
"""
self._author = {"name": str(name)}
if url is not EmptyEmbed:
self._author["url"] = str(url)
if icon_url is not EmptyEmbed:
self._author["icon_url"] = str(icon_url)
return self
@property
def fields(self):
"""Returns a :class:`list` of ``EmbedProxy`` denoting the field contents.
See :meth:`add_field` for possible values you can access.
If the attribute has no value then :attr:`Empty` is returned.
"""
return [EmbedProxy(d) for d in getattr(self, "_fields", [])]
def add_field(self, *, name, value, inline=True):
"""Adds a field to the embed object.
This function returns the class instance to allow for fluent-style
chaining.
Parameters
-----------
name: str
The name of the field.
value: str
The value of the field.
inline: bool
Whether the field should be displayed inline.
"""
field = {"inline": inline, "name": str(name), "value": str(value)}
try:
self._fields.append(field)
except AttributeError:
self._fields = [field]
return self
def clear_fields(self):
"""Removes all fields from this embed."""
try:
self._fields.clear()
except AttributeError:
self._fields = []
def remove_field(self, index):
"""Removes a field at a specified index.
If the index is invalid or out of bounds then the error is
silently swallowed.
.. note::
When deleting a field by index, the index of the other fields
shift to fill the gap just like a regular list.
Parameters
-----------
index: int
The index of the field to remove.
"""
try:
del self._fields[index]
except (AttributeError, IndexError):
pass
def set_field_at(self, index, *, name, value, inline=True):
"""Modifies a field to the embed object.
The index must point to a valid pre-existing field.
This function returns the class instance to allow for fluent-style
chaining.
Parameters
-----------
index: int
The index of the field to modify.
name: str
The name of the field.
value: str
The value of the field.
inline: bool
Whether the field should be displayed inline.
Raises
-------
IndexError
An invalid index was provided.
"""
try:
field = self._fields[index]
except (TypeError, IndexError, AttributeError):
raise IndexError("field index out of range")
field["name"] = str(name)
field["value"] = str(value)
field["inline"] = inline
return self
def to_dict(self):
"""Converts this embed object into a dict."""
# add in the raw data into the dict
result = {
key[1:]: getattr(self, key)
for key in self.__slots__
if key[0] == "_" and hasattr(self, key)
}
# deal with basic convenience wrappers
try:
colour = result.pop("colour")
except KeyError:
pass
else:
if colour:
result["color"] = colour.value
try:
timestamp = result.pop("timestamp")
except KeyError:
pass
else:
if timestamp:
result["timestamp"] = timestamp.isoformat()
# add in the non raw attribute ones
if self.type:
result["type"] = self.type
if self.description:
result["description"] = self.description
if self.url:
result["url"] = self.url
if self.title:
result["title"] = self.title
return result

View File

@@ -1,269 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from collections import namedtuple
from . import utils
from .mixins import Hashable
class PartialEmoji(namedtuple("PartialEmoji", "animated name id")):
"""Represents a "partial" emoji.
This model will be given in two scenarios:
- "Raw" data events such as :func:`on_raw_reaction_add`
- Custom emoji that the bot cannot see from e.g. :attr:`Message.reactions`
.. container:: operations
.. describe:: x == y
Checks if two emoji are the same.
.. describe:: x != y
Checks if two emoji are not the same.
.. describe:: hash(x)
Return the emoji's hash.
.. describe:: str(x)
Returns the emoji rendered for discord.
Attributes
-----------
name: :class:`str`
The custom emoji name, if applicable, or the unicode codepoint
of the non-custom emoji.
animated: :class:`bool`
Whether the emoji is animated or not.
id: Optional[:class:`int`]
The ID of the custom emoji, if applicable.
"""
__slots__ = ()
def __str__(self):
if self.id is None:
return self.name
if self.animated:
return "<a:%s:%s>" % (self.name, self.id)
return "<:%s:%s>" % (self.name, self.id)
def is_custom_emoji(self):
"""Checks if this is a custom non-Unicode emoji."""
return self.id is not None
def is_unicode_emoji(self):
"""Checks if this is a Unicode emoji."""
return self.id is None
def _as_reaction(self):
if self.id is None:
return self.name
return "%s:%s" % (self.name, self.id)
@property
def url(self):
"""Returns a URL version of the emoji, if it is custom."""
if self.is_unicode_emoji():
return None
_format = "gif" if self.animated else "png"
return "https://cdn.discordapp.com/emojis/{0.id}.{1}".format(self, _format)
class Emoji(Hashable):
"""Represents a custom emoji.
Depending on the way this object was created, some of the attributes can
have a value of ``None``.
.. container:: operations
.. describe:: x == y
Checks if two emoji are the same.
.. describe:: x != y
Checks if two emoji are not the same.
.. describe:: hash(x)
Return the emoji's hash.
.. describe:: iter(x)
Returns an iterator of ``(field, value)`` pairs. This allows this class
to be used as an iterable in list/dict/etc constructions.
.. describe:: str(x)
Returns the emoji rendered for discord.
Attributes
-----------
name: :class:`str`
The name of the emoji.
id: :class:`int`
The emoji's ID.
require_colons: :class:`bool`
If colons are required to use this emoji in the client (:PJSalt: vs PJSalt).
animated: :class:`bool`
Whether an emoji is animated or not.
managed: :class:`bool`
If this emoji is managed by a Twitch integration.
guild_id: :class:`int`
The guild ID the emoji belongs to.
"""
__slots__ = (
"require_colons",
"animated",
"managed",
"id",
"name",
"_roles",
"guild_id",
"_state",
)
def __init__(self, *, guild, state, data):
self.guild_id = guild.id
self._state = state
self._from_data(data)
def _from_data(self, emoji):
self.require_colons = emoji["require_colons"]
self.managed = emoji["managed"]
self.id = int(emoji["id"])
self.name = emoji["name"]
self.animated = emoji.get("animated", False)
self._roles = utils.SnowflakeList(map(int, emoji.get("roles", [])))
def _iterator(self):
for attr in self.__slots__:
if attr[0] != "_":
value = getattr(self, attr, None)
if value is not None:
yield (attr, value)
def __iter__(self):
return self._iterator()
def __str__(self):
if self.animated:
return "<a:{0.name}:{0.id}>".format(self)
return "<:{0.name}:{0.id}>".format(self)
def __repr__(self):
return "<Emoji id={0.id} name={0.name!r}>".format(self)
@property
def created_at(self):
"""Returns the emoji's creation time in UTC."""
return utils.snowflake_time(self.id)
@property
def url(self):
"""Returns a URL version of the emoji."""
_format = "gif" if self.animated else "png"
return "https://cdn.discordapp.com/emojis/{0.id}.{1}".format(self, _format)
@property
def roles(self):
"""List[:class:`Role`]: A :class:`list` of roles that is allowed to use this emoji.
If roles is empty, the emoji is unrestricted.
"""
guild = self.guild
if guild is None:
return []
return [role for role in guild.roles if self._roles.has(role.id)]
@property
def guild(self):
""":class:`Guild`: The guild this emoji belongs to."""
return self._state._get_guild(self.guild_id)
async def delete(self, *, reason=None):
"""|coro|
Deletes the custom emoji.
You must have :attr:`~Permissions.manage_emojis` permission to
do this.
Parameters
-----------
reason: Optional[str]
The reason for deleting this emoji. Shows up on the audit log.
Raises
-------
Forbidden
You are not allowed to delete emojis.
HTTPException
An error occurred deleting the emoji.
"""
await self._state.http.delete_custom_emoji(self.guild.id, self.id, reason=reason)
async def edit(self, *, name, roles=None, reason=None):
r"""|coro|
Edits the custom emoji.
You must have :attr:`~Permissions.manage_emojis` permission to
do this.
Parameters
-----------
name: str
The new emoji name.
roles: Optional[list[:class:`Role`]]
A :class:`list` of :class:`Role`\s that can use this emoji. Leave empty to make it available to everyone.
reason: Optional[str]
The reason for editing this emoji. Shows up on the audit log.
Raises
-------
Forbidden
You are not allowed to edit emojis.
HTTPException
An error occurred editing the emoji.
"""
if roles:
roles = [role.id for role in roles]
await self._state.http.edit_custom_emoji(
self.guild.id, self.id, name=name, roles=roles, reason=reason
)

View File

@@ -1,274 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from enum import Enum, IntEnum
__all__ = [
"ChannelType",
"MessageType",
"VoiceRegion",
"VerificationLevel",
"ContentFilter",
"Status",
"DefaultAvatar",
"RelationshipType",
"AuditLogAction",
"AuditLogActionCategory",
"UserFlags",
"ActivityType",
"HypeSquadHouse",
"NotificationLevel",
]
class ChannelType(Enum):
text = 0
private = 1
voice = 2
group = 3
category = 4
def __str__(self):
return self.name
class MessageType(Enum):
default = 0
recipient_add = 1
recipient_remove = 2
call = 3
channel_name_change = 4
channel_icon_change = 5
pins_add = 6
new_member = 7
class VoiceRegion(Enum):
us_west = "us-west"
us_east = "us-east"
us_south = "us-south"
us_central = "us-central"
eu_west = "eu-west"
eu_central = "eu-central"
singapore = "singapore"
london = "london"
sydney = "sydney"
amsterdam = "amsterdam"
frankfurt = "frankfurt"
brazil = "brazil"
hongkong = "hongkong"
russia = "russia"
japan = "japan"
southafrica = "southafrica"
vip_us_east = "vip-us-east"
vip_us_west = "vip-us-west"
vip_amsterdam = "vip-amsterdam"
def __str__(self):
return self.value
class VerificationLevel(IntEnum):
none = 0
low = 1
medium = 2
high = 3
table_flip = 3
extreme = 4
double_table_flip = 4
def __str__(self):
return self.name
class ContentFilter(IntEnum):
disabled = 0
no_role = 1
all_members = 2
def __str__(self):
return self.name
class Status(Enum):
online = "online"
offline = "offline"
idle = "idle"
dnd = "dnd"
do_not_disturb = "dnd"
invisible = "invisible"
def __str__(self):
return self.value
class DefaultAvatar(Enum):
blurple = 0
grey = 1
gray = 1
green = 2
orange = 3
red = 4
def __str__(self):
return self.name
class RelationshipType(Enum):
friend = 1
blocked = 2
incoming_request = 3
outgoing_request = 4
class NotificationLevel(IntEnum):
all_messages = 0
only_mentions = 1
class AuditLogActionCategory(Enum):
create = 1
delete = 2
update = 3
class AuditLogAction(Enum):
guild_update = 1
channel_create = 10
channel_update = 11
channel_delete = 12
overwrite_create = 13
overwrite_update = 14
overwrite_delete = 15
kick = 20
member_prune = 21
ban = 22
unban = 23
member_update = 24
member_role_update = 25
role_create = 30
role_update = 31
role_delete = 32
invite_create = 40
invite_update = 41
invite_delete = 42
webhook_create = 50
webhook_update = 51
webhook_delete = 52
emoji_create = 60
emoji_update = 61
emoji_delete = 62
message_delete = 72
@property
def category(self):
lookup = {
AuditLogAction.guild_update: AuditLogActionCategory.update,
AuditLogAction.channel_create: AuditLogActionCategory.create,
AuditLogAction.channel_update: AuditLogActionCategory.update,
AuditLogAction.channel_delete: AuditLogActionCategory.delete,
AuditLogAction.overwrite_create: AuditLogActionCategory.create,
AuditLogAction.overwrite_update: AuditLogActionCategory.update,
AuditLogAction.overwrite_delete: AuditLogActionCategory.delete,
AuditLogAction.kick: None,
AuditLogAction.member_prune: None,
AuditLogAction.ban: None,
AuditLogAction.unban: None,
AuditLogAction.member_update: AuditLogActionCategory.update,
AuditLogAction.member_role_update: AuditLogActionCategory.update,
AuditLogAction.role_create: AuditLogActionCategory.create,
AuditLogAction.role_update: AuditLogActionCategory.update,
AuditLogAction.role_delete: AuditLogActionCategory.delete,
AuditLogAction.invite_create: AuditLogActionCategory.create,
AuditLogAction.invite_update: AuditLogActionCategory.update,
AuditLogAction.invite_delete: AuditLogActionCategory.delete,
AuditLogAction.webhook_create: AuditLogActionCategory.create,
AuditLogAction.webhook_update: AuditLogActionCategory.update,
AuditLogAction.webhook_delete: AuditLogActionCategory.delete,
AuditLogAction.emoji_create: AuditLogActionCategory.create,
AuditLogAction.emoji_update: AuditLogActionCategory.update,
AuditLogAction.emoji_delete: AuditLogActionCategory.delete,
AuditLogAction.message_delete: AuditLogActionCategory.delete,
}
return lookup[self]
@property
def target_type(self):
v = self.value
if v == -1:
return "all"
elif v < 10:
return "guild"
elif v < 20:
return "channel"
elif v < 30:
return "user"
elif v < 40:
return "role"
elif v < 50:
return "invite"
elif v < 60:
return "webhook"
elif v < 70:
return "emoji"
elif v < 80:
return "message"
class UserFlags(Enum):
staff = 1
partner = 2
hypesquad = 4
bug_hunter = 8
hypesquad_bravery = 64
hypesquad_brilliance = 128
hypesquad_balance = 256
early_supporter = 512
class ActivityType(IntEnum):
unknown = -1
playing = 0
streaming = 1
listening = 2
watching = 3
class HypeSquadHouse(Enum):
bravery = 1
brilliance = 2
balance = 3
def try_enum(cls, val):
"""A function that tries to turn the value into enum ``cls``.
If it fails it returns the value instead.
"""
try:
return cls(val)
except ValueError:
return val

View File

@@ -1,183 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
class DiscordException(Exception):
"""Base exception class for discord.py
Ideally speaking, this could be caught to handle any exceptions thrown from this library.
"""
pass
class ClientException(DiscordException):
"""Exception that's thrown when an operation in the :class:`Client` fails.
These are usually for exceptions that happened due to user input.
"""
pass
class NoMoreItems(DiscordException):
"""Exception that is thrown when an async iteration operation has no more
items."""
pass
class GatewayNotFound(DiscordException):
"""An exception that is usually thrown when the gateway hub
for the :class:`Client` websocket is not found."""
def __init__(self):
message = "The gateway to connect to discord was not found."
super(GatewayNotFound, self).__init__(message)
def flatten_error_dict(d, key=""):
items = []
for k, v in d.items():
new_key = key + "." + k if key else k
if isinstance(v, dict):
try:
_errors = v["_errors"]
except KeyError:
items.extend(flatten_error_dict(v, new_key).items())
else:
items.append((new_key, " ".join(x.get("message", "") for x in _errors)))
else:
items.append((new_key, v))
return dict(items)
class HTTPException(DiscordException):
"""Exception that's thrown when an HTTP request operation fails.
Attributes
------------
response: aiohttp.ClientResponse
The response of the failed HTTP request. This is an
instance of `aiohttp.ClientResponse`__. In some cases
this could also be a ``requests.Response``.
__ http://aiohttp.readthedocs.org/en/stable/client_reference.html#aiohttp.ClientResponse
text: :class:`str`
The text of the error. Could be an empty string.
status: :class:`int`
The status code of the HTTP request.
code: :class:`int`
The Discord specific error code for the failure.
"""
def __init__(self, response, message):
self.response = response
self.status = response.status
if isinstance(message, dict):
self.code = message.get("code", 0)
base = message.get("message", "")
errors = message.get("errors")
if errors:
errors = flatten_error_dict(errors)
helpful = "\n".join("In %s: %s" % t for t in errors.items())
self.text = base + "\n" + helpful
else:
self.text = base
else:
self.text = message
self.code = 0
fmt = "{0.reason} (status code: {0.status})"
if len(self.text):
fmt = fmt + ": {1}"
super().__init__(fmt.format(self.response, self.text))
class Forbidden(HTTPException):
"""Exception that's thrown for when status code 403 occurs.
Subclass of :exc:`HTTPException`
"""
pass
class NotFound(HTTPException):
"""Exception that's thrown for when status code 404 occurs.
Subclass of :exc:`HTTPException`
"""
pass
class InvalidArgument(ClientException):
"""Exception that's thrown when an argument to a function
is invalid some way (e.g. wrong value or wrong type).
This could be considered the analogous of ``ValueError`` and
``TypeError`` except derived from :exc:`ClientException` and thus
:exc:`DiscordException`.
"""
pass
class LoginFailure(ClientException):
"""Exception that's thrown when the :meth:`Client.login` function
fails to log you in from improper credentials or some other misc.
failure.
"""
pass
class ConnectionClosed(ClientException):
"""Exception that's thrown when the gateway connection is
closed for reasons that could not be handled internally.
Attributes
-----------
code: :class:`int`
The close code of the websocket.
reason: :class:`str`
The reason provided for the closure.
shard_id: Optional[:class:`int`]
The shard ID that got closed if applicable.
"""
def __init__(self, original, *, shard_id):
# This exception is just the same exception except
# reconfigured to subclass ClientException for users
self.code = original.code
self.reason = original.reason
self.shard_id = shard_id
super().__init__(str(original))

View File

@@ -1,19 +0,0 @@
# -*- coding: utf-8 -*-
"""
discord.ext.commands
~~~~~~~~~~~~~~~~~~~~~
An extension module to facilitate creation of bot commands.
:copyright: (c) 2017 Rapptz
:license: MIT, see LICENSE for more details.
"""
from .bot import Bot, AutoShardedBot, when_mentioned, when_mentioned_or
from .context import Context
from .core import *
from .errors import *
from .formatter import HelpFormatter, Paginator
from .converter import *
from .cooldowns import *

File diff suppressed because it is too large Load Diff

View File

@@ -1,225 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import discord.abc
import discord.utils
class Context(discord.abc.Messageable):
r"""Represents the context in which a command is being invoked under.
This class contains a lot of meta data to help you understand more about
the invocation context. This class is not created manually and is instead
passed around to commands as the first parameter.
This class implements the :class:`abc.Messageable` ABC.
Attributes
-----------
message: :class:`discord.Message`
The message that triggered the command being executed.
bot: :class:`.Bot`
The bot that contains the command being executed.
args: :class:`list`
The list of transformed arguments that were passed into the command.
If this is accessed during the :func:`on_command_error` event
then this list could be incomplete.
kwargs: :class:`dict`
A dictionary of transformed arguments that were passed into the command.
Similar to :attr:`args`\, if this is accessed in the
:func:`on_command_error` event then this dict could be incomplete.
prefix: :class:`str`
The prefix that was used to invoke the command.
command
The command (i.e. :class:`.Command` or its superclasses) that is being
invoked currently.
invoked_with: :class:`str`
The command name that triggered this invocation. Useful for finding out
which alias called the command.
invoked_subcommand
The subcommand (i.e. :class:`.Command` or its superclasses) that was
invoked. If no valid subcommand was invoked then this is equal to
`None`.
subcommand_passed: Optional[:class:`str`]
The string that was attempted to call a subcommand. This does not have
to point to a valid registered subcommand and could just point to a
nonsense string. If nothing was passed to attempt a call to a
subcommand then this is set to `None`.
command_failed: :class:`bool`
A boolean that indicates if the command failed to be parsed, checked,
or invoked.
"""
def __init__(self, **attrs):
self.message = attrs.pop("message", None)
self.bot = attrs.pop("bot", None)
self.args = attrs.pop("args", [])
self.kwargs = attrs.pop("kwargs", {})
self.prefix = attrs.pop("prefix")
self.command = attrs.pop("command", None)
self.view = attrs.pop("view", None)
self.invoked_with = attrs.pop("invoked_with", None)
self.invoked_subcommand = attrs.pop("invoked_subcommand", None)
self.subcommand_passed = attrs.pop("subcommand_passed", None)
self.command_failed = attrs.pop("command_failed", False)
self._state = self.message._state
async def invoke(self, *args, **kwargs):
r"""|coro|
Calls a command with the arguments given.
This is useful if you want to just call the callback that a
:class:`.Command` holds internally.
Note
------
You do not pass in the context as it is done for you.
Warning
---------
The first parameter passed **must** be the command being invoked.
Parameters
-----------
command: :class:`.Command`
A command or superclass of a command that is going to be called.
\*args
The arguments to to use.
\*\*kwargs
The keyword arguments to use.
"""
try:
command = args[0]
except IndexError:
raise TypeError("Missing command to invoke.") from None
arguments = []
if command.instance is not None:
arguments.append(command.instance)
arguments.append(self)
arguments.extend(args[1:])
ret = await command.callback(*arguments, **kwargs)
return ret
async def reinvoke(self, *, call_hooks=False, restart=True):
"""|coro|
Calls the command again.
This is similar to :meth:`~.Context.invoke` except that it bypasses
checks, cooldowns, and error handlers.
.. note::
If you want to bypass :exc:`.UserInputError` derived exceptions,
it is recommended to use the regular :meth:`~.Context.invoke`
as it will work more naturally. After all, this will end up
using the old arguments the user has used and will thus just
fail again.
Parameters
------------
call_hooks: bool
Whether to call the before and after invoke hooks.
restart: bool
Whether to start the call chain from the very beginning
or where we left off (i.e. the command that caused the error).
The default is to start where we left off.
"""
cmd = self.command
view = self.view
if cmd is None:
raise ValueError("This context is not valid.")
# some state to revert to when we're done
index, previous = view.index, view.previous
invoked_with = self.invoked_with
invoked_subcommand = self.invoked_subcommand
subcommand_passed = self.subcommand_passed
if restart:
to_call = cmd.root_parent or cmd
view.index = len(self.prefix)
view.previous = 0
view.get_word() # advance to get the root command
else:
to_call = cmd
try:
await to_call.reinvoke(self, call_hooks=call_hooks)
finally:
self.command = cmd
view.index = index
view.previous = previous
self.invoked_with = invoked_with
self.invoked_subcommand = invoked_subcommand
self.subcommand_passed = subcommand_passed
@property
def valid(self):
"""Checks if the invocation context is valid to be invoked with."""
return self.prefix is not None and self.command is not None
async def _get_channel(self):
return self.channel
@property
def cog(self):
"""Returns the cog associated with this context's command. None if it does not exist."""
if self.command is None:
return None
return self.command.instance
@discord.utils.cached_property
def guild(self):
"""Returns the guild associated with this context's command. None if not available."""
return self.message.guild
@discord.utils.cached_property
def channel(self):
"""Returns the channel associated with this context's command. Shorthand for :attr:`Message.channel`."""
return self.message.channel
@discord.utils.cached_property
def author(self):
"""Returns the author associated with this context's command. Shorthand for :attr:`Message.author`"""
return self.message.author
@discord.utils.cached_property
def me(self):
"""Similar to :attr:`Guild.me` except it may return the :class:`ClientUser` in private message contexts."""
return self.guild.me if self.guild is not None else self.bot.user
@property
def voice_client(self):
r"""Optional[:class:`VoiceClient`]: A shortcut to :attr:`Guild.voice_client`\, if applicable."""
g = self.guild
return g.voice_client if g else None

View File

@@ -1,560 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import re
import inspect
import discord
from .errors import BadArgument, NoPrivateMessage
__all__ = [
"Converter",
"MemberConverter",
"UserConverter",
"TextChannelConverter",
"InviteConverter",
"RoleConverter",
"GameConverter",
"ColourConverter",
"VoiceChannelConverter",
"EmojiConverter",
"PartialEmojiConverter",
"CategoryChannelConverter",
"IDConverter",
"clean_content",
"Greedy",
]
def _get_from_guilds(bot, getter, argument):
result = None
for guild in bot.guilds:
result = getattr(guild, getter)(argument)
if result:
return result
return result
class Converter:
"""The base class of custom converters that require the :class:`.Context`
to be passed to be useful.
This allows you to implement converters that function similar to the
special cased ``discord`` classes.
Classes that derive from this should override the :meth:`~.Converter.convert`
method to do its conversion logic. This method must be a coroutine.
"""
async def convert(self, ctx, argument):
"""|coro|
The method to override to do conversion logic.
If an error is found while converting, it is recommended to
raise a :exc:`.CommandError` derived exception as it will
properly propagate to the error handlers.
Parameters
-----------
ctx: :class:`.Context`
The invocation context that the argument is being used in.
argument: str
The argument that is being converted.
"""
raise NotImplementedError("Derived classes need to implement this.")
class IDConverter(Converter):
def __init__(self):
self._id_regex = re.compile(r"([0-9]{15,21})$")
super().__init__()
def _get_id_match(self, argument):
return self._id_regex.match(argument)
class MemberConverter(IDConverter):
"""Converts to a :class:`Member`.
All lookups are via the local guild. If in a DM context, then the lookup
is done by the global cache.
The lookup strategy is as follows (in order):
1. Lookup by ID.
2. Lookup by mention.
3. Lookup by name#discrim
4. Lookup by name
5. Lookup by nickname
"""
async def convert(self, ctx, argument):
bot = ctx.bot
match = self._get_id_match(argument) or re.match(r"<@!?([0-9]+)>$", argument)
guild = ctx.guild
result = None
if match is None:
# not a mention...
if guild:
result = guild.get_member_named(argument)
else:
result = _get_from_guilds(bot, "get_member_named", argument)
else:
user_id = int(match.group(1))
if guild:
result = guild.get_member(user_id)
else:
result = _get_from_guilds(bot, "get_member", user_id)
if result is None:
raise BadArgument('Member "{}" not found'.format(argument))
return result
class UserConverter(IDConverter):
"""Converts to a :class:`User`.
All lookups are via the global user cache.
The lookup strategy is as follows (in order):
1. Lookup by ID.
2. Lookup by mention.
3. Lookup by name#discrim
4. Lookup by name
"""
async def convert(self, ctx, argument):
match = self._get_id_match(argument) or re.match(r"<@!?([0-9]+)>$", argument)
result = None
state = ctx._state
if match is not None:
user_id = int(match.group(1))
result = ctx.bot.get_user(user_id)
else:
arg = argument
# check for discriminator if it exists
if len(arg) > 5 and arg[-5] == "#":
discrim = arg[-4:]
name = arg[:-5]
predicate = lambda u: u.name == name and u.discriminator == discrim
result = discord.utils.find(predicate, state._users.values())
if result is not None:
return result
predicate = lambda u: u.name == arg
result = discord.utils.find(predicate, state._users.values())
if result is None:
raise BadArgument('User "{}" not found'.format(argument))
return result
class TextChannelConverter(IDConverter):
"""Converts to a :class:`TextChannel`.
All lookups are via the local guild. If in a DM context, then the lookup
is done by the global cache.
The lookup strategy is as follows (in order):
1. Lookup by ID.
2. Lookup by mention.
3. Lookup by name
"""
async def convert(self, ctx, argument):
bot = ctx.bot
match = self._get_id_match(argument) or re.match(r"<#([0-9]+)>$", argument)
result = None
guild = ctx.guild
if match is None:
# not a mention
if guild:
result = discord.utils.get(guild.text_channels, name=argument)
else:
def check(c):
return isinstance(c, discord.TextChannel) and c.name == argument
result = discord.utils.find(check, bot.get_all_channels())
else:
channel_id = int(match.group(1))
if guild:
result = guild.get_channel(channel_id)
else:
result = _get_from_guilds(bot, "get_channel", channel_id)
if not isinstance(result, discord.TextChannel):
raise BadArgument('Channel "{}" not found.'.format(argument))
return result
class VoiceChannelConverter(IDConverter):
"""Converts to a :class:`VoiceChannel`.
All lookups are via the local guild. If in a DM context, then the lookup
is done by the global cache.
The lookup strategy is as follows (in order):
1. Lookup by ID.
2. Lookup by mention.
3. Lookup by name
"""
async def convert(self, ctx, argument):
bot = ctx.bot
match = self._get_id_match(argument) or re.match(r"<#([0-9]+)>$", argument)
result = None
guild = ctx.guild
if match is None:
# not a mention
if guild:
result = discord.utils.get(guild.voice_channels, name=argument)
else:
def check(c):
return isinstance(c, discord.VoiceChannel) and c.name == argument
result = discord.utils.find(check, bot.get_all_channels())
else:
channel_id = int(match.group(1))
if guild:
result = guild.get_channel(channel_id)
else:
result = _get_from_guilds(bot, "get_channel", channel_id)
if not isinstance(result, discord.VoiceChannel):
raise BadArgument('Channel "{}" not found.'.format(argument))
return result
class CategoryChannelConverter(IDConverter):
"""Converts to a :class:`CategoryChannel`.
All lookups are via the local guild. If in a DM context, then the lookup
is done by the global cache.
The lookup strategy is as follows (in order):
1. Lookup by ID.
2. Lookup by mention.
3. Lookup by name
"""
async def convert(self, ctx, argument):
bot = ctx.bot
match = self._get_id_match(argument) or re.match(r"<#([0-9]+)>$", argument)
result = None
guild = ctx.guild
if match is None:
# not a mention
if guild:
result = discord.utils.get(guild.categories, name=argument)
else:
def check(c):
return isinstance(c, discord.CategoryChannel) and c.name == argument
result = discord.utils.find(check, bot.get_all_channels())
else:
channel_id = int(match.group(1))
if guild:
result = guild.get_channel(channel_id)
else:
result = _get_from_guilds(bot, "get_channel", channel_id)
if not isinstance(result, discord.CategoryChannel):
raise BadArgument('Channel "{}" not found.'.format(argument))
return result
class ColourConverter(Converter):
"""Converts to a :class:`Colour`.
The following formats are accepted:
- ``0x<hex>``
- ``#<hex>``
- ``0x#<hex>``
- Any of the ``classmethod`` in :class:`Colour`
- The ``_`` in the name can be optionally replaced with spaces.
"""
async def convert(self, ctx, argument):
arg = argument.replace("0x", "").lower()
if arg[0] == "#":
arg = arg[1:]
try:
value = int(arg, base=16)
return discord.Colour(value=value)
except ValueError:
method = getattr(discord.Colour, arg.replace(" ", "_"), None)
if method is None or not inspect.ismethod(method):
raise BadArgument('Colour "{}" is invalid.'.format(arg))
return method()
class RoleConverter(IDConverter):
"""Converts to a :class:`Role`.
All lookups are via the local guild. If in a DM context, then the lookup
is done by the global cache.
The lookup strategy is as follows (in order):
1. Lookup by ID.
2. Lookup by mention.
3. Lookup by name
"""
async def convert(self, ctx, argument):
guild = ctx.guild
if not guild:
raise NoPrivateMessage()
match = self._get_id_match(argument) or re.match(r"<@&([0-9]+)>$", argument)
if match:
result = guild.get_role(int(match.group(1)))
else:
result = discord.utils.get(guild._roles.values(), name=argument)
if result is None:
raise BadArgument('Role "{}" not found.'.format(argument))
return result
class GameConverter(Converter):
"""Converts to :class:`Game`."""
async def convert(self, ctx, argument):
return discord.Game(name=argument)
class InviteConverter(Converter):
"""Converts to a :class:`Invite`.
This is done via an HTTP request using :meth:`.Bot.get_invite`.
"""
async def convert(self, ctx, argument):
try:
invite = await ctx.bot.get_invite(argument)
return invite
except Exception as exc:
raise BadArgument("Invite is invalid or expired") from exc
class EmojiConverter(IDConverter):
"""Converts to a :class:`Emoji`.
All lookups are done for the local guild first, if available. If that lookup
fails, then it checks the client's global cache.
The lookup strategy is as follows (in order):
1. Lookup by ID.
2. Lookup by extracting ID from the emoji.
3. Lookup by name
"""
async def convert(self, ctx, argument):
match = self._get_id_match(argument) or re.match(
r"<a?:[a-zA-Z0-9\_]+:([0-9]+)>$", argument
)
result = None
bot = ctx.bot
guild = ctx.guild
if match is None:
# Try to get the emoji by name. Try local guild first.
if guild:
result = discord.utils.get(guild.emojis, name=argument)
if result is None:
result = discord.utils.get(bot.emojis, name=argument)
else:
emoji_id = int(match.group(1))
# Try to look up emoji by id.
if guild:
result = discord.utils.get(guild.emojis, id=emoji_id)
if result is None:
result = discord.utils.get(bot.emojis, id=emoji_id)
if result is None:
raise BadArgument('Emoji "{}" not found.'.format(argument))
return result
class PartialEmojiConverter(Converter):
"""Converts to a :class:`PartialEmoji`.
This is done by extracting the animated flag, name and ID from the emoji.
"""
async def convert(self, ctx, argument):
match = re.match(r"<(a?):([a-zA-Z0-9\_]+):([0-9]+)>$", argument)
if match:
emoji_animated = bool(match.group(1))
emoji_name = match.group(2)
emoji_id = int(match.group(3))
return discord.PartialEmoji(animated=emoji_animated, name=emoji_name, id=emoji_id)
raise BadArgument('Couldn\'t convert "{}" to PartialEmoji.'.format(argument))
class clean_content(Converter):
"""Converts the argument to mention scrubbed version of
said content.
This behaves similarly to :attr:`.Message.clean_content`.
Attributes
------------
fix_channel_mentions: :obj:`bool`
Whether to clean channel mentions.
use_nicknames: :obj:`bool`
Whether to use nicknames when transforming mentions.
escape_markdown: :obj:`bool`
Whether to also escape special markdown characters.
"""
def __init__(self, *, fix_channel_mentions=False, use_nicknames=True, escape_markdown=False):
self.fix_channel_mentions = fix_channel_mentions
self.use_nicknames = use_nicknames
self.escape_markdown = escape_markdown
async def convert(self, ctx, argument):
message = ctx.message
transformations = {}
if self.fix_channel_mentions and ctx.guild:
def resolve_channel(id, *, _get=ctx.guild.get_channel):
ch = _get(id)
return ("<#%s>" % id), ("#" + ch.name if ch else "#deleted-channel")
transformations.update(
resolve_channel(channel) for channel in message.raw_channel_mentions
)
if self.use_nicknames and ctx.guild:
def resolve_member(id, *, _get=ctx.guild.get_member):
m = _get(id)
return "@" + m.display_name if m else "@deleted-user"
else:
def resolve_member(id, *, _get=ctx.bot.get_user):
m = _get(id)
return "@" + m.name if m else "@deleted-user"
transformations.update(
("<@%s>" % member_id, resolve_member(member_id)) for member_id in message.raw_mentions
)
transformations.update(
("<@!%s>" % member_id, resolve_member(member_id)) for member_id in message.raw_mentions
)
if ctx.guild:
def resolve_role(_id, *, _find=ctx.guild.get_role):
r = _find(_id)
return "@" + r.name if r else "@deleted-role"
transformations.update(
("<@&%s>" % role_id, resolve_role(role_id))
for role_id in message.raw_role_mentions
)
def repl(obj):
return transformations.get(obj.group(0), "")
pattern = re.compile("|".join(transformations.keys()))
result = pattern.sub(repl, argument)
if self.escape_markdown:
transformations = {re.escape(c): "\\" + c for c in ("*", "`", "_", "~", "\\")}
def replace(obj):
return transformations.get(re.escape(obj.group(0)), "")
pattern = re.compile("|".join(transformations.keys()))
result = pattern.sub(replace, result)
# Completely ensure no mentions escape:
return re.sub(r"@(everyone|here|[!&]?[0-9]{17,21})", "@\u200b\\1", result)
class _Greedy:
__slots__ = ("converter",)
def __init__(self, *, converter=None):
self.converter = converter
def __getitem__(self, params):
if not isinstance(params, tuple):
params = (params,)
if len(params) != 1:
raise TypeError("Greedy[...] only takes a single argument")
converter = params[0]
if not inspect.isclass(converter):
raise TypeError("Greedy[...] expects a type.")
if converter is str or converter is type(None) or converter is _Greedy:
raise TypeError("Greedy[%s] is invalid." % converter.__name__)
return self.__class__(converter=converter)
Greedy = _Greedy()

View File

@@ -1,148 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import enum
import time
__all__ = ["BucketType", "Cooldown", "CooldownMapping"]
class BucketType(enum.Enum):
default = 0
user = 1
guild = 2
channel = 3
member = 4
category = 5
class Cooldown:
__slots__ = ("rate", "per", "type", "_window", "_tokens", "_last")
def __init__(self, rate, per, type):
self.rate = int(rate)
self.per = float(per)
self.type = type
self._window = 0.0
self._tokens = self.rate
self._last = 0.0
if not isinstance(self.type, BucketType):
raise TypeError("Cooldown type must be a BucketType")
def get_tokens(self, current=None):
if not current:
current = time.time()
tokens = self._tokens
if current > self._window + self.per:
tokens = self.rate
return tokens
def update_rate_limit(self):
current = time.time()
self._last = current
self._tokens = self.get_tokens(current)
# first token used means that we start a new rate limit window
if self._tokens == self.rate:
self._window = current
# check if we are rate limited
if self._tokens == 0:
return self.per - (current - self._window)
# we're not so decrement our tokens
self._tokens -= 1
# see if we got rate limited due to this token change, and if
# so update the window to point to our current time frame
if self._tokens == 0:
self._window = current
def reset(self):
self._tokens = self.rate
self._last = 0.0
def copy(self):
return Cooldown(self.rate, self.per, self.type)
def __repr__(self):
return "<Cooldown rate: {0.rate} per: {0.per} window: {0._window} tokens: {0._tokens}>".format(
self
)
class CooldownMapping:
def __init__(self, original):
self._cache = {}
self._cooldown = original
@property
def valid(self):
return self._cooldown is not None
@classmethod
def from_cooldown(cls, rate, per, type):
return cls(Cooldown(rate, per, type))
def _bucket_key(self, msg):
bucket_type = self._cooldown.type
if bucket_type is BucketType.user:
return msg.author.id
elif bucket_type is BucketType.guild:
return (msg.guild or msg.author).id
elif bucket_type is BucketType.channel:
return msg.channel.id
elif bucket_type is BucketType.member:
return ((msg.guild and msg.guild.id), msg.author.id)
elif bucket_type is BucketType.category:
return (msg.channel.category or msg.channel).id
def _verify_cache_integrity(self):
# we want to delete all cache objects that haven't been used
# in a cooldown window. e.g. if we have a command that has a
# cooldown of 60s and it has not been used in 60s then that key should be deleted
current = time.time()
dead_keys = [k for k, v in self._cache.items() if current > v._last + v.per]
for k in dead_keys:
del self._cache[k]
def get_bucket(self, message):
if self._cooldown.type is BucketType.default:
return self._cooldown
self._verify_cache_integrity()
key = self._bucket_key(message)
if key not in self._cache:
bucket = self._cooldown.copy()
self._cache[key] = bucket
else:
bucket = self._cache[key]
return bucket

File diff suppressed because it is too large Load Diff

View File

@@ -1,279 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from discord.errors import DiscordException
__all__ = [
"CommandError",
"MissingRequiredArgument",
"BadArgument",
"NoPrivateMessage",
"CheckFailure",
"CommandNotFound",
"DisabledCommand",
"CommandInvokeError",
"TooManyArguments",
"UserInputError",
"CommandOnCooldown",
"NotOwner",
"MissingPermissions",
"BotMissingPermissions",
"ConversionError",
"BadUnionArgument",
]
class CommandError(DiscordException):
r"""The base exception type for all command related errors.
This inherits from :exc:`discord.DiscordException`.
This exception and exceptions derived from it are handled
in a special way as they are caught and passed into a special event
from :class:`.Bot`\, :func:`on_command_error`.
"""
def __init__(self, message=None, *args):
if message is not None:
# clean-up @everyone and @here mentions
m = message.replace("@everyone", "@\u200beveryone").replace("@here", "@\u200bhere")
super().__init__(m, *args)
else:
super().__init__(*args)
class ConversionError(CommandError):
"""Exception raised when a Converter class raises non-CommandError.
This inherits from :exc:`.CommandError`.
Attributes
----------
converter: :class:`discord.ext.commands.Converter`
The converter that failed.
original
The original exception that was raised. You can also get this via
the ``__cause__`` attribute.
"""
def __init__(self, converter, original):
self.converter = converter
self.original = original
class UserInputError(CommandError):
"""The base exception type for errors that involve errors
regarding user input.
This inherits from :exc:`.CommandError`.
"""
pass
class CommandNotFound(CommandError):
"""Exception raised when a command is attempted to be invoked
but no command under that name is found.
This is not raised for invalid subcommands, rather just the
initial main command that is attempted to be invoked.
"""
pass
class MissingRequiredArgument(UserInputError):
"""Exception raised when parsing a command and a parameter
that is required is not encountered.
Attributes
-----------
param: :class:`inspect.Parameter`
The argument that is missing.
"""
def __init__(self, param):
self.param = param
super().__init__("{0.name} is a required argument that is missing.".format(param))
class TooManyArguments(UserInputError):
"""Exception raised when the command was passed too many arguments and its
:attr:`.Command.ignore_extra` attribute was not set to ``True``.
"""
pass
class BadArgument(UserInputError):
"""Exception raised when a parsing or conversion failure is encountered
on an argument to pass into a command.
"""
pass
class CheckFailure(CommandError):
"""Exception raised when the predicates in :attr:`.Command.checks` have failed."""
pass
class NoPrivateMessage(CheckFailure):
"""Exception raised when an operation does not work in private message
contexts.
"""
pass
class NotOwner(CheckFailure):
"""Exception raised when the message author is not the owner of the bot."""
pass
class DisabledCommand(CommandError):
"""Exception raised when the command being invoked is disabled."""
pass
class CommandInvokeError(CommandError):
"""Exception raised when the command being invoked raised an exception.
Attributes
-----------
original
The original exception that was raised. You can also get this via
the ``__cause__`` attribute.
"""
def __init__(self, e):
self.original = e
super().__init__("Command raised an exception: {0.__class__.__name__}: {0}".format(e))
class CommandOnCooldown(CommandError):
"""Exception raised when the command being invoked is on cooldown.
Attributes
-----------
cooldown: Cooldown
A class with attributes ``rate``, ``per``, and ``type`` similar to
the :func:`.cooldown` decorator.
retry_after: :class:`float`
The amount of seconds to wait before you can retry again.
"""
def __init__(self, cooldown, retry_after):
self.cooldown = cooldown
self.retry_after = retry_after
super().__init__("You are on cooldown. Try again in {:.2f}s".format(retry_after))
class MissingPermissions(CheckFailure):
"""Exception raised when the command invoker lacks permissions to run
command.
Attributes
-----------
missing_perms: :class:`list`
The required permissions that are missing.
"""
def __init__(self, missing_perms, *args):
self.missing_perms = missing_perms
missing = [
perm.replace("_", " ").replace("guild", "server").title() for perm in missing_perms
]
if len(missing) > 2:
fmt = "{}, and {}".format(", ".join(missing[:-1]), missing[-1])
else:
fmt = " and ".join(missing)
message = "You are missing {} permission(s) to run command.".format(fmt)
super().__init__(message, *args)
class BotMissingPermissions(CheckFailure):
"""Exception raised when the bot lacks permissions to run command.
Attributes
-----------
missing_perms: :class:`list`
The required permissions that are missing.
"""
def __init__(self, missing_perms, *args):
self.missing_perms = missing_perms
missing = [
perm.replace("_", " ").replace("guild", "server").title() for perm in missing_perms
]
if len(missing) > 2:
fmt = "{}, and {}".format(", ".join(missing[:-1]), missing[-1])
else:
fmt = " and ".join(missing)
message = "Bot requires {} permission(s) to run command.".format(fmt)
super().__init__(message, *args)
class BadUnionArgument(UserInputError):
"""Exception raised when a :class:`typing.Union` converter fails for all
its associated types.
Attributes
-----------
param: :class:`inspect.Parameter`
The parameter that failed being converted.
converters: Tuple[Type, ...]
A tuple of converters attempted in conversion, in order of failure.
errors: List[:class:`CommandError`]
A list of errors that were caught from failing the conversion.
"""
def __init__(self, param, converters, errors):
self.param = param
self.converters = converters
self.errors = errors
def _get_name(x):
try:
return x.__name__
except AttributeError:
return x.__class__.__name__
to_string = [_get_name(x) for x in converters]
if len(to_string) > 2:
fmt = "{}, or {}".format(", ".join(to_string[:-1]), to_string[-1])
else:
fmt = " or ".join(to_string)
super().__init__('Could not convert "{0.name}" into {1}.'.format(param, fmt))

View File

@@ -1,365 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import itertools
import inspect
from .core import GroupMixin, Command
from .errors import CommandError
# from discord.iterators import _FilteredAsyncIterator
# help -> shows info of bot on top/bottom and lists subcommands
# help command -> shows detailed info of command
# help command <subcommand chain> -> same as above
# <description>
# <command signature with aliases>
# <long doc>
# Cog:
# <command> <shortdoc>
# <command> <shortdoc>
# Other Cog:
# <command> <shortdoc>
# No Category:
# <command> <shortdoc>
# Type <prefix>help command for more info on a command.
# You can also type <prefix>help category for more info on a category.
class Paginator:
"""A class that aids in paginating code blocks for Discord messages.
Attributes
-----------
prefix: :class:`str`
The prefix inserted to every page. e.g. three backticks.
suffix: :class:`str`
The suffix appended at the end of every page. e.g. three backticks.
max_size: :class:`int`
The maximum amount of codepoints allowed in a page.
"""
def __init__(self, prefix="```", suffix="```", max_size=2000):
self.prefix = prefix
self.suffix = suffix
self.max_size = max_size - len(suffix)
self._current_page = [prefix]
self._count = len(prefix) + 1 # prefix + newline
self._pages = []
def add_line(self, line="", *, empty=False):
"""Adds a line to the current page.
If the line exceeds the :attr:`max_size` then an exception
is raised.
Parameters
-----------
line: str
The line to add.
empty: bool
Indicates if another empty line should be added.
Raises
------
RuntimeError
The line was too big for the current :attr:`max_size`.
"""
if len(line) > self.max_size - len(self.prefix) - 2:
raise RuntimeError(
"Line exceeds maximum page size %s" % (self.max_size - len(self.prefix) - 2)
)
if self._count + len(line) + 1 > self.max_size:
self.close_page()
self._count += len(line) + 1
self._current_page.append(line)
if empty:
self._current_page.append("")
self._count += 1
def close_page(self):
"""Prematurely terminate a page."""
self._current_page.append(self.suffix)
self._pages.append("\n".join(self._current_page))
self._current_page = [self.prefix]
self._count = len(self.prefix) + 1 # prefix + newline
@property
def pages(self):
"""Returns the rendered list of pages."""
# we have more than just the prefix in our current page
if len(self._current_page) > 1:
self.close_page()
return self._pages
def __repr__(self):
fmt = "<Paginator prefix: {0.prefix} suffix: {0.suffix} max_size: {0.max_size} count: {0._count}>"
return fmt.format(self)
class HelpFormatter:
"""The default base implementation that handles formatting of the help
command.
To override the behaviour of the formatter, :meth:`~.HelpFormatter.format`
should be overridden. A number of utility functions are provided for use
inside that method.
Attributes
-----------
show_hidden: :class:`bool`
Dictates if hidden commands should be shown in the output.
Defaults to ``False``.
show_check_failure: :class:`bool`
Dictates if commands that have their :attr:`.Command.checks` failed
shown. Defaults to ``False``.
width: :class:`int`
The maximum number of characters that fit in a line.
Defaults to 80.
"""
def __init__(self, show_hidden=False, show_check_failure=False, width=80):
self.width = width
self.show_hidden = show_hidden
self.show_check_failure = show_check_failure
def has_subcommands(self):
""":class:`bool`: Specifies if the command has subcommands."""
return isinstance(self.command, GroupMixin)
def is_bot(self):
""":class:`bool`: Specifies if the command being formatted is the bot itself."""
return self.command is self.context.bot
def is_cog(self):
""":class:`bool`: Specifies if the command being formatted is actually a cog."""
return not self.is_bot() and not isinstance(self.command, Command)
def shorten(self, text):
"""Shortens text to fit into the :attr:`width`."""
if len(text) > self.width:
return text[: self.width - 3] + "..."
return text
@property
def max_name_size(self):
""":class:`int`: Returns the largest name length of a command or if it has subcommands
the largest subcommand name."""
try:
commands = (
self.command.all_commands if not self.is_cog() else self.context.bot.all_commands
)
if commands:
return max(
map(
lambda c: len(c.name) if self.show_hidden or not c.hidden else 0,
commands.values(),
)
)
return 0
except AttributeError:
return len(self.command.name)
@property
def clean_prefix(self):
"""The cleaned up invoke prefix. i.e. mentions are ``@name`` instead of ``<@id>``."""
user = self.context.guild.me if self.context.guild else self.context.bot.user
# this breaks if the prefix mention is not the bot itself but I
# consider this to be an *incredibly* strange use case. I'd rather go
# for this common use case rather than waste performance for the
# odd one.
return self.context.prefix.replace(user.mention, "@" + user.display_name)
def get_command_signature(self):
"""Retrieves the signature portion of the help page."""
prefix = self.clean_prefix
cmd = self.command
return prefix + cmd.signature
def get_ending_note(self):
command_name = self.context.invoked_with
return (
"Type {0}{1} command for more info on a command.\n"
"You can also type {0}{1} category for more info on a category.".format(
self.clean_prefix, command_name
)
)
async def filter_command_list(self):
"""Returns a filtered list of commands based on the two attributes
provided, :attr:`show_check_failure` and :attr:`show_hidden`.
Also filters based on if :meth:`~.HelpFormatter.is_cog` is valid.
Returns
--------
iterable
An iterable with the filter being applied. The resulting value is
a (key, value) :class:`tuple` of the command name and the command itself.
"""
def sane_no_suspension_point_predicate(tup):
cmd = tup[1]
if self.is_cog():
# filter commands that don't exist to this cog.
if cmd.instance is not self.command:
return False
if cmd.hidden and not self.show_hidden:
return False
return True
async def predicate(tup):
if sane_no_suspension_point_predicate(tup) is False:
return False
cmd = tup[1]
try:
return await cmd.can_run(self.context)
except CommandError:
return False
iterator = (
self.command.all_commands.items()
if not self.is_cog()
else self.context.bot.all_commands.items()
)
if self.show_check_failure:
return filter(sane_no_suspension_point_predicate, iterator)
# Gotta run every check and verify it
ret = []
for elem in iterator:
valid = await predicate(elem)
if valid:
ret.append(elem)
return ret
def _add_subcommands_to_page(self, max_width, commands):
for name, command in commands:
if name in command.aliases:
# skip aliases
continue
entry = " {0:<{width}} {1}".format(name, command.short_doc, width=max_width)
shortened = self.shorten(entry)
self._paginator.add_line(shortened)
async def format_help_for(self, context, command_or_bot):
"""Formats the help page and handles the actual heavy lifting of how
the help command looks like. To change the behaviour, override the
:meth:`~.HelpFormatter.format` method.
Parameters
-----------
context: :class:`.Context`
The context of the invoked help command.
command_or_bot: :class:`.Command` or :class:`.Bot`
The bot or command that we are getting the help of.
Returns
--------
list
A paginated output of the help command.
"""
self.context = context
self.command = command_or_bot
return await self.format()
async def format(self):
"""Handles the actual behaviour involved with formatting.
To change the behaviour, this method should be overridden.
Returns
--------
list
A paginated output of the help command.
"""
self._paginator = Paginator()
# we need a padding of ~80 or so
description = (
self.command.description if not self.is_cog() else inspect.getdoc(self.command)
)
if description:
# <description> portion
self._paginator.add_line(description, empty=True)
if isinstance(self.command, Command):
# <signature portion>
signature = self.get_command_signature()
self._paginator.add_line(signature, empty=True)
# <long doc> section
if self.command.help:
self._paginator.add_line(self.command.help, empty=True)
# end it here if it's just a regular command
if not self.has_subcommands():
self._paginator.close_page()
return self._paginator.pages
max_width = self.max_name_size
def category(tup):
cog = tup[1].cog_name
# we insert the zero width space there to give it approximate
# last place sorting position.
return cog + ":" if cog is not None else "\u200bNo Category:"
filtered = await self.filter_command_list()
if self.is_bot():
data = sorted(filtered, key=category)
for category, commands in itertools.groupby(data, key=category):
# there simply is no prettier way of doing this.
commands = sorted(commands)
if len(commands) > 0:
self._paginator.add_line(category)
self._add_subcommands_to_page(max_width, commands)
else:
filtered = sorted(filtered)
if filtered:
self._paginator.add_line("Commands:")
self._add_subcommands_to_page(max_width, filtered)
# add the ending note
self._paginator.add_line()
ending_note = self.get_ending_note()
self._paginator.add_line(ending_note)
return self._paginator.pages

View File

@@ -1,201 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from .errors import BadArgument
class StringView:
def __init__(self, buffer):
self.index = 0
self.buffer = buffer
self.end = len(buffer)
self.previous = 0
@property
def current(self):
return None if self.eof else self.buffer[self.index]
@property
def eof(self):
return self.index >= self.end
def undo(self):
self.index = self.previous
def skip_ws(self):
pos = 0
while not self.eof:
try:
current = self.buffer[self.index + pos]
if not current.isspace():
break
pos += 1
except IndexError:
break
self.previous = self.index
self.index += pos
return self.previous != self.index
def skip_string(self, string):
strlen = len(string)
if self.buffer[self.index : self.index + strlen] == string:
self.previous = self.index
self.index += strlen
return True
return False
def read_rest(self):
result = self.buffer[self.index :]
self.previous = self.index
self.index = self.end
return result
def read(self, n):
result = self.buffer[self.index : self.index + n]
self.previous = self.index
self.index += n
return result
def get(self):
try:
result = self.buffer[self.index + 1]
except IndexError:
result = None
self.previous = self.index
self.index += 1
return result
def get_word(self):
pos = 0
while not self.eof:
try:
current = self.buffer[self.index + pos]
if current.isspace():
break
pos += 1
except IndexError:
break
self.previous = self.index
result = self.buffer[self.index : self.index + pos]
self.index += pos
return result
def __repr__(self):
return "<StringView pos: {0.index} prev: {0.previous} end: {0.end} eof: {0.eof}>".format(
self
)
# Parser
# map from opening quotes to closing quotes
_quotes = {
'"': '"',
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"": "",
"«": "»",
"": "",
"": "",
"": "",
}
_all_quotes = set(_quotes.keys()) | set(_quotes.values())
def quoted_word(view):
current = view.current
if current is None:
return None
close_quote = _quotes.get(current)
is_quoted = bool(close_quote)
if is_quoted:
result = []
_escaped_quotes = (current, close_quote)
else:
result = [current]
_escaped_quotes = _all_quotes
while not view.eof:
current = view.get()
if not current:
if is_quoted:
# unexpected EOF
raise BadArgument("Expected closing {}.".format(close_quote))
return "".join(result)
# currently we accept strings in the format of "hello world"
# to embed a quote inside the string you must escape it: "a \"world\""
if current == "\\":
next_char = view.get()
if not next_char:
# string ends with \ and no character after it
if is_quoted:
# if we're quoted then we're expecting a closing quote
raise BadArgument("Expected closing {}.".format(close_quote))
# if we aren't then we just let it through
return "".join(result)
if next_char in _escaped_quotes:
# escaped quote
result.append(next_char)
else:
# different escape character, ignore it
view.undo()
result.append(current)
continue
if not is_quoted and current in _all_quotes:
# we aren't quoted
raise BadArgument("Unexpected quote mark in non-quoted string")
# closing quote
if is_quoted and current == close_quote:
next_char = view.get()
valid_eof = not next_char or next_char.isspace()
if not valid_eof:
raise BadArgument("Expected space after closing quotation")
# we're quoted so it's okay
return "".join(result)
if current.isspace() and not is_quoted:
# end of word found
return "".join(result)
result.append(current)

View File

@@ -1,81 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import os.path
class File:
"""A parameter object used for :meth:`abc.Messageable.send`
for sending file objects.
Attributes
-----------
fp: Union[:class:`str`, BinaryIO]
A file-like object opened in binary mode and read mode
or a filename representing a file in the hard drive to
open.
.. note::
If the file-like object passed is opened via ``open`` then the
modes 'rb' should be used.
To pass binary data, consider usage of ``io.BytesIO``.
filename: Optional[:class:`str`]
The filename to display when uploading to Discord.
If this is not given then it defaults to ``fp.name`` or if ``fp`` is
a string then the ``filename`` will default to the string given.
spoiler: :class:`bool`
Whether the attachment is a spoiler.
"""
__slots__ = ("fp", "filename", "_true_fp")
def __init__(self, fp, filename=None, *, spoiler=False):
self.fp = fp
self._true_fp = None
if filename is None:
if isinstance(fp, str):
_, self.filename = os.path.split(fp)
else:
self.filename = getattr(fp, "name", None)
else:
self.filename = filename
if spoiler and not self.filename.startswith("SPOILER_"):
self.filename = "SPOILER_" + self.filename
def open_file(self):
fp = self.fp
if isinstance(fp, str):
self._true_fp = fp = open(fp, "rb")
return fp
def close(self):
if self._true_fp:
self._true_fp.close()

View File

@@ -1,701 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import asyncio
from collections import namedtuple
import json
import logging
import struct
import sys
import time
import threading
import zlib
import websockets
from . import utils
from .activity import _ActivityTag
from .errors import ConnectionClosed, InvalidArgument
log = logging.getLogger(__name__)
__all__ = [
"DiscordWebSocket",
"KeepAliveHandler",
"VoiceKeepAliveHandler",
"DiscordVoiceWebSocket",
"ResumeWebSocket",
]
class ResumeWebSocket(Exception):
"""Signals to initialise via RESUME opcode instead of IDENTIFY."""
def __init__(self, shard_id):
self.shard_id = shard_id
EventListener = namedtuple("EventListener", "predicate event result future")
class KeepAliveHandler(threading.Thread):
def __init__(self, *args, **kwargs):
ws = kwargs.pop("ws", None)
interval = kwargs.pop("interval", None)
shard_id = kwargs.pop("shard_id", None)
threading.Thread.__init__(self, *args, **kwargs)
self.ws = ws
self.interval = interval
self.daemon = True
self.shard_id = shard_id
self.msg = "Keeping websocket alive with sequence %s."
self._stop_ev = threading.Event()
self._last_ack = time.perf_counter()
self._last_send = time.perf_counter()
self.latency = float("inf")
self.heartbeat_timeout = ws._max_heartbeat_timeout
def run(self):
while not self._stop_ev.wait(self.interval):
if self._last_ack + self.heartbeat_timeout < time.perf_counter():
log.warning(
"Shard ID %s has stopped responding to the gateway. Closing and restarting.",
self.shard_id,
)
coro = self.ws.close(4000)
f = asyncio.run_coroutine_threadsafe(coro, loop=self.ws.loop)
try:
f.result()
except Exception:
pass
finally:
self.stop()
return
data = self.get_payload()
log.debug(self.msg, data["d"])
coro = self.ws.send_as_json(data)
f = asyncio.run_coroutine_threadsafe(coro, loop=self.ws.loop)
try:
# block until sending is complete
f.result()
except Exception:
self.stop()
else:
self._last_send = time.perf_counter()
def get_payload(self):
return {"op": self.ws.HEARTBEAT, "d": self.ws.sequence}
def stop(self):
self._stop_ev.set()
def ack(self):
ack_time = time.perf_counter()
self._last_ack = ack_time
self.latency = ack_time - self._last_send
class VoiceKeepAliveHandler(KeepAliveHandler):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.msg = "Keeping voice websocket alive with timestamp %s."
def get_payload(self):
return {"op": self.ws.HEARTBEAT, "d": int(time.time() * 1000)}
class DiscordWebSocket(websockets.client.WebSocketClientProtocol):
"""Implements a WebSocket for Discord's gateway v6.
This is created through :func:`create_main_websocket`. Library
users should never create this manually.
Attributes
-----------
DISPATCH
Receive only. Denotes an event to be sent to Discord, such as READY.
HEARTBEAT
When received tells Discord to keep the connection alive.
When sent asks if your connection is currently alive.
IDENTIFY
Send only. Starts a new session.
PRESENCE
Send only. Updates your presence.
VOICE_STATE
Send only. Starts a new connection to a voice guild.
VOICE_PING
Send only. Checks ping time to a voice guild, do not use.
RESUME
Send only. Resumes an existing connection.
RECONNECT
Receive only. Tells the client to reconnect to a new gateway.
REQUEST_MEMBERS
Send only. Asks for the full member list of a guild.
INVALIDATE_SESSION
Receive only. Tells the client to optionally invalidate the session
and IDENTIFY again.
HELLO
Receive only. Tells the client the heartbeat interval.
HEARTBEAT_ACK
Receive only. Confirms receiving of a heartbeat. Not having it implies
a connection issue.
GUILD_SYNC
Send only. Requests a guild sync.
gateway
The gateway we are currently connected to.
token
The authentication token for discord.
"""
DISPATCH = 0
HEARTBEAT = 1
IDENTIFY = 2
PRESENCE = 3
VOICE_STATE = 4
VOICE_PING = 5
RESUME = 6
RECONNECT = 7
REQUEST_MEMBERS = 8
INVALIDATE_SESSION = 9
HELLO = 10
HEARTBEAT_ACK = 11
GUILD_SYNC = 12
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.max_size = None
# an empty dispatcher to prevent crashes
self._dispatch = lambda *args: None
# generic event listeners
self._dispatch_listeners = []
# the keep alive
self._keep_alive = None
# ws related stuff
self.session_id = None
self.sequence = None
self._zlib = zlib.decompressobj()
self._buffer = bytearray()
@classmethod
async def from_client(
cls, client, *, shard_id=None, session=None, sequence=None, resume=False
):
"""Creates a main websocket for Discord from a :class:`Client`.
This is for internal use only.
"""
gateway = await client.http.get_gateway()
ws = await websockets.connect(gateway, loop=client.loop, klass=cls, compression=None)
# dynamically add attributes needed
ws.token = client.http.token
ws._connection = client._connection
ws._dispatch = client.dispatch
ws.gateway = gateway
ws.shard_id = shard_id
ws.shard_count = client._connection.shard_count
ws.session_id = session
ws.sequence = sequence
ws._max_heartbeat_timeout = client._connection.heartbeat_timeout
client._connection._update_references(ws)
log.info("Created websocket connected to %s", gateway)
# poll event for OP Hello
await ws.poll_event()
if not resume:
await ws.identify()
return ws
await ws.resume()
try:
await ws.ensure_open()
except websockets.exceptions.ConnectionClosed:
# ws got closed so let's just do a regular IDENTIFY connect.
log.info(
"RESUME failed (the websocket decided to close) for Shard ID %s. Retrying.",
shard_id,
)
return await cls.from_client(client, shard_id=shard_id)
else:
return ws
def wait_for(self, event, predicate, result=None):
"""Waits for a DISPATCH'd event that meets the predicate.
Parameters
-----------
event : str
The event name in all upper case to wait for.
predicate
A function that takes a data parameter to check for event
properties. The data parameter is the 'd' key in the JSON message.
result
A function that takes the same data parameter and executes to send
the result to the future. If None, returns the data.
Returns
--------
asyncio.Future
A future to wait for.
"""
future = self.loop.create_future()
entry = EventListener(event=event, predicate=predicate, result=result, future=future)
self._dispatch_listeners.append(entry)
return future
async def identify(self):
"""Sends the IDENTIFY packet."""
payload = {
"op": self.IDENTIFY,
"d": {
"token": self.token,
"properties": {
"$os": sys.platform,
"$browser": "discord.py",
"$device": "discord.py",
"$referrer": "",
"$referring_domain": "",
},
"compress": True,
"large_threshold": 250,
"v": 3,
},
}
if not self._connection.is_bot:
payload["d"]["synced_guilds"] = []
if self.shard_id is not None and self.shard_count is not None:
payload["d"]["shard"] = [self.shard_id, self.shard_count]
state = self._connection
if state._activity is not None or state._status is not None:
payload["d"]["presence"] = {
"status": state._status,
"game": state._activity,
"since": 0,
"afk": False,
}
await self.send_as_json(payload)
log.info("Shard ID %s has sent the IDENTIFY payload.", self.shard_id)
async def resume(self):
"""Sends the RESUME packet."""
payload = {
"op": self.RESUME,
"d": {"seq": self.sequence, "session_id": self.session_id, "token": self.token},
}
await self.send_as_json(payload)
log.info("Shard ID %s has sent the RESUME payload.", self.shard_id)
async def received_message(self, msg):
self._dispatch("socket_raw_receive", msg)
if type(msg) is bytes:
self._buffer.extend(msg)
if len(msg) >= 4:
if msg[-4:] == b"\x00\x00\xff\xff":
msg = self._zlib.decompress(self._buffer)
msg = msg.decode("utf-8")
self._buffer = bytearray()
else:
return
else:
return
msg = json.loads(msg)
log.debug("For Shard ID %s: WebSocket Event: %s", self.shard_id, msg)
self._dispatch("socket_response", msg)
op = msg.get("op")
data = msg.get("d")
seq = msg.get("s")
if seq is not None:
self.sequence = seq
if op != self.DISPATCH:
if op == self.RECONNECT:
# "reconnect" can only be handled by the Client
# so we terminate our connection and raise an
# internal exception signalling to reconnect.
log.info("Received RECONNECT opcode.")
await self.close()
raise ResumeWebSocket(self.shard_id)
if op == self.HEARTBEAT_ACK:
self._keep_alive.ack()
return
if op == self.HEARTBEAT:
beat = self._keep_alive.get_payload()
await self.send_as_json(beat)
return
if op == self.HELLO:
interval = data["heartbeat_interval"] / 1000.0
self._keep_alive = KeepAliveHandler(
ws=self, interval=interval, shard_id=self.shard_id
)
# send a heartbeat immediately
await self.send_as_json(self._keep_alive.get_payload())
self._keep_alive.start()
return
if op == self.INVALIDATE_SESSION:
if data is True:
await asyncio.sleep(5.0, loop=self.loop)
await self.close()
raise ResumeWebSocket(self.shard_id)
self.sequence = None
self.session_id = None
log.info("Shard ID %s session has been invalidated.", self.shard_id)
await self.identify()
return
log.warning("Unknown OP code %s.", op)
return
event = msg.get("t")
if event == "READY":
self._trace = trace = data.get("_trace", [])
self.sequence = msg["s"]
self.session_id = data["session_id"]
log.info(
"Shard ID %s has connected to Gateway: %s (Session ID: %s).",
self.shard_id,
", ".join(trace),
self.session_id,
)
elif event == "RESUMED":
self._trace = trace = data.get("_trace", [])
log.info(
"Shard ID %s has successfully RESUMED session %s under trace %s.",
self.shard_id,
self.session_id,
", ".join(trace),
)
parser = "parse_" + event.lower()
try:
func = getattr(self._connection, parser)
except AttributeError:
log.warning("Unknown event %s.", event)
else:
func(data)
# remove the dispatched listeners
removed = []
for index, entry in enumerate(self._dispatch_listeners):
if entry.event != event:
continue
future = entry.future
if future.cancelled():
removed.append(index)
continue
try:
valid = entry.predicate(data)
except Exception as exc:
future.set_exception(exc)
removed.append(index)
else:
if valid:
ret = data if entry.result is None else entry.result(data)
future.set_result(ret)
removed.append(index)
for index in reversed(removed):
del self._dispatch_listeners[index]
@property
def latency(self):
""":obj:`float`: Measures latency between a HEARTBEAT and a HEARTBEAT_ACK in seconds."""
heartbeat = self._keep_alive
return float("inf") if heartbeat is None else heartbeat.latency
def _can_handle_close(self, code):
return code not in (1000, 4004, 4010, 4011)
async def poll_event(self):
"""Polls for a DISPATCH event and handles the general gateway loop.
Raises
------
ConnectionClosed
The websocket connection was terminated for unhandled reasons.
"""
try:
msg = await self.recv()
await self.received_message(msg)
except websockets.exceptions.ConnectionClosed as exc:
if self._can_handle_close(exc.code):
log.info(
"Websocket closed with %s (%s), attempting a reconnect.", exc.code, exc.reason
)
raise ResumeWebSocket(self.shard_id) from exc
else:
log.info("Websocket closed with %s (%s), cannot reconnect.", exc.code, exc.reason)
raise ConnectionClosed(exc, shard_id=self.shard_id) from exc
async def send(self, data):
self._dispatch("socket_raw_send", data)
await super().send(data)
async def send_as_json(self, data):
try:
await super().send(utils.to_json(data))
except websockets.exceptions.ConnectionClosed as exc:
if not self._can_handle_close(exc.code):
raise ConnectionClosed(exc, shard_id=self.shard_id) from exc
async def change_presence(self, *, activity=None, status=None, afk=False, since=0.0):
if activity is not None:
if not isinstance(activity, _ActivityTag):
raise InvalidArgument("activity must be one of Game, Streaming, or Activity.")
activity = activity.to_dict()
if status == "idle":
since = int(time.time() * 1000)
payload = {
"op": self.PRESENCE,
"d": {"game": activity, "afk": afk, "since": since, "status": status},
}
sent = utils.to_json(payload)
log.debug('Sending "%s" to change status', sent)
await self.send(sent)
async def request_sync(self, guild_ids):
payload = {"op": self.GUILD_SYNC, "d": list(guild_ids)}
await self.send_as_json(payload)
async def voice_state(self, guild_id, channel_id, self_mute=False, self_deaf=False):
payload = {
"op": self.VOICE_STATE,
"d": {
"guild_id": guild_id,
"channel_id": channel_id,
"self_mute": self_mute,
"self_deaf": self_deaf,
},
}
log.debug("Updating our voice state to %s.", payload)
await self.send_as_json(payload)
async def close(self, code=1000, reason=""):
if self._keep_alive:
self._keep_alive.stop()
await super().close(code, reason)
async def close_connection(self, *args, **kwargs):
if self._keep_alive:
self._keep_alive.stop()
await super().close_connection(*args, **kwargs)
class DiscordVoiceWebSocket(websockets.client.WebSocketClientProtocol):
"""Implements the websocket protocol for handling voice connections.
Attributes
-----------
IDENTIFY
Send only. Starts a new voice session.
SELECT_PROTOCOL
Send only. Tells discord what encryption mode and how to connect for voice.
READY
Receive only. Tells the websocket that the initial connection has completed.
HEARTBEAT
Send only. Keeps your websocket connection alive.
SESSION_DESCRIPTION
Receive only. Gives you the secret key required for voice.
SPEAKING
Send only. Notifies the client if you are currently speaking.
HEARTBEAT_ACK
Receive only. Tells you your heartbeat has been acknowledged.
RESUME
Sent only. Tells the client to resume its session.
HELLO
Receive only. Tells you that your websocket connection was acknowledged.
INVALIDATE_SESSION
Sent only. Tells you that your RESUME request has failed and to re-IDENTIFY.
"""
IDENTIFY = 0
SELECT_PROTOCOL = 1
READY = 2
HEARTBEAT = 3
SESSION_DESCRIPTION = 4
SPEAKING = 5
HEARTBEAT_ACK = 6
RESUME = 7
HELLO = 8
INVALIDATE_SESSION = 9
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.max_size = None
self._keep_alive = None
async def send_as_json(self, data):
log.debug("Sending voice websocket frame: %s.", data)
await self.send(utils.to_json(data))
async def resume(self):
state = self._connection
payload = {
"op": self.RESUME,
"d": {
"token": state.token,
"server_id": str(state.server_id),
"session_id": state.session_id,
},
}
await self.send_as_json(payload)
async def identify(self):
state = self._connection
payload = {
"op": self.IDENTIFY,
"d": {
"server_id": str(state.server_id),
"user_id": str(state.user.id),
"session_id": state.session_id,
"token": state.token,
},
}
await self.send_as_json(payload)
@classmethod
async def from_client(cls, client, *, resume=False):
"""Creates a voice websocket for the :class:`VoiceClient`."""
gateway = "wss://" + client.endpoint + "/?v=3"
ws = await websockets.connect(gateway, loop=client.loop, klass=cls, compression=None)
ws.gateway = gateway
ws._connection = client
ws._max_heartbeat_timeout = 60.0
if resume:
await ws.resume()
else:
await ws.identify()
return ws
async def select_protocol(self, ip, port):
payload = {
"op": self.SELECT_PROTOCOL,
"d": {
"protocol": "udp",
"data": {"address": ip, "port": port, "mode": "xsalsa20_poly1305"},
},
}
await self.send_as_json(payload)
async def speak(self, is_speaking=True):
payload = {"op": self.SPEAKING, "d": {"speaking": is_speaking, "delay": 0}}
await self.send_as_json(payload)
async def received_message(self, msg):
log.debug("Voice websocket frame received: %s", msg)
op = msg["op"]
data = msg.get("d")
if op == self.READY:
interval = data["heartbeat_interval"] / 1000.0
self._keep_alive = VoiceKeepAliveHandler(ws=self, interval=interval)
self._keep_alive.start()
await self.initial_connection(data)
elif op == self.HEARTBEAT_ACK:
self._keep_alive.ack()
elif op == self.INVALIDATE_SESSION:
log.info("Voice RESUME failed.")
await self.identify()
elif op == self.SESSION_DESCRIPTION:
await self.load_secret_key(data)
async def initial_connection(self, data):
state = self._connection
state.ssrc = data["ssrc"]
state.voice_port = data["port"]
packet = bytearray(70)
struct.pack_into(">I", packet, 0, state.ssrc)
state.socket.sendto(packet, (state.endpoint_ip, state.voice_port))
recv = await self.loop.sock_recv(state.socket, 70)
log.debug("received packet in initial_connection: %s", recv)
# the ip is ascii starting at the 4th byte and ending at the first null
ip_start = 4
ip_end = recv.index(0, ip_start)
state.ip = recv[ip_start:ip_end].decode("ascii")
# the port is a little endian unsigned short in the last two bytes
# yes, this is different endianness from everything else
state.port = struct.unpack_from("<H", recv, len(recv) - 2)[0]
log.debug("detected ip: %s port: %s", state.ip, state.port)
await self.select_protocol(state.ip, state.port)
log.info("selected the voice protocol for use")
async def load_secret_key(self, data):
log.info("received secret key for voice connection")
self._connection.secret_key = data.get("secret_key")
await self.speak()
async def poll_event(self):
try:
msg = await asyncio.wait_for(self.recv(), timeout=30.0, loop=self.loop)
await self.received_message(json.loads(msg))
except websockets.exceptions.ConnectionClosed as exc:
raise ConnectionClosed(exc, shard_id=None) from exc
async def close_connection(self, *args, **kwargs):
if self._keep_alive:
self._keep_alive.stop()
await super().close_connection(*args, **kwargs)

File diff suppressed because it is too large Load Diff

View File

@@ -1,911 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import asyncio
import json
import logging
import sys
from urllib.parse import quote as _uriquote
import weakref
import aiohttp
from .errors import HTTPException, Forbidden, NotFound, LoginFailure, GatewayNotFound
from . import __version__, utils
log = logging.getLogger(__name__)
async def json_or_text(response):
text = await response.text(encoding="utf-8")
if response.headers["content-type"] == "application/json":
return json.loads(text)
return text
class Route:
BASE = "https://discordapp.com/api/v7"
def __init__(self, method, path, **parameters):
self.path = path
self.method = method
url = self.BASE + self.path
if parameters:
self.url = url.format(
**{k: _uriquote(v) if isinstance(v, str) else v for k, v in parameters.items()}
)
else:
self.url = url
# major parameters:
self.channel_id = parameters.get("channel_id")
self.guild_id = parameters.get("guild_id")
@property
def bucket(self):
# the bucket is just method + path w/ major parameters
return "{0.method}:{0.channel_id}:{0.guild_id}:{0.path}".format(self)
class MaybeUnlock:
def __init__(self, lock):
self.lock = lock
self._unlock = True
def __enter__(self):
return self
def defer(self):
self._unlock = False
def __exit__(self, type, value, traceback):
if self._unlock:
self.lock.release()
class HTTPClient:
"""Represents an HTTP client sending HTTP requests to the Discord API."""
SUCCESS_LOG = "{method} {url} has received {text}"
REQUEST_LOG = "{method} {url} with {json} has returned {status}"
def __init__(self, connector=None, *, proxy=None, proxy_auth=None, loop=None):
self.loop = asyncio.get_event_loop() if loop is None else loop
self.connector = connector
self._session = aiohttp.ClientSession(connector=connector, loop=self.loop)
self._locks = weakref.WeakValueDictionary()
self._global_over = asyncio.Event(loop=self.loop)
self._global_over.set()
self.token = None
self.bot_token = False
self.proxy = proxy
self.proxy_auth = proxy_auth
user_agent = "DiscordBot (https://github.com/Rapptz/discord.py {0}) Python/{1[0]}.{1[1]} aiohttp/{2}"
self.user_agent = user_agent.format(__version__, sys.version_info, aiohttp.__version__)
def recreate(self):
if self._session.closed:
self._session = aiohttp.ClientSession(connector=self.connector, loop=self.loop)
async def request(self, route, *, header_bypass_delay=None, **kwargs):
bucket = route.bucket
method = route.method
url = route.url
lock = self._locks.get(bucket)
if lock is None:
lock = asyncio.Lock(loop=self.loop)
if bucket is not None:
self._locks[bucket] = lock
# header creation
headers = {"User-Agent": self.user_agent}
if self.token is not None:
headers["Authorization"] = "Bot " + self.token if self.bot_token else self.token
# some checking if it's a JSON request
if "json" in kwargs:
headers["Content-Type"] = "application/json"
kwargs["data"] = utils.to_json(kwargs.pop("json"))
try:
reason = kwargs.pop("reason")
except KeyError:
pass
else:
if reason:
headers["X-Audit-Log-Reason"] = _uriquote(reason, safe="/ ")
kwargs["headers"] = headers
# Proxy support
if self.proxy is not None:
kwargs["proxy"] = self.proxy
if self.proxy_auth is not None:
kwargs["proxy_auth"] = self.proxy_auth
if not self._global_over.is_set():
# wait until the global lock is complete
await self._global_over.wait()
await lock
with MaybeUnlock(lock) as maybe_lock:
for tries in range(5):
async with self._session.request(method, url, **kwargs) as r:
log.debug(
"%s %s with %s has returned %s", method, url, kwargs.get("data"), r.status
)
# even errors have text involved in them so this is safe to call
data = await json_or_text(r)
# check if we have rate limit header information
remaining = r.headers.get("X-Ratelimit-Remaining")
if remaining == "0" and r.status != 429:
# we've depleted our current bucket
if header_bypass_delay is None:
delta = utils._parse_ratelimit_header(r)
else:
delta = header_bypass_delay
log.debug(
"A rate limit bucket has been exhausted (bucket: %s, retry: %s).",
bucket,
delta,
)
maybe_lock.defer()
self.loop.call_later(delta, lock.release)
# the request was successful so just return the text/json
if 300 > r.status >= 200:
log.debug("%s %s has received %s", method, url, data)
return data
# we are being rate limited
if r.status == 429:
fmt = 'We are being rate limited. Retrying in %.2f seconds. Handled under the bucket "%s"'
# sleep a bit
retry_after = data["retry_after"] / 1000.0
log.warning(fmt, retry_after, bucket)
# check if it's a global rate limit
is_global = data.get("global", False)
if is_global:
log.warning(
"Global rate limit has been hit. Retrying in %.2f seconds.",
retry_after,
)
self._global_over.clear()
await asyncio.sleep(retry_after, loop=self.loop)
log.debug("Done sleeping for the rate limit. Retrying...")
# release the global lock now that the
# global rate limit has passed
if is_global:
self._global_over.set()
log.debug("Global rate limit is now over.")
continue
# we've received a 500 or 502, unconditional retry
if r.status in {500, 502}:
await asyncio.sleep(1 + tries * 2, loop=self.loop)
continue
# the usual error cases
if r.status == 403:
raise Forbidden(r, data)
elif r.status == 404:
raise NotFound(r, data)
else:
raise HTTPException(r, data)
# We've run out of retries, raise.
raise HTTPException(r, data)
async def get_attachment(self, url):
async with self._session.get(url) as resp:
if resp.status == 200:
return await resp.read()
elif resp.status == 404:
raise NotFound(resp, "attachment not found")
elif resp.status == 403:
raise Forbidden(resp, "cannot retrieve attachment")
else:
raise HTTPException(resp, "failed to get attachment")
# state management
async def close(self):
await self._session.close()
def _token(self, token, *, bot=True):
self.token = token
self.bot_token = bot
self._ack_token = None
# login management
async def static_login(self, token, *, bot):
old_token, old_bot = self.token, self.bot_token
self._token(token, bot=bot)
try:
data = await self.request(Route("GET", "/users/@me"))
except HTTPException as exc:
self._token(old_token, bot=old_bot)
if exc.response.status == 401:
raise LoginFailure("Improper token has been passed.") from exc
raise
return data
def logout(self):
return self.request(Route("POST", "/auth/logout"))
# Group functionality
def start_group(self, user_id, recipients):
payload = {"recipients": recipients}
return self.request(
Route("POST", "/users/{user_id}/channels", user_id=user_id), json=payload
)
def leave_group(self, channel_id):
return self.request(Route("DELETE", "/channels/{channel_id}", channel_id=channel_id))
def add_group_recipient(self, channel_id, user_id):
r = Route(
"PUT",
"/channels/{channel_id}/recipients/{user_id}",
channel_id=channel_id,
user_id=user_id,
)
return self.request(r)
def remove_group_recipient(self, channel_id, user_id):
r = Route(
"DELETE",
"/channels/{channel_id}/recipients/{user_id}",
channel_id=channel_id,
user_id=user_id,
)
return self.request(r)
def edit_group(self, channel_id, **options):
valid_keys = ("name", "icon")
payload = {k: v for k, v in options.items() if k in valid_keys}
return self.request(
Route("PATCH", "/channels/{channel_id}", channel_id=channel_id), json=payload
)
def convert_group(self, channel_id):
return self.request(Route("POST", "/channels/{channel_id}/convert", channel_id=channel_id))
# Message management
def start_private_message(self, user_id):
payload = {"recipient_id": user_id}
return self.request(Route("POST", "/users/@me/channels"), json=payload)
def send_message(self, channel_id, content, *, tts=False, embed=None, nonce=None):
r = Route("POST", "/channels/{channel_id}/messages", channel_id=channel_id)
payload = {}
if content:
payload["content"] = content
if tts:
payload["tts"] = True
if embed:
payload["embed"] = embed
if nonce:
payload["nonce"] = nonce
return self.request(r, json=payload)
def send_typing(self, channel_id):
return self.request(Route("POST", "/channels/{channel_id}/typing", channel_id=channel_id))
def send_files(self, channel_id, *, files, content=None, tts=False, embed=None, nonce=None):
r = Route("POST", "/channels/{channel_id}/messages", channel_id=channel_id)
form = aiohttp.FormData()
payload = {"tts": tts}
if content:
payload["content"] = content
if embed:
payload["embed"] = embed
if nonce:
payload["nonce"] = nonce
form.add_field("payload_json", utils.to_json(payload))
if len(files) == 1:
fp = files[0]
form.add_field("file", fp[0], filename=fp[1], content_type="application/octet-stream")
else:
for index, (buffer, filename) in enumerate(files):
form.add_field(
"file%s" % index,
buffer,
filename=filename,
content_type="application/octet-stream",
)
return self.request(r, data=form)
async def ack_message(self, channel_id, message_id):
r = Route(
"POST",
"/channels/{channel_id}/messages/{message_id}/ack",
channel_id=channel_id,
message_id=message_id,
)
data = await self.request(r, json={"token": self._ack_token})
self._ack_token = data["token"]
def ack_guild(self, guild_id):
return self.request(Route("POST", "/guilds/{guild_id}/ack", guild_id=guild_id))
def delete_message(self, channel_id, message_id, *, reason=None):
r = Route(
"DELETE",
"/channels/{channel_id}/messages/{message_id}",
channel_id=channel_id,
message_id=message_id,
)
return self.request(r, reason=reason)
def delete_messages(self, channel_id, message_ids, *, reason=None):
r = Route("POST", "/channels/{channel_id}/messages/bulk_delete", channel_id=channel_id)
payload = {"messages": message_ids}
return self.request(r, json=payload, reason=reason)
def edit_message(self, message_id, channel_id, **fields):
r = Route(
"PATCH",
"/channels/{channel_id}/messages/{message_id}",
channel_id=channel_id,
message_id=message_id,
)
return self.request(r, json=fields)
def add_reaction(self, message_id, channel_id, emoji):
r = Route(
"PUT",
"/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me",
channel_id=channel_id,
message_id=message_id,
emoji=emoji,
)
return self.request(r, header_bypass_delay=0.25)
def remove_reaction(self, message_id, channel_id, emoji, member_id):
r = Route(
"DELETE",
"/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/{member_id}",
channel_id=channel_id,
message_id=message_id,
member_id=member_id,
emoji=emoji,
)
return self.request(r, header_bypass_delay=0.25)
def remove_own_reaction(self, message_id, channel_id, emoji):
r = Route(
"DELETE",
"/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me",
channel_id=channel_id,
message_id=message_id,
emoji=emoji,
)
return self.request(r, header_bypass_delay=0.25)
def get_reaction_users(self, message_id, channel_id, emoji, limit, after=None):
r = Route(
"GET",
"/channels/{channel_id}/messages/{message_id}/reactions/{emoji}",
channel_id=channel_id,
message_id=message_id,
emoji=emoji,
)
params = {"limit": limit}
if after:
params["after"] = after
return self.request(r, params=params)
def clear_reactions(self, message_id, channel_id):
r = Route(
"DELETE",
"/channels/{channel_id}/messages/{message_id}/reactions",
channel_id=channel_id,
message_id=message_id,
)
return self.request(r)
def get_message(self, channel_id, message_id):
r = Route(
"GET",
"/channels/{channel_id}/messages/{message_id}",
channel_id=channel_id,
message_id=message_id,
)
return self.request(r)
def logs_from(self, channel_id, limit, before=None, after=None, around=None):
params = {"limit": limit}
if before:
params["before"] = before
if after:
params["after"] = after
if around:
params["around"] = around
return self.request(
Route("GET", "/channels/{channel_id}/messages", channel_id=channel_id), params=params
)
def pin_message(self, channel_id, message_id):
return self.request(
Route(
"PUT",
"/channels/{channel_id}/pins/{message_id}",
channel_id=channel_id,
message_id=message_id,
)
)
def unpin_message(self, channel_id, message_id):
return self.request(
Route(
"DELETE",
"/channels/{channel_id}/pins/{message_id}",
channel_id=channel_id,
message_id=message_id,
)
)
def pins_from(self, channel_id):
return self.request(Route("GET", "/channels/{channel_id}/pins", channel_id=channel_id))
# Member management
def kick(self, user_id, guild_id, reason=None):
r = Route(
"DELETE", "/guilds/{guild_id}/members/{user_id}", guild_id=guild_id, user_id=user_id
)
if reason:
# thanks aiohttp
r.url = "{0.url}?reason={1}".format(r, _uriquote(reason))
return self.request(r)
def ban(self, user_id, guild_id, delete_message_days=1, reason=None):
r = Route("PUT", "/guilds/{guild_id}/bans/{user_id}", guild_id=guild_id, user_id=user_id)
params = {"delete-message-days": delete_message_days}
if reason:
# thanks aiohttp
r.url = "{0.url}?reason={1}".format(r, _uriquote(reason))
return self.request(r, params=params)
def unban(self, user_id, guild_id, *, reason=None):
r = Route(
"DELETE", "/guilds/{guild_id}/bans/{user_id}", guild_id=guild_id, user_id=user_id
)
return self.request(r, reason=reason)
def guild_voice_state(self, user_id, guild_id, *, mute=None, deafen=None, reason=None):
r = Route(
"PATCH", "/guilds/{guild_id}/members/{user_id}", guild_id=guild_id, user_id=user_id
)
payload = {}
if mute is not None:
payload["mute"] = mute
if deafen is not None:
payload["deaf"] = deafen
return self.request(r, json=payload, reason=reason)
def edit_profile(self, password, username, avatar, **fields):
payload = {"password": password, "username": username, "avatar": avatar}
if "email" in fields:
payload["email"] = fields["email"]
if "new_password" in fields:
payload["new_password"] = fields["new_password"]
return self.request(Route("PATCH", "/users/@me"), json=payload)
def change_my_nickname(self, guild_id, nickname, *, reason=None):
r = Route("PATCH", "/guilds/{guild_id}/members/@me/nick", guild_id=guild_id)
payload = {"nick": nickname}
return self.request(r, json=payload, reason=reason)
def change_nickname(self, guild_id, user_id, nickname, *, reason=None):
r = Route(
"PATCH", "/guilds/{guild_id}/members/{user_id}", guild_id=guild_id, user_id=user_id
)
payload = {"nick": nickname}
return self.request(r, json=payload, reason=reason)
def edit_member(self, guild_id, user_id, *, reason=None, **fields):
r = Route(
"PATCH", "/guilds/{guild_id}/members/{user_id}", guild_id=guild_id, user_id=user_id
)
return self.request(r, json=fields, reason=reason)
# Channel management
def edit_channel(self, channel_id, *, reason=None, **options):
r = Route("PATCH", "/channels/{channel_id}", channel_id=channel_id)
valid_keys = (
"name",
"parent_id",
"topic",
"bitrate",
"nsfw",
"user_limit",
"position",
"permission_overwrites",
"rate_limit_per_user",
)
payload = {k: v for k, v in options.items() if k in valid_keys}
return self.request(r, reason=reason, json=payload)
def bulk_channel_update(self, guild_id, data, *, reason=None):
r = Route("PATCH", "/guilds/{guild_id}/channels", guild_id=guild_id)
return self.request(r, json=data, reason=reason)
def create_channel(
self,
guild_id,
name,
channel_type,
parent_id=None,
permission_overwrites=None,
*,
reason=None
):
payload = {"name": name, "type": channel_type}
if permission_overwrites is not None:
payload["permission_overwrites"] = permission_overwrites
if parent_id is not None:
payload["parent_id"] = parent_id
return self.request(
Route("POST", "/guilds/{guild_id}/channels", guild_id=guild_id),
json=payload,
reason=reason,
)
def delete_channel(self, channel_id, *, reason=None):
return self.request(
Route("DELETE", "/channels/{channel_id}", channel_id=channel_id), reason=reason
)
# Webhook management
def create_webhook(self, channel_id, *, name, avatar=None):
payload = {"name": name}
if avatar is not None:
payload["avatar"] = avatar
return self.request(
Route("POST", "/channels/{channel_id}/webhooks", channel_id=channel_id), json=payload
)
def channel_webhooks(self, channel_id):
return self.request(Route("GET", "/channels/{channel_id}/webhooks", channel_id=channel_id))
def guild_webhooks(self, guild_id):
return self.request(Route("GET", "/guilds/{guild_id}/webhooks", guild_id=guild_id))
def get_webhook(self, webhook_id):
return self.request(Route("GET", "/webhooks/{webhook_id}", webhook_id=webhook_id))
# Guild management
def leave_guild(self, guild_id):
return self.request(Route("DELETE", "/users/@me/guilds/{guild_id}", guild_id=guild_id))
def delete_guild(self, guild_id):
return self.request(Route("DELETE", "/guilds/{guild_id}", guild_id=guild_id))
def create_guild(self, name, region, icon):
payload = {"name": name, "icon": icon, "region": region}
return self.request(Route("POST", "/guilds"), json=payload)
def edit_guild(self, guild_id, *, reason=None, **fields):
valid_keys = (
"name",
"region",
"icon",
"afk_timeout",
"owner_id",
"afk_channel_id",
"splash",
"verification_level",
"system_channel_id",
"default_message_notifications",
"explicit_content_filter",
)
payload = {k: v for k, v in fields.items() if k in valid_keys}
return self.request(
Route("PATCH", "/guilds/{guild_id}", guild_id=guild_id), json=payload, reason=reason
)
def get_bans(self, guild_id):
return self.request(Route("GET", "/guilds/{guild_id}/bans", guild_id=guild_id))
def get_ban(self, user_id, guild_id):
return self.request(
Route("GET", "/guilds/{guild_id}/bans/{user_id}", guild_id=guild_id, user_id=user_id)
)
def get_vanity_code(self, guild_id):
return self.request(Route("GET", "/guilds/{guild_id}/vanity-url", guild_id=guild_id))
def change_vanity_code(self, guild_id, code, *, reason=None):
payload = {"code": code}
return self.request(
Route("PATCH", "/guilds/{guild_id}/vanity-url", guild_id=guild_id),
json=payload,
reason=reason,
)
def prune_members(self, guild_id, days, *, reason=None):
params = {"days": days}
return self.request(
Route("POST", "/guilds/{guild_id}/prune", guild_id=guild_id),
params=params,
reason=reason,
)
def estimate_pruned_members(self, guild_id, days):
params = {"days": days}
return self.request(
Route("GET", "/guilds/{guild_id}/prune", guild_id=guild_id), params=params
)
def create_custom_emoji(self, guild_id, name, image, *, roles=None, reason=None):
payload = {"name": name, "image": image, "roles": roles or []}
r = Route("POST", "/guilds/{guild_id}/emojis", guild_id=guild_id)
return self.request(r, json=payload, reason=reason)
def delete_custom_emoji(self, guild_id, emoji_id, *, reason=None):
r = Route(
"DELETE", "/guilds/{guild_id}/emojis/{emoji_id}", guild_id=guild_id, emoji_id=emoji_id
)
return self.request(r, reason=reason)
def edit_custom_emoji(self, guild_id, emoji_id, *, name, roles=None, reason=None):
payload = {"name": name, "roles": roles or []}
r = Route(
"PATCH", "/guilds/{guild_id}/emojis/{emoji_id}", guild_id=guild_id, emoji_id=emoji_id
)
return self.request(r, json=payload, reason=reason)
def get_audit_logs(
self, guild_id, limit=100, before=None, after=None, user_id=None, action_type=None
):
params = {"limit": limit}
if before:
params["before"] = before
if after:
params["after"] = after
if user_id:
params["user_id"] = user_id
if action_type:
params["action_type"] = action_type
r = Route("GET", "/guilds/{guild_id}/audit-logs", guild_id=guild_id)
return self.request(r, params=params)
# Invite management
def create_invite(self, channel_id, *, reason=None, **options):
r = Route("POST", "/channels/{channel_id}/invites", channel_id=channel_id)
payload = {
"max_age": options.get("max_age", 0),
"max_uses": options.get("max_uses", 0),
"temporary": options.get("temporary", False),
"unique": options.get("unique", True),
}
return self.request(r, reason=reason, json=payload)
def get_invite(self, invite_id):
return self.request(Route("GET", "/invite/{invite_id}", invite_id=invite_id))
def invites_from(self, guild_id):
return self.request(Route("GET", "/guilds/{guild_id}/invites", guild_id=guild_id))
def invites_from_channel(self, channel_id):
return self.request(Route("GET", "/channels/{channel_id}/invites", channel_id=channel_id))
def delete_invite(self, invite_id, *, reason=None):
return self.request(
Route("DELETE", "/invite/{invite_id}", invite_id=invite_id), reason=reason
)
# Role management
def edit_role(self, guild_id, role_id, *, reason=None, **fields):
r = Route(
"PATCH", "/guilds/{guild_id}/roles/{role_id}", guild_id=guild_id, role_id=role_id
)
valid_keys = ("name", "permissions", "color", "hoist", "mentionable")
payload = {k: v for k, v in fields.items() if k in valid_keys}
return self.request(r, json=payload, reason=reason)
def delete_role(self, guild_id, role_id, *, reason=None):
r = Route(
"DELETE", "/guilds/{guild_id}/roles/{role_id}", guild_id=guild_id, role_id=role_id
)
return self.request(r, reason=reason)
def replace_roles(self, user_id, guild_id, role_ids, *, reason=None):
return self.edit_member(guild_id=guild_id, user_id=user_id, roles=role_ids, reason=reason)
def create_role(self, guild_id, *, reason=None, **fields):
r = Route("POST", "/guilds/{guild_id}/roles", guild_id=guild_id)
return self.request(r, json=fields, reason=reason)
def move_role_position(self, guild_id, positions, *, reason=None):
r = Route("PATCH", "/guilds/{guild_id}/roles", guild_id=guild_id)
return self.request(r, json=positions, reason=reason)
def add_role(self, guild_id, user_id, role_id, *, reason=None):
r = Route(
"PUT",
"/guilds/{guild_id}/members/{user_id}/roles/{role_id}",
guild_id=guild_id,
user_id=user_id,
role_id=role_id,
)
return self.request(r, reason=reason)
def remove_role(self, guild_id, user_id, role_id, *, reason=None):
r = Route(
"DELETE",
"/guilds/{guild_id}/members/{user_id}/roles/{role_id}",
guild_id=guild_id,
user_id=user_id,
role_id=role_id,
)
return self.request(r, reason=reason)
def edit_channel_permissions(self, channel_id, target, allow, deny, type, *, reason=None):
payload = {"id": target, "allow": allow, "deny": deny, "type": type}
r = Route(
"PUT",
"/channels/{channel_id}/permissions/{target}",
channel_id=channel_id,
target=target,
)
return self.request(r, json=payload, reason=reason)
def delete_channel_permissions(self, channel_id, target, *, reason=None):
r = Route(
"DELETE",
"/channels/{channel_id}/permissions/{target}",
channel_id=channel_id,
target=target,
)
return self.request(r, reason=reason)
# Voice management
def move_member(self, user_id, guild_id, channel_id, *, reason=None):
return self.edit_member(
guild_id=guild_id, user_id=user_id, channel_id=channel_id, reason=reason
)
# Relationship related
def remove_relationship(self, user_id):
r = Route("DELETE", "/users/@me/relationships/{user_id}", user_id=user_id)
return self.request(r)
def add_relationship(self, user_id, type=None):
r = Route("PUT", "/users/@me/relationships/{user_id}", user_id=user_id)
payload = {}
if type is not None:
payload["type"] = type
return self.request(r, json=payload)
def send_friend_request(self, username, discriminator):
r = Route("POST", "/users/@me/relationships")
payload = {"username": username, "discriminator": int(discriminator)}
return self.request(r, json=payload)
# Misc
def application_info(self):
return self.request(Route("GET", "/oauth2/applications/@me"))
async def get_gateway(self, *, encoding="json", v=6, zlib=True):
try:
data = await self.request(Route("GET", "/gateway"))
except HTTPException as exc:
raise GatewayNotFound() from exc
if zlib:
value = "{0}?encoding={1}&v={2}&compress=zlib-stream"
else:
value = "{0}?encoding={1}&v={2}"
return value.format(data["url"], encoding, v)
async def get_bot_gateway(self, *, encoding="json", v=6, zlib=True):
try:
data = await self.request(Route("GET", "/gateway/bot"))
except HTTPException as exc:
raise GatewayNotFound() from exc
if zlib:
value = "{0}?encoding={1}&v={2}&compress=zlib-stream"
else:
value = "{0}?encoding={1}&v={2}"
return data["shards"], value.format(data["url"], encoding, v)
def get_user_info(self, user_id):
return self.request(Route("GET", "/users/{user_id}", user_id=user_id))
def get_user_profile(self, user_id):
return self.request(Route("GET", "/users/{user_id}/profile", user_id=user_id))
def get_mutual_friends(self, user_id):
return self.request(Route("GET", "/users/{user_id}/relationships", user_id=user_id))
def change_hypesquad_house(self, house_id):
payload = {"house_id": house_id}
return self.request(Route("POST", "/hypesquad/online"), json=payload)
def leave_hypesquad_house(self):
return self.request(Route("DELETE", "/hypesquad/online"))

View File

@@ -1,176 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from .utils import parse_time
from .mixins import Hashable
from .object import Object
class Invite(Hashable):
"""Represents a Discord :class:`Guild` or :class:`abc.GuildChannel` invite.
Depending on the way this object was created, some of the attributes can
have a value of ``None``.
.. container:: operations
.. describe:: x == y
Checks if two invites are equal.
.. describe:: x != y
Checks if two invites are not equal.
.. describe:: hash(x)
Returns the invite hash.
.. describe:: str(x)
Returns the invite URL.
Attributes
-----------
max_age: :class:`int`
How long the before the invite expires in seconds. A value of 0 indicates that it doesn't expire.
code: :class:`str`
The URL fragment used for the invite.
guild: :class:`Guild`
The guild the invite is for.
revoked: :class:`bool`
Indicates if the invite has been revoked.
created_at: `datetime.datetime`
A datetime object denoting the time the invite was created.
temporary: :class:`bool`
Indicates that the invite grants temporary membership.
If True, members who joined via this invite will be kicked upon disconnect.
uses: :class:`int`
How many times the invite has been used.
max_uses: :class:`int`
How many times the invite can be used.
inviter: :class:`User`
The user who created the invite.
channel: :class:`abc.GuildChannel`
The channel the invite is for.
"""
__slots__ = (
"max_age",
"code",
"guild",
"revoked",
"created_at",
"uses",
"temporary",
"max_uses",
"inviter",
"channel",
"_state",
)
def __init__(self, *, state, data):
self._state = state
self.max_age = data.get("max_age")
self.code = data.get("code")
self.guild = data.get("guild")
self.revoked = data.get("revoked")
self.created_at = parse_time(data.get("created_at"))
self.temporary = data.get("temporary")
self.uses = data.get("uses")
self.max_uses = data.get("max_uses")
inviter_data = data.get("inviter")
self.inviter = None if inviter_data is None else self._state.store_user(inviter_data)
self.channel = data.get("channel")
@classmethod
def from_incomplete(cls, *, state, data):
guild_id = int(data["guild"]["id"])
channel_id = int(data["channel"]["id"])
guild = state._get_guild(guild_id)
if guild is not None:
channel = guild.get_channel(channel_id)
else:
guild = Object(id=guild_id)
channel = Object(id=channel_id)
guild.name = data["guild"]["name"]
guild.splash = data["guild"]["splash"]
guild.splash_url = ""
if guild.splash:
guild.splash_url = "https://cdn.discordapp.com/splashes/{0.id}/{0.splash}.jpg?size=2048".format(
guild
)
channel.name = data["channel"]["name"]
data["guild"] = guild
data["channel"] = channel
return cls(state=state, data=data)
def __str__(self):
return self.url
def __repr__(self):
return "<Invite code={0.code!r}>".format(self)
def __hash__(self):
return hash(self.code)
@property
def id(self):
"""Returns the proper code portion of the invite."""
return self.code
@property
def url(self):
"""A property that retrieves the invite URL."""
return "http://discord.gg/" + self.code
async def delete(self, *, reason=None):
"""|coro|
Revokes the instant invite.
You must have the :attr:`~Permissions.manage_channels` permission to do this.
Parameters
-----------
reason: Optional[str]
The reason for deleting this invite. Shows up on the audit log.
Raises
-------
Forbidden
You do not have permissions to revoke invites.
NotFound
The invite is invalid or expired.
HTTPException
Revoking the invite failed.
"""
await self._state.http.delete_invite(self.code, reason=reason)

View File

@@ -1,489 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import asyncio
import datetime
from .errors import NoMoreItems
from .utils import time_snowflake, maybe_coroutine
from .object import Object
from .audit_logs import AuditLogEntry
class _AsyncIterator:
__slots__ = ()
def get(self, **attrs):
def predicate(elem):
for attr, val in attrs.items():
nested = attr.split("__")
obj = elem
for attribute in nested:
obj = getattr(obj, attribute)
if obj != val:
return False
return True
return self.find(predicate)
async def find(self, predicate):
while True:
try:
elem = await self.next()
except NoMoreItems:
return None
ret = await maybe_coroutine(predicate, elem)
if ret:
return elem
def map(self, func):
return _MappedAsyncIterator(self, func)
def filter(self, predicate):
return _FilteredAsyncIterator(self, predicate)
async def flatten(self):
ret = []
while True:
try:
item = await self.next()
except NoMoreItems:
return ret
else:
ret.append(item)
def __aiter__(self):
return self
async def __anext__(self):
try:
msg = await self.next()
except NoMoreItems:
raise StopAsyncIteration()
else:
return msg
def _identity(x):
return x
class _MappedAsyncIterator(_AsyncIterator):
def __init__(self, iterator, func):
self.iterator = iterator
self.func = func
async def next(self):
# this raises NoMoreItems and will propagate appropriately
item = await self.iterator.next()
return await maybe_coroutine(self.func, item)
class _FilteredAsyncIterator(_AsyncIterator):
def __init__(self, iterator, predicate):
self.iterator = iterator
if predicate is None:
predicate = _identity
self.predicate = predicate
async def next(self):
getter = self.iterator.next
pred = self.predicate
while True:
# propagate NoMoreItems similar to _MappedAsyncIterator
item = await getter()
ret = await maybe_coroutine(pred, item)
if ret:
return item
class ReactionIterator(_AsyncIterator):
def __init__(self, message, emoji, limit=100, after=None):
self.message = message
self.limit = limit
self.after = after
state = message._state
self.getter = state.http.get_reaction_users
self.state = state
self.emoji = emoji
self.guild = message.guild
self.channel_id = message.channel.id
self.users = asyncio.Queue(loop=state.loop)
async def next(self):
if self.users.empty():
await self.fill_users()
try:
return self.users.get_nowait()
except asyncio.QueueEmpty:
raise NoMoreItems()
async def fill_users(self):
# this is a hack because >circular imports<
from .user import User
if self.limit > 0:
retrieve = self.limit if self.limit <= 100 else 100
after = self.after.id if self.after else None
data = await self.getter(
self.message.id, self.channel_id, self.emoji, retrieve, after=after
)
if data:
self.limit -= retrieve
self.after = Object(id=int(data[0]["id"]))
if self.guild is None:
for element in reversed(data):
await self.users.put(User(state=self.state, data=element))
else:
for element in reversed(data):
member_id = int(element["id"])
member = self.guild.get_member(member_id)
if member is not None:
await self.users.put(member)
else:
await self.users.put(User(state=self.state, data=element))
class HistoryIterator(_AsyncIterator):
"""Iterator for receiving a channel's message history.
The messages endpoint has two behaviours we care about here:
If `before` is specified, the messages endpoint returns the `limit`
newest messages before `before`, sorted with newest first. For filling over
100 messages, update the `before` parameter to the oldest message received.
Messages will be returned in order by time.
If `after` is specified, it returns the `limit` oldest messages after
`after`, sorted with newest first. For filling over 100 messages, update the
`after` parameter to the newest message received. If messages are not
reversed, they will be out of order (99-0, 199-100, so on)
A note that if both before and after are specified, before is ignored by the
messages endpoint.
Parameters
-----------
messageable: :class:`abc.Messageable`
Messageable class to retrieve message history fro.
limit : int
Maximum number of messages to retrieve
before : :class:`Message` or id-like
Message before which all messages must be.
after : :class:`Message` or id-like
Message after which all messages must be.
around : :class:`Message` or id-like
Message around which all messages must be. Limit max 101. Note that if
limit is an even number, this will return at most limit+1 messages.
reverse: bool
If set to true, return messages in oldest->newest order. Recommended
when using with "after" queries with limit over 100, otherwise messages
will be out of order.
"""
def __init__(self, messageable, limit, before=None, after=None, around=None, reverse=None):
if isinstance(before, datetime.datetime):
before = Object(id=time_snowflake(before, high=False))
if isinstance(after, datetime.datetime):
after = Object(id=time_snowflake(after, high=True))
if isinstance(around, datetime.datetime):
around = Object(id=time_snowflake(around))
self.messageable = messageable
self.limit = limit
self.before = before
self.after = after
self.around = around
if reverse is None:
self.reverse = after is not None
else:
self.reverse = reverse
self._filter = None # message dict -> bool
self.state = self.messageable._state
self.logs_from = self.state.http.logs_from
self.messages = asyncio.Queue(loop=self.state.loop)
if self.around:
if self.limit is None:
raise ValueError("history does not support around with limit=None")
if self.limit > 101:
raise ValueError("history max limit 101 when specifying around parameter")
elif self.limit == 101:
self.limit = 100 # Thanks discord
elif self.limit == 1:
raise ValueError("Use get_message.")
self._retrieve_messages = self._retrieve_messages_around_strategy
if self.before and self.after:
self._filter = lambda m: self.after.id < int(m["id"]) < self.before.id
elif self.before:
self._filter = lambda m: int(m["id"]) < self.before.id
elif self.after:
self._filter = lambda m: self.after.id < int(m["id"])
elif self.before and self.after:
if self.reverse:
self._retrieve_messages = self._retrieve_messages_after_strategy
self._filter = lambda m: int(m["id"]) < self.before.id
else:
self._retrieve_messages = self._retrieve_messages_before_strategy
self._filter = lambda m: int(m["id"]) > self.after.id
elif self.after:
self._retrieve_messages = self._retrieve_messages_after_strategy
else:
self._retrieve_messages = self._retrieve_messages_before_strategy
async def next(self):
if self.messages.empty():
await self.fill_messages()
try:
return self.messages.get_nowait()
except asyncio.QueueEmpty:
raise NoMoreItems()
def _get_retrieve(self):
l = self.limit
if l is None:
r = 100
elif l <= 100:
r = l
else:
r = 100
self.retrieve = r
return r > 0
async def flatten(self):
# this is similar to fill_messages except it uses a list instead
# of a queue to place the messages in.
result = []
channel = await self.messageable._get_channel()
self.channel = channel
while self._get_retrieve():
data = await self._retrieve_messages(self.retrieve)
if len(data) < 100:
self.limit = 0 # terminate the infinite loop
if self.reverse:
data = reversed(data)
if self._filter:
data = filter(self._filter, data)
for element in data:
result.append(self.state.create_message(channel=channel, data=element))
return result
async def fill_messages(self):
if not hasattr(self, "channel"):
# do the required set up
channel = await self.messageable._get_channel()
self.channel = channel
if self._get_retrieve():
data = await self._retrieve_messages(self.retrieve)
if self.limit is None and len(data) < 100:
self.limit = 0 # terminate the infinite loop
if self.reverse:
data = reversed(data)
if self._filter:
data = filter(self._filter, data)
channel = self.channel
for element in data:
await self.messages.put(self.state.create_message(channel=channel, data=element))
async def _retrieve_messages(self, retrieve):
"""Retrieve messages and update next parameters."""
pass
async def _retrieve_messages_before_strategy(self, retrieve):
"""Retrieve messages using before parameter."""
before = self.before.id if self.before else None
data = await self.logs_from(self.channel.id, retrieve, before=before)
if len(data):
if self.limit is not None:
self.limit -= retrieve
self.before = Object(id=int(data[-1]["id"]))
return data
async def _retrieve_messages_after_strategy(self, retrieve):
"""Retrieve messages using after parameter."""
after = self.after.id if self.after else None
data = await self.logs_from(self.channel.id, retrieve, after=after)
if len(data):
if self.limit is not None:
self.limit -= retrieve
self.after = Object(id=int(data[0]["id"]))
return data
async def _retrieve_messages_around_strategy(self, retrieve):
"""Retrieve messages using around parameter."""
if self.around:
around = self.around.id if self.around else None
data = await self.logs_from(self.channel.id, retrieve, around=around)
self.around = None
return data
return []
class AuditLogIterator(_AsyncIterator):
def __init__(
self,
guild,
limit=None,
before=None,
after=None,
reverse=None,
user_id=None,
action_type=None,
):
if isinstance(before, datetime.datetime):
before = Object(id=time_snowflake(before, high=False))
if isinstance(after, datetime.datetime):
after = Object(id=time_snowflake(after, high=True))
self.guild = guild
self.loop = guild._state.loop
self.request = guild._state.http.get_audit_logs
self.limit = limit
self.before = before
self.user_id = user_id
self.action_type = action_type
self.after = after
self._users = {}
self._state = guild._state
if reverse is None:
self.reverse = after is not None
else:
self.reverse = reverse
self._filter = None # entry dict -> bool
self.entries = asyncio.Queue(loop=self.loop)
if self.before and self.after:
if self.reverse:
self._strategy = self._after_strategy
self._filter = lambda m: int(m["id"]) < self.before.id
else:
self._strategy = self._before_strategy
self._filter = lambda m: int(m["id"]) > self.after.id
elif self.after:
self._strategy = self._after_strategy
else:
self._strategy = self._before_strategy
async def _before_strategy(self, retrieve):
before = self.before.id if self.before else None
data = await self.request(
self.guild.id,
limit=retrieve,
user_id=self.user_id,
action_type=self.action_type,
before=before,
)
entries = data.get("audit_log_entries", [])
if len(data) and entries:
if self.limit is not None:
self.limit -= retrieve
self.before = Object(id=int(entries[-1]["id"]))
return data.get("users", []), entries
async def _after_strategy(self, retrieve):
after = self.after.id if self.after else None
data = await self.request(
self.guild.id,
limit=retrieve,
user_id=self.user_id,
action_type=self.action_type,
after=after,
)
entries = data.get("audit_log_entries", [])
if len(data) and entries:
if self.limit is not None:
self.limit -= retrieve
self.after = Object(id=int(entries[0]["id"]))
return data.get("users", []), entries
async def next(self):
if self.entries.empty():
await self._fill()
try:
return self.entries.get_nowait()
except asyncio.QueueEmpty:
raise NoMoreItems()
def _get_retrieve(self):
l = self.limit
if l is None:
r = 100
elif l <= 100:
r = l
else:
r = 100
self.retrieve = r
return r > 0
async def _fill(self):
from .user import User
if self._get_retrieve():
users, data = await self._strategy(self.retrieve)
if self.limit is None and len(data) < 100:
self.limit = 0 # terminate the infinite loop
if self.reverse:
data = reversed(data)
if self._filter:
data = filter(self._filter, data)
for user in users:
u = User(data=user, state=self._state)
self._users[u.id] = u
for element in data:
# TODO: remove this if statement later
if element["action_type"] is None:
continue
await self.entries.put(
AuditLogEntry(data=element, users=self._users, guild=self.guild)
)

View File

@@ -1,621 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import itertools
import discord.abc
from . import utils
from .user import BaseUser, User
from .activity import create_activity
from .permissions import Permissions
from .enums import Status, try_enum
from .colour import Colour
from .object import Object
class VoiceState:
"""Represents a Discord user's voice state.
Attributes
------------
deaf: :class:`bool`
Indicates if the user is currently deafened by the guild.
mute: :class:`bool`
Indicates if the user is currently muted by the guild.
self_mute: :class:`bool`
Indicates if the user is currently muted by their own accord.
self_deaf: :class:`bool`
Indicates if the user is currently deafened by their own accord.
afk: :class:`bool`
Indicates if the user is currently in the AFK channel in the guild.
channel: :class:`VoiceChannel`
The voice channel that the user is currently connected to. None if the user
is not currently in a voice channel.
"""
__slots__ = ("session_id", "deaf", "mute", "self_mute", "self_deaf", "afk", "channel")
def __init__(self, *, data, channel=None):
self.session_id = data.get("session_id")
self._update(data, channel)
def _update(self, data, channel):
self.self_mute = data.get("self_mute", False)
self.self_deaf = data.get("self_deaf", False)
self.afk = data.get("suppress", False)
self.mute = data.get("mute", False)
self.deaf = data.get("deaf", False)
self.channel = channel
def __repr__(self):
return "<VoiceState self_mute={0.self_mute} self_deaf={0.self_deaf} channel={0.channel!r}>".format(
self
)
def flatten_user(cls):
for attr, value in itertools.chain(BaseUser.__dict__.items(), User.__dict__.items()):
# ignore private/special methods
if attr.startswith("_"):
continue
# don't override what we already have
if attr in cls.__dict__:
continue
# if it's a slotted attribute or a property, redirect it
# slotted members are implemented as member_descriptors in Type.__dict__
if not hasattr(value, "__annotations__"):
def getter(self, x=attr):
return getattr(self._user, x)
setattr(cls, attr, property(getter, doc="Equivalent to :attr:`User.%s`" % attr))
else:
# probably a member function by now
def generate_function(x):
def general(self, *args, **kwargs):
return getattr(self._user, x)(*args, **kwargs)
general.__name__ = x
return general
func = generate_function(attr)
func.__doc__ = value.__doc__
setattr(cls, attr, func)
return cls
_BaseUser = discord.abc.User
@flatten_user
class Member(discord.abc.Messageable, _BaseUser):
"""Represents a Discord member to a :class:`Guild`.
This implements a lot of the functionality of :class:`User`.
.. container:: operations
.. describe:: x == y
Checks if two members are equal.
Note that this works with :class:`User` instances too.
.. describe:: x != y
Checks if two members are not equal.
Note that this works with :class:`User` instances too.
.. describe:: hash(x)
Returns the member's hash.
.. describe:: str(x)
Returns the member's name with the discriminator.
Attributes
----------
joined_at: `datetime.datetime`
A datetime object that specifies the date and time in UTC that the member joined the guild for
the first time.
activities: Tuple[Union[:class:`Game`, :class:`Streaming`, :class:`Spotify`, :class:`Activity`]]
The activities that the user is currently doing.
guild: :class:`Guild`
The guild that the member belongs to.
nick: Optional[:class:`str`]
The guild specific nickname of the user.
"""
__slots__ = (
"_roles",
"joined_at",
"_client_status",
"activities",
"guild",
"nick",
"_user",
"_state",
)
def __init__(self, *, data, guild, state):
self._state = state
self._user = state.store_user(data["user"])
self.guild = guild
self.joined_at = utils.parse_time(data.get("joined_at"))
self._update_roles(data)
self._client_status = {None: Status.offline}
self.activities = tuple(map(create_activity, data.get("activities", [])))
self.nick = data.get("nick", None)
def __str__(self):
return str(self._user)
def __repr__(self):
return (
"<Member id={1.id} name={1.name!r} discriminator={1.discriminator!r}"
" bot={1.bot} nick={0.nick!r} guild={0.guild!r}>".format(self, self._user)
)
def __eq__(self, other):
return isinstance(other, _BaseUser) and other.id == self.id
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self._user)
@classmethod
def _copy(cls, member):
self = cls.__new__(cls) # to bypass __init__
self._roles = utils.SnowflakeList(member._roles, is_sorted=True)
self.joined_at = member.joined_at
self._client_status = member._client_status.copy()
self.guild = member.guild
self.nick = member.nick
self.activities = member.activities
self._state = member._state
self._user = User._copy(member._user)
return self
async def _get_channel(self):
ch = await self.create_dm()
return ch
def _update_roles(self, data):
self._roles = utils.SnowflakeList(map(int, data["roles"]))
def _update(self, data, user=None):
if user:
self._user.name = user["username"]
self._user.discriminator = user["discriminator"]
self._user.avatar = user["avatar"]
self._user.bot = user.get("bot", False)
# the nickname change is optional,
# if it isn't in the payload then it didn't change
try:
self.nick = data["nick"]
except KeyError:
pass
self._update_roles(data)
def _presence_update(self, data, user):
self.activities = tuple(map(create_activity, data.get("activities", [])))
self._client_status = {key: value for key, value in data.get("client_status", {}).items()}
self._client_status[None] = data["status"]
if len(user) > 1:
u = self._user
u.name = user.get("username", u.name)
u.avatar = user.get("avatar", u.avatar)
u.discriminator = user.get("discriminator", u.discriminator)
@property
def status(self):
""":class:`Status`: The member's overall status. If the value is unknown, then it will be a :class:`str` instead."""
return try_enum(Status, self._client_status[None])
@status.setter
def status(self, value):
# internal use only
self._client_status[None] = str(value)
@property
def mobile_status(self):
""":class:`Status`: The member's status on a mobile device, if applicable."""
return try_enum(Status, self._client_status.get("mobile", "offline"))
@property
def desktop_status(self):
""":class:`Status`: The member's status on the desktop client, if applicable."""
return try_enum(Status, self._client_status.get("desktop", "offline"))
@property
def web_status(self):
""":class:`Status`: The member's status on the web client, if applicable."""
return try_enum(Status, self._client_status.get("web", "offline"))
def is_on_mobile(self):
""":class:`bool`: A helper function that determines if a member is active on a mobile device."""
return "mobile" in self._client_status
@property
def colour(self):
"""A property that returns a :class:`Colour` denoting the rendered colour
for the member. If the default colour is the one rendered then an instance
of :meth:`Colour.default` is returned.
There is an alias for this under ``color``.
"""
roles = self.roles[1:] # remove @everyone
# highest order of the colour is the one that gets rendered.
# if the highest is the default colour then the next one with a colour
# is chosen instead
for role in reversed(roles):
if role.colour.value:
return role.colour
return Colour.default()
color = colour
@property
def roles(self):
"""A :class:`list` of :class:`Role` that the member belongs to. Note
that the first element of this list is always the default '@everyone'
role.
These roles are sorted by their position in the role hierarchy.
"""
result = []
g = self.guild
for role_id in self._roles:
role = g.get_role(role_id)
if role:
result.append(role)
result.append(g.default_role)
result.sort()
return result
@property
def mention(self):
"""Returns a string that mentions the member."""
if self.nick:
return "<@!%s>" % self.id
return "<@%s>" % self.id
@property
def display_name(self):
"""Returns the user's display name.
For regular users this is just their username, but
if they have a guild specific nickname then that
is returned instead.
"""
return self.nick if self.nick is not None else self.name
@property
def activity(self):
"""Returns a class Union[:class:`Game`, :class:`Streaming`, :class:`Spotify`, :class:`Activity`] for the primary
activity the user is currently doing. Could be None if no activity is being done.
.. note::
A user may have multiple activities, these can be accessed under :attr:`activities`.
"""
if self.activities:
return self.activities[0]
def mentioned_in(self, message):
"""Checks if the member is mentioned in the specified message.
Parameters
-----------
message: :class:`Message`
The message to check if you're mentioned in.
"""
if self._user.mentioned_in(message):
return True
for role in message.role_mentions:
has_role = utils.get(self.roles, id=role.id) is not None
if has_role:
return True
return False
def permissions_in(self, channel):
"""An alias for :meth:`abc.GuildChannel.permissions_for`.
Basically equivalent to:
.. code-block:: python3
channel.permissions_for(self)
Parameters
-----------
channel
The channel to check your permissions for.
"""
return channel.permissions_for(self)
@property
def top_role(self):
"""Returns the member's highest role.
This is useful for figuring where a member stands in the role
hierarchy chain.
"""
return self.roles[-1]
@property
def guild_permissions(self):
"""Returns the member's guild permissions.
This only takes into consideration the guild permissions
and not most of the implied permissions or any of the
channel permission overwrites. For 100% accurate permission
calculation, please use either :meth:`permissions_in` or
:meth:`abc.GuildChannel.permissions_for`.
This does take into consideration guild ownership and the
administrator implication.
"""
if self.guild.owner == self:
return Permissions.all()
base = Permissions.none()
for r in self.roles:
base.value |= r.permissions.value
if base.administrator:
return Permissions.all()
return base
@property
def voice(self):
"""Optional[:class:`VoiceState`]: Returns the member's current voice state."""
return self.guild._voice_state_for(self._user.id)
async def ban(self, **kwargs):
"""|coro|
Bans this member. Equivalent to :meth:`Guild.ban`
"""
await self.guild.ban(self, **kwargs)
async def unban(self, *, reason=None):
"""|coro|
Unbans this member. Equivalent to :meth:`Guild.unban`
"""
await self.guild.unban(self, reason=reason)
async def kick(self, *, reason=None):
"""|coro|
Kicks this member. Equivalent to :meth:`Guild.kick`
"""
await self.guild.kick(self, reason=reason)
async def edit(self, *, reason=None, **fields):
"""|coro|
Edits the member's data.
Depending on the parameter passed, this requires different permissions listed below:
+---------------+--------------------------------------+
| Parameter | Permission |
+---------------+--------------------------------------+
| nick | :attr:`Permissions.manage_nicknames` |
+---------------+--------------------------------------+
| mute | :attr:`Permissions.mute_members` |
+---------------+--------------------------------------+
| deafen | :attr:`Permissions.deafen_members` |
+---------------+--------------------------------------+
| roles | :attr:`Permissions.manage_roles` |
+---------------+--------------------------------------+
| voice_channel | :attr:`Permissions.move_members` |
+---------------+--------------------------------------+
All parameters are optional.
Parameters
-----------
nick: str
The member's new nickname. Use ``None`` to remove the nickname.
mute: bool
Indicates if the member should be guild muted or un-muted.
deafen: bool
Indicates if the member should be guild deafened or un-deafened.
roles: List[:class:`Roles`]
The member's new list of roles. This *replaces* the roles.
voice_channel: :class:`VoiceChannel`
The voice channel to move the member to.
reason: Optional[str]
The reason for editing this member. Shows up on the audit log.
Raises
-------
Forbidden
You do not have the proper permissions to the action requested.
HTTPException
The operation failed.
"""
http = self._state.http
guild_id = self.guild.id
payload = {}
try:
nick = fields["nick"]
except KeyError:
# nick not present so...
pass
else:
nick = nick if nick else ""
if self._state.self_id == self.id:
await http.change_my_nickname(guild_id, nick, reason=reason)
else:
payload["nick"] = nick
deafen = fields.get("deafen")
if deafen is not None:
payload["deaf"] = deafen
mute = fields.get("mute")
if mute is not None:
payload["mute"] = mute
try:
vc = fields["voice_channel"]
except KeyError:
pass
else:
payload["channel_id"] = vc.id
try:
roles = fields["roles"]
except KeyError:
pass
else:
payload["roles"] = tuple(r.id for r in roles)
await http.edit_member(guild_id, self.id, reason=reason, **payload)
# TODO: wait for WS event for modify-in-place behaviour
async def move_to(self, channel, *, reason=None):
"""|coro|
Moves a member to a new voice channel (they must be connected first).
You must have the :attr:`~Permissions.move_members` permission to
use this.
This raises the same exceptions as :meth:`edit`.
Parameters
-----------
channel: :class:`VoiceChannel`
The new voice channel to move the member to.
reason: Optional[str]
The reason for doing this action. Shows up on the audit log.
"""
await self.edit(voice_channel=channel, reason=reason)
async def add_roles(self, *roles, reason=None, atomic=True):
r"""|coro|
Gives the member a number of :class:`Role`\s.
You must have the :attr:`~Permissions.manage_roles` permission to
use this.
Parameters
-----------
\*roles
An argument list of :class:`abc.Snowflake` representing a :class:`Role`
to give to the member.
reason: Optional[str]
The reason for adding these roles. Shows up on the audit log.
atomic: bool
Whether to atomically add roles. This will ensure that multiple
operations will always be applied regardless of the current
state of the cache.
Raises
-------
Forbidden
You do not have permissions to add these roles.
HTTPException
Adding roles failed.
"""
if not atomic:
new_roles = utils._unique(Object(id=r.id) for s in (self.roles[1:], roles) for r in s)
await self.edit(roles=new_roles, reason=reason)
else:
req = self._state.http.add_role
guild_id = self.guild.id
user_id = self.id
for role in roles:
await req(guild_id, user_id, role.id, reason=reason)
async def remove_roles(self, *roles, reason=None, atomic=True):
r"""|coro|
Removes :class:`Role`\s from this member.
You must have the :attr:`~Permissions.manage_roles` permission to
use this.
Parameters
-----------
\*roles
An argument list of :class:`abc.Snowflake` representing a :class:`Role`
to remove from the member.
reason: Optional[str]
The reason for removing these roles. Shows up on the audit log.
atomic: bool
Whether to atomically remove roles. This will ensure that multiple
operations will always be applied regardless of the current
state of the cache.
Raises
-------
Forbidden
You do not have permissions to remove these roles.
HTTPException
Removing the roles failed.
"""
if not atomic:
new_roles = [Object(id=r.id) for r in self.roles[1:]] # remove @everyone
for role in roles:
try:
new_roles.remove(Object(id=role.id))
except ValueError:
pass
await self.edit(roles=new_roles, reason=reason)
else:
req = self._state.http.remove_role
guild_id = self.guild.id
user_id = self.id
for role in roles:
await req(guild_id, user_id, role.id, reason=reason)

View File

@@ -1,799 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import asyncio
import re
from . import utils
from .reaction import Reaction
from .emoji import Emoji, PartialEmoji
from .calls import CallMessage
from .enums import MessageType, try_enum
from .errors import InvalidArgument, ClientException, HTTPException
from .embeds import Embed
class Attachment:
"""Represents an attachment from Discord.
Attributes
------------
id: :class:`int`
The attachment ID.
size: :class:`int`
The attachment size in bytes.
height: Optional[:class:`int`]
The attachment's height, in pixels. Only applicable to images.
width: Optional[:class:`int`]
The attachment's width, in pixels. Only applicable to images.
filename: :class:`str`
The attachment's filename.
url: :class:`str`
The attachment URL. If the message this attachment was attached
to is deleted, then this will 404.
proxy_url: :class:`str`
The proxy URL. This is a cached version of the :attr:`~Attachment.url` in the
case of images. When the message is deleted, this URL might be valid for a few
minutes or not valid at all.
"""
__slots__ = ("id", "size", "height", "width", "filename", "url", "proxy_url", "_http")
def __init__(self, *, data, state):
self.id = int(data["id"])
self.size = data["size"]
self.height = data.get("height")
self.width = data.get("width")
self.filename = data["filename"]
self.url = data.get("url")
self.proxy_url = data.get("proxy_url")
self._http = state.http
def is_spoiler(self):
""":class:`bool`: Whether this attachment contains a spoiler."""
return self.filename.startswith("SPOILER_")
async def save(self, fp, *, seek_begin=True):
"""|coro|
Saves this attachment into a file-like object.
Parameters
-----------
fp: Union[BinaryIO, str]
The file-like object to save this attachment to or the filename
to use. If a filename is passed then a file is created with that
filename and used instead.
seek_begin: bool
Whether to seek to the beginning of the file after saving is
successfully done.
Raises
--------
HTTPException
Saving the attachment failed.
NotFound
The attachment was deleted.
Returns
--------
int
The number of bytes written.
"""
data = await self._http.get_attachment(self.url)
if isinstance(fp, str):
with open(fp, "wb") as f:
return f.write(data)
else:
written = fp.write(data)
if seek_begin:
fp.seek(0)
return written
class Message:
r"""Represents a message from Discord.
There should be no need to create one of these manually.
Attributes
-----------
tts: :class:`bool`
Specifies if the message was done with text-to-speech.
type: :class:`MessageType`
The type of message. In most cases this should not be checked, but it is helpful
in cases where it might be a system message for :attr:`system_content`.
author
A :class:`Member` that sent the message. If :attr:`channel` is a
private channel or the user has the left the guild, then it is a :class:`User` instead.
content: :class:`str`
The actual contents of the message.
nonce
The value used by the discord guild and the client to verify that the message is successfully sent.
This is typically non-important.
embeds: List[:class:`Embed`]
A list of embeds the message has.
channel
The :class:`TextChannel` that the message was sent from.
Could be a :class:`DMChannel` or :class:`GroupChannel` if it's a private message.
call: Optional[:class:`CallMessage`]
The call that the message refers to. This is only applicable to messages of type
:attr:`MessageType.call`.
mention_everyone: :class:`bool`
Specifies if the message mentions everyone.
.. note::
This does not check if the ``@everyone`` or the ``@here`` text is in the message itself.
Rather this boolean indicates if either the ``@everyone`` or the ``@here`` text is in the message
**and** it did end up mentioning.
mentions: :class:`list`
A list of :class:`Member` that were mentioned. If the message is in a private message
then the list will be of :class:`User` instead. For messages that are not of type
:attr:`MessageType.default`\, this array can be used to aid in system messages.
For more information, see :attr:`system_content`.
.. warning::
The order of the mentions list is not in any particular order so you should
not rely on it. This is a discord limitation, not one with the library.
channel_mentions: :class:`list`
A list of :class:`abc.GuildChannel` that were mentioned. If the message is in a private message
then the list is always empty.
role_mentions: :class:`list`
A list of :class:`Role` that were mentioned. If the message is in a private message
then the list is always empty.
id: :class:`int`
The message ID.
webhook_id: Optional[:class:`int`]
If this message was sent by a webhook, then this is the webhook ID's that sent this
message.
attachments: List[:class:`Attachment`]
A list of attachments given to a message.
pinned: :class:`bool`
Specifies if the message is currently pinned.
reactions : List[:class:`Reaction`]
Reactions to a message. Reactions can be either custom emoji or standard unicode emoji.
activity: Optional[:class:`dict`]
The activity associated with this message. Sent with Rich-Presence related messages that for
example, request joining, spectating, or listening to or with another member.
It is a dictionary with the following optional keys:
- ``type``: An integer denoting the type of message activity being requested.
- ``party_id``: The party ID associated with the party.
application: Optional[:class:`dict`]
The rich presence enabled application associated with this message.
It is a dictionary with the following keys:
- ``id``: A string representing the application's ID.
- ``name``: A string representing the application's name.
- ``description``: A string representing the application's description.
- ``icon``: A string representing the icon ID of the application.
- ``cover_image``: A string representing the embed's image asset ID.
"""
__slots__ = (
"_edited_timestamp",
"tts",
"content",
"channel",
"webhook_id",
"mention_everyone",
"embeds",
"id",
"mentions",
"author",
"_cs_channel_mentions",
"_cs_raw_mentions",
"attachments",
"_cs_clean_content",
"_cs_raw_channel_mentions",
"nonce",
"pinned",
"role_mentions",
"_cs_raw_role_mentions",
"type",
"call",
"_cs_system_content",
"_cs_guild",
"_state",
"reactions",
"application",
"activity",
)
def __init__(self, *, state, channel, data):
self._state = state
self.id = int(data["id"])
self.webhook_id = utils._get_as_snowflake(data, "webhook_id")
self.reactions = [Reaction(message=self, data=d) for d in data.get("reactions", [])]
self.application = data.get("application")
self.activity = data.get("activity")
self._update(channel, data)
def __repr__(self):
return "<Message id={0.id} pinned={0.pinned} author={0.author!r}>".format(self)
def _try_patch(self, data, key, transform=None):
try:
value = data[key]
except KeyError:
pass
else:
if transform is None:
setattr(self, key, value)
else:
setattr(self, key, transform(value))
def _add_reaction(self, data, emoji, user_id):
reaction = utils.find(lambda r: r.emoji == emoji, self.reactions)
is_me = data["me"] = user_id == self._state.self_id
if reaction is None:
reaction = Reaction(message=self, data=data, emoji=emoji)
self.reactions.append(reaction)
else:
reaction.count += 1
if is_me:
reaction.me = is_me
return reaction
def _remove_reaction(self, data, emoji, user_id):
reaction = utils.find(lambda r: r.emoji == emoji, self.reactions)
if reaction is None:
# already removed?
raise ValueError("Emoji already removed?")
# if reaction isn't in the list, we crash. This means discord
# sent bad data, or we stored improperly
reaction.count -= 1
if user_id == self._state.self_id:
reaction.me = False
if reaction.count == 0:
# this raises ValueError if something went wrong as well.
self.reactions.remove(reaction)
return reaction
def _update(self, channel, data):
self.channel = channel
self._edited_timestamp = utils.parse_time(data.get("edited_timestamp"))
self._try_patch(data, "pinned")
self._try_patch(data, "application")
self._try_patch(data, "activity")
self._try_patch(data, "mention_everyone")
self._try_patch(data, "tts")
self._try_patch(data, "type", lambda x: try_enum(MessageType, x))
self._try_patch(data, "content")
self._try_patch(
data, "attachments", lambda x: [Attachment(data=a, state=self._state) for a in x]
)
self._try_patch(data, "embeds", lambda x: list(map(Embed.from_data, x)))
self._try_patch(data, "nonce")
for handler in ("author", "mentions", "mention_roles", "call"):
try:
getattr(self, "_handle_%s" % handler)(data[handler])
except KeyError:
continue
# clear the cached properties
cached = filter(lambda attr: attr.startswith("_cs_"), self.__slots__)
for attr in cached:
try:
delattr(self, attr)
except AttributeError:
pass
def _handle_author(self, author):
self.author = self._state.store_user(author)
if self.guild is not None:
found = self.guild.get_member(self.author.id)
if found is not None:
self.author = found
def _handle_mentions(self, mentions):
self.mentions = []
if self.guild is None:
self.mentions = [self._state.store_user(m) for m in mentions]
return
for mention in filter(None, mentions):
id_search = int(mention["id"])
member = self.guild.get_member(id_search)
if member is not None:
self.mentions.append(member)
def _handle_mention_roles(self, role_mentions):
self.role_mentions = []
if self.guild is not None:
for role_id in map(int, role_mentions):
role = self.guild.get_role(role_id)
if role is not None:
self.role_mentions.append(role)
def _handle_call(self, call):
if call is None or self.type is not MessageType.call:
self.call = None
return
# we get the participant source from the mentions array or
# the author
participants = []
for uid in map(int, call.get("participants", [])):
if uid == self.author.id:
participants.append(self.author)
else:
user = utils.find(lambda u: u.id == uid, self.mentions)
if user is not None:
participants.append(user)
call["participants"] = participants
self.call = CallMessage(message=self, **call)
@utils.cached_slot_property("_cs_guild")
def guild(self):
"""Optional[:class:`Guild`]: The guild that the message belongs to, if applicable."""
return getattr(self.channel, "guild", None)
@utils.cached_slot_property("_cs_raw_mentions")
def raw_mentions(self):
"""A property that returns an array of user IDs matched with
the syntax of <@user_id> in the message content.
This allows you to receive the user IDs of mentioned users
even in a private message context.
"""
return [int(x) for x in re.findall(r"<@!?([0-9]+)>", self.content)]
@utils.cached_slot_property("_cs_raw_channel_mentions")
def raw_channel_mentions(self):
"""A property that returns an array of channel IDs matched with
the syntax of <#channel_id> in the message content.
"""
return [int(x) for x in re.findall(r"<#([0-9]+)>", self.content)]
@utils.cached_slot_property("_cs_raw_role_mentions")
def raw_role_mentions(self):
"""A property that returns an array of role IDs matched with
the syntax of <@&role_id> in the message content.
"""
return [int(x) for x in re.findall(r"<@&([0-9]+)>", self.content)]
@utils.cached_slot_property("_cs_channel_mentions")
def channel_mentions(self):
if self.guild is None:
return []
it = filter(None, map(self.guild.get_channel, self.raw_channel_mentions))
return utils._unique(it)
@utils.cached_slot_property("_cs_clean_content")
def clean_content(self):
"""A property that returns the content in a "cleaned up"
manner. This basically means that mentions are transformed
into the way the client shows it. e.g. ``<#id>`` will transform
into ``#name``.
This will also transform @everyone and @here mentions into
non-mentions.
"""
transformations = {
re.escape("<#%s>" % channel.id): "#" + channel.name
for channel in self.channel_mentions
}
mention_transforms = {
re.escape("<@%s>" % member.id): "@" + member.display_name for member in self.mentions
}
# add the <@!user_id> cases as well..
second_mention_transforms = {
re.escape("<@!%s>" % member.id): "@" + member.display_name for member in self.mentions
}
transformations.update(mention_transforms)
transformations.update(second_mention_transforms)
if self.guild is not None:
role_transforms = {
re.escape("<@&%s>" % role.id): "@" + role.name for role in self.role_mentions
}
transformations.update(role_transforms)
def repl(obj):
return transformations.get(re.escape(obj.group(0)), "")
pattern = re.compile("|".join(transformations.keys()))
result = pattern.sub(repl, self.content)
transformations = {"@everyone": "@\u200beveryone", "@here": "@\u200bhere"}
def repl2(obj):
return transformations.get(obj.group(0), "")
pattern = re.compile("|".join(transformations.keys()))
return pattern.sub(repl2, result)
@property
def created_at(self):
"""datetime.datetime: The message's creation time in UTC."""
return utils.snowflake_time(self.id)
@property
def edited_at(self):
"""Optional[datetime.datetime]: A naive UTC datetime object containing the edited time of the message."""
return self._edited_timestamp
@property
def jump_url(self):
""":class:`str`: Returns a URL that allows the client to jump to this message."""
guild_id = getattr(self.guild, "id", "@me")
return "https://discordapp.com/channels/{0}/{1.channel.id}/{1.id}".format(guild_id, self)
@utils.cached_slot_property("_cs_system_content")
def system_content(self):
r"""A property that returns the content that is rendered
regardless of the :attr:`Message.type`.
In the case of :attr:`MessageType.default`\, this just returns the
regular :attr:`Message.content`. Otherwise this returns an English
message denoting the contents of the system message.
"""
if self.type is MessageType.default:
return self.content
if self.type is MessageType.pins_add:
return "{0.name} pinned a message to this channel.".format(self.author)
if self.type is MessageType.recipient_add:
return "{0.name} added {1.name} to the group.".format(self.author, self.mentions[0])
if self.type is MessageType.recipient_remove:
return "{0.name} removed {1.name} from the group.".format(
self.author, self.mentions[0]
)
if self.type is MessageType.channel_name_change:
return "{0.author.name} changed the channel name: {0.content}".format(self)
if self.type is MessageType.channel_icon_change:
return "{0.author.name} changed the channel icon.".format(self)
if self.type is MessageType.new_member:
formats = [
"{0} just joined the server - glhf!",
"{0} just joined. Everyone, look busy!",
"{0} just joined. Can I get a heal?",
"{0} joined your party.",
"{0} joined. You must construct additional pylons.",
"Ermagherd. {0} is here.",
"Welcome, {0}. Stay awhile and listen.",
"Welcome, {0}. We were expecting you ( ͡° ͜ʖ ͡°)",
"Welcome, {0}. We hope you brought pizza.",
"Welcome {0}. Leave your weapons by the door.",
"A wild {0} appeared.",
"Swoooosh. {0} just landed.",
"Brace yourselves. {0} just joined the server.",
"{0} just joined. Hide your bananas.",
"{0} just arrived. Seems OP - please nerf.",
"{0} just slid into the server.",
"A {0} has spawned in the server.",
"Big {0} showed up!",
"Wheres {0}? In the server!",
"{0} hopped into the server. Kangaroo!!",
"{0} just showed up. Hold my beer.",
"Challenger approaching - {0} has appeared!",
"It's a bird! It's a plane! Nevermind, it's just {0}.",
"It's {0}! Praise the sun! [T]/",
"Never gonna give {0} up. Never gonna let {0} down.",
"Ha! {0} has joined! You activated my trap card!",
"Cheers, love! {0}'s here!",
"Hey! Listen! {0} has joined!",
"We've been expecting you {0}",
"It's dangerous to go alone, take {0}!",
"{0} has joined the server! It's super effective!",
"Cheers, love! {0} is here!",
"{0} is here, as the prophecy foretold.",
"{0} has arrived. Party's over.",
"Ready player {0}",
"{0} is here to kick butt and chew bubblegum. And {0} is all out of gum.",
"Hello. Is it {0} you're looking for?",
"{0} has joined. Stay a while and listen!",
"Roses are red, violets are blue, {0} joined this server with you",
]
index = int(self.created_at.timestamp()) % len(formats)
return formats[index].format(self.author.name)
if self.type is MessageType.call:
# we're at the call message type now, which is a bit more complicated.
# we can make the assumption that Message.channel is a PrivateChannel
# with the type ChannelType.group or ChannelType.private
call_ended = self.call.ended_timestamp is not None
if self.channel.me in self.call.participants:
return "{0.author.name} started a call.".format(self)
elif call_ended:
return "You missed a call from {0.author.name}".format(self)
else:
return "{0.author.name} started a call \N{EM DASH} Join the call.".format(self)
async def delete(self):
"""|coro|
Deletes the message.
Your own messages could be deleted without any proper permissions. However to
delete other people's messages, you need the :attr:`~Permissions.manage_messages`
permission.
Raises
------
Forbidden
You do not have proper permissions to delete the message.
HTTPException
Deleting the message failed.
"""
await self._state.http.delete_message(self.channel.id, self.id)
async def edit(self, **fields):
"""|coro|
Edits the message.
The content must be able to be transformed into a string via ``str(content)``.
Parameters
-----------
content: Optional[str]
The new content to replace the message with.
Could be ``None`` to remove the content.
embed: Optional[:class:`Embed`]
The new embed to replace the original with.
Could be ``None`` to remove the embed.
delete_after: Optional[float]
If provided, the number of seconds to wait in the background
before deleting the message we just edited. If the deletion fails,
then it is silently ignored.
Raises
-------
HTTPException
Editing the message failed.
"""
try:
content = fields["content"]
except KeyError:
pass
else:
if content is not None:
fields["content"] = str(content)
try:
embed = fields["embed"]
except KeyError:
pass
else:
if embed is not None:
fields["embed"] = embed.to_dict()
data = await self._state.http.edit_message(self.id, self.channel.id, **fields)
self._update(channel=self.channel, data=data)
try:
delete_after = fields["delete_after"]
except KeyError:
pass
else:
if delete_after is not None:
async def delete():
await asyncio.sleep(delete_after, loop=self._state.loop)
try:
await self._state.http.delete_message(self.channel.id, self.id)
except HTTPException:
pass
asyncio.ensure_future(delete(), loop=self._state.loop)
async def pin(self):
"""|coro|
Pins the message.
You must have the :attr:`~Permissions.manage_messages` permission to do
this in a non-private channel context.
Raises
-------
Forbidden
You do not have permissions to pin the message.
NotFound
The message or channel was not found or deleted.
HTTPException
Pinning the message failed, probably due to the channel
having more than 50 pinned messages.
"""
await self._state.http.pin_message(self.channel.id, self.id)
self.pinned = True
async def unpin(self):
"""|coro|
Unpins the message.
You must have the :attr:`~Permissions.manage_messages` permission to do
this in a non-private channel context.
Raises
-------
Forbidden
You do not have permissions to unpin the message.
NotFound
The message or channel was not found or deleted.
HTTPException
Unpinning the message failed.
"""
await self._state.http.unpin_message(self.channel.id, self.id)
self.pinned = False
async def add_reaction(self, emoji):
"""|coro|
Add a reaction to the message.
The emoji may be a unicode emoji or a custom guild :class:`Emoji`.
You must have the :attr:`~Permissions.read_message_history` permission
to use this. If nobody else has reacted to the message using this
emoji, the :attr:`~Permissions.add_reactions` permission is required.
Parameters
------------
emoji: Union[:class:`Emoji`, :class:`Reaction`, :class:`PartialEmoji`, str]
The emoji to react with.
Raises
--------
HTTPException
Adding the reaction failed.
Forbidden
You do not have the proper permissions to react to the message.
NotFound
The emoji you specified was not found.
InvalidArgument
The emoji parameter is invalid.
"""
emoji = self._emoji_reaction(emoji)
await self._state.http.add_reaction(self.id, self.channel.id, emoji)
async def remove_reaction(self, emoji, member):
"""|coro|
Remove a reaction by the member from the message.
The emoji may be a unicode emoji or a custom guild :class:`Emoji`.
If the reaction is not your own (i.e. ``member`` parameter is not you) then
the :attr:`~Permissions.manage_messages` permission is needed.
The ``member`` parameter must represent a member and meet
the :class:`abc.Snowflake` abc.
Parameters
------------
emoji: Union[:class:`Emoji`, :class:`Reaction`, :class:`PartialEmoji`, str]
The emoji to remove.
member: :class:`abc.Snowflake`
The member for which to remove the reaction.
Raises
--------
HTTPException
Removing the reaction failed.
Forbidden
You do not have the proper permissions to remove the reaction.
NotFound
The member or emoji you specified was not found.
InvalidArgument
The emoji parameter is invalid.
"""
emoji = self._emoji_reaction(emoji)
if member.id == self._state.self_id:
await self._state.http.remove_own_reaction(self.id, self.channel.id, emoji)
else:
await self._state.http.remove_reaction(self.id, self.channel.id, emoji, member.id)
@staticmethod
def _emoji_reaction(emoji):
if isinstance(emoji, Reaction):
emoji = emoji.emoji
if isinstance(emoji, Emoji):
return "%s:%s" % (emoji.name, emoji.id)
if isinstance(emoji, PartialEmoji):
return emoji._as_reaction()
if isinstance(emoji, str):
return emoji # this is okay
raise InvalidArgument(
"emoji argument must be str, Emoji, or Reaction not {.__class__.__name__}.".format(
emoji
)
)
async def clear_reactions(self):
"""|coro|
Removes all the reactions from the message.
You need the :attr:`~Permissions.manage_messages` permission to use this.
Raises
--------
HTTPException
Removing the reactions failed.
Forbidden
You do not have the proper permissions to remove all the reactions.
"""
await self._state.http.clear_reactions(self.id, self.channel.id)
def ack(self):
"""|coro|
Marks this message as read.
The user must not be a bot user.
Raises
-------
HTTPException
Acking failed.
ClientException
You must not be a bot user.
"""
state = self._state
if state.is_bot:
raise ClientException("Must not be a bot account to ack messages.")
return state.http.ack_message(self.channel.id, self.id)

View File

@@ -1,71 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from . import utils
from .mixins import Hashable
class Object(Hashable):
"""Represents a generic Discord object.
The purpose of this class is to allow you to create 'miniature'
versions of data classes if you want to pass in just an ID. Most functions
that take in a specific data class with an ID can also take in this class
as a substitute instead. Note that even though this is the case, not all
objects (if any) actually inherit from this class.
There are also some cases where some websocket events are received
in :issue:`strange order <21>` and when such events happened you would
receive this class rather than the actual data class. These cases are
extremely rare.
.. container:: operations
.. describe:: x == y
Checks if two objects are equal.
.. describe:: x != y
Checks if two objects are not equal.
.. describe:: hash(x)
Returns the object's hash.
Attributes
-----------
id : :class:`str`
The ID of the object.
"""
def __init__(self, id):
self.id = id
@property
def created_at(self):
"""Returns the snowflake's creation time in UTC."""
return utils.snowflake_time(self.id)

View File

@@ -1,286 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import array
import ctypes
import ctypes.util
import logging
import os.path
import sys
from .errors import DiscordException
log = logging.getLogger(__name__)
c_int_ptr = ctypes.POINTER(ctypes.c_int)
c_int16_ptr = ctypes.POINTER(ctypes.c_int16)
c_float_ptr = ctypes.POINTER(ctypes.c_float)
class EncoderStruct(ctypes.Structure):
pass
EncoderStructPtr = ctypes.POINTER(EncoderStruct)
def _err_lt(result, func, args):
if result < 0:
log.info("error has happened in %s", func.__name__)
raise OpusError(result)
return result
def _err_ne(result, func, args):
ret = args[-1]._obj
if ret.value != 0:
log.info("error has happened in %s", func.__name__)
raise OpusError(ret.value)
return result
# A list of exported functions.
# The first argument is obviously the name.
# The second one are the types of arguments it takes.
# The third is the result type.
# The fourth is the error handler.
exported_functions = [
("opus_strerror", [ctypes.c_int], ctypes.c_char_p, None),
("opus_encoder_get_size", [ctypes.c_int], ctypes.c_int, None),
(
"opus_encoder_create",
[ctypes.c_int, ctypes.c_int, ctypes.c_int, c_int_ptr],
EncoderStructPtr,
_err_ne,
),
(
"opus_encode",
[EncoderStructPtr, c_int16_ptr, ctypes.c_int, ctypes.c_char_p, ctypes.c_int32],
ctypes.c_int32,
_err_lt,
),
("opus_encoder_ctl", None, ctypes.c_int32, _err_lt),
("opus_encoder_destroy", [EncoderStructPtr], None, None),
]
def libopus_loader(name):
# create the library...
lib = ctypes.cdll.LoadLibrary(name)
# register the functions...
for item in exported_functions:
func = getattr(lib, item[0])
try:
if item[1]:
func.argtypes = item[1]
func.restype = item[2]
except KeyError:
pass
try:
if item[3]:
func.errcheck = item[3]
except KeyError:
log.exception("Error assigning check function to %s", func)
return lib
try:
if sys.platform == "win32":
_basedir = os.path.dirname(os.path.abspath(__file__))
_bitness = "x64" if sys.maxsize > 2 ** 32 else "x86"
_filename = os.path.join(_basedir, "bin", "libopus-0.{}.dll".format(_bitness))
_lib = libopus_loader(_filename)
else:
_lib = libopus_loader(ctypes.util.find_library("opus"))
except Exception:
_lib = None
def load_opus(name):
"""Loads the libopus shared library for use with voice.
If this function is not called then the library uses the function
`ctypes.util.find_library`__ and then loads that one
if available.
.. _find library: https://docs.python.org/3.5/library/ctypes.html#finding-shared-libraries
__ `find library`_
Not loading a library leads to voice not working.
This function propagates the exceptions thrown.
Warning
--------
The bitness of the library must match the bitness of your python
interpreter. If the library is 64-bit then your python interpreter
must be 64-bit as well. Usually if there's a mismatch in bitness then
the load will throw an exception.
Note
----
On Windows, the .dll extension is not necessary. However, on Linux
the full extension is required to load the library, e.g. ``libopus.so.1``.
On Linux however, `find library`_ will usually find the library automatically
without you having to call this.
Parameters
----------
name: str
The filename of the shared library.
"""
global _lib
_lib = libopus_loader(name)
def is_loaded():
"""Function to check if opus lib is successfully loaded either
via the ``ctypes.util.find_library`` call of :func:`load_opus`.
This must return ``True`` for voice to work.
Returns
-------
bool
Indicates if the opus library has been loaded.
"""
global _lib
return _lib is not None
class OpusError(DiscordException):
"""An exception that is thrown for libopus related errors.
Attributes
----------
code : :class:`int`
The error code returned.
"""
def __init__(self, code):
self.code = code
msg = _lib.opus_strerror(self.code).decode("utf-8")
log.info('"%s" has happened', msg)
super().__init__(msg)
class OpusNotLoaded(DiscordException):
"""An exception that is thrown for when libopus is not loaded."""
pass
# Some constants...
OK = 0
APPLICATION_AUDIO = 2049
APPLICATION_VOIP = 2048
APPLICATION_LOWDELAY = 2051
CTL_SET_BITRATE = 4002
CTL_SET_BANDWIDTH = 4008
CTL_SET_FEC = 4012
CTL_SET_PLP = 4014
CTL_SET_SIGNAL = 4024
band_ctl = {"narrow": 1101, "medium": 1102, "wide": 1103, "superwide": 1104, "full": 1105}
signal_ctl = {"auto": -1000, "voice": 3001, "music": 3002}
class Encoder:
SAMPLING_RATE = 48000
CHANNELS = 2
FRAME_LENGTH = 20
SAMPLE_SIZE = 4 # (bit_rate / 8) * CHANNELS (bit_rate == 16)
SAMPLES_PER_FRAME = int(SAMPLING_RATE / 1000 * FRAME_LENGTH)
FRAME_SIZE = SAMPLES_PER_FRAME * SAMPLE_SIZE
def __init__(self, application=APPLICATION_AUDIO):
self.application = application
if not is_loaded():
raise OpusNotLoaded()
self._state = self._create_state()
self.set_bitrate(128)
self.set_fec(True)
self.set_expected_packet_loss_percent(0.15)
self.set_bandwidth("full")
self.set_signal_type("auto")
def __del__(self):
if hasattr(self, "_state"):
_lib.opus_encoder_destroy(self._state)
self._state = None
def _create_state(self):
ret = ctypes.c_int()
return _lib.opus_encoder_create(
self.SAMPLING_RATE, self.CHANNELS, self.application, ctypes.byref(ret)
)
def set_bitrate(self, kbps):
kbps = min(128, max(16, int(kbps)))
_lib.opus_encoder_ctl(self._state, CTL_SET_BITRATE, kbps * 1024)
return kbps
def set_bandwidth(self, req):
if req not in band_ctl:
raise KeyError(
"%r is not a valid bandwidth setting. Try one of: %s" % (req, ",".join(band_ctl))
)
k = band_ctl[req]
_lib.opus_encoder_ctl(self._state, CTL_SET_BANDWIDTH, k)
def set_signal_type(self, req):
if req not in signal_ctl:
raise KeyError(
"%r is not a valid signal setting. Try one of: %s" % (req, ",".join(signal_ctl))
)
k = signal_ctl[req]
_lib.opus_encoder_ctl(self._state, CTL_SET_SIGNAL, k)
def set_fec(self, enabled=True):
_lib.opus_encoder_ctl(self._state, CTL_SET_FEC, 1 if enabled else 0)
def set_expected_packet_loss_percent(self, percentage):
_lib.opus_encoder_ctl(self._state, CTL_SET_PLP, min(100, max(0, int(percentage * 100))))
def encode(self, pcm, frame_size):
max_data_bytes = len(pcm)
pcm = ctypes.cast(pcm, c_int16_ptr)
data = (ctypes.c_char * max_data_bytes)()
ret = _lib.opus_encode(self._state, pcm, frame_size, data, max_data_bytes)
return array.array("b", data[:ret]).tobytes()

View File

@@ -1,636 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
class Permissions:
"""Wraps up the Discord permission value.
The properties provided are two way. You can set and retrieve individual
bits using the properties as if they were regular bools. This allows
you to edit permissions.
.. container:: operations
.. describe:: x == y
Checks if two permissions are equal.
.. describe:: x != y
Checks if two permissions are not equal.
.. describe:: x <= y
Checks if a permission is a subset of another permission.
.. describe:: x >= y
Checks if a permission is a superset of another permission.
.. describe:: x < y
Checks if a permission is a strict subset of another permission.
.. describe:: x > y
Checks if a permission is a strict superset of another permission.
.. describe:: hash(x)
Return the permission's hash.
.. describe:: iter(x)
Returns an iterator of ``(perm, value)`` pairs. This allows it
to be, for example, constructed as a dict or a list of pairs.
Attributes
-----------
value
The raw value. This value is a bit array field of a 53-bit integer
representing the currently available permissions. You should query
permissions via the properties rather than using this raw value.
"""
__slots__ = ("value",)
def __init__(self, permissions=0):
if not isinstance(permissions, int):
raise TypeError(
"Expected int parameter, received %s instead." % permissions.__class__.__name__
)
self.value = permissions
def __eq__(self, other):
return isinstance(other, Permissions) and self.value == other.value
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self.value)
def __repr__(self):
return "<Permissions value=%s>" % self.value
def _perm_iterator(self):
for attr in dir(self):
# check if it's a property, because if so it's a permission
is_property = isinstance(getattr(self.__class__, attr), property)
if is_property:
yield (attr, getattr(self, attr))
def __iter__(self):
return self._perm_iterator()
def is_subset(self, other):
"""Returns True if self has the same or fewer permissions as other."""
if isinstance(other, Permissions):
return (self.value & other.value) == self.value
else:
raise TypeError(
"cannot compare {} with {}".format(
self.__class__.__name__, other.__class__.__name__
)
)
def is_superset(self, other):
"""Returns True if self has the same or more permissions as other."""
if isinstance(other, Permissions):
return (self.value | other.value) == self.value
else:
raise TypeError(
"cannot compare {} with {}".format(
self.__class__.__name__, other.__class__.__name__
)
)
def is_strict_subset(self, other):
"""Returns True if the permissions on other are a strict subset of those on self."""
return self.is_subset(other) and self != other
def is_strict_superset(self, other):
"""Returns True if the permissions on other are a strict superset of those on self."""
return self.is_superset(other) and self != other
__le__ = is_subset
__ge__ = is_superset
__lt__ = is_strict_subset
__gt__ = is_strict_superset
@classmethod
def none(cls):
"""A factory method that creates a :class:`Permissions` with all
permissions set to False."""
return cls(0)
@classmethod
def all(cls):
"""A factory method that creates a :class:`Permissions` with all
permissions set to True."""
return cls(0b01111111111101111111110111111111)
@classmethod
def all_channel(cls):
"""A :class:`Permissions` with all channel-specific permissions set to
True and the guild-specific ones set to False. The guild-specific
permissions are currently:
- manage_guild
- kick_members
- ban_members
- administrator
- change_nicknames
- manage_nicknames
"""
return cls(0b00110011111101111111110001010001)
@classmethod
def general(cls):
"""A factory method that creates a :class:`Permissions` with all
"General" permissions from the official Discord UI set to True."""
return cls(0b01111100000000000000000010111111)
@classmethod
def text(cls):
"""A factory method that creates a :class:`Permissions` with all
"Text" permissions from the official Discord UI set to True."""
return cls(0b00000000000001111111110001000000)
@classmethod
def voice(cls):
"""A factory method that creates a :class:`Permissions` with all
"Voice" permissions from the official Discord UI set to True."""
return cls(0b00000011111100000000000100000000)
def update(self, **kwargs):
r"""Bulk updates this permission object.
Allows you to set multiple attributes by using keyword
arguments. The names must be equivalent to the properties
listed. Extraneous key/value pairs will be silently ignored.
Parameters
------------
\*\*kwargs
A list of key/value pairs to bulk update permissions with.
"""
for key, value in kwargs.items():
try:
is_property = isinstance(getattr(self.__class__, key), property)
except AttributeError:
continue
if is_property:
setattr(self, key, value)
def _bit(self, index):
return bool((self.value >> index) & 1)
def _set(self, index, value):
if value is True:
self.value |= 1 << index
elif value is False:
self.value &= ~(1 << index)
else:
raise TypeError("Value to set for Permissions must be a bool.")
def handle_overwrite(self, allow, deny):
# Basically this is what's happening here.
# We have an original bit array, e.g. 1010
# Then we have another bit array that is 'denied', e.g. 1111
# And then we have the last one which is 'allowed', e.g. 0101
# We want original OP denied to end up resulting in
# whatever is in denied to be set to 0.
# So 1010 OP 1111 -> 0000
# Then we take this value and look at the allowed values.
# And whatever is allowed is set to 1.
# So 0000 OP2 0101 -> 0101
# The OP is base & ~denied.
# The OP2 is base | allowed.
self.value = (self.value & ~deny) | allow
@property
def create_instant_invite(self):
"""Returns True if the user can create instant invites."""
return self._bit(0)
@create_instant_invite.setter
def create_instant_invite(self, value):
self._set(0, value)
@property
def kick_members(self):
"""Returns True if the user can kick users from the guild."""
return self._bit(1)
@kick_members.setter
def kick_members(self, value):
self._set(1, value)
@property
def ban_members(self):
"""Returns True if a user can ban users from the guild."""
return self._bit(2)
@ban_members.setter
def ban_members(self, value):
self._set(2, value)
@property
def administrator(self):
"""Returns True if a user is an administrator. This role overrides all other permissions.
This also bypasses all channel-specific overrides.
"""
return self._bit(3)
@administrator.setter
def administrator(self, value):
self._set(3, value)
@property
def manage_channels(self):
"""Returns True if a user can edit, delete, or create channels in the guild.
This also corresponds to the "Manage Channel" channel-specific override."""
return self._bit(4)
@manage_channels.setter
def manage_channels(self, value):
self._set(4, value)
@property
def manage_guild(self):
"""Returns True if a user can edit guild properties."""
return self._bit(5)
@manage_guild.setter
def manage_guild(self, value):
self._set(5, value)
@property
def add_reactions(self):
"""Returns True if a user can add reactions to messages."""
return self._bit(6)
@add_reactions.setter
def add_reactions(self, value):
self._set(6, value)
@property
def view_audit_log(self):
"""Returns True if a user can view the guild's audit log."""
return self._bit(7)
@view_audit_log.setter
def view_audit_log(self, value):
self._set(7, value)
@property
def priority_speaker(self):
"""Returns True if a user can be more easily heard while talking."""
return self._bit(8)
@priority_speaker.setter
def priority_speaker(self, value):
self._set(8, value)
# 1 unused
@property
def read_messages(self):
"""Returns True if a user can read messages from all or specific text channels."""
return self._bit(10)
@read_messages.setter
def read_messages(self, value):
self._set(10, value)
@property
def send_messages(self):
"""Returns True if a user can send messages from all or specific text channels."""
return self._bit(11)
@send_messages.setter
def send_messages(self, value):
self._set(11, value)
@property
def send_tts_messages(self):
"""Returns True if a user can send TTS messages from all or specific text channels."""
return self._bit(12)
@send_tts_messages.setter
def send_tts_messages(self, value):
self._set(12, value)
@property
def manage_messages(self):
"""Returns True if a user can delete or pin messages in a text channel. Note that there are currently no ways to edit other people's messages."""
return self._bit(13)
@manage_messages.setter
def manage_messages(self, value):
self._set(13, value)
@property
def embed_links(self):
"""Returns True if a user's messages will automatically be embedded by Discord."""
return self._bit(14)
@embed_links.setter
def embed_links(self, value):
self._set(14, value)
@property
def attach_files(self):
"""Returns True if a user can send files in their messages."""
return self._bit(15)
@attach_files.setter
def attach_files(self, value):
self._set(15, value)
@property
def read_message_history(self):
"""Returns True if a user can read a text channel's previous messages."""
return self._bit(16)
@read_message_history.setter
def read_message_history(self, value):
self._set(16, value)
@property
def mention_everyone(self):
"""Returns True if a user's @everyone or @here will mention everyone in the text channel."""
return self._bit(17)
@mention_everyone.setter
def mention_everyone(self, value):
self._set(17, value)
@property
def external_emojis(self):
"""Returns True if a user can use emojis from other guilds."""
return self._bit(18)
@external_emojis.setter
def external_emojis(self, value):
self._set(18, value)
# 1 unused
@property
def connect(self):
"""Returns True if a user can connect to a voice channel."""
return self._bit(20)
@connect.setter
def connect(self, value):
self._set(20, value)
@property
def speak(self):
"""Returns True if a user can speak in a voice channel."""
return self._bit(21)
@speak.setter
def speak(self, value):
self._set(21, value)
@property
def mute_members(self):
"""Returns True if a user can mute other users."""
return self._bit(22)
@mute_members.setter
def mute_members(self, value):
self._set(22, value)
@property
def deafen_members(self):
"""Returns True if a user can deafen other users."""
return self._bit(23)
@deafen_members.setter
def deafen_members(self, value):
self._set(23, value)
@property
def move_members(self):
"""Returns True if a user can move users between other voice channels."""
return self._bit(24)
@move_members.setter
def move_members(self, value):
self._set(24, value)
@property
def use_voice_activation(self):
"""Returns True if a user can use voice activation in voice channels."""
return self._bit(25)
@use_voice_activation.setter
def use_voice_activation(self, value):
self._set(25, value)
@property
def change_nickname(self):
"""Returns True if a user can change their nickname in the guild."""
return self._bit(26)
@change_nickname.setter
def change_nickname(self, value):
self._set(26, value)
@property
def manage_nicknames(self):
"""Returns True if a user can change other user's nickname in the guild."""
return self._bit(27)
@manage_nicknames.setter
def manage_nicknames(self, value):
self._set(27, value)
@property
def manage_roles(self):
"""Returns True if a user can create or edit roles less than their role's position.
This also corresponds to the "Manage Permissions" channel-specific override.
"""
return self._bit(28)
@manage_roles.setter
def manage_roles(self, value):
self._set(28, value)
@property
def manage_webhooks(self):
"""Returns True if a user can create, edit, or delete webhooks."""
return self._bit(29)
@manage_webhooks.setter
def manage_webhooks(self, value):
self._set(29, value)
@property
def manage_emojis(self):
"""Returns True if a user can create, edit, or delete emojis."""
return self._bit(30)
@manage_emojis.setter
def manage_emojis(self, value):
self._set(30, value)
# 1 unused
# after these 32 bits, there's 21 more unused ones technically
def augment_from_permissions(cls):
cls.VALID_NAMES = {
name for name in dir(Permissions) if isinstance(getattr(Permissions, name), property)
}
# make descriptors for all the valid names
for name in cls.VALID_NAMES:
# god bless Python
def getter(self, x=name):
return self._values.get(x)
def setter(self, value, x=name):
self._set(x, value)
prop = property(getter, setter)
setattr(cls, name, prop)
return cls
@augment_from_permissions
class PermissionOverwrite:
r"""A type that is used to represent a channel specific permission.
Unlike a regular :class:`Permissions`\, the default value of a
permission is equivalent to ``None`` and not ``False``. Setting
a value to ``False`` is **explicitly** denying that permission,
while setting a value to ``True`` is **explicitly** allowing
that permission.
The values supported by this are the same as :class:`Permissions`
with the added possibility of it being set to ``None``.
Supported operations:
+-----------+------------------------------------------+
| Operation | Description |
+===========+==========================================+
| iter(x) | Returns an iterator of (perm, value) |
| | pairs. This allows this class to be used |
| | as an iterable in e.g. set/list/dict |
| | constructions. |
+-----------+------------------------------------------+
Parameters
-----------
\*\*kwargs
Set the value of permissions by their name.
"""
__slots__ = ("_values",)
def __init__(self, **kwargs):
self._values = {}
for key, value in kwargs.items():
if key not in self.VALID_NAMES:
raise ValueError("no permission called {0}.".format(key))
setattr(self, key, value)
def _set(self, key, value):
if value not in (True, None, False):
raise TypeError(
"Expected bool or NoneType, received {0.__class__.__name__}".format(value)
)
self._values[key] = value
def pair(self):
"""Returns the (allow, deny) pair from this overwrite.
The value of these pairs is :class:`Permissions`.
"""
allow = Permissions.none()
deny = Permissions.none()
for key, value in self._values.items():
if value is True:
setattr(allow, key, True)
elif value is False:
setattr(deny, key, True)
return allow, deny
@classmethod
def from_pair(cls, allow, deny):
"""Creates an overwrite from an allow/deny pair of :class:`Permissions`."""
ret = cls()
for key, value in allow:
if value is True:
setattr(ret, key, True)
for key, value in deny:
if value is True:
setattr(ret, key, False)
return ret
def is_empty(self):
"""Checks if the permission overwrite is currently empty.
An empty permission overwrite is one that has no overwrites set
to True or False.
"""
return all(x is None for x in self._values.values())
def update(self, **kwargs):
r"""Bulk updates this permission overwrite object.
Allows you to set multiple attributes by using keyword
arguments. The names must be equivalent to the properties
listed. Extraneous key/value pairs will be silently ignored.
Parameters
------------
\*\*kwargs
A list of key/value pairs to bulk update with.
"""
for key, value in kwargs.items():
if key not in self.VALID_NAMES:
continue
setattr(self, key, value)
def __iter__(self):
for key in self.VALID_NAMES:
yield key, self._values.get(key)

View File

@@ -1,356 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import threading
import subprocess
import audioop
import logging
import shlex
import time
from .errors import ClientException
from .opus import Encoder as OpusEncoder
log = logging.getLogger(__name__)
__all__ = ["AudioSource", "PCMAudio", "FFmpegPCMAudio", "PCMVolumeTransformer"]
class AudioSource:
"""Represents an audio stream.
The audio stream can be Opus encoded or not, however if the audio stream
is not Opus encoded then the audio format must be 16-bit 48KHz stereo PCM.
.. warning::
The audio source reads are done in a separate thread.
"""
def read(self):
"""Reads 20ms worth of audio.
Subclasses must implement this.
If the audio is complete, then returning an empty
:term:`py:bytes-like object` to signal this is the way to do so.
If :meth:`is_opus` method returns ``True``, then it must return
20ms worth of Opus encoded audio. Otherwise, it must be 20ms
worth of 16-bit 48KHz stereo PCM, which is about 3,840 bytes
per frame (20ms worth of audio).
Returns
--------
bytes
A bytes like object that represents the PCM or Opus data.
"""
raise NotImplementedError
def is_opus(self):
"""Checks if the audio source is already encoded in Opus.
Defaults to ``False``.
"""
return False
def cleanup(self):
"""Called when clean-up is needed to be done.
Useful for clearing buffer data or processes after
it is done playing audio.
"""
pass
def __del__(self):
self.cleanup()
class PCMAudio(AudioSource):
"""Represents raw 16-bit 48KHz stereo PCM audio source.
Attributes
-----------
stream: file-like object
A file-like object that reads byte data representing raw PCM.
"""
def __init__(self, stream):
self.stream = stream
def read(self):
ret = self.stream.read(OpusEncoder.FRAME_SIZE)
if len(ret) != OpusEncoder.FRAME_SIZE:
return b""
return ret
class FFmpegPCMAudio(AudioSource):
"""An audio source from FFmpeg (or AVConv).
This launches a sub-process to a specific input file given.
.. warning::
You must have the ffmpeg or avconv executable in your path environment
variable in order for this to work.
Parameters
------------
source: Union[str, BinaryIO]
The input that ffmpeg will take and convert to PCM bytes.
If ``pipe`` is True then this is a file-like object that is
passed to the stdin of ffmpeg.
executable: str
The executable name (and path) to use. Defaults to ``ffmpeg``.
pipe: bool
If true, denotes that ``source`` parameter will be passed
to the stdin of ffmpeg. Defaults to ``False``.
stderr: Optional[BinaryIO]
A file-like object to pass to the Popen constructor.
Could also be an instance of ``subprocess.PIPE``.
options: Optional[str]
Extra command line arguments to pass to ffmpeg after the ``-i`` flag.
before_options: Optional[str]
Extra command line arguments to pass to ffmpeg before the ``-i`` flag.
Raises
--------
ClientException
The subprocess failed to be created.
"""
def __init__(
self,
source,
*,
executable="ffmpeg",
pipe=False,
stderr=None,
before_options=None,
options=None
):
stdin = None if not pipe else source
args = [executable]
if isinstance(before_options, str):
args.extend(shlex.split(before_options))
args.append("-i")
args.append("-" if pipe else source)
args.extend(("-f", "s16le", "-ar", "48000", "-ac", "2", "-loglevel", "warning"))
if isinstance(options, str):
args.extend(shlex.split(options))
args.append("pipe:1")
self._process = None
try:
self._process = subprocess.Popen(
args, stdin=stdin, stdout=subprocess.PIPE, stderr=stderr
)
self._stdout = self._process.stdout
except FileNotFoundError:
raise ClientException(executable + " was not found.") from None
except subprocess.SubprocessError as exc:
raise ClientException("Popen failed: {0.__class__.__name__}: {0}".format(exc)) from exc
def read(self):
ret = self._stdout.read(OpusEncoder.FRAME_SIZE)
if len(ret) != OpusEncoder.FRAME_SIZE:
return b""
return ret
def cleanup(self):
proc = self._process
if proc is None:
return
log.info("Preparing to terminate ffmpeg process %s.", proc.pid)
proc.kill()
if proc.poll() is None:
log.info("ffmpeg process %s has not terminated. Waiting to terminate...", proc.pid)
proc.communicate()
log.info(
"ffmpeg process %s should have terminated with a return code of %s.",
proc.pid,
proc.returncode,
)
else:
log.info(
"ffmpeg process %s successfully terminated with return code of %s.",
proc.pid,
proc.returncode,
)
self._process = None
class PCMVolumeTransformer(AudioSource):
"""Transforms a previous :class:`AudioSource` to have volume controls.
This does not work on audio sources that have :meth:`AudioSource.is_opus`
set to ``True``.
Parameters
------------
original: :class:`AudioSource`
The original AudioSource to transform.
volume: float
The initial volume to set it to.
See :attr:`volume` for more info.
Raises
-------
TypeError
Not an audio source.
ClientException
The audio source is opus encoded.
"""
def __init__(self, original, volume=1.0):
if not isinstance(original, AudioSource):
raise TypeError("expected AudioSource not {0.__class__.__name__}.".format(original))
if original.is_opus():
raise ClientException("AudioSource must not be Opus encoded.")
self.original = original
self.volume = volume
@property
def volume(self):
"""Retrieves or sets the volume as a floating point percentage (e.g. 1.0 for 100%)."""
return self._volume
@volume.setter
def volume(self, value):
self._volume = max(value, 0.0)
def cleanup(self):
self.original.cleanup()
def read(self):
ret = self.original.read()
return audioop.mul(ret, 2, min(self._volume, 2.0))
class AudioPlayer(threading.Thread):
DELAY = OpusEncoder.FRAME_LENGTH / 1000.0
def __init__(self, source, client, *, after=None):
threading.Thread.__init__(self)
self.daemon = True
self.source = source
self.client = client
self.after = after
self._end = threading.Event()
self._resumed = threading.Event()
self._resumed.set() # we are not paused
self._current_error = None
self._connected = client._connected
self._lock = threading.Lock()
if after is not None and not callable(after):
raise TypeError('Expected a callable for the "after" parameter.')
def _do_run(self):
self.loops = 0
self._start = time.time()
# getattr lookup speed ups
play_audio = self.client.send_audio_packet
while not self._end.is_set():
# are we paused?
if not self._resumed.is_set():
# wait until we aren't
self._resumed.wait()
continue
# are we disconnected from voice?
if not self._connected.is_set():
# wait until we are connected
self._connected.wait()
# reset our internal data
self.loops = 0
self._start = time.time()
self.loops += 1
data = self.source.read()
if not data:
self.stop()
break
play_audio(data, encode=not self.source.is_opus())
next_time = self._start + self.DELAY * self.loops
delay = max(0, self.DELAY + (next_time - time.time()))
time.sleep(delay)
def run(self):
try:
self._do_run()
except Exception as exc:
self._current_error = exc
self.stop()
finally:
self.source.cleanup()
self._call_after()
def _call_after(self):
if self.after is not None:
try:
self.after(self._current_error)
except Exception:
log.exception("Calling the after function failed.")
def stop(self):
self._end.set()
self._resumed.set()
def pause(self):
self._resumed.clear()
def resume(self):
self.loops = 0
self._start = time.time()
self._resumed.set()
def is_playing(self):
return self._resumed.is_set() and not self._end.is_set()
def is_paused(self):
return not self._end.is_set() and not self._resumed.is_set()
def _set_source(self, source):
with self._lock:
self.pause()
self.source = source
self.resume()

View File

@@ -1,151 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2018 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
class RawMessageDeleteEvent:
"""Represents the event payload for a :func:`on_raw_message_delete` event.
Attributes
------------
channel_id: :class:`int`
The channel ID where the deletion took place.
guild_id: Optional[:class:`int`]
The guild ID where the deletion took place, if applicable.
message_id: :class:`int`
The message ID that got deleted.
"""
__slots__ = ("message_id", "channel_id", "guild_id")
def __init__(self, data):
self.message_id = int(data["id"])
self.channel_id = int(data["channel_id"])
try:
self.guild_id = int(data["guild_id"])
except KeyError:
self.guild_id = None
class RawBulkMessageDeleteEvent:
"""Represents the event payload for a :func:`on_raw_bulk_message_delete` event.
Attributes
-----------
message_ids: Set[:class:`int`]
A :class:`set` of the message IDs that were deleted.
channel_id: :class:`int`
The channel ID where the message got deleted.
guild_id: Optional[:class:`int`]
The guild ID where the message got deleted, if applicable.
"""
__slots__ = ("message_ids", "channel_id", "guild_id")
def __init__(self, data):
self.message_ids = {int(x) for x in data.get("ids", [])}
self.channel_id = int(data["channel_id"])
try:
self.guild_id = int(data["guild_id"])
except KeyError:
self.guild_id = None
class RawMessageUpdateEvent:
"""Represents the payload for a :func:`on_raw_message_edit` event.
Attributes
-----------
message_id: :class:`int`
The message ID that got updated.
data: :class:`dict`
The raw data given by the
`gateway <https://discordapp.com/developers/docs/topics/gateway#message-update>`_
"""
__slots__ = ("message_id", "data")
def __init__(self, data):
self.message_id = int(data["id"])
self.data = data
class RawReactionActionEvent:
"""Represents the payload for a :func:`on_raw_reaction_add` or
:func:`on_raw_reaction_remove` event.
Attributes
-----------
message_id: :class:`int`
The message ID that got or lost a reaction.
user_id: :class:`int`
The user ID who added or removed the reaction.
channel_id: :class:`int`
The channel ID where the reaction got added or removed.
guild_id: Optional[:class:`int`]
The guild ID where the reaction got added or removed, if applicable.
emoji: :class:`PartialEmoji`
The custom or unicode emoji being used.
"""
__slots__ = ("message_id", "user_id", "channel_id", "guild_id", "emoji")
def __init__(self, data, emoji):
self.message_id = int(data["message_id"])
self.channel_id = int(data["channel_id"])
self.user_id = int(data["user_id"])
self.emoji = emoji
try:
self.guild_id = int(data["guild_id"])
except KeyError:
self.guild_id = None
class RawReactionClearEvent:
"""Represents the payload for a :func:`on_raw_reaction_clear` event.
Attributes
-----------
message_id: :class:`int`
The message ID that got its reactions cleared.
channel_id: :class:`int`
The channel ID where the reactions got cleared.
guild_id: Optional[:class:`int`]
The guild ID where the reactions got cleared.
"""
__slots__ = ("message_id", "channel_id", "guild_id")
def __init__(self, data):
self.message_id = int(data["message_id"])
self.channel_id = int(data["channel_id"])
try:
self.guild_id = int(data["guild_id"])
except KeyError:
self.guild_id = None

View File

@@ -1,151 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from .iterators import ReactionIterator
class Reaction:
"""Represents a reaction to a message.
Depending on the way this object was created, some of the attributes can
have a value of ``None``.
.. container:: operations
.. describe:: x == y
Checks if two reactions are equal. This works by checking if the emoji
is the same. So two messages with the same reaction will be considered
"equal".
.. describe:: x != y
Checks if two reactions are not equal.
.. describe:: hash(x)
Returns the reaction's hash.
.. describe:: str(x)
Returns the string form of the reaction's emoji.
Attributes
-----------
emoji: :class:`Emoji` or :class:`str`
The reaction emoji. May be a custom emoji, or a unicode emoji.
count: :class:`int`
Number of times this reaction was made
me: :class:`bool`
If the user sent this reaction.
message: :class:`Message`
Message this reaction is for.
"""
__slots__ = ("message", "count", "emoji", "me")
def __init__(self, *, message, data, emoji=None):
self.message = message
self.emoji = emoji or message._state.get_reaction_emoji(data["emoji"])
self.count = data.get("count", 1)
self.me = data.get("me")
@property
def custom_emoji(self):
""":class:`bool`: If this is a custom emoji."""
return not isinstance(self.emoji, str)
def __eq__(self, other):
return isinstance(other, self.__class__) and other.emoji == self.emoji
def __ne__(self, other):
if isinstance(other, self.__class__):
return other.emoji != self.emoji
return True
def __hash__(self):
return hash(self.emoji)
def __str__(self):
return str(self.emoji)
def __repr__(self):
return "<Reaction emoji={0.emoji!r} me={0.me} count={0.count}>".format(self)
def users(self, limit=None, after=None):
"""Returns an :class:`AsyncIterator` representing the users that have reacted to the message.
The ``after`` parameter must represent a member
and meet the :class:`abc.Snowflake` abc.
Parameters
------------
limit: int
The maximum number of results to return.
If not provided, returns all the users who
reacted to the message.
after: :class:`abc.Snowflake`
For pagination, reactions are sorted by member.
Raises
--------
HTTPException
Getting the users for the reaction failed.
Examples
---------
Usage ::
# I do not actually recommend doing this.
async for user in reaction.users():
await channel.send('{0} has reacted with {1.emoji}!'.format(user, reaction))
Flattening into a list: ::
users = await reaction.users().flatten()
# users is now a list...
winner = random.choice(users)
await channel.send('{} has won the raffle.'.format(winner))
Yields
--------
Union[:class:`User`, :class:`Member`]
The member (if retrievable) or the user that has reacted
to this message. The case where it can be a :class:`Member` is
in a guild message context. Sometimes it can be a :class:`User`
if the member has left the guild.
"""
if self.custom_emoji:
emoji = "{0.name}:{0.id}".format(self.emoji)
else:
emoji = self.emoji
if limit is None:
limit = self.count
return ReactionIterator(self.message, emoji, limit, after)

View File

@@ -1,79 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from .enums import RelationshipType, try_enum
class Relationship:
"""Represents a relationship in Discord.
A relationship is like a friendship, a person who is blocked, etc.
Only non-bot accounts can have relationships.
Attributes
-----------
user: :class:`User`
The user you have the relationship with.
type: :class:`RelationshipType`
The type of relationship you have.
"""
__slots__ = ("type", "user", "_state")
def __init__(self, *, state, data):
self._state = state
self.type = try_enum(RelationshipType, data["type"])
self.user = state.store_user(data["user"])
def __repr__(self):
return "<Relationship user={0.user!r} type={0.type!r}>".format(self)
async def delete(self):
"""|coro|
Deletes the relationship.
Raises
------
HTTPException
Deleting the relationship failed.
"""
await self._state.http.remove_relationship(self.user.id)
async def accept(self):
"""|coro|
Accepts the relationship request. e.g. accepting a
friend request.
Raises
-------
HTTPException
Accepting the relationship failed.
"""
await self._state.http.add_relationship(self.user.id)

View File

@@ -1,297 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from .permissions import Permissions
from .errors import InvalidArgument
from .colour import Colour
from .mixins import Hashable
from .utils import snowflake_time
class Role(Hashable):
"""Represents a Discord role in a :class:`Guild`.
.. container:: operations
.. describe:: x == y
Checks if two roles are equal.
.. describe:: x != y
Checks if two roles are not equal.
.. describe:: x > y
Checks if a role is higher than another in the hierarchy.
.. describe:: x < y
Checks if a role is lower than another in the hierarchy.
.. describe:: x >= y
Checks if a role is higher or equal to another in the hierarchy.
.. describe:: x <= y
Checks if a role is lower or equal to another in the hierarchy.
.. describe:: hash(x)
Return the role's hash.
.. describe:: str(x)
Returns the role's name.
Attributes
----------
id: :class:`int`
The ID for the role.
name: :class:`str`
The name of the role.
permissions: :class:`Permissions`
Represents the role's permissions.
guild: :class:`Guild`
The guild the role belongs to.
colour: :class:`Colour`
Represents the role colour. An alias exists under ``color``.
hoist: :class:`bool`
Indicates if the role will be displayed separately from other members.
position: :class:`int`
The position of the role. This number is usually positive. The bottom
role has a position of 0.
managed: :class:`bool`
Indicates if the role is managed by the guild through some form of
integrations such as Twitch.
mentionable: :class:`bool`
Indicates if the role can be mentioned by users.
"""
__slots__ = (
"id",
"name",
"permissions",
"color",
"colour",
"position",
"managed",
"mentionable",
"hoist",
"guild",
"_state",
)
def __init__(self, *, guild, state, data):
self.guild = guild
self._state = state
self.id = int(data["id"])
self._update(data)
def __str__(self):
return self.name
def __repr__(self):
return "<Role id={0.id} name={0.name!r}>".format(self)
def __lt__(self, other):
if not isinstance(other, Role) or not isinstance(self, Role):
return NotImplemented
if self.guild != other.guild:
raise RuntimeError("cannot compare roles from two different guilds.")
# the @everyone role is always the lowest role in hierarchy
guild_id = self.guild.id
if self.id == guild_id:
# everyone_role < everyone_role -> False
return other.id != guild_id
if self.position < other.position:
return True
if self.position == other.position:
return int(self.id) > int(other.id)
return False
def __le__(self, other):
r = Role.__lt__(other, self)
if r is NotImplemented:
return NotImplemented
return not r
def __gt__(self, other):
return Role.__lt__(other, self)
def __ge__(self, other):
r = Role.__lt__(self, other)
if r is NotImplemented:
return NotImplemented
return not r
def _update(self, data):
self.name = data["name"]
self.permissions = Permissions(data.get("permissions", 0))
self.position = data.get("position", 0)
self.colour = Colour(data.get("color", 0))
self.hoist = data.get("hoist", False)
self.managed = data.get("managed", False)
self.mentionable = data.get("mentionable", False)
self.color = self.colour
def is_default(self):
"""Checks if the role is the default role."""
return self.guild.id == self.id
@property
def created_at(self):
"""Returns the role's creation time in UTC."""
return snowflake_time(self.id)
@property
def mention(self):
"""Returns a string that allows you to mention a role."""
return "<@&%s>" % self.id
@property
def members(self):
"""Returns a :class:`list` of :class:`Member` with this role."""
all_members = self.guild.members
if self.is_default():
return all_members
role_id = self.id
return [member for member in all_members if member._roles.has(role_id)]
async def _move(self, position, reason):
if position <= 0:
raise InvalidArgument("Cannot move role to position 0 or below")
if self.is_default():
raise InvalidArgument("Cannot move default role")
if self.position == position:
return # Save discord the extra request.
http = self._state.http
change_range = range(min(self.position, position), max(self.position, position) + 1)
roles = [
r.id for r in self.guild.roles[1:] if r.position in change_range and r.id != self.id
]
if self.position > position:
roles.insert(0, self.id)
else:
roles.append(self.id)
payload = [{"id": z[0], "position": z[1]} for z in zip(roles, change_range)]
await http.move_role_position(self.guild.id, payload, reason=reason)
async def edit(self, *, reason=None, **fields):
"""|coro|
Edits the role.
You must have the :attr:`~Permissions.manage_roles` permission to
use this.
All fields are optional.
Parameters
-----------
name: str
The new role name to change to.
permissions: :class:`Permissions`
The new permissions to change to.
colour: :class:`Colour`
The new colour to change to. (aliased to color as well)
hoist: bool
Indicates if the role should be shown separately in the member list.
mentionable: bool
Indicates if the role should be mentionable by others.
position: int
The new role's position. This must be below your top role's
position or it will fail.
reason: Optional[str]
The reason for editing this role. Shows up on the audit log.
Raises
-------
Forbidden
You do not have permissions to change the role.
HTTPException
Editing the role failed.
InvalidArgument
An invalid position was given or the default
role was asked to be moved.
"""
position = fields.get("position")
if position is not None:
await self._move(position, reason=reason)
self.position = position
try:
colour = fields["colour"]
except KeyError:
colour = fields.get("color", self.colour)
payload = {
"name": fields.get("name", self.name),
"permissions": fields.get("permissions", self.permissions).value,
"color": colour.value,
"hoist": fields.get("hoist", self.hoist),
"mentionable": fields.get("mentionable", self.mentionable),
}
data = await self._state.http.edit_role(self.guild.id, self.id, reason=reason, **payload)
self._update(data)
async def delete(self, *, reason=None):
"""|coro|
Deletes the role.
You must have the :attr:`~Permissions.manage_roles` permission to
use this.
Parameters
-----------
reason: Optional[str]
The reason for deleting this role. Shows up on the audit log.
Raises
--------
Forbidden
You do not have permissions to delete the role.
HTTPException
Deleting the role failed.
"""
await self._state.http.delete_role(self.guild.id, self.id, reason=reason)

View File

@@ -1,370 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
import asyncio
import itertools
import logging
import websockets
from .state import AutoShardedConnectionState
from .client import Client
from .gateway import *
from .errors import ClientException, InvalidArgument
from . import utils
from .enums import Status
log = logging.getLogger(__name__)
class Shard:
def __init__(self, ws, client):
self.ws = ws
self._client = client
self.loop = self._client.loop
self._current = self.loop.create_future()
self._current.set_result(None) # we just need an already done future
self._pending = asyncio.Event(loop=self.loop)
self._pending_task = None
@property
def id(self):
return self.ws.shard_id
def is_pending(self):
return not self._pending.is_set()
def complete_pending_reads(self):
self._pending.set()
async def _pending_reads(self):
try:
while self.is_pending():
await self.poll()
except asyncio.CancelledError:
pass
def launch_pending_reads(self):
self._pending_task = asyncio.ensure_future(self._pending_reads(), loop=self.loop)
def wait(self):
return self._pending_task
async def poll(self):
try:
await self.ws.poll_event()
except ResumeWebSocket:
log.info("Got a request to RESUME the websocket at Shard ID %s.", self.id)
coro = DiscordWebSocket.from_client(
self._client,
resume=True,
shard_id=self.id,
session=self.ws.session_id,
sequence=self.ws.sequence,
)
self.ws = await asyncio.wait_for(coro, timeout=180.0, loop=self.loop)
def get_future(self):
if self._current.done():
self._current = asyncio.ensure_future(self.poll(), loop=self.loop)
return self._current
class AutoShardedClient(Client):
"""A client similar to :class:`Client` except it handles the complications
of sharding for the user into a more manageable and transparent single
process bot.
When using this client, you will be able to use it as-if it was a regular
:class:`Client` with a single shard when implementation wise internally it
is split up into multiple shards. This allows you to not have to deal with
IPC or other complicated infrastructure.
It is recommended to use this client only if you have surpassed at least
1000 guilds.
If no :attr:`shard_count` is provided, then the library will use the
Bot Gateway endpoint call to figure out how many shards to use.
If a ``shard_ids`` parameter is given, then those shard IDs will be used
to launch the internal shards. Note that :attr:`shard_count` must be provided
if this is used. By default, when omitted, the client will launch shards from
0 to ``shard_count - 1``.
Attributes
------------
shard_ids: Optional[List[:class:`int`]]
An optional list of shard_ids to launch the shards with.
"""
def __init__(self, *args, loop=None, **kwargs):
kwargs.pop("shard_id", None)
self.shard_ids = kwargs.pop("shard_ids", None)
super().__init__(*args, loop=loop, **kwargs)
if self.shard_ids is not None:
if self.shard_count is None:
raise ClientException(
"When passing manual shard_ids, you must provide a shard_count."
)
elif not isinstance(self.shard_ids, (list, tuple)):
raise ClientException("shard_ids parameter must be a list or a tuple.")
self._connection = AutoShardedConnectionState(
dispatch=self.dispatch,
chunker=self._chunker,
handlers=self._handlers,
syncer=self._syncer,
http=self.http,
loop=self.loop,
**kwargs
)
# instead of a single websocket, we have multiple
# the key is the shard_id
self.shards = {}
def _get_websocket(guild_id):
i = (guild_id >> 22) % self.shard_count
return self.shards[i].ws
self._connection._get_websocket = _get_websocket
async def _chunker(self, guild, *, shard_id=None):
try:
guild_id = guild.id
shard_id = shard_id or guild.shard_id
except AttributeError:
guild_id = [s.id for s in guild]
payload = {"op": 8, "d": {"guild_id": guild_id, "query": "", "limit": 0}}
ws = self.shards[shard_id].ws
await ws.send_as_json(payload)
@property
def latency(self):
""":class:`float`: Measures latency between a HEARTBEAT and a HEARTBEAT_ACK in seconds.
This operates similarly to :meth:`.Client.latency` except it uses the average
latency of every shard's latency. To get a list of shard latency, check the
:attr:`latencies` property. Returns ``nan`` if there are no shards ready.
"""
if not self.shards:
return float("nan")
return sum(latency for _, latency in self.latencies) / len(self.shards)
@property
def latencies(self):
"""List[Tuple[:class:`int`, :class:`float`]]: A list of latencies between a HEARTBEAT and a HEARTBEAT_ACK in seconds.
This returns a list of tuples with elements ``(shard_id, latency)``.
"""
return [(shard_id, shard.ws.latency) for shard_id, shard in self.shards.items()]
async def request_offline_members(self, *guilds):
r"""|coro|
Requests previously offline members from the guild to be filled up
into the :attr:`Guild.members` cache. This function is usually not
called. It should only be used if you have the ``fetch_offline_members``
parameter set to ``False``.
When the client logs on and connects to the websocket, Discord does
not provide the library with offline members if the number of members
in the guild is larger than 250. You can check if a guild is large
if :attr:`Guild.large` is ``True``.
Parameters
-----------
\*guilds
An argument list of guilds to request offline members for.
Raises
-------
InvalidArgument
If any guild is unavailable or not large in the collection.
"""
if any(not g.large or g.unavailable for g in guilds):
raise InvalidArgument("An unavailable or non-large guild was passed.")
_guilds = sorted(guilds, key=lambda g: g.shard_id)
for shard_id, sub_guilds in itertools.groupby(_guilds, key=lambda g: g.shard_id):
sub_guilds = list(sub_guilds)
await self._connection.request_offline_members(sub_guilds, shard_id=shard_id)
async def launch_shard(self, gateway, shard_id):
try:
coro = websockets.connect(
gateway, loop=self.loop, klass=DiscordWebSocket, compression=None
)
ws = await asyncio.wait_for(coro, loop=self.loop, timeout=180.0)
except Exception:
log.info("Failed to connect for shard_id: %s. Retrying...", shard_id)
await asyncio.sleep(5.0, loop=self.loop)
return await self.launch_shard(gateway, shard_id)
ws.token = self.http.token
ws._connection = self._connection
ws._dispatch = self.dispatch
ws.gateway = gateway
ws.shard_id = shard_id
ws.shard_count = self.shard_count
ws._max_heartbeat_timeout = self._connection.heartbeat_timeout
try:
# OP HELLO
await asyncio.wait_for(ws.poll_event(), loop=self.loop, timeout=180.0)
await asyncio.wait_for(ws.identify(), loop=self.loop, timeout=180.0)
except asyncio.TimeoutError:
log.info("Timed out when connecting for shard_id: %s. Retrying...", shard_id)
await asyncio.sleep(5.0, loop=self.loop)
return await self.launch_shard(gateway, shard_id)
# keep reading the shard while others connect
self.shards[shard_id] = ret = Shard(ws, self)
ret.launch_pending_reads()
await asyncio.sleep(5.0, loop=self.loop)
async def launch_shards(self):
if self.shard_count is None:
self.shard_count, gateway = await self.http.get_bot_gateway()
else:
gateway = await self.http.get_gateway()
self._connection.shard_count = self.shard_count
shard_ids = self.shard_ids if self.shard_ids else range(self.shard_count)
for shard_id in shard_ids:
await self.launch_shard(gateway, shard_id)
shards_to_wait_for = []
for shard in self.shards.values():
shard.complete_pending_reads()
shards_to_wait_for.append(shard.wait())
# wait for all pending tasks to finish
await utils.sane_wait_for(shards_to_wait_for, timeout=300.0, loop=self.loop)
async def _connect(self):
await self.launch_shards()
while True:
pollers = [shard.get_future() for shard in self.shards.values()]
done, _ = await asyncio.wait(
pollers, loop=self.loop, return_when=asyncio.FIRST_COMPLETED
)
for f in done:
# we wanna re-raise to the main Client.connect handler if applicable
f.result()
async def close(self):
"""|coro|
Closes the connection to discord.
"""
if self.is_closed():
return
self._closed.set()
for vc in self.voice_clients:
try:
await vc.disconnect()
except Exception:
pass
to_close = [shard.ws.close() for shard in self.shards.values()]
if to_close:
await asyncio.wait(to_close, loop=self.loop)
await self.http.close()
async def change_presence(self, *, activity=None, status=None, afk=False, shard_id=None):
"""|coro|
Changes the client's presence.
The activity parameter is a :class:`Activity` object (not a string) that represents
the activity being done currently. This could also be the slimmed down versions,
:class:`Game` and :class:`Streaming`.
Example: ::
game = discord.Game("with the API")
await client.change_presence(status=discord.Status.idle, activity=game)
Parameters
----------
activity: Optional[Union[:class:`Game`, :class:`Streaming`, :class:`Activity`]]
The activity being done. ``None`` if no currently active activity is done.
status: Optional[:class:`Status`]
Indicates what status to change to. If None, then
:attr:`Status.online` is used.
afk: bool
Indicates if you are going AFK. This allows the discord
client to know how to handle push notifications better
for you in case you are actually idle and not lying.
shard_id: Optional[int]
The shard_id to change the presence to. If not specified
or ``None``, then it will change the presence of every
shard the bot can see.
Raises
------
InvalidArgument
If the ``activity`` parameter is not of proper type.
"""
if status is None:
status = "online"
status_enum = Status.online
elif status is Status.offline:
status = "invisible"
status_enum = Status.offline
else:
status_enum = status
status = str(status)
if shard_id is None:
for shard in self.shards.values():
await shard.ws.change_presence(activity=activity, status=status, afk=afk)
guilds = self._connection.guilds
else:
shard = self.shards[shard_id]
await shard.ws.change_presence(activity=activity, status=status, afk=afk)
guilds = [g for g in self._connection.guilds if g.shard_id == shard_id]
for guild in guilds:
me = guild.me
if me is None:
continue
me.activities = (activity,)
me.status = status_enum

File diff suppressed because it is too large Load Diff

View File

@@ -1,699 +0,0 @@
# -*- coding: utf-8 -*-
"""
The MIT License (MIT)
Copyright (c) 2015-2017 Rapptz
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from collections import namedtuple
import discord.abc
from .utils import snowflake_time, _bytes_to_base64_data, parse_time, valid_icon_size
from .enums import DefaultAvatar, RelationshipType, UserFlags, HypeSquadHouse
from .errors import ClientException, InvalidArgument
from .colour import Colour
VALID_STATIC_FORMATS = {"jpeg", "jpg", "webp", "png"}
VALID_AVATAR_FORMATS = VALID_STATIC_FORMATS | {"gif"}
class Profile(namedtuple("Profile", "flags user mutual_guilds connected_accounts premium_since")):
__slots__ = ()
@property
def nitro(self):
return self.premium_since is not None
premium = nitro
def _has_flag(self, o):
v = o.value
return (self.flags & v) == v
@property
def staff(self):
return self._has_flag(UserFlags.staff)
@property
def partner(self):
return self._has_flag(UserFlags.partner)
@property
def bug_hunter(self):
return self._has_flag(UserFlags.bug_hunter)
@property
def early_supporter(self):
return self._has_flag(UserFlags.early_supporter)
@property
def hypesquad(self):
return self._has_flag(UserFlags.hypesquad)
@property
def hypesquad_houses(self):
flags = (
UserFlags.hypesquad_bravery,
UserFlags.hypesquad_brilliance,
UserFlags.hypesquad_balance,
)
return [house for house, flag in zip(HypeSquadHouse, flags) if self._has_flag(flag)]
_BaseUser = discord.abc.User
class BaseUser(_BaseUser):
__slots__ = ("name", "id", "discriminator", "avatar", "bot", "_state")
def __init__(self, *, state, data):
self._state = state
self.name = data["username"]
self.id = int(data["id"])
self.discriminator = data["discriminator"]
self.avatar = data["avatar"]
self.bot = data.get("bot", False)
def __str__(self):
return "{0.name}#{0.discriminator}".format(self)
def __eq__(self, other):
return isinstance(other, _BaseUser) and other.id == self.id
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return self.id >> 22
@classmethod
def _copy(cls, user):
self = cls.__new__(cls) # bypass __init__
self.name = user.name
self.id = user.id
self.discriminator = user.discriminator
self.avatar = user.avatar
self.bot = user.bot
self._state = user._state
return self
@property
def avatar_url(self):
"""Returns a friendly URL version of the avatar the user has.
If the user does not have a traditional avatar, their default
avatar URL is returned instead.
This is equivalent to calling :meth:`avatar_url_as` with
the default parameters (i.e. webp/gif detection and a size of 1024).
"""
return self.avatar_url_as(format=None, size=1024)
def is_avatar_animated(self):
""":class:`bool`: Returns True if the user has an animated avatar."""
return bool(self.avatar and self.avatar.startswith("a_"))
def avatar_url_as(self, *, format=None, static_format="webp", size=1024):
"""Returns a friendly URL version of the avatar the user has.
If the user does not have a traditional avatar, their default
avatar URL is returned instead.
The format must be one of 'webp', 'jpeg', 'jpg', 'png' or 'gif', and
'gif' is only valid for animated avatars. The size must be a power of 2
between 16 and 1024.
Parameters
-----------
format: Optional[str]
The format to attempt to convert the avatar to.
If the format is ``None``, then it is automatically
detected into either 'gif' or static_format depending on the
avatar being animated or not.
static_format: 'str'
Format to attempt to convert only non-animated avatars to.
Defaults to 'webp'
size: int
The size of the image to display.
Returns
--------
str
The resulting CDN URL.
Raises
------
InvalidArgument
Bad image format passed to ``format`` or ``static_format``, or
invalid ``size``.
"""
if not valid_icon_size(size):
raise InvalidArgument("size must be a power of 2 between 16 and 1024")
if format is not None and format not in VALID_AVATAR_FORMATS:
raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS))
if format == "gif" and not self.is_avatar_animated():
raise InvalidArgument("non animated avatars do not support gif format")
if static_format not in VALID_STATIC_FORMATS:
raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS))
if self.avatar is None:
return self.default_avatar_url
if format is None:
if self.is_avatar_animated():
format = "gif"
else:
format = static_format
return "https://cdn.discordapp.com/avatars/{0.id}/{0.avatar}.{1}?size={2}".format(
self, format, size
)
@property
def default_avatar(self):
"""Returns the default avatar for a given user. This is calculated by the user's discriminator"""
return DefaultAvatar(int(self.discriminator) % len(DefaultAvatar))
@property
def default_avatar_url(self):
"""Returns a URL for a user's default avatar."""
return "https://cdn.discordapp.com/embed/avatars/{}.png".format(self.default_avatar.value)
@property
def colour(self):
"""A property that returns a :class:`Colour` denoting the rendered colour
for the user. This always returns :meth:`Colour.default`.
There is an alias for this under ``color``.
"""
return Colour.default()
color = colour
@property
def mention(self):
"""Returns a string that allows you to mention the given user."""
return "<@{0.id}>".format(self)
def permissions_in(self, channel):
"""An alias for :meth:`abc.GuildChannel.permissions_for`.
Basically equivalent to:
.. code-block:: python3
channel.permissions_for(self)
Parameters
-----------
channel
The channel to check your permissions for.
"""
return channel.permissions_for(self)
@property
def created_at(self):
"""Returns the user's creation time in UTC.
This is when the user's discord account was created."""
return snowflake_time(self.id)
@property
def display_name(self):
"""Returns the user's display name.
For regular users this is just their username, but
if they have a guild specific nickname then that
is returned instead.
"""
return self.name
def mentioned_in(self, message):
"""Checks if the user is mentioned in the specified message.
Parameters
-----------
message : :class:`Message`
The message to check if you're mentioned in.
"""
if message.mention_everyone:
return True
for user in message.mentions:
if user.id == self.id:
return True
return False
class ClientUser(BaseUser):
"""Represents your Discord user.
.. container:: operations
.. describe:: x == y
Checks if two users are equal.
.. describe:: x != y
Checks if two users are not equal.
.. describe:: hash(x)
Return the user's hash.
.. describe:: str(x)
Returns the user's name with discriminator.
Attributes
-----------
name: :class:`str`
The user's username.
id: :class:`int`
The user's unique ID.
discriminator: :class:`str`
The user's discriminator. This is given when the username has conflicts.
avatar: Optional[:class:`str`]
The avatar hash the user has. Could be None.
bot: :class:`bool`
Specifies if the user is a bot account.
verified: :class:`bool`
Specifies if the user is a verified account.
email: Optional[:class:`str`]
The email the user used when registering.
mfa_enabled: :class:`bool`
Specifies if the user has MFA turned on and working.
premium: :class:`bool`
Specifies if the user is a premium user (e.g. has Discord Nitro).
"""
__slots__ = ("email", "verified", "mfa_enabled", "premium", "_relationships")
def __init__(self, *, state, data):
super().__init__(state=state, data=data)
self.verified = data.get("verified", False)
self.email = data.get("email")
self.mfa_enabled = data.get("mfa_enabled", False)
self.premium = data.get("premium", False)
self._relationships = {}
def __repr__(self):
return (
"<ClientUser id={0.id} name={0.name!r} discriminator={0.discriminator!r}"
" bot={0.bot} verified={0.verified} mfa_enabled={0.mfa_enabled}>".format(self)
)
def get_relationship(self, user_id):
"""Retrieves the :class:`Relationship` if applicable.
Parameters
-----------
user_id: int
The user ID to check if we have a relationship with them.
Returns
--------
Optional[:class:`Relationship`]
The relationship if available or ``None``
"""
return self._relationships.get(user_id)
@property
def relationships(self):
"""Returns a :class:`list` of :class:`Relationship` that the user has."""
return list(self._relationships.values())
@property
def friends(self):
r"""Returns a :class:`list` of :class:`User`\s that the user is friends with."""
return [r.user for r in self._relationships.values() if r.type is RelationshipType.friend]
@property
def blocked(self):
r"""Returns a :class:`list` of :class:`User`\s that the user has blocked."""
return [r.user for r in self._relationships.values() if r.type is RelationshipType.blocked]
async def edit(self, **fields):
"""|coro|
Edits the current profile of the client.
If a bot account is used then a password field is optional,
otherwise it is required.
Note
-----
To upload an avatar, a :term:`py:bytes-like object` must be passed in that
represents the image being uploaded. If this is done through a file
then the file must be opened via ``open('some_filename', 'rb')`` and
the :term:`py:bytes-like object` is given through the use of ``fp.read()``.
The only image formats supported for uploading is JPEG and PNG.
Parameters
-----------
password : str
The current password for the client's account.
Only applicable to user accounts.
new_password: str
The new password you wish to change to.
Only applicable to user accounts.
email: str
The new email you wish to change to.
Only applicable to user accounts.
house: Optional[:class:`HypeSquadHouse`]
The hypesquad house you wish to change to.
Could be ``None`` to leave the current house.
Only applicable to user accounts.
username :str
The new username you wish to change to.
avatar: bytes
A :term:`py:bytes-like object` representing the image to upload.
Could be ``None`` to denote no avatar.
Raises
------
HTTPException
Editing your profile failed.
InvalidArgument
Wrong image format passed for ``avatar``.
ClientException
Password is required for non-bot accounts.
House field was not a HypeSquadHouse.
"""
try:
avatar_bytes = fields["avatar"]
except KeyError:
avatar = self.avatar
else:
if avatar_bytes is not None:
avatar = _bytes_to_base64_data(avatar_bytes)
else:
avatar = None
not_bot_account = not self.bot
password = fields.get("password")
if not_bot_account and password is None:
raise ClientException("Password is required for non-bot accounts.")
args = {
"password": password,
"username": fields.get("username", self.name),
"avatar": avatar,
}
if not_bot_account:
args["email"] = fields.get("email", self.email)
if "new_password" in fields:
args["new_password"] = fields["new_password"]
http = self._state.http
if "house" in fields:
house = fields["house"]
if house is None:
await http.leave_hypesquad_house()
elif not isinstance(house, HypeSquadHouse):
raise ClientException("`house` parameter was not a HypeSquadHouse")
else:
value = house.value
await http.change_hypesquad_house(value)
data = await http.edit_profile(**args)
if not_bot_account:
self.email = data["email"]
try:
http._token(data["token"], bot=False)
except KeyError:
pass
# manually update data by calling __init__ explicitly.
self.__init__(state=self._state, data=data)
async def create_group(self, *recipients):
r"""|coro|
Creates a group direct message with the recipients
provided. These recipients must be have a relationship
of type :attr:`RelationshipType.friend`.
Bot accounts cannot create a group.
Parameters
-----------
\*recipients
An argument :class:`list` of :class:`User` to have in
your group.
Return
-------
:class:`GroupChannel`
The new group channel.
Raises
-------
HTTPException
Failed to create the group direct message.
ClientException
Attempted to create a group with only one recipient.
This does not include yourself.
"""
from .channel import GroupChannel
if len(recipients) < 2:
raise ClientException("You must have two or more recipients to create a group.")
users = [str(u.id) for u in recipients]
data = await self._state.http.start_group(self.id, users)
return GroupChannel(me=self, data=data, state=self._state)
class User(BaseUser, discord.abc.Messageable):
"""Represents a Discord user.
.. container:: operations
.. describe:: x == y
Checks if two users are equal.
.. describe:: x != y
Checks if two users are not equal.
.. describe:: hash(x)
Return the user's hash.
.. describe:: str(x)
Returns the user's name with discriminator.
Attributes
-----------
name: :class:`str`
The user's username.
id: :class:`int`
The user's unique ID.
discriminator: :class:`str`
The user's discriminator. This is given when the username has conflicts.
avatar: Optional[:class:`str`]
The avatar hash the user has. Could be None.
bot: :class:`bool`
Specifies if the user is a bot account.
"""
__slots__ = ("__weakref__",)
def __repr__(self):
return "<User id={0.id} name={0.name!r} discriminator={0.discriminator!r} bot={0.bot}>".format(
self
)
async def _get_channel(self):
ch = await self.create_dm()
return ch
@property
def dm_channel(self):
"""Returns the :class:`DMChannel` associated with this user if it exists.
If this returns ``None``, you can create a DM channel by calling the
:meth:`create_dm` coroutine function.
"""
return self._state._get_private_channel_by_user(self.id)
async def create_dm(self):
"""Creates a :class:`DMChannel` with this user.
This should be rarely called, as this is done transparently for most
people.
"""
found = self.dm_channel
if found is not None:
return found
state = self._state
data = await state.http.start_private_message(self.id)
return state.add_dm_channel(data)
@property
def relationship(self):
"""Returns the :class:`Relationship` with this user if applicable, ``None`` otherwise."""
return self._state.user.get_relationship(self.id)
async def mutual_friends(self):
"""|coro|
Gets all mutual friends of this user. This can only be used by non-bot accounts
Returns
-------
List[:class:`User`]
The users that are mutual friends.
Raises
-------
Forbidden
Not allowed to get mutual friends of this user.
HTTPException
Getting mutual friends failed.
"""
state = self._state
mutuals = await state.http.get_mutual_friends(self.id)
return [User(state=state, data=friend) for friend in mutuals]
def is_friend(self):
""":class:`bool`: Checks if the user is your friend."""
r = self.relationship
if r is None:
return False
return r.type is RelationshipType.friend
def is_blocked(self):
""":class:`bool`: Checks if the user is blocked."""
r = self.relationship
if r is None:
return False
return r.type is RelationshipType.blocked
async def block(self):
"""|coro|
Blocks the user.
Raises
-------
Forbidden
Not allowed to block this user.
HTTPException
Blocking the user failed.
"""
await self._state.http.add_relationship(self.id, type=RelationshipType.blocked.value)
async def unblock(self):
"""|coro|
Unblocks the user.
Raises
-------
Forbidden
Not allowed to unblock this user.
HTTPException
Unblocking the user failed.
"""
await self._state.http.remove_relationship(self.id)
async def remove_friend(self):
"""|coro|
Removes the user as a friend.
Raises
-------
Forbidden
Not allowed to remove this user as a friend.
HTTPException
Removing the user as a friend failed.
"""
await self._state.http.remove_relationship(self.id)
async def send_friend_request(self):
"""|coro|
Sends the user a friend request.
Raises
-------
Forbidden
Not allowed to send a friend request to the user.
HTTPException
Sending the friend request failed.
"""
await self._state.http.send_friend_request(
username=self.name, discriminator=self.discriminator
)
async def profile(self):
"""|coro|
Gets the user's profile. This can only be used by non-bot accounts.
Raises
-------
Forbidden
Not allowed to fetch profiles.
HTTPException
Fetching the profile failed.
Returns
--------
:class:`Profile`
The profile of the user.
"""
state = self._state
data = await state.http.get_user_profile(self.id)
def transform(d):
return state._get_guild(int(d["id"]))
since = data.get("premium_since")
mutual_guilds = list(filter(None, map(transform, data.get("mutual_guilds", []))))
return Profile(
flags=data["user"].get("flags", 0),
premium_since=parse_time(since),
mutual_guilds=mutual_guilds,
user=self,
connected_accounts=data["connected_accounts"],
)

Some files were not shown because too many files have changed in this diff Show More