diff options
| author | 2021-03-17 15:36:33 +0100 | |
|---|---|---|
| committer | 2021-03-17 15:36:33 +0100 | |
| commit | d498cc6ecd3faeef9cbae6d329e9ad048db205fd (patch) | |
| tree | db949f921e4da10236517ccddf0bf53b2779bf41 | |
| parent | Merge branch 'master' into swfarnsworth/infraction_message (diff) | |
| parent | Merge pull request #1467 from python-discord/bug/info/bot-xr/code-block-null-... (diff) | |
Merge branch 'main' into swfarnsworth/infraction_message
33 files changed, 358 insertions, 429 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..176a458f9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 6d9919ef2..000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,2 +0,0 @@ -patreon: python_discord -custom: https://www.redbubble.com/people/pythondiscord diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6c97e8784..e6826e09b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: workflow_run: workflows: ["Lint & Test"] branches: - - master + - main types: - completed diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5a4aede30..8b809b777 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,12 +4,13 @@ on: workflow_run: workflows: ["Build"] branches: - - master + - main types: - completed jobs: build: + environment: production if: github.event.workflow_run.conclusion == 'success' name: Build & Push runs-on: ubuntu-latest diff --git a/.github/workflows/lint-test.yml b/.github/workflows/lint-test.yml index 6fa8e8333..95bed2e14 100644 --- a/.github/workflows/lint-test.yml +++ b/.github/workflows/lint-test.yml @@ -3,7 +3,7 @@ name: Lint & Test on: push: branches: - - master + - main pull_request: diff --git a/.github/workflows/sentry_release.yml b/.github/workflows/sentry_release.yml index b8d92e90a..f6a1e1f0e 100644 --- a/.github/workflows/sentry_release.yml +++ b/.github/workflows/sentry_release.yml @@ -3,14 +3,14 @@ name: Create Sentry release on: push: branches: - - master + - main jobs: create_sentry_release: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@master + uses: actions/checkout@main - name: Create a Sentry.io release uses: tclindner/[email protected] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1597592ca..52500a282 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,8 +7,6 @@ repos: - id: check-yaml args: [--unsafe] # Required due to custom constructors (e.g. !ENV) - id: end-of-file-fixer - - id: mixed-line-ending - args: [--fix=lf] - id: trailing-whitespace args: [--markdown-linebreak-ext=md] - repo: https://github.com/pre-commit/pygrep-hooks diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index be591d17e..addab32ff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to one of Our Projects -Our projects are open-source and are automatically deployed whenever commits are pushed to the `master` branch on each repository, so we've created a set of guidelines in order to keep everything clean and in working order. +Our projects are open-source and are automatically deployed whenever commits are pushed to the `main` branch on each repository, so we've created a set of guidelines in order to keep everything clean and in working order. Note that contributions may be rejected on the basis of a contributor failing to follow these guidelines. @@ -8,7 +8,7 @@ Note that contributions may be rejected on the basis of a contributor failing to 1. **No force-pushes** or modifying the Git history in any way. 2. If you have direct access to the repository, **create a branch for your changes** and create a pull request for that branch. If not, create a branch on a fork of the repository and create a pull request from there. - * It's common practice for a repository to reject direct pushes to `master`, so make branching a habit! + * It's common practice for a repository to reject direct pushes to `main`, so make branching a habit! * If PRing from your own fork, **ensure that "Allow edits from maintainers" is checked**. This gives permission for maintainers to commit changes directly to your fork, speeding up the review process. 3. **Adhere to the prevailing code style**, which we enforce using [`flake8`](http://flake8.pycqa.org/en/latest/index.html) and [`pre-commit`](https://pre-commit.com/). * Run `flake8` and `pre-commit` against your code [**before** you push it](https://soundcloud.com/lemonsaurusrex/lint-before-you-push). Your commit will be rejected by the build server if it fails to lint. @@ -18,7 +18,7 @@ Note that contributions may be rejected on the basis of a contributor failing to * Avoid making minor commits for fixing typos or linting errors. Since you've already set up a `pre-commit` hook to run the linting pipeline before a commit, you shouldn't be committing linting issues anyway. * A more in-depth guide to writing great commit messages can be found in Chris Beam's [*How to Write a Git Commit Message*](https://chris.beams.io/posts/git-commit/) 5. **Avoid frequent pushes to the main repository**. This goes for PRs opened against your fork as well. Our test build pipelines are triggered every time a push to the repository (or PR) is made. Try to batch your commits until you've finished working for that session, or you've reached a point where collaborators need your commits to continue their own work. This also provides you the opportunity to amend commits for minor changes rather than having to commit them on their own because you've already pushed. - * This includes merging master into your branch. Try to leave merging from master for after your PR passes review; a maintainer will bring your PR up to date before merging. Exceptions to this include: resolving merge conflicts, needing something that was pushed to master for your branch, or something was pushed to master that could potentionally affect the functionality of what you're writing. + * This includes merging main into your branch. Try to leave merging from main for after your PR passes review; a maintainer will bring your PR up to date before merging. Exceptions to this include: resolving merge conflicts, needing something that was pushed to main for your branch, or something was pushed to main that could potentionally affect the functionality of what you're writing. 6. **Don't fight the framework**. Every framework has its flaws, but the frameworks we've picked out have been carefully chosen for their particular merits. If you can avoid it, please resist reimplementing swathes of framework logic - the work has already been done for you! 7. If someone is working on an issue or pull request, **do not open your own pull request for the same task**. Instead, collaborate with the author(s) of the existing pull request. Duplicate PRs opened without communicating with the other author(s) and/or PyDis staff will be closed. Communication is key, and there's no point in two separate implementations of the same thing. * One option is to fork the other contributor's repository and submit your changes to their branch with your own pull request. We suggest following these guidelines when interacting with their repository as well. @@ -28,7 +28,6 @@ sphinx = "~=2.2" statsd = "~=3.3" arrow = "~=0.17" emoji = "~=0.6" -python-json-logger = "~=2.0" [dev-packages] coverage = "~=5.0" diff --git a/Pipfile.lock b/Pipfile.lock index dc7f6f21f..f8cedb08f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "81ca9d1891e71de1c3f71958f082e1a8cad71e5b3ca425dc561d0ae74664fdb0" + "sha256": "228ae55fe5700ac3827ba6b661933b60b1d06f44fea8bcbe8c5a769fa10ab2fd" }, "pipfile-spec": 6, "requires": { @@ -18,11 +18,11 @@ "default": { "aio-pika": { "hashes": [ - "sha256:1d4305a5f78af3857310b4fe48348cdcf6c097e0e275ea88c2cd08570531a369", - "sha256:e69afef8695f47c5d107bbdba21bdb845d5c249acb3be53ef5c2d497b02657c0" + "sha256:9773440a89840941ac3099a7720bf9d51e8764a484066b82ede4d395660ff430", + "sha256:a8065be3c722eb8f9fff8c0e7590729e7782202cdb9363d9830d7d5d47b45c7c" ], "index": "pypi", - "version": "==6.8.0" + "version": "==6.7.1" }, "aiodns": { "hashes": [ @@ -96,7 +96,6 @@ "sha256:8218dd9f7198d6e7935855468326bbacf0089f926c70baa8dd92944cb2496573", "sha256:e584dac13a242589aaf42470fd3006cb0dc5aed6506cbd20357c7ec8bbe4a89e" ], - "markers": "python_version >= '3.6'", "version": "==3.3.1" }, "alabaster": { @@ -123,7 +122,6 @@ "sha256:c25e4fff73f64d20645254783c3224a4c49e083e3fab67c44f17af944c5e26af" ], "index": "pypi", - "markers": "python_version ~= '3.7'", "version": "==0.1.4" }, "async-timeout": { @@ -131,7 +129,6 @@ "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" ], - "markers": "python_full_version >= '3.5.3'", "version": "==3.0.1" }, "attrs": { @@ -139,7 +136,6 @@ "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.3.0" }, "babel": { @@ -147,7 +143,6 @@ "sha256:9d35c22fcc79893c3ecc85ac4a56cde1ecf3f19c540bba0922308a6c06ca6fa5", "sha256:da031ab54472314f210b0adcff1588ee5d1d1d0ba4dbd07b94dba82bde791e05" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.9.0" }, "beautifulsoup4": { @@ -220,6 +215,7 @@ "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" ], + "index": "pypi", "markers": "sys_platform == 'win32'", "version": "==0.4.4" }, @@ -252,7 +248,6 @@ "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af", "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==0.16" }, "emoji": { @@ -335,7 +330,6 @@ "sha256:e64be68255234bb489a574c4f2f8df7029c98c81ec4d160d6cd836e7f0679390", "sha256:e82d6b930e02e80e5109b678c663a9ed210680ded81c1abaf54635d88d1da298" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.1.0" }, "humanfriendly": { @@ -343,7 +337,6 @@ "sha256:066562956639ab21ff2676d1fda0b5987e985c534fc76700a19bd54bcb81121d", "sha256:d5c731705114b9ad673754f3317d9fa4c23212f36b29bdc4272a892eafc9bc72" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==9.1" }, "idna": { @@ -351,7 +344,6 @@ "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.10" }, "imagesize": { @@ -359,7 +351,6 @@ "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1", "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.2.0" }, "jinja2": { @@ -367,7 +358,6 @@ "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==2.11.3" }, "lxml": { @@ -476,16 +466,15 @@ "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be", "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.1.1" }, "more-itertools": { "hashes": [ - "sha256:5652a9ac72209ed7df8d9c15daf4e1aa0e3d2ccd3c87f8265a0673cd9cbc9ced", - "sha256:c5d6da9ca3ff65220c3bfd2a8db06d698f05d4d2b9be57e1deb2be5a45019713" + "sha256:8e1a2a43b2f2727425f2b5839587ae37093f19153dc26c0927d1048ff6557330", + "sha256:b3a9005928e5bed54076e6e549c792b306fddfe72b2d1d22dd63d42d5d3899cf" ], "index": "pypi", - "version": "==8.7.0" + "version": "==8.6.0" }, "multidict": { "hashes": [ @@ -527,14 +516,12 @@ "sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281", "sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80" ], - "markers": "python_version >= '3.6'", "version": "==5.1.0" }, "ordered-set": { "hashes": [ "sha256:ba93b2df055bca202116ec44b9bead3df33ea63a7d5827ff8e16738b97f33a95" ], - "markers": "python_version >= '3.5'", "version": "==4.0.2" }, "packaging": { @@ -542,7 +529,6 @@ "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5", "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.9" }, "pamqp": { @@ -591,7 +577,6 @@ "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.20" }, "pygments": { @@ -599,7 +584,6 @@ "sha256:37a13ba168a02ac54cc5891a42b1caec333e59b66addb7fa633ea8a6d73445c0", "sha256:b21b072d0ccdf29297a82a2363359d99623597b8a265b8081760e4d0f7153c88" ], - "markers": "python_version >= '3.5'", "version": "==2.8.0" }, "pyparsing": { @@ -607,7 +591,6 @@ "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.4.7" }, "python-dateutil": { @@ -618,13 +601,6 @@ "index": "pypi", "version": "==2.8.1" }, - "python-json-logger": { - "hashes": [ - "sha256:f26eea7898db40609563bed0a7ca11af12e2a79858632706d835a0f961b7d398" - ], - "index": "pypi", - "version": "==2.0.1" - }, "pytz": { "hashes": [ "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da", @@ -634,37 +610,28 @@ }, "pyyaml": { "hashes": [ - "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", - "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", - "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", - "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", - "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", - "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", - "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", - "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", - "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", - "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", - "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", - "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", - "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", - "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", - "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", - "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", - "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", - "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", - "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", - "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", - "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc" + "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", + "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", + "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", + "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e", + "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", + "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", + "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", + "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", + "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", + "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a", + "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", + "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", + "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" ], "index": "pypi", - "version": "==5.4.1" + "version": "==5.3.1" }, "redis": { "hashes": [ "sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2", "sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==3.5.3" }, "requests": { @@ -677,18 +644,17 @@ }, "sentry-sdk": { "hashes": [ - "sha256:4ae8d1ced6c67f1c8ea51d82a16721c166c489b76876c9f2c202b8a50334b237", - "sha256:e75c8c58932bda8cd293ea8e4b242527129e1caaec91433d21b8b2f20fee030b" + "sha256:0a711ec952441c2ec89b8f5d226c33bc697914f46e876b44a4edd3e7864cf4d0", + "sha256:737a094e49a529dd0fdcaafa9e97cf7c3d5eb964bd229821d640bc77f3502b3f" ], "index": "pypi", - "version": "==0.20.3" + "version": "==0.19.5" }, "six": { "hashes": [ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.15.0" }, "snowballstemmer": { @@ -726,7 +692,6 @@ "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a", "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58" ], - "markers": "python_version >= '3.5'", "version": "==1.0.2" }, "sphinxcontrib-devhelp": { @@ -734,7 +699,6 @@ "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e", "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4" ], - "markers": "python_version >= '3.5'", "version": "==1.0.2" }, "sphinxcontrib-htmlhelp": { @@ -742,7 +706,6 @@ "sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f", "sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b" ], - "markers": "python_version >= '3.5'", "version": "==1.0.3" }, "sphinxcontrib-jsmath": { @@ -750,7 +713,6 @@ "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8" ], - "markers": "python_version >= '3.5'", "version": "==1.0.1" }, "sphinxcontrib-qthelp": { @@ -758,7 +720,6 @@ "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72", "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6" ], - "markers": "python_version >= '3.5'", "version": "==1.0.3" }, "sphinxcontrib-serializinghtml": { @@ -766,7 +727,6 @@ "sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc", "sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a" ], - "markers": "python_version >= '3.5'", "version": "==1.1.4" }, "statsd": { @@ -790,7 +750,6 @@ "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80", "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", "version": "==1.26.3" }, "yarl": { @@ -833,7 +792,6 @@ "sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a", "sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71" ], - "markers": "python_version >= '3.6'", "version": "==1.6.3" } }, @@ -850,7 +808,6 @@ "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.3.0" }, "certifi": { @@ -865,7 +822,6 @@ "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d", "sha256:cf22deb93d4bcf92f345a5c3cd39d3d41d6340adc60c78bbbd6588c384fda6a1" ], - "markers": "python_full_version >= '3.6.1'", "version": "==3.2.0" }, "chardet": { @@ -877,61 +833,58 @@ }, "coverage": { "hashes": [ - "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c", - "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6", - "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45", - "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a", - "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03", - "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529", - "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a", - "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a", - "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2", - "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6", - "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759", - "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53", - "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a", - "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4", - "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff", - "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502", - "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793", - "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb", - "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905", - "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821", - "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b", - "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81", - "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0", - "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b", - "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3", - "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184", - "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701", - "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a", - "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82", - "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638", - "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5", - "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083", - "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6", - "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90", - "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465", - "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a", - "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3", - "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e", - "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066", - "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf", - "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b", - "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae", - "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669", - "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873", - "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b", - "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6", - "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb", - "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160", - "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c", - "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079", - "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d", - "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6" + "sha256:08b3ba72bd981531fd557f67beee376d6700fba183b167857038997ba30dd297", + "sha256:2757fa64e11ec12220968f65d086b7a29b6583d16e9a544c889b22ba98555ef1", + "sha256:3102bb2c206700a7d28181dbe04d66b30780cde1d1c02c5f3c165cf3d2489497", + "sha256:3498b27d8236057def41de3585f317abae235dd3a11d33e01736ffedb2ef8606", + "sha256:378ac77af41350a8c6b8801a66021b52da8a05fd77e578b7380e876c0ce4f528", + "sha256:38f16b1317b8dd82df67ed5daa5f5e7c959e46579840d77a67a4ceb9cef0a50b", + "sha256:3911c2ef96e5ddc748a3c8b4702c61986628bb719b8378bf1e4a6184bbd48fe4", + "sha256:3a3c3f8863255f3c31db3889f8055989527173ef6192a283eb6f4db3c579d830", + "sha256:3b14b1da110ea50c8bcbadc3b82c3933974dbeea1832e814aab93ca1163cd4c1", + "sha256:535dc1e6e68fad5355f9984d5637c33badbdc987b0c0d303ee95a6c979c9516f", + "sha256:6f61319e33222591f885c598e3e24f6a4be3533c1d70c19e0dc59e83a71ce27d", + "sha256:723d22d324e7997a651478e9c5a3120a0ecbc9a7e94071f7e1954562a8806cf3", + "sha256:76b2775dda7e78680d688daabcb485dc87cf5e3184a0b3e012e1d40e38527cc8", + "sha256:782a5c7df9f91979a7a21792e09b34a658058896628217ae6362088b123c8500", + "sha256:7e4d159021c2029b958b2363abec4a11db0ce8cd43abb0d9ce44284cb97217e7", + "sha256:8dacc4073c359f40fcf73aede8428c35f84639baad7e1b46fce5ab7a8a7be4bb", + "sha256:8f33d1156241c43755137288dea619105477961cfa7e47f48dbf96bc2c30720b", + "sha256:8ffd4b204d7de77b5dd558cdff986a8274796a1e57813ed005b33fd97e29f059", + "sha256:93a280c9eb736a0dcca19296f3c30c720cb41a71b1f9e617f341f0a8e791a69b", + "sha256:9a4f66259bdd6964d8cf26142733c81fb562252db74ea367d9beb4f815478e72", + "sha256:9a9d4ff06804920388aab69c5ea8a77525cf165356db70131616acd269e19b36", + "sha256:a2070c5affdb3a5e751f24208c5c4f3d5f008fa04d28731416e023c93b275277", + "sha256:a4857f7e2bc6921dbd487c5c88b84f5633de3e7d416c4dc0bb70256775551a6c", + "sha256:a607ae05b6c96057ba86c811d9c43423f35e03874ffb03fbdcd45e0637e8b631", + "sha256:a66ca3bdf21c653e47f726ca57f46ba7fc1f260ad99ba783acc3e58e3ebdb9ff", + "sha256:ab110c48bc3d97b4d19af41865e14531f300b482da21783fdaacd159251890e8", + "sha256:b239711e774c8eb910e9b1ac719f02f5ae4bf35fa0420f438cdc3a7e4e7dd6ec", + "sha256:be0416074d7f253865bb67630cf7210cbc14eb05f4099cc0f82430135aaa7a3b", + "sha256:c46643970dff9f5c976c6512fd35768c4a3819f01f61169d8cdac3f9290903b7", + "sha256:c5ec71fd4a43b6d84ddb88c1df94572479d9a26ef3f150cef3dacefecf888105", + "sha256:c6e5174f8ca585755988bc278c8bb5d02d9dc2e971591ef4a1baabdf2d99589b", + "sha256:c89b558f8a9a5a6f2cfc923c304d49f0ce629c3bd85cb442ca258ec20366394c", + "sha256:cc44e3545d908ecf3e5773266c487ad1877be718d9dc65fc7eb6e7d14960985b", + "sha256:cc6f8246e74dd210d7e2b56c76ceaba1cc52b025cd75dbe96eb48791e0250e98", + "sha256:cd556c79ad665faeae28020a0ab3bda6cd47d94bec48e36970719b0b86e4dcf4", + "sha256:ce6f3a147b4b1a8b09aae48517ae91139b1b010c5f36423fa2b866a8b23df879", + "sha256:ceb499d2b3d1d7b7ba23abe8bf26df5f06ba8c71127f188333dddcf356b4b63f", + "sha256:cef06fb382557f66d81d804230c11ab292d94b840b3cb7bf4450778377b592f4", + "sha256:e448f56cfeae7b1b3b5bcd99bb377cde7c4eb1970a525c770720a352bc4c8044", + "sha256:e52d3d95df81c8f6b2a1685aabffadf2d2d9ad97203a40f8d61e51b70f191e4e", + "sha256:ee2f1d1c223c3d2c24e3afbb2dd38be3f03b1a8d6a83ee3d9eb8c36a52bee899", + "sha256:f2c6888eada180814b8583c3e793f3f343a692fc802546eed45f40a001b1169f", + "sha256:f51dbba78d68a44e99d484ca8c8f604f17e957c1ca09c3ebc2c7e3bbd9ba0448", + "sha256:f54de00baf200b4539a5a092a759f000b5f45fd226d6d25a76b0dff71177a714", + "sha256:fa10fee7e32213f5c7b0d6428ea92e3a3fdd6d725590238a3f92c0de1c78b9d2", + "sha256:fabeeb121735d47d8eab8671b6b031ce08514c86b7ad8f7d5490a7b6dcd6267d", + "sha256:fac3c432851038b3e6afe086f777732bcf7f6ebbfd90951fa04ee53db6d0bcdd", + "sha256:fda29412a66099af6d6de0baa6bd7c52674de177ec2ad2630ca264142d69c6c7", + "sha256:ff1330e8bc996570221b450e2d539134baa9465f5cb98aff0e0f73f34172e0ae" ], "index": "pypi", - "version": "==5.5" + "version": "==5.3.1" }, "coveralls": { "hashes": [ @@ -971,11 +924,11 @@ }, "flake8-annotations": { "hashes": [ - "sha256:8968ff12f296433028ad561c680ccc03a7cd62576d100c3f1475e058b3c11b43", - "sha256:bd0505616c0d85ebb45c6052d339c69f320d3f87fa079ab4e91a4f234a863d05" + "sha256:3a377140556aecf11fa9f3bb18c10db01f5ea56dc79a730e2ec9b4f1f49e2055", + "sha256:e17947a48a5b9f632fe0c72682fc797c385e451048e7dfb20139f448a074cb3e" ], "index": "pypi", - "version": "==2.6.0" + "version": "==2.5.0" }, "flake8-bugbear": { "hashes": [ @@ -1033,18 +986,16 @@ }, "identify": { "hashes": [ - "sha256:2179e7359471ab55729f201b3fdf7dc2778e221f868410fedcb0987b791ba552", - "sha256:2a5fdf2f5319cc357eda2550bea713a404392495961022cf2462624ce62f0f46" + "sha256:de7129142a5c86d75a52b96f394d94d96d497881d2aaf8eafe320cdbe8ac4bcc", + "sha256:e0dae57c0397629ce13c289f6ddde0204edf518f557bfdb1e56474aa143e77c3" ], - "markers": "python_full_version >= '3.6.1'", - "version": "==2.1.0" + "version": "==1.5.14" }, "idna": { "hashes": [ "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.10" }, "mccabe": { @@ -1071,18 +1022,17 @@ }, "pre-commit": { "hashes": [ - "sha256:16212d1fde2bed88159287da88ff03796863854b04dc9f838a55979325a3d20e", - "sha256:399baf78f13f4de82a29b649afd74bef2c4e28eb4f021661fc7f29246e8c7a3a" + "sha256:6c86d977d00ddc8a60d68eec19f51ef212d9462937acf3ea37c7adec32284ac0", + "sha256:ee784c11953e6d8badb97d19bc46b997a3a9eded849881ec587accd8608d74a4" ], "index": "pypi", - "version": "==2.10.1" + "version": "==2.9.3" }, "pycodestyle": { "hashes": [ "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367", "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.6.0" }, "pydocstyle": { @@ -1090,7 +1040,6 @@ "sha256:19b86fa8617ed916776a11cd8bc0197e5b9856d5433b777f51a3defe13075325", "sha256:aca749e190a01726a4fb472dd4ef23b5c9da7b9205c0a7857c06533de13fd678" ], - "markers": "python_version >= '3.5'", "version": "==5.1.1" }, "pyflakes": { @@ -1098,35 +1047,26 @@ "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92", "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.2.0" }, "pyyaml": { "hashes": [ - "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", - "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", - "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", - "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", - "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", - "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", - "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", - "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", - "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", - "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", - "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", - "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", - "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", - "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", - "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", - "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", - "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", - "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", - "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", - "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", - "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc" + "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", + "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", + "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", + "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e", + "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", + "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", + "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", + "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", + "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", + "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a", + "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", + "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", + "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" ], "index": "pypi", - "version": "==5.4.1" + "version": "==5.3.1" }, "requests": { "hashes": [ @@ -1141,7 +1081,6 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.15.0" }, "snowballstemmer": { @@ -1156,7 +1095,6 @@ "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.10.2" }, "urllib3": { @@ -1164,7 +1102,6 @@ "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80", "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", "version": "==1.26.3" }, "virtualenv": { @@ -1172,7 +1109,6 @@ "sha256:147b43894e51dd6bba882cf9c282447f780e2251cd35172403745fc381a0a80d", "sha256:2be72df684b74df0ea47679a7df93fd0e04e72520022c57b479d8f881485dbe3" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.4.2" } } @@ -12,11 +12,11 @@ and other tools to help keep the server running like a well-oiled machine. Read the [Contributing Guide](https://pythondiscord.com/pages/contributing/bot/) on our website if you're interested in helping out. -[1]: https://github.com/python-discord/bot/workflows/Lint%20&%20Test/badge.svg?branch=master -[2]: https://github.com/python-discord/bot/actions?query=workflow%3A%22Lint+%26+Test%22+branch%3Amaster -[3]: https://github.com/python-discord/bot/workflows/Build/badge.svg?branch=master -[4]: https://github.com/python-discord/bot/actions?query=workflow%3ABuild+branch%3Amaster -[5]: https://github.com/python-discord/bot/workflows/Deploy/badge.svg?branch=master -[6]: https://github.com/python-discord/bot/actions?query=workflow%3ADeploy+branch%3Amaster -[7]: https://raw.githubusercontent.com/python-discord/branding/master/logos/badge/badge_github.svg +[1]: https://github.com/python-discord/bot/workflows/Lint%20&%20Test/badge.svg?branch=main +[2]: https://github.com/python-discord/bot/actions?query=workflow%3A%22Lint+%26+Test%22+branch%3Amain +[3]: https://github.com/python-discord/bot/workflows/Build/badge.svg?branch=main +[4]: https://github.com/python-discord/bot/actions?query=workflow%3ABuild+branch%3Amain +[5]: https://github.com/python-discord/bot/workflows/Deploy/badge.svg?branch=main +[6]: https://github.com/python-discord/bot/actions?query=workflow%3ADeploy+branch%3Amain +[7]: https://raw.githubusercontent.com/python-discord/branding/main/logos/badge/badge_github.svg [8]: https://discord.gg/python diff --git a/bot/exts/backend/branding/_constants.py b/bot/exts/backend/branding/_constants.py index dbc7615f2..ca8e8c5f5 100644 --- a/bot/exts/backend/branding/_constants.py +++ b/bot/exts/backend/branding/_constants.py @@ -42,7 +42,7 @@ SERVER_ICONS = "server_icons" BRANDING_URL = "https://api.github.com/repos/python-discord/branding/contents" -PARAMS = {"ref": "master"} # Target branch +PARAMS = {"ref": "main"} # Target branch HEADERS = {"Accept": "application/vnd.github.v3+json"} # Ensure we use API v3 # A GitHub token is not necessary for the cog to operate, diff --git a/bot/exts/backend/logging.py b/bot/exts/backend/logging.py index 94fa2b139..823f14ea4 100644 --- a/bot/exts/backend/logging.py +++ b/bot/exts/backend/logging.py @@ -29,7 +29,7 @@ class Logging(Cog): url="https://github.com/python-discord/bot", icon_url=( "https://raw.githubusercontent.com/" - "python-discord/branding/master/logos/logo_circle/logo_circle_large.png" + "python-discord/branding/main/logos/logo_circle/logo_circle_large.png" ) ) diff --git a/bot/exts/filters/webhook_remover.py b/bot/exts/filters/webhook_remover.py index 08fe94055..f11fc8912 100644 --- a/bot/exts/filters/webhook_remover.py +++ b/bot/exts/filters/webhook_remover.py @@ -14,7 +14,7 @@ WEBHOOK_URL_RE = re.compile(r"((?:https?://)?discord(?:app)?\.com/api/webhooks/\ ALERT_MESSAGE_TEMPLATE = ( "{user}, looks like you posted a Discord webhook URL. Therefore, your " "message has been removed. Your webhook may have been **compromised** so " - "please re-create the webhook **immediately**. If you believe this was " + "please re-create the webhook **immediately**. If you believe this was a " "mistake, please let us know." ) diff --git a/bot/exts/help_channels/_cog.py b/bot/exts/help_channels/_cog.py index 6abf99810..1c730dce9 100644 --- a/bot/exts/help_channels/_cog.py +++ b/bot/exts/help_channels/_cog.py @@ -54,7 +54,7 @@ class HelpChannels(commands.Cog): * Contains channels which aren't in use * Channels are used to refill the Available category - Help channels are named after the chemical elements in `bot/resources/elements.json`. + Help channels are named after the foods in `bot/resources/foods.json`. """ def __init__(self, bot: Bot): diff --git a/bot/exts/help_channels/_name.py b/bot/exts/help_channels/_name.py index 728234b1e..061f855ae 100644 --- a/bot/exts/help_channels/_name.py +++ b/bot/exts/help_channels/_name.py @@ -14,11 +14,11 @@ log = logging.getLogger(__name__) def create_name_queue(*categories: discord.CategoryChannel) -> deque: """ - Return a queue of element names to use for creating new channels. + Return a queue of food names to use for creating new channels. Skip names that are already in use by channels in `categories`. """ - log.trace("Creating the chemical element name queue.") + log.trace("Creating the food name queue.") used_names = _get_used_names(*categories) @@ -31,7 +31,7 @@ def create_name_queue(*categories: discord.CategoryChannel) -> deque: def _get_names() -> t.List[str]: """ - Return a truncated list of prefixed element names. + Return a truncated list of prefixed food names. The amount of names is configured with `HelpChannels.max_total_channels`. The prefix is configured with `HelpChannels.name_prefix`. @@ -39,10 +39,10 @@ def _get_names() -> t.List[str]: count = constants.HelpChannels.max_total_channels prefix = constants.HelpChannels.name_prefix - log.trace(f"Getting the first {count} element names from JSON.") + log.trace(f"Getting the first {count} food names from JSON.") - with Path("bot/resources/elements.json").open(encoding="utf-8") as elements_file: - all_names = json.load(elements_file) + with Path("bot/resources/foods.json").open(encoding="utf-8") as foods_file: + all_names = json.load(foods_file) if prefix: return [prefix + name for name in all_names[:count]] diff --git a/bot/exts/info/codeblock/_parsing.py b/bot/exts/info/codeblock/_parsing.py index e35fbca22..73fd11b94 100644 --- a/bot/exts/info/codeblock/_parsing.py +++ b/bot/exts/info/codeblock/_parsing.py @@ -103,6 +103,9 @@ def _is_python_code(content: str) -> bool: """Return True if `content` is valid Python consisting of more than just expressions.""" log.trace("Checking if content is Python code.") try: + # Remove null bytes because they cause ast.parse to raise a ValueError. + content = content.replace("\x00", "") + # Attempt to parse the message into an AST node. # Invalid Python code will raise a SyntaxError. tree = ast.parse(content) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 92ddf0fbd..c54ca96bf 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -64,7 +64,8 @@ class Information(Cog): defcon_info = "" if cog := self.bot.get_cog("Defcon"): - defcon_info = f"Defcon threshold: {humanize_delta(cog.threshold)}\n" + threshold = humanize_delta(cog.threshold) if cog.threshold else "-" + defcon_info = f"Defcon threshold: {threshold}\n" verification = f"Verification level: {ctx.guild.verification_level.name}\n" diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py index 3e326e8bb..2e42e7d6b 100644 --- a/bot/exts/info/pypi.py +++ b/bot/exts/info/pypi.py @@ -1,19 +1,23 @@ import itertools import logging import random +import re from discord import Embed from discord.ext.commands import Cog, Context, command from discord.utils import escape_markdown from bot.bot import Bot -from bot.constants import Colours, NEGATIVE_REPLIES +from bot.constants import Colours, NEGATIVE_REPLIES, RedirectOutput URL = "https://pypi.org/pypi/{package}/json" -FIELDS = ("author", "requires_python", "summary", "license") PYPI_ICON = "https://cdn.discordapp.com/emojis/766274397257334814.png" + PYPI_COLOURS = itertools.cycle((Colours.yellow, Colours.blue, Colours.white)) +ILLEGAL_CHARACTERS = re.compile(r"[^-_.a-zA-Z0-9]+") +INVALID_INPUT_DELETE_DELAY = RedirectOutput.delete_delay + log = logging.getLogger(__name__) @@ -26,43 +30,47 @@ class PyPi(Cog): @command(name="pypi", aliases=("package", "pack")) async def get_package_info(self, ctx: Context, package: str) -> None: """Provide information about a specific package from PyPI.""" - embed = Embed( - title=random.choice(NEGATIVE_REPLIES), - colour=Colours.soft_red - ) + embed = Embed(title=random.choice(NEGATIVE_REPLIES), colour=Colours.soft_red) embed.set_thumbnail(url=PYPI_ICON) - async with self.bot.http_session.get(URL.format(package=package)) as response: - if response.status == 404: - embed.description = "Package could not be found." + error = True + + if characters := re.search(ILLEGAL_CHARACTERS, package): + embed.description = f"Illegal character(s) passed into command: '{escape_markdown(characters.group(0))}'" + + else: + async with self.bot.http_session.get(URL.format(package=package)) as response: + if response.status == 404: + embed.description = "Package could not be found." + + elif response.status == 200 and response.content_type == "application/json": + response_json = await response.json() + info = response_json["info"] - elif response.status == 200 and response.content_type == "application/json": - response_json = await response.json() - info = response_json["info"] + embed.title = f"{info['name']} v{info['version']}" - embed.title = f"{info['name']} v{info['version']}" - embed.url = info['package_url'] - embed.colour = next(PYPI_COLOURS) + embed.url = info["package_url"] + embed.colour = next(PYPI_COLOURS) - for field in FIELDS: - field_data = info[field] + summary = escape_markdown(info["summary"]) - # Field could be completely empty, in some cases can be a string with whitespaces, or None. - if field_data and not field_data.isspace(): - if '\n' in field_data and field == "license": - field_data = field_data.split('\n')[0] + # Summary could be completely empty, or just whitespace. + if summary and not summary.isspace(): + embed.description = summary + else: + embed.description = "No summary provided." - embed.add_field( - name=field.replace("_", " ").title(), - value=escape_markdown(field_data), - inline=False, - ) + error = False - else: - embed.description = "There was an error when fetching your PyPi package." - log.trace(f"Error when fetching PyPi package: {response.status}.") + else: + embed.description = "There was an error when fetching your PyPi package." + log.trace(f"Error when fetching PyPi package: {response.status}.") - await ctx.send(embed=embed) + if error: + await ctx.send(embed=embed, delete_after=INVALID_INPUT_DELETE_DELAY) + await ctx.message.delete(delay=INVALID_INPUT_DELETE_DELAY) + else: + await ctx.send(embed=embed) def setup(bot: Bot) -> None: diff --git a/bot/exts/info/source.py b/bot/exts/info/source.py index 7b41352d4..49e74f204 100644 --- a/bot/exts/info/source.py +++ b/bot/exts/info/source.py @@ -97,7 +97,7 @@ class BotSource(commands.Cog): else: file_location = Path(filename).relative_to(Path.cwd()).as_posix() - url = f"{URLs.github_bot_repo}/blob/master/{file_location}{lines_extension}" + url = f"{URLs.github_bot_repo}/blob/main/{file_location}{lines_extension}" return url, file_location, first_line_no or None diff --git a/bot/exts/moderation/defcon.py b/bot/exts/moderation/defcon.py index bd16289b9..bab95405c 100644 --- a/bot/exts/moderation/defcon.py +++ b/bot/exts/moderation/defcon.py @@ -157,9 +157,9 @@ class Defcon(Cog): await ctx.send(embed=embed) - @defcon_group.command(aliases=('t', 'd')) + @defcon_group.command(name="threshold", aliases=('t', 'd')) @has_any_role(*MODERATION_ROLES) - async def threshold( + async def threshold_command( self, ctx: Context, threshold: Union[DurationDelta, int], expiry: Optional[Expiry] = None ) -> None: """ diff --git a/bot/exts/moderation/infraction/_scheduler.py b/bot/exts/moderation/infraction/_scheduler.py index a73f2e8da..988fb7220 100644 --- a/bot/exts/moderation/infraction/_scheduler.py +++ b/bot/exts/moderation/infraction/_scheduler.py @@ -173,6 +173,8 @@ class InfractionScheduler: total = len(infractions) end_msg = f" (#{id_} ; {total} infraction{ngettext('', 's', total)} total)" + purge = infraction.get("purge", "") + # Execute the necessary actions to apply the infraction on Discord. if action_coro: log.trace(f"Awaiting the infraction #{id_} application action coroutine.") @@ -210,7 +212,7 @@ class InfractionScheduler: log.error(f"Deletion of {infr_type} infraction #{id_} failed with error code {e.status}.") infr_message = "" else: - infr_message = f" **{' '.join(infr_type.split('_'))}** to {user.mention}{expiry_msg}{end_msg}" + infr_message = f" **{purge}{' '.join(infr_type.split('_'))}** to {user.mention}{expiry_msg}{end_msg}" # Send a confirmation message to the invoking context. log.trace(f"Sending infraction #{id_} confirmation message.") @@ -234,7 +236,7 @@ class InfractionScheduler: footer=f"ID {infraction['id']}" ) - log.info(f"Applied {infr_type} infraction #{id_} to {user}.") + log.info(f"Applied {purge}{infr_type} infraction #{id_} to {user}.") return not failed async def pardon_infraction( diff --git a/bot/exts/moderation/infraction/infractions.py b/bot/exts/moderation/infraction/infractions.py index 3b5b1df45..d89e80acc 100644 --- a/bot/exts/moderation/infraction/infractions.py +++ b/bot/exts/moderation/infraction/infractions.py @@ -318,6 +318,8 @@ class Infractions(InfractionScheduler, commands.Cog): if infraction is None: return + infraction["purge"] = "purge " if purge_days else "" + self.mod_log.ignore(Event.member_remove, user.id) if reason: diff --git a/bot/exts/moderation/watchchannels/_watchchannel.py b/bot/exts/moderation/watchchannels/_watchchannel.py index f9fc12dc3..0793a66af 100644 --- a/bot/exts/moderation/watchchannels/_watchchannel.py +++ b/bot/exts/moderation/watchchannels/_watchchannel.py @@ -47,7 +47,9 @@ class WatchChannel(metaclass=CogABCMeta): webhook_id: int, api_endpoint: str, api_default_params: dict, - logger: logging.Logger + logger: logging.Logger, + *, + disable_header: bool = False ) -> None: self.bot = bot @@ -66,6 +68,7 @@ class WatchChannel(metaclass=CogABCMeta): self.channel = None self.webhook = None self.message_history = MessageHistory() + self.disable_header = disable_header self._start = self.bot.loop.create_task(self.start_watchchannel()) @@ -267,6 +270,9 @@ class WatchChannel(metaclass=CogABCMeta): async def send_header(self, msg: Message) -> None: """Sends a header embed with information about the relayed messages to the watch channel.""" + if self.disable_header: + return + user_id = msg.author.id guild = self.bot.get_guild(GuildConfig.id) diff --git a/bot/exts/moderation/watchchannels/talentpool.py b/bot/exts/moderation/watchchannels/talentpool.py index dd3349c3a..d75688fa6 100644 --- a/bot/exts/moderation/watchchannels/talentpool.py +++ b/bot/exts/moderation/watchchannels/talentpool.py @@ -14,6 +14,8 @@ from bot.exts.moderation.watchchannels._watchchannel import WatchChannel from bot.pagination import LinePaginator from bot.utils import time +REASON_MAX_CHARS = 1000 + log = logging.getLogger(__name__) @@ -28,6 +30,7 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): api_endpoint='bot/nominations', api_default_params={'active': 'true', 'ordering': '-inserted_at'}, logger=log, + disable_header=True, ) @group(name='talentpool', aliases=('tp', 'talent', 'nomination', 'n'), invoke_without_command=True) @@ -83,8 +86,8 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): await ctx.send(f":x: Failed to update the user cache; can't add {user}") return - if user.id in self.watched_users: - await ctx.send(f":x: {user} is already being watched in the talent pool") + if len(reason) > REASON_MAX_CHARS: + await ctx.send(f":x: Maxiumum allowed characters for the reason is {REASON_MAX_CHARS}.") return # Manual request with `raise_for_status` as False because we want the actual response @@ -101,14 +104,18 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): async with session.post(url, **kwargs) as resp: response_data = await resp.json() - if resp.status == 400 and response_data.get('user', False): - await ctx.send(":x: The specified user can't be found in the database tables") + if resp.status == 400: + if response_data.get('user', False): + await ctx.send(":x: The specified user can't be found in the database tables") + elif response_data.get('actor', False): + await ctx.send(":x: You have already nominated this user") + return else: resp.raise_for_status() self.watched_users[user.id] = response_data - msg = f":white_check_mark: Messages sent by {user} will now be relayed to the talent pool channel" + msg = f":white_check_mark: The nomination for {user} has been added to the talent pool" history = await self.bot.api_client.get( self.api_endpoint, @@ -120,9 +127,7 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): ) if history: - total = f"({len(history)} previous nominations in total)" - start_reason = f"Watched: {textwrap.shorten(history[0]['reason'], width=500, placeholder='...')}" - msg += f"\n\nUser's previous watch reasons {total}:```{start_reason}```" + msg += f"\n\n({len(history)} previous nominations in total)" await ctx.send(msg) @@ -163,6 +168,10 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): Providing a `reason` is required. """ + if len(reason) > REASON_MAX_CHARS: + await ctx.send(f":x: Maxiumum allowed characters for the end reason is {REASON_MAX_CHARS}.") + return + if await self.unwatch(user.id, reason): await ctx.send(f":white_check_mark: Messages sent by {user} will no longer be relayed") else: @@ -176,33 +185,69 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): @nomination_edit_group.command(name='reason') @has_any_role(*MODERATION_ROLES) - async def edit_reason_command(self, ctx: Context, nomination_id: int, *, reason: str) -> None: - """ - Edits the reason/unnominate reason for the nomination with the given `id` depending on the status. + async def edit_reason_command(self, ctx: Context, nomination_id: int, actor: FetchedMember, *, reason: str) -> None: + """Edits the reason of a specific nominator in a specific active nomination.""" + if len(reason) > REASON_MAX_CHARS: + await ctx.send(f":x: Maxiumum allowed characters for the reason is {REASON_MAX_CHARS}.") + return - If the nomination is active, the reason for nominating the user will be edited; - If the nomination is no longer active, the reason for ending the nomination will be edited instead. - """ try: nomination = await self.bot.api_client.get(f"{self.api_endpoint}/{nomination_id}") except ResponseCodeError as e: if e.response.status == 404: - self.log.trace(f"Nomination API 404: Can't nomination with id {nomination_id}") + self.log.trace(f"Nomination API 404: Can't find a nomination with id {nomination_id}") await ctx.send(f":x: Can't find a nomination with id `{nomination_id}`") return else: raise - field = "reason" if nomination["active"] else "end_reason" + if not nomination["active"]: + await ctx.send(":x: Can't edit the reason of an inactive nomination.") + return + + if not any(entry["actor"] == actor.id for entry in nomination["entries"]): + await ctx.send(f":x: {actor} doesn't have an entry in this nomination.") + return - self.log.trace(f"Changing {field} for nomination with id {nomination_id} to {reason}") + self.log.trace(f"Changing reason for nomination with id {nomination_id} of actor {actor} to {repr(reason)}") await self.bot.api_client.patch( f"{self.api_endpoint}/{nomination_id}", - json={field: reason} + json={"actor": actor.id, "reason": reason} + ) + await self.fetch_user_cache() # Update cache + await ctx.send(":white_check_mark: Successfully updated nomination reason.") + + @nomination_edit_group.command(name='end_reason') + @has_any_role(*MODERATION_ROLES) + async def edit_end_reason_command(self, ctx: Context, nomination_id: int, *, reason: str) -> None: + """Edits the unnominate reason for the nomination with the given `id`.""" + if len(reason) > REASON_MAX_CHARS: + await ctx.send(f":x: Maxiumum allowed characters for the end reason is {REASON_MAX_CHARS}.") + return + + try: + nomination = await self.bot.api_client.get(f"{self.api_endpoint}/{nomination_id}") + except ResponseCodeError as e: + if e.response.status == 404: + self.log.trace(f"Nomination API 404: Can't find a nomination with id {nomination_id}") + await ctx.send(f":x: Can't find a nomination with id `{nomination_id}`") + return + else: + raise + + if nomination["active"]: + await ctx.send(":x: Can't edit the end reason of an active nomination.") + return + + self.log.trace(f"Changing end reason for nomination with id {nomination_id} to {repr(reason)}") + + await self.bot.api_client.patch( + f"{self.api_endpoint}/{nomination_id}", + json={"end_reason": reason} ) await self.fetch_user_cache() # Update cache. - await ctx.send(f":white_check_mark: Updated the {field} of the nomination!") + await ctx.send(":white_check_mark: Updated the end reason of the nomination!") @Cog.listener() async def on_member_ban(self, guild: Guild, user: Union[User, Member]) -> None: @@ -237,14 +282,21 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): def _nomination_to_string(self, nomination_object: dict) -> str: """Creates a string representation of a nomination.""" guild = self.bot.get_guild(Guild.id) + entries = [] + for site_entry in nomination_object["entries"]: + actor_id = site_entry["actor"] + actor = guild.get_member(actor_id) + + reason = site_entry["reason"] or "*None*" + created = time.format_infraction(site_entry["inserted_at"]) + entries.append( + f"Actor: {actor.mention if actor else actor_id}\nCreated: {created}\nReason: {reason}" + ) - actor_id = nomination_object["actor"] - actor = guild.get_member(actor_id) + entries_string = "\n\n".join(entries) active = nomination_object["active"] - reason = nomination_object["reason"] or "*None*" - start_date = time.format_infraction(nomination_object["inserted_at"]) if active: lines = textwrap.dedent( @@ -252,9 +304,9 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): =============== Status: **Active** Date: {start_date} - Actor: {actor.mention if actor else actor_id} - Reason: {reason} Nomination ID: `{nomination_object["id"]}` + + {entries_string} =============== """ ) @@ -265,12 +317,12 @@ class TalentPool(WatchChannel, Cog, name="Talentpool"): =============== Status: Inactive Date: {start_date} - Actor: {actor.mention if actor else actor_id} - Reason: {reason} + Nomination ID: `{nomination_object["id"]}` + + {entries_string} End date: {end_date} Unwatch reason: {nomination_object["end_reason"]} - Nomination ID: `{nomination_object["id"]}` =============== """ ) diff --git a/bot/exts/utils/utils.py b/bot/exts/utils/utils.py index eb92dfca7..a5d6f69b9 100644 --- a/bot/exts/utils/utils.py +++ b/bot/exts/utils/utils.py @@ -14,6 +14,7 @@ from bot.converters import Snowflake from bot.decorators import in_whitelist from bot.pagination import LinePaginator from bot.utils import messages +from bot.utils.checks import has_no_roles_check from bot.utils.time import time_since log = logging.getLogger(__name__) @@ -156,18 +157,22 @@ class Utils(Cog): @command(aliases=("snf", "snfl", "sf")) @in_whitelist(channels=(Channels.bot_commands,), roles=STAFF_ROLES) - async def snowflake(self, ctx: Context, snowflake: Snowflake) -> None: + async def snowflake(self, ctx: Context, *snowflakes: Snowflake) -> None: """Get Discord snowflake creation time.""" - created_at = snowflake_time(snowflake) - embed = Embed( - description=f"**Created at {created_at}** ({time_since(created_at, max_units=3)}).", - colour=Colour.blue() - ) - embed.set_author( - name=f"Snowflake: {snowflake}", - icon_url="https://github.com/twitter/twemoji/blob/master/assets/72x72/2744.png?raw=true" - ) - await ctx.send(embed=embed) + if len(snowflakes) > 1 and await has_no_roles_check(ctx, *STAFF_ROLES): + raise BadArgument("Cannot process more than one snowflake in one invocation.") + + for snowflake in snowflakes: + created_at = snowflake_time(snowflake) + embed = Embed( + description=f"**Created at {created_at}** ({time_since(created_at, max_units=3)}).", + colour=Colour.blue() + ) + embed.set_author( + name=f"Snowflake: {snowflake}", + icon_url="https://github.com/twitter/twemoji/blob/master/assets/72x72/2744.png?raw=true" + ) + await ctx.send(embed=embed) @command(aliases=("poll",)) @has_any_role(*MODERATION_ROLES) diff --git a/bot/log.py b/bot/log.py index bc3bba0af..e92233a33 100644 --- a/bot/log.py +++ b/bot/log.py @@ -1,12 +1,11 @@ import logging import os import sys -from logging import Logger, StreamHandler, handlers +from logging import Logger, handlers from pathlib import Path import coloredlogs import sentry_sdk -from pythonjsonlogger import jsonlogger from sentry_sdk.integrations.logging import LoggingIntegration from sentry_sdk.integrations.redis import RedisIntegration @@ -14,15 +13,6 @@ from bot import constants TRACE_LEVEL = 5 -PROD_FIELDS = [ - "asctime", - "name", - "levelname", - "message", - "funcName", - "filename" -] - def setup() -> None: """Set up loggers.""" @@ -43,28 +33,21 @@ def setup() -> None: root_log.setLevel(log_level) root_log.addHandler(file_handler) - if constants.DEBUG_MODE: - if "COLOREDLOGS_LEVEL_STYLES" not in os.environ: - coloredlogs.DEFAULT_LEVEL_STYLES = { - **coloredlogs.DEFAULT_LEVEL_STYLES, - "trace": {"color": 246}, - "critical": {"background": "red"}, - "debug": coloredlogs.DEFAULT_LEVEL_STYLES["info"] - } - - if "COLOREDLOGS_LOG_FORMAT" not in os.environ: - coloredlogs.DEFAULT_LOG_FORMAT = format_string - - if "COLOREDLOGS_LOG_LEVEL" not in os.environ: - coloredlogs.DEFAULT_LOG_LEVEL = log_level - - coloredlogs.install(logger=root_log, stream=sys.stdout) - else: - json_format = " ".join([f"%({field})s" for field in PROD_FIELDS]) - stream_handler = StreamHandler() - formatter = jsonlogger.JsonFormatter(json_format) - stream_handler.setFormatter(formatter) - root_log.addHandler(stream_handler) + if "COLOREDLOGS_LEVEL_STYLES" not in os.environ: + coloredlogs.DEFAULT_LEVEL_STYLES = { + **coloredlogs.DEFAULT_LEVEL_STYLES, + "trace": {"color": 246}, + "critical": {"background": "red"}, + "debug": coloredlogs.DEFAULT_LEVEL_STYLES["info"] + } + + if "COLOREDLOGS_LOG_FORMAT" not in os.environ: + coloredlogs.DEFAULT_LOG_FORMAT = format_string + + if "COLOREDLOGS_LOG_LEVEL" not in os.environ: + coloredlogs.DEFAULT_LOG_LEVEL = log_level + + coloredlogs.install(logger=root_log, stream=sys.stdout) logging.getLogger("discord").setLevel(logging.WARNING) logging.getLogger("websockets").setLevel(logging.WARNING) diff --git a/bot/resources/elements.json b/bot/resources/elements.json deleted file mode 100644 index a3ac5b99f..000000000 --- a/bot/resources/elements.json +++ /dev/null @@ -1,119 +0,0 @@ -[ - "hydrogen", - "helium", - "lithium", - "beryllium", - "boron", - "carbon", - "nitrogen", - "oxygen", - "fluorine", - "neon", - "sodium", - "magnesium", - "aluminium", - "silicon", - "phosphorus", - "sulfur", - "chlorine", - "argon", - "potassium", - "calcium", - "scandium", - "titanium", - "vanadium", - "chromium", - "manganese", - "iron", - "cobalt", - "nickel", - "copper", - "zinc", - "gallium", - "germanium", - "arsenic", - "bromine", - "krypton", - "rubidium", - "strontium", - "yttrium", - "zirconium", - "niobium", - "molybdenum", - "technetium", - "ruthenium", - "rhodium", - "palladium", - "silver", - "cadmium", - "indium", - "tin", - "antimony", - "tellurium", - "iodine", - "xenon", - "caesium", - "barium", - "lanthanum", - "cerium", - "praseodymium", - "neodymium", - "promethium", - "samarium", - "europium", - "gadolinium", - "terbium", - "dysprosium", - "holmium", - "erbium", - "thulium", - "ytterbium", - "lutetium", - "hafnium", - "tantalum", - "tungsten", - "rhenium", - "osmium", - "iridium", - "platinum", - "gold", - "mercury", - "thallium", - "lead", - "bismuth", - "polonium", - "astatine", - "radon", - "francium", - "radium", - "actinium", - "thorium", - "protactinium", - "uranium", - "neptunium", - "plutonium", - "americium", - "curium", - "berkelium", - "californium", - "einsteinium", - "fermium", - "mendelevium", - "nobelium", - "lawrencium", - "rutherfordium", - "dubnium", - "seaborgium", - "bohrium", - "hassium", - "meitnerium", - "darmstadtium", - "roentgenium", - "copernicium", - "nihonium", - "flerovium", - "moscovium", - "livermorium", - "tennessine", - "oganesson" -] diff --git a/bot/resources/foods.json b/bot/resources/foods.json new file mode 100644 index 000000000..61d9ea98f --- /dev/null +++ b/bot/resources/foods.json @@ -0,0 +1,52 @@ +[ + "apple", + "avocado", + "bagel", + "banana", + "bread", + "broccoli", + "burrito", + "cake", + "candy", + "carrot", + "cheese", + "cherries", + "chestnut", + "chili", + "chocolate", + "coconut", + "coffee", + "cookie", + "corn", + "croissant", + "cupcake", + "donut", + "dumpling", + "falafel", + "grapes", + "honey", + "kiwi", + "lemon", + "lollipop", + "mango", + "mushroom", + "orange", + "pancakes", + "peanut", + "pear", + "pie", + "pineapple", + "popcorn", + "potato", + "pretzel", + "ramen", + "rice", + "salad", + "spaghetti", + "stew", + "strawberry", + "sushi", + "taco", + "tomato", + "watermelon" +] diff --git a/bot/resources/stars.json b/bot/resources/stars.json index c0b253120..5ecad0213 100644 --- a/bot/resources/stars.json +++ b/bot/resources/stars.json @@ -17,7 +17,7 @@ "Bruce Springsteen", "Bruno Mars", "Bryan Adams", - "Celine Dion", + "Céline Dion", "Cher", "Christina Aguilera", "David Bowie", diff --git a/config-default.yml b/config-default.yml index 18d9cd370..49d7f84ac 100644 --- a/config-default.yml +++ b/config-default.yml @@ -89,8 +89,8 @@ style: filtering: "https://cdn.discordapp.com/emojis/472472638594482195.png" - green_checkmark: "https://raw.githubusercontent.com/python-discord/branding/master/icons/checkmark/green-checkmark-dist.png" - green_questionmark: "https://raw.githubusercontent.com/python-discord/branding/master/icons/checkmark/green-question-mark-dist.png" + green_checkmark: "https://raw.githubusercontent.com/python-discord/branding/main/icons/checkmark/green-checkmark-dist.png" + green_questionmark: "https://raw.githubusercontent.com/python-discord/branding/main/icons/checkmark/green-question-mark-dist.png" guild_update: "https://cdn.discordapp.com/emojis/469954765141442561.png" hash_blurple: "https://cdn.discordapp.com/emojis/469950142942806017.png" @@ -195,6 +195,7 @@ guild: incidents_archive: 720668923636351037 mods: &MODS 305126844661760000 mod_alerts: 473092532147060736 + mod_appeals: &MOD_APPEALS 808790025688711198 mod_meta: &MOD_META 775412552795947058 mod_spam: &MOD_SPAM 620607373828030464 mod_tools: &MOD_TOOLS 775413915391098921 @@ -230,6 +231,7 @@ guild: moderation_channels: - *ADMINS - *ADMIN_SPAM + - *MOD_APPEALS - *MOD_META - *MOD_TOOLS - *MODS @@ -358,8 +360,8 @@ urls: discord_api: &DISCORD_API "https://discordapp.com/api/v7/" discord_invite_api: !JOIN [*DISCORD_API, "invites"] - # Misc URLs - bot_avatar: "https://raw.githubusercontent.com/discord-python/branding/master/logos/logo_circle/logo_circle.png" + # Misc URLsw + bot_avatar: "https://raw.githubusercontent.com/python-discord/branding/main/logos/logo_circle/logo_circle.png" github_bot_repo: "https://github.com/python-discord/bot" diff --git a/docker-compose.yml b/docker-compose.yml index 0002d1d56..8afdd6ef1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -57,8 +57,7 @@ services: - web - redis - snekbox + env_file: + - .env environment: - BOT_TOKEN: ${BOT_TOKEN} BOT_API_KEY: badbot13m0n8f570f942013fc818f234916ca531 - REDDIT_CLIENT_ID: ${REDDIT_CLIENT_ID} - REDDIT_SECRET: ${REDDIT_SECRET} diff --git a/tests/bot/exts/moderation/infraction/test_infractions.py b/tests/bot/exts/moderation/infraction/test_infractions.py index 86c2617ea..08f39cd50 100644 --- a/tests/bot/exts/moderation/infraction/test_infractions.py +++ b/tests/bot/exts/moderation/infraction/test_infractions.py @@ -39,7 +39,7 @@ class TruncationTests(unittest.IsolatedAsyncioTestCase): delete_message_days=0 ) self.cog.apply_infraction.assert_awaited_once_with( - self.ctx, {"foo": "bar"}, self.target, self.ctx.guild.ban.return_value + self.ctx, {"foo": "bar", "purge": ""}, self.target, self.ctx.guild.ban.return_value ) @patch("bot.exts.moderation.infraction._utils.post_infraction") |