diff options
| author | 2020-02-07 09:21:27 +0100 | |
|---|---|---|
| committer | 2020-02-07 09:21:27 +0100 | |
| commit | 4a685ed29bdfa764dfffec9cc99e7db9b5f839dc (patch) | |
| tree | d56fd5698e72f7c425a7a9498d94a9a75d2e490c | |
| parent | Made searching even stricter by searching from start of each word (diff) | |
| parent | Merge pull request #737 from python-discord/remove-prometheus (diff) | |
Merge branch 'master' into fuzzy-tag-search
| -rw-r--r-- | Pipfile | 1 | ||||
| -rw-r--r-- | Pipfile.lock | 297 | ||||
| -rw-r--r-- | bot/__main__.py | 1 | ||||
| -rw-r--r-- | bot/bot.py | 3 | ||||
| -rw-r--r-- | bot/cogs/antispam.py | 33 | ||||
| -rw-r--r-- | bot/cogs/metrics.py | 98 | ||||
| -rw-r--r-- | bot/cogs/moderation/modlog.py | 22 | ||||
| -rw-r--r-- | bot/cogs/site.py | 4 | ||||
| -rw-r--r-- | bot/constants.py | 1 | ||||
| -rw-r--r-- | bot/utils/messages.py | 49 | ||||
| -rw-r--r-- | config-default.yml | 3 |
11 files changed, 199 insertions, 313 deletions
@@ -19,7 +19,6 @@ deepdiff = "~=4.0" requests = "~=2.22" more_itertools = "~=7.2" urllib3 = ">=1.24.2,<1.25" -prometheus-async = {extras = ["aiohttp"],version = "~=19.2"} [dev-packages] coverage = "~=4.5" diff --git a/Pipfile.lock b/Pipfile.lock index ab5dfb538..279480d2a 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "d9349e8c704b2b2403004039856d8d75aaebc76e4aa93390c4d177f583e73b71" + "sha256": "c27d699b4aeeed204dee41f924f682ae2a670add8549a8826e58776594370582" }, "pipfile-spec": 6, "requires": { @@ -34,31 +34,21 @@ }, "aiohttp": { "hashes": [ - "sha256:00d198585474299c9c3b4f1d5de1a576cc230d562abc5e4a0e81d71a20a6ca55", - "sha256:0155af66de8c21b8dba4992aaeeabf55503caefae00067a3b1139f86d0ec50ed", - "sha256:09654a9eca62d1bd6d64aa44db2498f60a5c1e0ac4750953fdd79d5c88955e10", - "sha256:199f1d106e2b44b6dacdf6f9245493c7d716b01d0b7fbe1959318ba4dc64d1f5", - "sha256:296f30dedc9f4b9e7a301e5cc963012264112d78a1d3094cd83ef148fdf33ca1", - "sha256:368ed312550bd663ce84dc4b032a962fcb3c7cae099dbbd48663afc305e3b939", - "sha256:40d7ea570b88db017c51392349cf99b7aefaaddd19d2c78368aeb0bddde9d390", - "sha256:629102a193162e37102c50713e2e31dc9a2fe7ac5e481da83e5bb3c0cee700aa", - "sha256:6d5ec9b8948c3d957e75ea14d41e9330e1ac3fed24ec53766c780f82805140dc", - "sha256:87331d1d6810214085a50749160196391a712a13336cd02ce1c3ea3d05bcf8d5", - "sha256:9a02a04bbe581c8605ac423ba3a74999ec9d8bce7ae37977a3d38680f5780b6d", - "sha256:9c4c83f4fa1938377da32bc2d59379025ceeee8e24b89f72fcbccd8ca22dc9bf", - "sha256:9cddaff94c0135ee627213ac6ca6d05724bfe6e7a356e5e09ec57bd3249510f6", - "sha256:a25237abf327530d9561ef751eef9511ab56fd9431023ca6f4803f1994104d72", - "sha256:a5cbd7157b0e383738b8e29d6e556fde8726823dae0e348952a61742b21aeb12", - "sha256:a97a516e02b726e089cffcde2eea0d3258450389bbac48cbe89e0f0b6e7b0366", - "sha256:acc89b29b5f4e2332d65cd1b7d10c609a75b88ef8925d487a611ca788432dfa4", - "sha256:b05bd85cc99b06740aad3629c2585bda7b83bd86e080b44ba47faf905fdf1300", - "sha256:c2bec436a2b5dafe5eaeb297c03711074d46b6eb236d002c13c42f25c4a8ce9d", - "sha256:cc619d974c8c11fe84527e4b5e1c07238799a8c29ea1c1285149170524ba9303", - "sha256:d4392defd4648badaa42b3e101080ae3313e8f4787cb517efd3f5b8157eaefd6", - "sha256:e1c3c582ee11af7f63a34a46f0448fca58e59889396ffdae1f482085061a2889" + "sha256:1e984191d1ec186881ffaed4581092ba04f7c61582a177b187d3a2f07ed9719e", + "sha256:259ab809ff0727d0e834ac5e8a283dc5e3e0ecc30c4d80b3cd17a4139ce1f326", + "sha256:2f4d1a4fdce595c947162333353d4a44952a724fba9ca3205a3df99a33d1307a", + "sha256:32e5f3b7e511aa850829fbe5aa32eb455e5534eaa4b1ce93231d00e2f76e5654", + "sha256:344c780466b73095a72c616fac5ea9c4665add7fc129f285fbdbca3cccf4612a", + "sha256:460bd4237d2dbecc3b5ed57e122992f60188afe46e7319116da5eb8a9dfedba4", + "sha256:4c6efd824d44ae697814a2a85604d8e992b875462c6655da161ff18fd4f29f17", + "sha256:50aaad128e6ac62e7bf7bd1f0c0a24bc968a0c0590a726d5a955af193544bcec", + "sha256:6206a135d072f88da3e71cc501c59d5abffa9d0bb43269a6dcd28d66bfafdbdd", + "sha256:65f31b622af739a802ca6fd1a3076fd0ae523f8485c52924a89561ba10c49b48", + "sha256:ae55bac364c405caa23a4f2d6cfecc6a0daada500274ffca4a9230e7129eac59", + "sha256:b778ce0c909a2653741cb4b1ac7015b5c130ab9c897611df43ae6a58523cb965" ], "index": "pypi", - "version": "==3.5.4" + "version": "==3.6.2" }, "aiormq": { "hashes": [ @@ -157,26 +147,25 @@ }, "deepdiff": { "hashes": [ - "sha256:3457ea7cecd51ba48015d89edbb569358af4d9b9e65e28bdb3209608420627f9", - "sha256:5e2343398e90538edaa59c0c99207e996a3a834fdc878c666376f632a760c35a" + "sha256:b3fa588d1eac7fa318ec1fb4f2004568e04cb120a1989feda8e5e7164bcbf07a", + "sha256:ed7342d3ed3c0c2058a3fb05b477c943c9959ef62223dca9baa3375718a25d87" ], "index": "pypi", - "version": "==4.0.9" + "version": "==4.2.0" }, "discord-py": { "hashes": [ - "sha256:7c843b523bb011062b453864e75c7b675a03faf573c58d14c9f096e85984329d" + "sha256:8bfe5628d31771744000f19135c386c74ac337479d7282c26cc1627b9d31f360" ], "index": "pypi", - "version": "==1.2.5" + "version": "==1.3.1" }, "docutils": { "hashes": [ - "sha256:6c4f696463b79f1fb8ba0c594b63840ebd41f059e92b31957c46b74a4599b6d0", - "sha256:9e4d7ecfc600058e07ba661411a2b7de2fd0fafa17d1a7f7361cd47b1175c827", - "sha256:a2aeea129088da402665e92e0b25b04b073c04b2dce4ab65caaa38b7ce2e1a99" + "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af", + "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc" ], - "version": "==0.15.2" + "version": "==0.16" }, "fuzzywuzzy": { "hashes": [ @@ -202,17 +191,10 @@ }, "jinja2": { "hashes": [ - "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", - "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de" + "sha256:93187ffbc7808079673ef52771baa950426fd664d3aad1d0fa3e95644360e250", + "sha256:b0eaf100007721b5c16c1fc1eecb87409464edc10469ddc9a22a27a99123be49" ], - "version": "==2.10.3" - }, - "jsonpickle": { - "hashes": [ - "sha256:d0c5a4e6cb4e58f6d5406bdded44365c2bcf9c836c4f52910cc9ba7245a59dc2", - "sha256:d3e922d781b1d0096df2dad89a2e1f47177d7969b596aea806a9d91b4626b29b" - ], - "version": "==1.2" + "version": "==2.11.1" }, "logmatic-python": { "hashes": [ @@ -223,35 +205,36 @@ }, "lxml": { "hashes": [ - "sha256:00ac0d64949fef6b3693813fe636a2d56d97a5a49b5bbb86e4cc4cc50ebc9ea2", - "sha256:0571e607558665ed42e450d7bf0e2941d542c18e117b1ebbf0ba72f287ad841c", - "sha256:0e3f04a7615fdac0be5e18b2406529521d6dbdb0167d2a690ee328bef7807487", - "sha256:13cf89be53348d1c17b453867da68704802966c433b2bb4fa1f970daadd2ef70", - "sha256:217262fcf6a4c2e1c7cb1efa08bd9ebc432502abc6c255c4abab611e8be0d14d", - "sha256:223e544828f1955daaf4cefbb4853bc416b2ec3fd56d4f4204a8b17007c21250", - "sha256:277cb61fede2f95b9c61912fefb3d43fbd5f18bf18a14fae4911b67984486f5d", - "sha256:3213f753e8ae86c396e0e066866e64c6b04618e85c723b32ecb0909885211f74", - "sha256:4690984a4dee1033da0af6df0b7a6bde83f74e1c0c870623797cec77964de34d", - "sha256:4fcc472ef87f45c429d3b923b925704aa581f875d65bac80f8ab0c3296a63f78", - "sha256:61409bd745a265a742f2693e4600e4dbd45cc1daebe1d5fad6fcb22912d44145", - "sha256:678f1963f755c5d9f5f6968dded7b245dd1ece8cf53c1aa9d80e6734a8c7f41d", - "sha256:6c6d03549d4e2734133badb9ab1c05d9f0ef4bcd31d83e5d2b4747c85cfa21da", - "sha256:6e74d5f4d6ecd6942375c52ffcd35f4318a61a02328f6f1bd79fcb4ffedf969e", - "sha256:7b4fc7b1ecc987ca7aaf3f4f0e71bbfbd81aaabf87002558f5bc95da3a865bcd", - "sha256:7ed386a40e172ddf44c061ad74881d8622f791d9af0b6f5be20023029129bc85", - "sha256:8f54f0924d12c47a382c600c880770b5ebfc96c9fd94cf6f6bdc21caf6163ea7", - "sha256:ad9b81351fdc236bda538efa6879315448411a81186c836d4b80d6ca8217cdb9", - "sha256:bbd00e21ea17f7bcc58dccd13869d68441b32899e89cf6cfa90d624a9198ce85", - "sha256:c3c289762cc09735e2a8f8a49571d0e8b4f57ea831ea11558247b5bdea0ac4db", - "sha256:cf4650942de5e5685ad308e22bcafbccfe37c54aa7c0e30cd620c2ee5c93d336", - "sha256:cfcbc33c9c59c93776aa41ab02e55c288a042211708b72fdb518221cc803abc8", - "sha256:e301055deadfedbd80cf94f2f65ff23126b232b0d1fea28f332ce58137bcdb18", - "sha256:ebbfe24df7f7b5c6c7620702496b6419f6a9aa2fd7f005eb731cc80d7b4692b9", - "sha256:eff69ddbf3ad86375c344339371168640951c302450c5d3e9936e98d6459db06", - "sha256:f6ed60a62c5f1c44e789d2cf14009423cb1646b44a43e40a9cf6a21f077678a1" - ], - "index": "pypi", - "version": "==4.4.2" + "sha256:06d4e0bbb1d62e38ae6118406d7cdb4693a3fa34ee3762238bcb96c9e36a93cd", + "sha256:0701f7965903a1c3f6f09328c1278ac0eee8f56f244e66af79cb224b7ef3801c", + "sha256:1f2c4ec372bf1c4a2c7e4bb20845e8bcf8050365189d86806bad1e3ae473d081", + "sha256:4235bc124fdcf611d02047d7034164897ade13046bda967768836629bc62784f", + "sha256:5828c7f3e615f3975d48f40d4fe66e8a7b25f16b5e5705ffe1d22e43fb1f6261", + "sha256:585c0869f75577ac7a8ff38d08f7aac9033da2c41c11352ebf86a04652758b7a", + "sha256:5d467ce9c5d35b3bcc7172c06320dddb275fea6ac2037f72f0a4d7472035cea9", + "sha256:63dbc21efd7e822c11d5ddbedbbb08cd11a41e0032e382a0fd59b0b08e405a3a", + "sha256:7bc1b221e7867f2e7ff1933165c0cec7153dce93d0cdba6554b42a8beb687bdb", + "sha256:8620ce80f50d023d414183bf90cc2576c2837b88e00bea3f33ad2630133bbb60", + "sha256:8a0ebda56ebca1a83eb2d1ac266649b80af8dd4b4a3502b2c1e09ac2f88fe128", + "sha256:90ed0e36455a81b25b7034038e40880189169c308a3df360861ad74da7b68c1a", + "sha256:95e67224815ef86924fbc2b71a9dbd1f7262384bca4bc4793645794ac4200717", + "sha256:afdb34b715daf814d1abea0317b6d672476b498472f1e5aacbadc34ebbc26e89", + "sha256:b4b2c63cc7963aedd08a5f5a454c9f67251b1ac9e22fd9d72836206c42dc2a72", + "sha256:d068f55bda3c2c3fcaec24bd083d9e2eede32c583faf084d6e4b9daaea77dde8", + "sha256:d5b3c4b7edd2e770375a01139be11307f04341ec709cf724e0f26ebb1eef12c3", + "sha256:deadf4df349d1dcd7b2853a2c8796593cc346600726eff680ed8ed11812382a7", + "sha256:df533af6f88080419c5a604d0d63b2c33b1c0c4409aba7d0cb6de305147ea8c8", + "sha256:e4aa948eb15018a657702fee0b9db47e908491c64d36b4a90f59a64741516e77", + "sha256:e5d842c73e4ef6ed8c1bd77806bf84a7cb535f9c0cf9b2c74d02ebda310070e1", + "sha256:ebec08091a22c2be870890913bdadd86fcd8e9f0f22bcb398abd3af914690c15", + "sha256:edc15fcfd77395e24543be48871c251f38132bb834d9fdfdad756adb6ea37679", + "sha256:f2b74784ed7e0bc2d02bd53e48ad6ba523c9b36c194260b7a5045071abbb1012", + "sha256:fa071559f14bd1e92077b1b5f6c22cf09756c6de7139370249eb372854ce51e6", + "sha256:fd52e796fee7171c4361d441796b64df1acfceb51f29e545e812f16d023c4bbc", + "sha256:fe976a0f1ef09b3638778024ab9fb8cde3118f203364212c198f71341c0715ca" + ], + "index": "pypi", + "version": "==4.5.0" }, "markdownify": { "hashes": [ @@ -266,13 +249,16 @@ "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b", "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", @@ -289,7 +275,9 @@ "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", - "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", + "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be" ], "version": "==1.1.1" }, @@ -331,10 +319,10 @@ }, "packaging": { "hashes": [ - "sha256:aec3fdbb8bc9e4bb65f0634b9f551ced63983a529d6a8931817d52fdd0816ddb", - "sha256:fe1d8331dfa7cc0a883b49d75fc76380b2ab2734b220fbb87d774e4fd4b851f8" + "sha256:170748228214b70b672c581a3dd610ee51f733018650740e98c7df862a583f73", + "sha256:e665345f9eef0c621aa0bf2f8d78cf6d21904eef16a93f020240b704a57f1334" ], - "version": "==20.0" + "version": "==20.1" }, "pamqp": { "hashes": [ @@ -343,23 +331,6 @@ ], "version": "==2.3.0" }, - "prometheus-async": { - "extras": [ - "aiohttp" - ], - "hashes": [ - "sha256:227f516e5bf98a0dc602348381e182358f8b2ed24a8db05e8e34d9cf027bab83", - "sha256:3cc68d1f39e9bbf16dbd0b51103d87671b3cbd1d75a72cda472cd9a35cc9d0d2" - ], - "index": "pypi", - "version": "==19.2.0" - }, - "prometheus-client": { - "hashes": [ - "sha256:71cd24a2b3eb335cb800c7159f423df1bd4dcd5171b234be15e3f31ec9f622da" - ], - "version": "==0.7.1" - }, "pycares": { "hashes": [ "sha256:050f00b39ed77ea8a4e555f09417d4b1a6b5baa24bb9531a3e15d003d2319b3f", @@ -462,10 +433,10 @@ }, "six": { "hashes": [ - "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", - "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" + "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", + "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" ], - "version": "==1.13.0" + "version": "==1.14.0" }, "snowballstemmer": { "hashes": [ @@ -541,35 +512,30 @@ }, "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" - }, - "wrapt": { - "hashes": [ - "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1" - ], - "version": "==1.11.2" + "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5", + "sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5", + "sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308", + "sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb", + "sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a", + "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c", + "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170", + "sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422", + "sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8", + "sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485", + "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f", + "sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8", + "sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc", + "sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779", + "sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989", + "sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1", + "sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092", + "sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824", + "sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d", + "sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55", + "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36", + "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b" + ], + "version": "==8.1" }, "yarl": { "hashes": [ @@ -762,10 +728,10 @@ }, "identify": { "hashes": [ - "sha256:6f44e637caa40d1b4cb37f6ed3b262ede74901d28b1cc5b1fc07360871edd65d", - "sha256:72e9c4ed3bc713c7045b762b0d2e2115c572b85abfc1f4604f5a4fd4c6642b71" + "sha256:1222b648251bdcb8deb240b294f450fbf704c7984e08baa92507e4ea10b436d5", + "sha256:d824ebe21f38325c771c41b08a95a761db1982f1fc0eee37c6c97df3f1636b96" ], - "version": "==1.4.9" + "version": "==1.4.11" }, "idna": { "hashes": [ @@ -776,11 +742,11 @@ }, "importlib-metadata": { "hashes": [ - "sha256:bdd9b7c397c273bcc9a11d6629a38487cd07154fa255a467bf704cd2c258e359", - "sha256:f17c015735e1a88296994c0697ecea7e11db24290941983b08c9feb30921e6d8" + "sha256:06f5b3a99029c7134207dd882428a66992a9de2bef7c2b699b5641f9886c3302", + "sha256:b97607a1a18a5100839aec1dc26a1ea17ee0d93b20b0f008d80a5a050afb200b" ], "markers": "python_version < '3.8'", - "version": "==1.4.0" + "version": "==1.5.0" }, "mccabe": { "hashes": [ @@ -789,14 +755,6 @@ ], "version": "==0.6.1" }, - "more-itertools": { - "hashes": [ - "sha256:409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", - "sha256:92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4" - ], - "index": "pypi", - "version": "==7.2.0" - }, "nodeenv": { "hashes": [ "sha256:561057acd4ae3809e665a9aaaf214afff110bbb6a6d5c8a96121aea6878408b3" @@ -805,10 +763,10 @@ }, "packaging": { "hashes": [ - "sha256:aec3fdbb8bc9e4bb65f0634b9f551ced63983a529d6a8931817d52fdd0816ddb", - "sha256:fe1d8331dfa7cc0a883b49d75fc76380b2ab2734b220fbb87d774e4fd4b851f8" + "sha256:170748228214b70b672c581a3dd610ee51f733018650740e98c7df862a583f73", + "sha256:e665345f9eef0c621aa0bf2f8d78cf6d21904eef16a93f020240b704a57f1334" ], - "version": "==20.0" + "version": "==20.1" }, "pre-commit": { "hashes": [ @@ -881,10 +839,10 @@ }, "six": { "hashes": [ - "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", - "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" + "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", + "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" ], - "version": "==1.13.0" + "version": "==1.14.0" }, "snowballstemmer": { "hashes": [ @@ -902,29 +860,30 @@ }, "typed-ast": { "hashes": [ - "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", - "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", - "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", - "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", - "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", - "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", - "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", - "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", - "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", - "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", - "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", - "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", - "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", - "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", - "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", - "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", - "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", - "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", - "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", - "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" + "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", + "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", + "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", + "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", + "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", + "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", + "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", + "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", + "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", + "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", + "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", + "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", + "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", + "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", + "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", + "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", + "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", + "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", + "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", + "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", + "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" ], "markers": "python_version < '3.8'", - "version": "==1.4.0" + "version": "==1.4.1" }, "unittest-xml-reporting": { "hashes": [ @@ -951,10 +910,10 @@ }, "zipp": { "hashes": [ - "sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e", - "sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335" + "sha256:ccc94ed0909b58ffe34430ea5451f07bc0c76467d7081619a454bf5c98b89e28", + "sha256:feae2f18633c32fc71f2de629bfb3bd3c9325cd4419642b1f1da42ee488d9b98" ], - "version": "==0.6.0" + "version": "==2.1.0" } } } diff --git a/bot/__main__.py b/bot/__main__.py index 61271a692..84bc7094b 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -40,7 +40,6 @@ bot.load_extension("bot.cogs.duck_pond") bot.load_extension("bot.cogs.free") bot.load_extension("bot.cogs.information") bot.load_extension("bot.cogs.jams") -bot.load_extension("bot.cogs.metrics") bot.load_extension("bot.cogs.moderation") bot.load_extension("bot.cogs.off_topic_names") bot.load_extension("bot.cogs.reddit") diff --git a/bot/bot.py b/bot/bot.py index 930aaf70e..8f808272f 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -4,7 +4,6 @@ from typing import Optional import aiohttp from discord.ext import commands -from prometheus_async.aio.web import start_http_server as start_prometheus_http_server from bot import api @@ -51,6 +50,4 @@ class Bot(commands.Bot): """Open an aiohttp session before logging in and connecting to Discord.""" self.http_session = aiohttp.ClientSession(connector=self.connector) - await start_prometheus_http_server(addr="0.0.0.0", port=9330) - log.debug("Started Prometheus server on port 9330.") await super().start(*args, **kwargs) diff --git a/bot/cogs/antispam.py b/bot/cogs/antispam.py index f454061a6..f67ef6f05 100644 --- a/bot/cogs/antispam.py +++ b/bot/cogs/antispam.py @@ -19,6 +19,7 @@ from bot.constants import ( STAFF_ROLES, ) from bot.converters import Duration +from bot.utils.messages import send_attachments log = logging.getLogger(__name__) @@ -45,8 +46,9 @@ class DeletionContext: members: Dict[int, Member] = field(default_factory=dict) rules: Set[str] = field(default_factory=set) messages: Dict[int, Message] = field(default_factory=dict) + attachments: List[List[str]] = field(default_factory=list) - def add(self, rule_name: str, members: Iterable[Member], messages: Iterable[Message]) -> None: + async def add(self, rule_name: str, members: Iterable[Member], messages: Iterable[Message]) -> None: """Adds new rule violation events to the deletion context.""" self.rules.add(rule_name) @@ -58,6 +60,11 @@ class DeletionContext: if message.id not in self.messages: self.messages[message.id] = message + # Re-upload attachments + destination = message.guild.get_channel(Channels.attachment_log) + urls = await send_attachments(message, destination, link_large=False) + self.attachments.append(urls) + async def upload_messages(self, actor_id: int, modlog: ModLog) -> None: """Method that takes care of uploading the queue and posting modlog alert.""" triggered_by_users = ", ".join(f"{m} (`{m.id}`)" for m in self.members.values()) @@ -70,7 +77,7 @@ class DeletionContext: # For multiple messages or those with excessive newlines, use the logs API if len(self.messages) > 1 or 'newlines' in self.rules: - url = await modlog.upload_log(self.messages.values(), actor_id) + url = await modlog.upload_log(self.messages.values(), actor_id, self.attachments) mod_alert_message += f"A complete log of the offending messages can be found [here]({url})" else: mod_alert_message += "Message:\n" @@ -98,7 +105,7 @@ class DeletionContext: class AntiSpam(Cog): """Cog that controls our anti-spam measures.""" - def __init__(self, bot: Bot, validation_errors: bool) -> None: + def __init__(self, bot: Bot, validation_errors: Dict[str, str]) -> None: self.bot = bot self.validation_errors = validation_errors role_id = AntiSpamConfig.punishment['role_id'] @@ -106,7 +113,6 @@ class AntiSpam(Cog): self.expiration_date_converter = Duration() self.message_deletion_queue = dict() - self.queue_consumption_tasks = dict() self.bot.loop.create_task(self.alert_on_validation_error()) @@ -180,15 +186,14 @@ class AntiSpam(Cog): full_reason = f"`{rule_name}` rule: {reason}" # If there's no spam event going on for this channel, start a new Message Deletion Context - if message.channel.id not in self.message_deletion_queue: - log.trace(f"Creating queue for channel `{message.channel.id}`") - self.message_deletion_queue[message.channel.id] = DeletionContext(channel=message.channel) - self.queue_consumption_tasks = self.bot.loop.create_task( - self._process_deletion_context(message.channel.id) - ) + channel = message.channel + if channel.id not in self.message_deletion_queue: + log.trace(f"Creating queue for channel `{channel.id}`") + self.message_deletion_queue[message.channel.id] = DeletionContext(channel) + self.bot.loop.create_task(self._process_deletion_context(message.channel.id)) # Add the relevant of this trigger to the Deletion Context - self.message_deletion_queue[message.channel.id].add( + await self.message_deletion_queue[message.channel.id].add( rule_name=rule_name, members=members, messages=relevant_messages @@ -202,7 +207,7 @@ class AntiSpam(Cog): self.punish(message, member, full_reason) ) - await self.maybe_delete_messages(message.channel, relevant_messages) + await self.maybe_delete_messages(channel, relevant_messages) break async def punish(self, msg: Message, member: Member, reason: str) -> None: @@ -255,10 +260,10 @@ class AntiSpam(Cog): await deletion_context.upload_messages(self.bot.user.id, self.mod_log) -def validate_config(rules: Mapping = AntiSpamConfig.rules) -> Dict[str, str]: +def validate_config(rules_: Mapping = AntiSpamConfig.rules) -> Dict[str, str]: """Validates the antispam configs.""" validation_errors = {} - for name, config in rules.items(): + for name, config in rules_.items(): if name not in RULE_FUNCTION_MAPPING: log.error( f"Unrecognized antispam rule `{name}`. " diff --git a/bot/cogs/metrics.py b/bot/cogs/metrics.py deleted file mode 100644 index 47c3cc55e..000000000 --- a/bot/cogs/metrics.py +++ /dev/null @@ -1,98 +0,0 @@ -from collections import defaultdict - -from discord import Member, Message -from discord.ext.commands import Cog, Context -from prometheus_client import Counter, Gauge - -from bot.bot import Bot - - -class Metrics(Cog): - """ - Exports metrics for Prometheus. - - See https://github.com/prometheus/client_python for metric documentation. - """ - - PREFIX = 'pydis_bot' - - def __init__(self, bot: Bot) -> None: - self.bot = bot - - self.guild_members = Gauge( - name=f'{self.PREFIX}_guild_members', - documentation="Total members by guild by status.", - labelnames=('guild_id', 'status') - ) - self.guild_messages = Counter( - name=f'{self.PREFIX}_guild_messages', - documentation="Guild messages by guild by channel.", - labelnames=('channel_id', 'guild_id', 'channel_name') - ) - self.command_completions = Counter( - name=f'{self.PREFIX}_command_completions', - documentation="Completed commands by command, user, and guild.", - labelnames=('guild_id', 'user_id', 'user_name', 'command') - ) - - @Cog.listener() - async def on_ready(self) -> None: - """Initialize the guild member counter.""" - members_by_status = defaultdict(lambda: defaultdict(int)) - - for guild in self.bot.guilds: - if guild.large: - await self.bot.request_offline_members(guild) - for member in guild.members: - members_by_status[guild.id][member.status] += 1 - - for guild_id, members in members_by_status.items(): - for status, count in members.items(): - self.guild_members.labels(guild_id=guild_id, status=str(status)).set(count) - - @Cog.listener() - async def on_member_join(self, member: Member) -> None: - """Increment the member gauge.""" - self.guild_members.labels(guild_id=member.guild.id, status=str(member.status)).inc() - - @Cog.listener() - async def on_member_leave(self, member: Member) -> None: - """Decrement the member gauge.""" - self.guild_members.labels(guild_id=member.guild.id, status=str(member.status)).dec() - - @Cog.listener() - async def on_member_update(self, before: Member, after: Member) -> None: - """Update member gauges for the new and old status if applicable.""" - if before.status is not after.status: - self.guild_members.labels(guild_id=after.guild.id, status=str(before.status)).dec() - self.guild_members.labels(guild_id=after.guild.id, status=str(after.status)).inc() - - @Cog.listener() - async def on_message(self, message: Message) -> None: - """Increment the guild message counter.""" - self.guild_messages.labels( - channel_id=message.channel.id, - channel_name=message.channel.name, - guild_id=message.guild.id, - ).inc() - - @Cog.listener() - async def on_command_completion(self, ctx: Context) -> None: - """Increment the command completion counter.""" - if ctx.message.guild is not None: - if ctx.command.full_parent_name: - command = f'{ctx.command.full_parent_name} {ctx.command.name}' - else: - command = ctx.command.name - - self.command_completions.labels( - guild_id=ctx.message.guild.id, - user_id=ctx.author.id, - user_name=str(ctx.author), - command=command, - ).inc() - - -def setup(bot: Bot) -> None: - """Load the Metrics cog.""" - bot.add_cog(Metrics(bot)) diff --git a/bot/cogs/moderation/modlog.py b/bot/cogs/moderation/modlog.py index c78eb24a7..e8ae0dbe6 100644 --- a/bot/cogs/moderation/modlog.py +++ b/bot/cogs/moderation/modlog.py @@ -4,6 +4,7 @@ import itertools import logging import typing as t from datetime import datetime +from itertools import zip_longest import discord from dateutil.relativedelta import relativedelta @@ -42,14 +43,16 @@ class ModLog(Cog, name="ModLog"): self._cached_deletes = [] self._cached_edits = [] - async def upload_log(self, messages: t.List[discord.Message], actor_id: int) -> str: - """ - Uploads the log data to the database via an API endpoint for uploading logs. - - Used in several mod log embeds. + async def upload_log( + self, + messages: t.Iterable[discord.Message], + actor_id: int, + attachments: t.Iterable[t.List[str]] = None + ) -> str: + """Upload message logs to the database and return a URL to a page for viewing the logs.""" + if attachments is None: + attachments = [] - Returns a URL that can be used to view the log. - """ response = await self.bot.api_client.post( 'bot/deleted-messages', json={ @@ -61,9 +64,10 @@ class ModLog(Cog, name="ModLog"): 'author': message.author.id, 'channel_id': message.channel.id, 'content': message.content, - 'embeds': [embed.to_dict() for embed in message.embeds] + 'embeds': [embed.to_dict() for embed in message.embeds], + 'attachments': attachment, } - for message in messages + for message, attachment in zip_longest(messages, attachments) ] } ) diff --git a/bot/cogs/site.py b/bot/cogs/site.py index 2ea8c7a2e..853e29568 100644 --- a/bot/cogs/site.py +++ b/bot/cogs/site.py @@ -59,7 +59,7 @@ class Site(Cog): @site_group.command(name="tools") async def site_tools(self, ctx: Context) -> None: """Info about the site's Tools page.""" - tools_url = f"{PAGES_URL}/tools" + tools_url = f"{PAGES_URL}/resources/tools" embed = Embed(title="Tools") embed.set_footer(text=f"{tools_url}") @@ -74,7 +74,7 @@ class Site(Cog): @site_group.command(name="help") async def site_help(self, ctx: Context) -> None: """Info about the site's Getting Help page.""" - url = f"{PAGES_URL}/asking-good-questions" + url = f"{PAGES_URL}/resources/guides/asking-good-questions" embed = Embed(title="Asking Good Questions") embed.set_footer(text=url) diff --git a/bot/constants.py b/bot/constants.py index 25c7856ba..629985bdf 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -359,6 +359,7 @@ class Channels(metaclass=YAMLGetter): admins: int admin_spam: int announcements: int + attachment_log: int big_brother_logs: int bot: int checkpoint_test: int diff --git a/bot/utils/messages.py b/bot/utils/messages.py index 549b33ca6..c4e2753e0 100644 --- a/bot/utils/messages.py +++ b/bot/utils/messages.py @@ -1,7 +1,8 @@ import asyncio import contextlib +import logging from io import BytesIO -from typing import Optional, Sequence, Union +from typing import List, Optional, Sequence, Union from discord import Client, Embed, File, Member, Message, Reaction, TextChannel, Webhook from discord.abc import Snowflake @@ -9,7 +10,7 @@ from discord.errors import HTTPException from bot.constants import Emojis -MAX_SIZE = 1024 * 1024 * 8 # 8 Mebibytes +log = logging.getLogger(__name__) async def wait_for_deletion( @@ -51,42 +52,58 @@ async def wait_for_deletion( await message.delete() -async def send_attachments(message: Message, destination: Union[TextChannel, Webhook]) -> None: +async def send_attachments( + message: Message, + destination: Union[TextChannel, Webhook], + link_large: bool = True +) -> List[str]: """ - Re-uploads each attachment in a message to the given channel or webhook. + Re-upload the message's attachments to the destination and return a list of their new URLs. - Each attachment is sent as a separate message to more easily comply with the 8 MiB request size limit. - If attachments are too large, they are instead grouped into a single embed which links to them. + Each attachment is sent as a separate message to more easily comply with the request/file size + limit. If link_large is True, attachments which are too large are instead grouped into a single + embed which links to them. """ large = [] + urls = [] for attachment in message.attachments: + failure_msg = ( + f"Failed to re-upload attachment {attachment.filename} from message {message.id}" + ) + try: - # This should avoid most files that are too large, but some may get through hence the try-catch. # Allow 512 bytes of leeway for the rest of the request. - if attachment.size <= MAX_SIZE - 512: + # This should avoid most files that are too large, + # but some may get through hence the try-catch. + if attachment.size <= destination.guild.filesize_limit - 512: with BytesIO() as file: - await attachment.save(file) + await attachment.save(file, use_cached=True) attachment_file = File(file, filename=attachment.filename) if isinstance(destination, TextChannel): - await destination.send(file=attachment_file) + msg = await destination.send(file=attachment_file) + urls.append(msg.attachments[0].url) else: await destination.send( file=attachment_file, username=message.author.display_name, avatar_url=message.author.avatar_url ) - else: + elif link_large: large.append(attachment) + else: + log.warning(f"{failure_msg} because it's too large.") except HTTPException as e: - if e.status == 413: + if link_large and e.status == 413: large.append(attachment) else: - raise + log.warning(f"{failure_msg} with status {e.status}.") - if large: - embed = Embed(description=f"\n".join(f"[{attachment.filename}]({attachment.url})" for attachment in large)) + if link_large and large: + desc = f"\n".join(f"[{attachment.filename}]({attachment.url})" for attachment in large) + embed = Embed(description=desc) embed.set_footer(text="Attachments exceed upload size limit.") + if isinstance(destination, TextChannel): await destination.send(embed=embed) else: @@ -95,3 +112,5 @@ async def send_attachments(message: Message, destination: Union[TextChannel, Web username=message.author.display_name, avatar_url=message.author.avatar_url ) + + return urls diff --git a/config-default.yml b/config-default.yml index 1a8aaedae..c113d3330 100644 --- a/config-default.yml +++ b/config-default.yml @@ -115,6 +115,7 @@ guild: admin_spam: &ADMIN_SPAM 563594791770914816 admins_voice: &ADMINS_VOICE 500734494840717332 announcements: 354619224620138496 + attachment_log: &ATTCH_LOG 649243850006855680 big_brother_logs: &BBLOGS 468507907357409333 bot: 267659945086812160 checkpoint_test: 422077681434099723 @@ -152,7 +153,7 @@ guild: voice_log: 640292421988646961 staff_channels: [*ADMINS, *ADMIN_SPAM, *MOD_SPAM, *MODS, *HELPERS, *ORGANISATION, *DEFCON] - ignored: [*ADMINS, *MESSAGE_LOG, *MODLOG, *ADMINS_VOICE, *STAFF_VOICE] + ignored: [*ADMINS, *MESSAGE_LOG, *MODLOG, *ADMINS_VOICE, *STAFF_VOICE, *ATTCH_LOG] roles: admin: &ADMIN_ROLE 267628507062992896 |