1
0
Fork 0
mirror of https://github.com/myned/modufur.git synced 2024-11-01 13:02:38 +00:00

Merge branch 'dev'

This commit is contained in:
Dylan Dizon 2018-11-15 16:27:54 -05:00
commit bc854ef1d8
8 changed files with 418 additions and 747 deletions

1
.gitignore vendored
View file

@ -6,6 +6,7 @@
*.pkl *.pkl
*.png *.png
*.bat *.bat
*.lock
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/

View file

@ -9,13 +9,9 @@ name = "pypi"
aiohttp = "*" aiohttp = "*"
beautifulsoup4 = "*" beautifulsoup4 = "*"
"discord.py" = {extras = ["voice"], git = "https://github.com/Rapptz/discord.py", ref = "rewrite"} "discord.py" = {extras = ["voice"], git = "https://github.com/Rapptz/discord.py", ref = "rewrite"}
gitpython = "*"
google-api-python-client = "*"
hurry = "*"
"hurry.filesize" = "*" "hurry.filesize" = "*"
lxml = "*" lxml = "*"
pyrasite = "*"
requests = "*" requests = "*"
websockets = "*" websockets = "*"
[dev-packages] [dev-packages]

358
Pipfile.lock generated
View file

@ -1,358 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "28a6c84504aba172b55cf50f8aba8eb059351bd393414e3f39e1696a2a86f526"
},
"pipfile-spec": 6,
"requires": {},
"sources": [
{
"name": "pypi",
"url": "https://pypi.python.org/simple",
"verify_ssl": true
}
]
},
"default": {
"aiohttp": {
"hashes": [
"sha256:0419705a36b43c0ac6f15469f9c2a08cad5c939d78bd12a5c23ea167c8253b2b",
"sha256:1812fc4bc6ac1bde007daa05d2d0f61199324e0cc893b11523e646595047ca08",
"sha256:2214b5c0153f45256d5d52d1e0cafe53f9905ed035a142191727a5fb620c03dd",
"sha256:275909137f0c92c61ba6bb1af856a522d5546f1de8ea01e4e726321c697754ac",
"sha256:3983611922b561868428ea1e7269e757803713f55b53502423decc509fef1650",
"sha256:51afec6ffa50a9da4cdef188971a802beb1ca8e8edb40fa429e5e529db3475fa",
"sha256:589f2ec8a101a0f340453ee6945bdfea8e1cd84c8d88e5be08716c34c0799d95",
"sha256:789820ddc65e1f5e71516adaca2e9022498fa5a837c79ba9c692a9f8f916c330",
"sha256:7a968a0bdaaf9abacc260911775611c9a602214a23aeb846f2eb2eeaa350c4dc",
"sha256:7aeefbed253f59ea39e70c5848de42ed85cb941165357fc7e87ab5d8f1f9592b",
"sha256:7b2eb55c66512405103485bd7d285a839d53e7fdc261ab20e5bcc51d7aaff5de",
"sha256:87bc95d3d333bb689c8d755b4a9d7095a2356108002149523dfc8e607d5d32a4",
"sha256:9d80e40db208e29168d3723d1440ecbb06054d349c5ece6a2c5a611490830dd7",
"sha256:a1b442195c2a77d33e4dbee67c9877ccbdd3a1f686f91eb479a9577ed8cc326b",
"sha256:ab3d769413b322d6092f169f316f7b21cd261a7589f7e31db779d5731b0480d8",
"sha256:b066d3dec5d0f5aee6e34e5765095dc3d6d78ef9839640141a2b20816a0642bd",
"sha256:b24e7845ae8de3e388ef4bcfcf7f96b05f52c8e633b33cf8003a6b1d726fc7c2",
"sha256:c59a953c3f8524a7c86eaeaef5bf702555be12f5668f6384149fe4bb75c52698",
"sha256:cf2cc6c2c10d242790412bea7ccf73726a9a44b4c4b073d2699ef3b48971fd95",
"sha256:e0c9c8d4150ae904f308ff27b35446990d2b1dfc944702a21925937e937394c6",
"sha256:f1839db4c2b08a9c8f9788112644f8a8557e8e0ecc77b07091afabb941dc55d0",
"sha256:f3df52362be39908f9c028a65490fae0475e4898b43a03d8aa29d1e765b45e07"
],
"index": "pypi",
"version": "==3.4.4"
},
"async-timeout": {
"hashes": [
"sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f",
"sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"
],
"version": "==3.0.1"
},
"attrs": {
"hashes": [
"sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
"sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
],
"version": "==18.2.0"
},
"beautifulsoup4": {
"hashes": [
"sha256:194ec62a25438adcb3fdb06378b26559eda1ea8a747367d34c33cef9c7f48d57",
"sha256:90f8e61121d6ae58362ce3bed8cd997efb00c914eae0ff3d363c32f9a9822d10",
"sha256:f0abd31228055d698bb392a826528ea08ebb9959e6bea17c606fd9c9009db938"
],
"index": "pypi",
"version": "==4.6.3"
},
"cachetools": {
"hashes": [
"sha256:0a258d82933a1dd18cb540aca4ac5d5690731e24d1239a08577b814998f49785",
"sha256:4621965b0d9d4c82a79a29edbad19946f5e7702df4afae7d1ed2df951559a8cc"
],
"version": "==3.0.0"
},
"certifi": {
"hashes": [
"sha256:339dc09518b07e2fa7eda5450740925974815557727d6bd35d319c1524a04a4c",
"sha256:6d58c986d22b038c8c0df30d639f23a3e6d172a05c3583e766f4c0b785c0986a"
],
"version": "==2018.10.15"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"discord-py": {
"extras": [
"voice"
],
"git": "https://github.com/Rapptz/discord.py",
"ref": "860d6a9ace8248dfeec18b8b159e7b757d9f56bb"
},
"discord.py": {
"extras": [
"voice"
],
"git": "https://github.com/Rapptz/discord.py",
"ref": "rewrite"
},
"docopt": {
"hashes": [
"sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"
],
"version": "==0.6.2"
},
"gitdb2": {
"hashes": [
"sha256:83361131a1836661a155172932a13c08bda2db3674e4caa32368aa6eb02f38c2",
"sha256:e3a0141c5f2a3f635c7209d56c496ebe1ad35da82fe4d3ec4aaa36278d70648a"
],
"version": "==2.0.5"
},
"gitpython": {
"hashes": [
"sha256:563221e5a44369c6b79172f455584c9ebbb122a13368cc82cb4b5addff788f82",
"sha256:8237dc5bfd6f1366abeee5624111b9d6879393d84745a507de0fda86043b65a8"
],
"index": "pypi",
"version": "==2.1.11"
},
"google-api-python-client": {
"hashes": [
"sha256:5d5cb02c6f3112c68eed51b74891a49c0e35263380672d662f8bfe85b8114d7c",
"sha256:7cc47cf80b25ecd7f3d917ea247bb6c62587514e40604ae29c47c0e4ebd1174b"
],
"index": "pypi",
"version": "==1.7.4"
},
"google-auth": {
"hashes": [
"sha256:9ca363facbf2622d9ba828017536ccca2e0f58bd15e659b52f312172f8815530",
"sha256:a4cf9e803f2176b5de442763bd339b313d3f1ed3002e3e1eb6eec1d7c9bbc9b4"
],
"version": "==1.5.1"
},
"google-auth-httplib2": {
"hashes": [
"sha256:098fade613c25b4527b2c08fa42d11f3c2037dda8995d86de0745228e965d445",
"sha256:f1c437842155680cf9918df9bc51c1182fda41feef88c34004bd1978c8157e08"
],
"version": "==0.0.3"
},
"httplib2": {
"hashes": [
"sha256:e71daed9a0e6373642db61166fa70beecc9bf04383477f84671348c02a04cbdf"
],
"version": "==0.11.3"
},
"hurry": {
"hashes": [
"sha256:d94d3bb94573c17b215257f3f77a9279f2dbb2e794c1862bdb180529edeb8d3f"
],
"index": "pypi",
"version": "==1.0"
},
"hurry.filesize": {
"hashes": [
"sha256:f5368329adbef86accd3bc9490522340bb79260455ae89b1a42c10f63801b9a6"
],
"index": "pypi",
"version": "==0.9"
},
"idna": {
"hashes": [
"sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
"sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
],
"version": "==2.7"
},
"lxml": {
"hashes": [
"sha256:02bc220d61f46e9b9d5a53c361ef95e9f5e1d27171cd461dddb17677ae2289a5",
"sha256:22f253b542a342755f6cfc047fe4d3a296515cf9b542bc6e261af45a80b8caf6",
"sha256:2f31145c7ff665b330919bfa44aacd3a0211a76ca7e7b441039d2a0b0451e415",
"sha256:36720698c29e7a9626a0dc802ef8885f8f0239bfd1689628ecd459a061f2807f",
"sha256:438a1b0203545521f6616132bfe0f4bca86f8a401364008b30e2b26ec408ce85",
"sha256:4815892904c336bbaf73dafd54f45f69f4021c22b5bad7332176bbf4fb830568",
"sha256:5be031b0f15ad63910d8e5038b489d95a79929513b3634ad4babf77100602588",
"sha256:5c93ae37c3c588e829b037fdfbd64a6e40c901d3f93f7beed6d724c44829a3ad",
"sha256:60842230678674cdac4a1cf0f707ef12d75b9a4fc4a565add4f710b5fcf185d5",
"sha256:62939a8bb6758d1bf923aa1c13f0bcfa9bf5b2fc0f5fa917a6e25db5fe0cfa4e",
"sha256:75830c06a62fe7b8fe3bbb5f269f0b308f19f3949ac81cfd40062f47c1455faf",
"sha256:81992565b74332c7c1aff6a913a3e906771aa81c9d0c68c68113cffcae45bc53",
"sha256:8c892fb0ee52c594d9a7751c7d7356056a9682674b92cc1c4dc968ff0f30c52f",
"sha256:9d862e3cf4fc1f2837dedce9c42269c8c76d027e49820a548ac89fdcee1e361f",
"sha256:a623965c086a6e91bb703d4da62dabe59fe88888e82c4117d544e11fd74835d6",
"sha256:a7783ab7f6a508b0510490cef9f857b763d796ba7476d9703f89722928d1e113",
"sha256:aab09fbe8abfa3b9ce62aaf45aca2d28726b1b9ee44871dbe644050a2fff4940",
"sha256:abf181934ac3ef193832fb973fd7f6149b5c531903c2ec0f1220941d73eee601",
"sha256:ae07fa0c115733fce1e9da96a3ac3fa24801742ca17e917e0c79d63a01eeb843",
"sha256:b9c78242219f674ab645ec571c9a95d70f381319a23911941cd2358a8e0521cf",
"sha256:bccb267678b870d9782c3b44d0cefe3ba0e329f9af8c946d32bf3778e7a4f271",
"sha256:c4df4d27f4c93b2cef74579f00b1d3a31a929c7d8023f870c4b476f03a274db4",
"sha256:caf0e50b546bb60dfa99bb18dfa6748458a83131ecdceaf5c071d74907e7e78a",
"sha256:d3266bd3ac59ac4edcd5fa75165dee80b94a3e5c91049df5f7c057ccf097551c",
"sha256:db0d213987bcd4e6d41710fb4532b22315b0d8fb439ff901782234456556aed1",
"sha256:dbbd5cf7690a40a9f0a9325ab480d0fccf46d16b378eefc08e195d84299bfae1",
"sha256:e16e07a0ec3a75b5ee61f2b1003c35696738f937dc8148fbda9fe2147ccb6e61",
"sha256:e175a006725c7faadbe69e791877d09936c0ef2cf49d01b60a6c1efcb0e8be6f",
"sha256:edd9c13a97f6550f9da2236126bb51c092b3b1ce6187f2bd966533ad794bbb5e",
"sha256:fa39ea60d527fbdd94215b5e5552f1c6a912624521093f1384a491a8ad89ad8b"
],
"index": "pypi",
"version": "==4.2.5"
},
"multidict": {
"hashes": [
"sha256:05eeab69bf2b0664644c62bd92fabb045163e5b8d4376a31dfb52ce0210ced7b",
"sha256:0c85880efa7cadb18e3b5eef0aa075dc9c0a3064cbbaef2e20be264b9cf47a64",
"sha256:136f5a4a6a4adeacc4dc820b8b22f0a378fb74f326e259c54d1817639d1d40a0",
"sha256:14906ad3347c7d03e9101749b16611cf2028547716d0840838d3c5e2b3b0f2d3",
"sha256:1ade4a3b71b1bf9e90c5f3d034a87fe4949c087ef1f6cd727fdd766fe8bbd121",
"sha256:22939a00a511a59f9ecc0158b8db728afef57975ce3782b3a265a319d05b9b12",
"sha256:2b86b02d872bc5ba5b3a4530f6a7ba0b541458ab4f7c1429a12ac326231203f7",
"sha256:3c11e92c3dfc321014e22fb442bc9eb70e01af30d6ce442026b0c35723448c66",
"sha256:4ba3bd26f282b201fdbce351f1c5d17ceb224cbedb73d6e96e6ce391b354aacc",
"sha256:4c6e78d042e93751f60672989efbd6a6bc54213ed7ff695fff82784bbb9ea035",
"sha256:4d80d1901b89cc935a6cf5b9fd89df66565272722fe2e5473168927a9937e0ca",
"sha256:4fcf71d33178a00cc34a57b29f5dab1734b9ce0f1c97fb34666deefac6f92037",
"sha256:52f7670b41d4b4d97866ebc38121de8bcb9813128b7c4942b07794d08193c0ab",
"sha256:5368e2b7649a26b7253c6c9e53241248aab9da49099442f5be238fde436f18c9",
"sha256:5bb65fbb48999044938f0c0508e929b14a9b8bf4939d8263e9ea6691f7b54663",
"sha256:60672bb5577472800fcca1ac9dae232d1461db9f20f055184be8ce54b0052572",
"sha256:669e9be6d148fc0283f53e17dd140cde4dc7c87edac8319147edd5aa2a830771",
"sha256:6a0b7a804e8d1716aa2c72e73210b48be83d25ba9ec5cf52cf91122285707bb1",
"sha256:79034ea3da3cf2a815e3e52afdc1f6c1894468c98bdce5d2546fa2342585497f",
"sha256:79247feeef6abcc11137ad17922e865052f23447152059402fc320f99ff544bb",
"sha256:81671c2049e6bf42c7fd11a060f8bc58f58b7b3d6f3f951fc0b15e376a6a5a98",
"sha256:82ac4a5cb56cc9280d4ae52c2d2ebcd6e0668dd0f9ef17f0a9d7c82bd61e24fa",
"sha256:9436267dbbaa49dad18fbbb54f85386b0f5818d055e7b8e01d219661b6745279",
"sha256:94e4140bb1343115a1afd6d84ebf8fca5fb7bfb50e1c2cbd6f2fb5d3117ef102",
"sha256:a2cab366eae8a0ffe0813fd8e335cf0d6b9bb6c5227315f53bb457519b811537",
"sha256:a596019c3eafb1b0ae07db9f55a08578b43c79adb1fe1ab1fd818430ae59ee6f",
"sha256:e8848ae3cd6a784c29fae5055028bee9bffcc704d8bcad09bd46b42b44a833e2",
"sha256:e8a048bfd7d5a280f27527d11449a509ddedf08b58a09a24314828631c099306",
"sha256:f6dd28a0ac60e2426a6918f36f1b4e2620fc785a0de7654cd206ba842eee57fd"
],
"version": "==4.4.2"
},
"py": {
"hashes": [
"sha256:0f2d585d22050e90c7d293b6451c83db097df77871974d90efd5a30dc12fcde3",
"sha256:2ccb79b01769d99115aa600d7eed99f524bf752bba8f041dc1c184853514655a"
],
"version": "==1.4.34"
},
"pyasn1": {
"hashes": [
"sha256:b9d3abc5031e61927c82d4d96c1cec1e55676c1a991623cfed28faea73cdd7ca",
"sha256:f58f2a3d12fd754aa123e9fa74fb7345333000a035f3921dbdaa08597aa53137"
],
"version": "==0.4.4"
},
"pyasn1-modules": {
"hashes": [
"sha256:a0cf3e1842e7c60fde97cb22d275eb6f9524f5c5250489e292529de841417547",
"sha256:a38a8811ea784c0136abfdba73963876328f66172db21a05a82f9515909bfb4e"
],
"version": "==0.2.2"
},
"pyrasite": {
"hashes": [
"sha256:e5f7a36a04379d00a46688c60a8e9bbba7c807526a9252a60cbed8de701f6ccf"
],
"index": "pypi",
"version": "==2.0"
},
"requests": {
"hashes": [
"sha256:99dcfdaaeb17caf6e526f32b6a7b780461512ab3f1d992187801694cba42770c",
"sha256:a84b8c9ab6239b578f22d1c21d51b696dcfe004032bb80ea832398d6909d7279"
],
"index": "pypi",
"version": "==2.20.0"
},
"rsa": {
"hashes": [
"sha256:14ba45700ff1ec9eeb206a2ce76b32814958a98e372006c8fb76ba820211be66",
"sha256:1a836406405730121ae9823e19c6e806c62bbad73f890574fff50efa4122c487"
],
"version": "==4.0"
},
"six": {
"hashes": [
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
],
"version": "==1.11.0"
},
"smmap2": {
"hashes": [
"sha256:0555a7bf4df71d1ef4218e4807bbf9b201f910174e6e08af2e138d4e517b4dde",
"sha256:29a9ffa0497e7f2be94ca0ed1ca1aa3cd4cf25a1f6b4f5f87f74b46ed91d609a"
],
"version": "==2.0.5"
},
"uritemplate": {
"hashes": [
"sha256:01c69f4fe8ed503b2951bef85d996a9d22434d2431584b5b107b2981ff416fbd",
"sha256:1b9c467a940ce9fb9f50df819e8ddd14696f89b9a8cc87ac77952ba416e0a8fd",
"sha256:c02643cebe23fc8adb5e6becffe201185bf06c40bda5c0b4028a93f1527d011d"
],
"version": "==3.0.0"
},
"urllib3": {
"hashes": [
"sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39",
"sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22"
],
"version": "==1.24.1"
},
"websockets": {
"hashes": [
"sha256:04b42a1b57096ffa5627d6a78ea1ff7fad3bc2c0331ffc17bc32a4024da7fea0",
"sha256:08e3c3e0535befa4f0c4443824496c03ecc25062debbcf895874f8a0b4c97c9f",
"sha256:10d89d4326045bf5e15e83e9867c85d686b612822e4d8f149cf4840aab5f46e0",
"sha256:232fac8a1978fc1dead4b1c2fa27c7756750fb393eb4ac52f6bc87ba7242b2fa",
"sha256:4bf4c8097440eff22bc78ec76fe2a865a6e658b6977a504679aaf08f02c121da",
"sha256:51642ea3a00772d1e48fb0c492f0d3ae3b6474f34d20eca005a83f8c9c06c561",
"sha256:55d86102282a636e195dad68aaaf85b81d0bef449d7e2ef2ff79ac450bb25d53",
"sha256:564d2675682bd497b59907d2205031acbf7d3fadf8c763b689b9ede20300b215",
"sha256:5d13bf5197a92149dc0badcc2b699267ff65a867029f465accfca8abab95f412",
"sha256:5eda665f6789edb9b57b57a159b9c55482cbe5b046d7db458948370554b16439",
"sha256:5edb2524d4032be4564c65dc4f9d01e79fe8fad5f966e5b552f4e5164fef0885",
"sha256:79691794288bc51e2a3b8de2bc0272ca8355d0b8503077ea57c0716e840ebaef",
"sha256:7fcc8681e9981b9b511cdee7c580d5b005f3bb86b65bde2188e04a29f1d63317",
"sha256:8e447e05ec88b1b408a4c9cde85aa6f4b04f06aa874b9f0b8e8319faf51b1fee",
"sha256:90ea6b3e7787620bb295a4ae050d2811c807d65b1486749414f78cfd6fb61489",
"sha256:9e13239952694b8b831088431d15f771beace10edfcf9ef230cefea14f18508f",
"sha256:d40f081187f7b54d7a99d8a5c782eaa4edc335a057aa54c85059272ed826dc09",
"sha256:e1df1a58ed2468c7b7ce9a2f9752a32ad08eac2bcd56318625c3647c2cd2da6f",
"sha256:e98d0cec437097f09c7834a11c69d79fe6241729b23f656cfc227e93294fc242",
"sha256:f8d59627702d2ff27cb495ca1abdea8bd8d581de425c56e93bff6517134e0a9b",
"sha256:fc30cdf2e949a2225b012a7911d1d031df3d23e99b7eda7dfc982dc4a860dae9"
],
"index": "pypi",
"version": "==7.0"
},
"yarl": {
"hashes": [
"sha256:2556b779125621b311844a072e0ed367e8409a18fa12cbd68eb1258d187820f9",
"sha256:4aec0769f1799a9d4496827292c02a7b1f75c0bab56ab2b60dd94ebb57cbd5ee",
"sha256:55369d95afaacf2fa6b49c84d18b51f1704a6560c432a0f9a1aeb23f7b971308",
"sha256:6c098b85442c8fe3303e708bbb775afd0f6b29f77612e8892627bcab4b939357",
"sha256:9182cd6f93412d32e009020a44d6d170d2093646464a88aeec2aef50592f8c78",
"sha256:c8cbc21bbfa1dd7d5386d48cc814fe3d35b80f60299cdde9279046f399c3b0d8",
"sha256:db6f70a4b09cde813a4807843abaaa60f3b15fb4a2a06f9ae9c311472662daa1",
"sha256:f17495e6fe3d377e3faac68121caef6f974fcb9e046bc075bcff40d8e5cc69a4",
"sha256:f85900b9cca0c67767bb61b2b9bd53208aaa7373dae633dbe25d179b4bf38aa7"
],
"version": "==1.2.6"
}
},
"develop": {}
}

View file

@ -39,9 +39,7 @@ class MsG:
# self.suggested = u.setdefault('cogs/suggested.pkl', {'last_update': 'test', 'tags': {}, 'total': 1}) # self.suggested = u.setdefault('cogs/suggested.pkl', {'last_update': 'test', 'tags': {}, 'total': 1})
print(self.suggested) print(self.suggested)
self.favorites = u.setdefault('cogs/favorites.pkl', {}) self.favorites = u.setdefault('cogs/favorites.pkl', {})
self.blacklists = u.setdefault( self.blacklists = u.setdefault('cogs/blacklists.pkl', {'global': {}, 'channel': {}, 'user': {}})
'cogs/blacklists.pkl', {'global_blacklist': set(), 'guild_blacklist': {}, 'user_blacklist': {}})
self.aliases = u.setdefault('cogs/aliases.pkl', {})
if not self.hearting: if not self.hearting:
self.hearting = True self.hearting = True
@ -657,14 +655,21 @@ class MsG:
# Messy code that checks image limit and tags in blacklists # Messy code that checks image limit and tags in blacklists
async def _get_posts(self, ctx, *, booru='e621', tags=[], limit=1, previous={}): async def _get_posts(self, ctx, *, booru='e621', tags=[], limit=1, previous={}):
guild = ctx.guild if isinstance(
ctx.guild, d.Guild) else ctx.channel
blacklist = set() blacklist = set()
# Creates temp blacklist based on context # Creates temp blacklist based on context
for bl in (self.blacklists['global_blacklist'], self.blacklists['guild_blacklist'].get(guild.id, {}).get(ctx.channel.id, set()), self.blacklists['user_blacklist'].get(ctx.author.id, set())): for lst in ('blacklist', 'aliases'):
for tag in bl: default = set() if lst == 'blacklist' else {}
blacklist.update([tag] + list(self.aliases[tag]))
for bl in (self.blacklists['global'].get(lst, default),
self.blacklists['channel'].get(ctx.channel.id, {}).get(lst, default),
self.blacklists['user'].get(ctx.author.id, {}).get(lst, default)):
if lst == 'aliases':
temp = list(bl.keys()) + [tag for tags in bl.values() for tag in tags]
temp = set(temp)
else:
temp = bl
blacklist.update(temp)
# Checks for, assigns, and removes first order in tags if possible # Checks for, assigns, and removes first order in tags if possible
order = [tag for tag in tags if 'order:' in tag] order = [tag for tag in tags if 'order:' in tag]
if order: if order:
@ -698,8 +703,9 @@ class MsG:
if 'swf' in post['file_ext'] or 'webm' in post['file_ext']: if 'swf' in post['file_ext'] or 'webm' in post['file_ext']:
continue continue
try: try:
post_tags = post['tags'].split(' ')
for tag in blacklist: for tag in blacklist:
if tag in post['tags']: if tag in post_tags:
raise exc.Continue raise exc.Continue
except exc.Continue: except exc.Continue:
continue continue
@ -771,8 +777,8 @@ class MsG:
while not self.bot.is_closed(): while not self.bot.is_closed():
try: try:
await asyncio.gather(*[self.bot.wait_for('reaction_add', check=on_reaction, timeout=8 * 60), await asyncio.gather(*[self.bot.wait_for('reaction_add', check=on_reaction, timeout=8*60),
self.bot.wait_for('reaction_remove', check=on_reaction, timeout=8 * 60)]) self.bot.wait_for('reaction_remove', check=on_reaction, timeout=8*60)])
except exc.Save: except exc.Save:
if keys[c - 1] not in hearted: if keys[c - 1] not in hearted:
@ -800,7 +806,7 @@ class MsG:
except exc.GoTo: except exc.GoTo:
await paginator.edit(content='\N{INPUT SYMBOL FOR NUMBERS}') await paginator.edit(content='\N{INPUT SYMBOL FOR NUMBERS}')
number = await self.bot.wait_for('message', check=on_message, timeout=8 * 60) number = await self.bot.wait_for('message', check=on_message, timeout=8*60)
if int(number.content) != 0: if int(number.content) != 0:
c = int(number.content) c = int(number.content)
@ -911,8 +917,8 @@ class MsG:
while not self.bot.is_closed(): while not self.bot.is_closed():
try: try:
await asyncio.gather(*[self.bot.wait_for('reaction_add', check=on_reaction, timeout=8 * 60), await asyncio.gather(*[self.bot.wait_for('reaction_add', check=on_reaction, timeout=8*60),
self.bot.wait_for('reaction_remove', check=on_reaction, timeout=8 * 60)]) self.bot.wait_for('reaction_remove', check=on_reaction, timeout=8*60)])
except exc.Save: except exc.Save:
if keys[c - 1] not in hearted.keys(): if keys[c - 1] not in hearted.keys():
@ -940,7 +946,7 @@ class MsG:
except exc.GoTo: except exc.GoTo:
await paginator.edit(content=f'`{c} / {len(posts)}`') await paginator.edit(content=f'`{c} / {len(posts)}`')
number = await self.bot.wait_for('message', check=on_message, timeout=8 * 60) number = await self.bot.wait_for('message', check=on_message, timeout=8*60)
if int(number.content) != 0: if int(number.content) != 0:
c = int(number.content) c = int(number.content)
@ -1075,8 +1081,8 @@ class MsG:
while not self.bot.is_closed(): while not self.bot.is_closed():
try: try:
await asyncio.gather(*[self.bot.wait_for('reaction_add', check=on_reaction, timeout=8 * 60), await asyncio.gather(*[self.bot.wait_for('reaction_add', check=on_reaction, timeout=8*60),
self.bot.wait_for('reaction_remove', check=on_reaction, timeout=8 * 60)]) self.bot.wait_for('reaction_remove', check=on_reaction, timeout=8*60)])
except exc.Save: except exc.Save:
if keys[c - 1] not in hearted: if keys[c - 1] not in hearted:
@ -1104,7 +1110,7 @@ class MsG:
except exc.GoTo: except exc.GoTo:
await paginator.edit(content=f'`{c} / {len(posts)}`') await paginator.edit(content=f'`{c} / {len(posts)}`')
number = await self.bot.wait_for('message', check=on_message, timeout=8 * 60) number = await self.bot.wait_for('message', check=on_message, timeout=8*60)
if int(number.content) != 0: if int(number.content) != 0:
c = int(number.content) c = int(number.content)
@ -1278,425 +1284,442 @@ class MsG:
await ctx.send('**Request timed out**') await ctx.send('**Request timed out**')
await ctx.message.add_reaction('\N{CROSS MARK}') await ctx.message.add_reaction('\N{CROSS MARK}')
@cmds.group(aliases=['fave', 'fav', 'f']) # @cmds.group(aliases=['fave', 'fav', 'f'])
async def favorite(self, ctx): # async def favorite(self, ctx):
if not ctx.invoked_subcommand: # if not ctx.invoked_subcommand:
await ctx.send('**Use a flag to manage favorites.**\n*Type* `{}help fav` *for more info.*'.format(ctx.prefix)) # await ctx.send('**Use a flag to manage favorites.**\n*Type* `{}help fav` *for more info.*'.format(ctx.prefix))
await ctx.message.add_reaction('\N{CROSS MARK}') # await ctx.message.add_reaction('\N{CROSS MARK}')
#
# @favorite.error
# async def favorite_error(self, ctx, error):
# pass
#
# @favorite.group(name='get', aliases=['g'])
# async def _get_favorite(self, ctx):
# pass
#
# @_get_favorite.command(name='tags', aliases=['t'])
# async def __get_favorite_tags(self, ctx, *args):
# await ctx.send('\N{WHITE MEDIUM STAR} {}**\'s favorite tags:**\n```\n{}```'.format(ctx.author.mention, ' '.join(self.favorites.get(ctx.author.id, {}).get('tags', set()))))
#
# @_get_favorite.command(name='posts', aliases=['p'])
# async def __get_favorite_posts(self, ctx):
# pass
#
# @favorite.group(name='add', aliases=['a'])
# async def _add_favorite(self, ctx):
# pass
#
# @_add_favorite.command(name='tags', aliases=['t'])
# async def __add_favorite_tags(self, ctx, *args):
# try:
# kwargs = u.get_kwargs(ctx, args)
# tags = kwargs['remaining']
#
# for tag in tags:
# if tag in self.blacklists['user']['blacklist'].get(ctx.author.id, set()):
# raise exc.TagBlacklisted(tag)
# with suppress(KeyError):
# if len(self.favorites[ctx.author.id]['tags']) + len(tags) > 5:
# raise exc.BoundsError
#
# self.favorites.setdefault(ctx.author.id, {}).setdefault(
# 'tags', set()).update(tags)
# u.dump(self.favorites, 'cogs/favorites.pkl')
#
# await ctx.send('{} **added to their favorites:**\n```\n{}```'.format(ctx.author.mention, ' '.join(tags)))
#
# except exc.BoundsError:
# await ctx.send('**Favorites list currently limited to:** `5`')
# await ctx.message.add_reaction('\N{CROSS MARK}')
# except exc.TagBlacklisted as e:
# await ctx.send('\N{NO ENTRY SIGN} `{}` **blacklisted**')
# await ctx.message.add_reaction('\N{NO ENTRY SIGN}')
#
# @_add_favorite.command(name='posts', aliases=['p'])
# async def __add_favorite_posts(self, ctx, *posts):
# pass
#
# @favorite.group(name='remove', aliases=['r'])
# async def _remove_favorite(self, ctx):
# pass
#
# @_remove_favorite.command(name='tags', aliases=['t'])
# async def __remove_favorite_tags(self, ctx, *args):
# try:
# kwargs = u.get_kwargs(ctx, args)
# tags = kwargs['remaining']
#
# for tag in tags:
# try:
# self.favorites[ctx.author.id].get(
# 'tags', set()).remove(tag)
#
# except KeyError:
# raise exc.TagError(tag)
#
# u.dump(self.favorites, 'cogs/favorites.pkl')
#
# await ctx.send('{} **removed from their favorites:**\n```\n{}```'.format(ctx.author.mention, ' '.join(tags)))
#
# except KeyError:
# await ctx.send('**You do not have any favorites**')
# await ctx.message.add_reaction('\N{CROSS MARK}')
# except exc.TagError as e:
# await ctx.send('`{}` **not in favorites**'.format(e))
# await ctx.message.add_reaction('\N{CROSS MARK}')
#
# @_remove_favorite.command(name='posts', aliases=['p'])
# async def __remove_favorite_posts(self, ctx):
# pass
#
# @favorite.group(name='clear', aliases=['c'])
# async def _clear_favorite(self, ctx):
# pass
#
# @_clear_favorite.command(name='tags', aliases=['t'])
# async def __clear_favorite_tags(self, ctx, *args):
# with suppress(KeyError):
# del self.favorites[ctx.author.id]
# u.dump(self.favorites, 'cogs/favorites.pkl')
#
# await ctx.send('{}**\'s favorites cleared**'.format(ctx.author.mention))
#
# @_clear_favorite.command(name='posts', aliases=['p'])
# async def __clear_favorite_posts(self, ctx):
# pass
@favorite.error @cmds.group(
async def favorite_error(self, ctx, error): aliases=['bl', 'b'],
pass brief='(G) Manage blacklists',
description='Manage global, guild (WIP), channel, and personal blacklists',
@favorite.group(name='get', aliases=['g']) usage='[option] [blacklist] [--aliases|-a] [tags...]')
async def _get_favorite(self, ctx):
pass
@_get_favorite.command(name='tags', aliases=['t'])
async def __get_favorite_tags(self, ctx, *args):
await ctx.send('\N{WHITE MEDIUM STAR} {}**\'s favorite tags:**\n```\n{}```'.format(ctx.author.mention, ' '.join(self.favorites.get(ctx.author.id, {}).get('tags', set()))))
@_get_favorite.command(name='posts', aliases=['p'])
async def __get_favorite_posts(self, ctx):
pass
@favorite.group(name='add', aliases=['a'])
async def _add_favorite(self, ctx):
pass
@_add_favorite.command(name='tags', aliases=['t'])
async def __add_favorite_tags(self, ctx, *args):
try:
kwargs = u.get_kwargs(ctx, args)
tags = kwargs['remaining']
for tag in tags:
if tag in self.blacklists['user_blacklist'].get(ctx.author.id, set()):
raise exc.TagBlacklisted(tag)
with suppress(KeyError):
if len(self.favorites[ctx.author.id]['tags']) + len(tags) > 5:
raise exc.BoundsError
self.favorites.setdefault(ctx.author.id, {}).setdefault(
'tags', set()).update(tags)
u.dump(self.favorites, 'cogs/favorites.pkl')
await ctx.send('{} **added to their favorites:**\n```\n{}```'.format(ctx.author.mention, ' '.join(tags)))
except exc.BoundsError:
await ctx.send('**Favorites list currently limited to:** `5`')
await ctx.message.add_reaction('\N{CROSS MARK}')
except exc.TagBlacklisted as e:
await ctx.send('\N{NO ENTRY SIGN} `{}` **blacklisted**')
await ctx.message.add_reaction('\N{NO ENTRY SIGN}')
@_add_favorite.command(name='posts', aliases=['p'])
async def __add_favorite_posts(self, ctx, *posts):
pass
@favorite.group(name='remove', aliases=['r'])
async def _remove_favorite(self, ctx):
pass
@_remove_favorite.command(name='tags', aliases=['t'])
async def __remove_favorite_tags(self, ctx, *args):
try:
kwargs = u.get_kwargs(ctx, args)
tags = kwargs['remaining']
for tag in tags:
try:
self.favorites[ctx.author.id].get(
'tags', set()).remove(tag)
except KeyError:
raise exc.TagError(tag)
u.dump(self.favorites, 'cogs/favorites.pkl')
await ctx.send('{} **removed from their favorites:**\n```\n{}```'.format(ctx.author.mention, ' '.join(tags)))
except KeyError:
await ctx.send('**You do not have any favorites**')
await ctx.message.add_reaction('\N{CROSS MARK}')
except exc.TagError as e:
await ctx.send('`{}` **not in favorites**'.format(e))
await ctx.message.add_reaction('\N{CROSS MARK}')
@_remove_favorite.command(name='posts', aliases=['p'])
async def __remove_favorite_posts(self, ctx):
pass
@favorite.group(name='clear', aliases=['c'])
async def _clear_favorite(self, ctx):
pass
@_clear_favorite.command(name='tags', aliases=['t'])
async def __clear_favorite_tags(self, ctx, *args):
with suppress(KeyError):
del self.favorites[ctx.author.id]
u.dump(self.favorites, 'cogs/favorites.pkl')
await ctx.send('{}**\'s favorites cleared**'.format(ctx.author.mention))
@_clear_favorite.command(name='posts', aliases=['p'])
async def __clear_favorite_posts(self, ctx):
pass
# Umbrella command structure to manage global, channel, and user blacklists
@cmds.group(aliases=['bl', 'b'], brief='(G) Manage blacklists', description='Manage channel or personal blacklists\n\nUsage:\n{p}bl get {blacklist} to show a blacklist\n{p}bl clear {blacklist} to clear a blacklist\n{p}bl add {blacklist} {tags...} to add tag(s) to a blacklist\n{p}bl remove {blacklist} {tags...} to remove tags from a blacklist')
async def blacklist(self, ctx): async def blacklist(self, ctx):
if not ctx.invoked_subcommand: if not ctx.invoked_subcommand:
await ctx.send('**Use a flag to manage blacklists.**\n*Type* `{}help bl` *for more info.*'.format(ctx.prefix)) await ctx.send(
'**Use a flag to manage blacklists.**\n'
f'*Type* `{ctx.prefix}help bl` *for more info.*')
await ctx.message.add_reaction('\N{CROSS MARK}') await ctx.message.add_reaction('\N{CROSS MARK}')
# @blacklist.error @blacklist.group(
# async def blacklist_error(self, ctx, error): name='get',
# if isinstance(error, KeyError): aliases=['g'],
# return await ctx.send('**Blacklist does not exist**') brief='Get a blacklist',
description='Get global, channel, or personal blacklists',
@blacklist.group(name='get', aliases=['g'], brief='(G) Get a blacklist\n\nUsage:\n\{p\}bl get \{blacklist\}') usage='[blacklist]')
async def _get_blacklist(self, ctx): async def get_blacklist(self, ctx):
if not ctx.invoked_subcommand: if not ctx.invoked_subcommand:
await ctx.send('**Invalid blacklist**') await ctx.send('**Invalid blacklist**')
await ctx.message.add_reaction('\N{CROSS MARK}') await ctx.message.add_reaction('\N{CROSS MARK}')
@_get_blacklist.command(name='alias', aliases=['aliases']) @get_blacklist.command(
async def __get_blacklist_aliases(self, ctx, *args): name='global',
guild = ctx.guild if isinstance( aliases=['gl', 'g'],
ctx.guild, d.Guild) else ctx.channel brief='Get global blacklist',
description='Get global blacklist\n\n'
'In accordance with Discord\'s ToS: cub, related tags, and their aliases are blacklisted')
async def get_global_blacklist(self, ctx, *args):
args, lst = u.kwargs(args)
aliases = {} await formatter.paginate(
# Creates temp aliases based on context ctx,
for bl in (self.blacklists['global_blacklist'], self.blacklists['guild_blacklist'].get(guild.id, {}).get(ctx.channel.id, set()), self.blacklists['user_blacklist'].get(ctx.author.id, set())): self.blacklists['global'].get(lst, set()),
for tag in bl: start=f'\N{NO ENTRY SIGN} **Global {lst}:**\n')
aliases[tag] = list(self.aliases[tag])
# paginator.add_line(f'{tag}\n```{" ".join(alias_list)}```') @get_blacklist.command(
name='channel',
aliases=['chan', 'ch', 'c'],
brief='Get channel blacklist',
description='Get channel blacklist')
async def get_channel_blacklist(self, ctx, *args):
args, lst = u.kwargs(args)
await formatter.paginate(ctx, aliases, start='\N{NO ENTRY SIGN} **Contextual blacklist aliases:**\n') await formatter.paginate(
ctx,
self.blacklists['channel'].get(ctx.channel.id, {}).get(lst, set()),
start=f'\N{NO ENTRY SIGN} {ctx.channel.mention} **{lst}:**\n')
@_get_blacklist.command(name='global', aliases=['gl', 'g'], brief='Get current global blacklist', description='Get current global blacklist\n\nThis applies to all booru commands, in accordance with Discord\'s ToS agreement\n\nExample:\n\{p\}bl get global') @get_blacklist.command(
async def __get_global_blacklist(self, ctx, *args): name='me',
await ctx.send('\N{NO ENTRY SIGN} **Global blacklist:**\n```\n{}```'.format(' '.join(self.blacklists['global_blacklist']))) aliases=['m'],
brief='Get your personal blacklist',
description='Get your personal blacklist')
async def get_user_blacklist(self, ctx, *args):
args, lst = u.kwargs(args)
@_get_blacklist.command(name='channel', aliases=['ch', 'c'], brief='Get current channel blacklist', description='Get current channel blacklist\n\nThis is based on context - the channel where the command was executed\n\nExample:\{p\}bl get channel') await formatter.paginate(
async def __get_channel_blacklist(self, ctx, *args): ctx,
guild = ctx.guild if isinstance( self.blacklists['user'].get(ctx.author.id, {}).get(lst, set()),
ctx.guild, d.Guild) else ctx.channel start=f'\N{NO ENTRY SIGN} {ctx.author.mention}**\'s {lst}:**\n')
await ctx.send('\N{NO ENTRY SIGN} {} **blacklist:**\n```\n{}```'.format(ctx.channel.mention, ' '.join(self.blacklists['guild_blacklist'].get(guild.id, {}).get(ctx.channel.id, set())))) @blacklist.group(
name='add',
@_get_blacklist.command(name='me', aliases=['m'], brief='Get your personal blacklist', description='Get your personal blacklist\n\nYour blacklist is not viewable by anyone but you, except if you call this command in a public channel. The blacklist will be deleted soon after for your privacy\n\nExample:\n\{p\}bl get me') aliases=['a'],
async def __get_user_blacklist(self, ctx, *args): brief='Add tags to a blacklist',
await ctx.send('\N{NO ENTRY SIGN} {}**\'s blacklist:**\n```\n{}```'.format(ctx.author.mention, ' '.join(self.blacklists['user_blacklist'].get(ctx.author.id, set())))) description='Add tags to global, channel, or personal blacklists',
usage='[blacklist] [tags...]')
@_get_blacklist.command(name='here', aliases=['h'], brief='Get current global and channel blacklists', description='Get current global and channel blacklists in a single message\n\nExample:\{p\}bl get here') async def add_tags(self, ctx):
async def __get_here_blacklists(self, ctx, *args):
guild = ctx.guild if isinstance(
ctx.guild, d.Guild) else ctx.channel
await ctx.send('\N{NO ENTRY SIGN} **__Blacklisted:__**\n\n**Global:**\n```\n{}```\n**{}:**\n```\n{}```'.format(' '.join(self.blacklists['global_blacklist']), ctx.channel.mention, ' '.join(self.blacklists['guild_blacklist'].get(guild.id, {}).get(ctx.channel.id, set()))))
@blacklist.group(name='add', aliases=['a'], brief='(G) Add tag(s) to a blacklist\n\nUsage:\n\{p\}bl add \{blacklist\} \{tags...\}')
async def _add_tags(self, ctx):
if not ctx.invoked_subcommand: if not ctx.invoked_subcommand:
await ctx.send('**Invalid blacklist**') await ctx.send('**Invalid blacklist**')
await ctx.message.add_reaction('\N{CROSS MARK}') await ctx.message.add_reaction('\N{CROSS MARK}')
async def _aliases(self, ctx, tags, blacklist): async def _add(self, tags, lst, alias=False):
def on_reaction(reaction, user): if not alias:
if user is ctx.author and reaction.message.channel is ctx.message.channel: if tags:
if reaction.emoji == '\N{THUMBS DOWN SIGN}': lst.update(tags)
raise exc.Continue u.dump(self.blacklists, 'cogs/blacklists.pkl')
if reaction.emoji == '\N{HEAVY MINUS SIGN}':
raise exc.Remove
if reaction.emoji == '\N{THUMBS UP SIGN}':
return True
return False
def on_message(msg):
if msg.author is ctx.message.author and msg.channel is ctx.message.channel:
if msg.content == '0':
raise exc.Continue
return True
return False
if not tags:
raise exc.MissingArgument
aliases = {}
messages = []
try:
for tag in tags:
blacklist.add(tag)
aliases[tag] = set()
alias_request = await u.fetch('https://e621.net/tag_alias/index.json', params={'aliased_to': tag, 'approved': 'true'}, json=True)
if alias_request:
for dic in alias_request:
if dic['name']:
aliases[tag].add(dic['name'])
messages = await formatter.paginate(ctx, aliases)
message = await ctx.send(
'**Also add aliases?** React with the minus sign (\N{HEAVY MINUS SIGN}) to remove unwanted aliases')
await message.add_reaction('\N{THUMBS DOWN SIGN}')
await message.add_reaction('\N{HEAVY MINUS SIGN}')
await message.add_reaction('\N{THUMBS UP SIGN}')
try:
await self.bot.wait_for('reaction_add', check=on_reaction, timeout=8 * 60)
except exc.Remove:
await message.edit(content=f'Type the tag(s) to remove or `0` to continue:')
try:
while not self.bot.is_closed():
response = await self.bot.wait_for('message', check=on_message, timeout=8 * 60)
for tag in response.content.split(' '):
try:
for e in aliases.values():
e.remove(tag)
messages.append(await ctx.send(f'\N{WHITE HEAVY CHECK MARK} `{tag}` **removed**'))
except KeyError:
await ctx.send(f'\N{CROSS MARK} `{tag}` **not in aliases**', delete_after=8)
except exc.Continue:
pass
await message.edit(content=f'Confirm or deny changes')
await self.bot.wait_for('reaction_add', check=on_reaction, timeout=8 * 60)
self.aliases.update(aliases)
u.dump(self.aliases, 'cogs/aliases.pkl')
return blacklist
except exc.Continue:
return tags return tags
except asyncio.TimeoutError: else:
await ctx.send('\N{CROSS MARK} **Command timed out**') aliases = {}
raise exc.Abort
except exc.Abort:
raise exc.Abort
finally: if tags:
if messages: for tag in tags:
with suppress(err.NotFound): request = await u.fetch(
for msg in messages: 'https://e621.net/tag_alias/index.json',
await msg.delete() params={'aliased_to': tag, 'approved': 'true'},
await message.delete() json=True)
@_add_tags.command(name='global', aliases=['gl', 'g']) for elem in request:
if elem['name']:
aliases.setdefault(tag, set()).add(elem['name'])
if aliases:
lst.update(aliases)
u.dump(self.blacklists, 'cogs/blacklists.pkl')
return list(aliases.keys())
@add_tags.command(
name='global',
aliases=['gl', 'g'],
brief='Add tags to global blacklist',
description='Add tags to global blacklist',
usage='[tags...]')
@cmds.is_owner() @cmds.is_owner()
async def __add_global_tags(self, ctx, *args): async def add_global_tags(self, ctx, *args):
kwargs = u.get_kwargs(ctx, args) tags, lst = u.kwargs(args)
tags = kwargs['remaining']
try: async with ctx.channel.typing():
async with ctx.channel.typing(): added = await self._add(
tags = await self._aliases(ctx, tags, self.blacklists['global_blacklist']) tags,
self.blacklists['global'].setdefault(lst, set() if lst == 'blacklist' else {}),
alias=True if lst == 'aliases' else False)
u.dump(self.blacklists, 'cogs/blacklists.pkl') await formatter.paginate(
ctx,
added,
start=f'\N{WHITE HEAVY CHECK MARK} **Added to global {lst}:**\n')
await ctx.send('\N{WHITE HEAVY CHECK MARK} **Added to global blacklist:**\n```\n{}```'.format(' '.join(tags))) @add_tags.command(
name='channel',
except exc.Abort: aliases=['chan', 'ch', 'c'],
await ctx.send('**Aborted**') brief='Add tags to channel blacklist',
except exc.MissingArgument: description='Add tags to channel blacklist',
await ctx.send('\N{CROSS MARK} **Missing tags**') usage='[tags...]')
await ctx.message.add_reaction('\N{CROSS MARK}')
@_add_tags.command(name='channel', aliases=['ch', 'c'], brief='@manage_channel@ Add tag(s) to the current channel blacklist (requires manage_channel)', description='Add tag(s) to the current channel blacklist ')
@cmds.has_permissions(manage_channels=True) @cmds.has_permissions(manage_channels=True)
async def __add_channel_tags(self, ctx, *args): async def add_channel_tags(self, ctx, *args):
kwargs = u.get_kwargs(ctx, args) tags, lst = u.kwargs(args)
tags = kwargs['remaining']
guild = ctx.guild if isinstance( async with ctx.channel.typing():
ctx.guild, d.Guild) else ctx.channel added = await self._add(
tags,
self.blacklists['channel'].setdefault(ctx.channel.id, {}).setdefault(lst, set() if lst == 'blacklist' else {}),
alias=True if lst == 'aliases' else False)
try: await formatter.paginate(
async with ctx.channel.typing(): ctx,
tags = await self._aliases(ctx, tags, self.blacklists['guild_blacklist'].setdefault(guild.id, {}).setdefault(ctx.channel.id, set())) added,
start=f'\N{WHITE HEAVY CHECK MARK} **Added to {ctx.channel.mention} {lst}:**\n')
u.dump(self.blacklists, 'cogs/blacklists.pkl') @add_tags.command(
name='me',
aliases=['m'],
brief='Add tags to personal blacklist',
description='Add tags to personal blacklist',
usage='[tags...]')
async def add_user_tags(self, ctx, *args):
tags, lst = u.kwargs(args)
await ctx.send('\N{WHITE HEAVY CHECK MARK} **Added to** {} **blacklist:**\n```\n{}```'.format(ctx.channel.mention, ' '.join(tags))) async with ctx.channel.typing():
added = await self._add(
tags,
self.blacklists['user'].setdefault(ctx.author.id, {}).setdefault(lst, set() if lst == 'blacklist' else {}),
alias=True if lst == 'aliases' else False)
except exc.Abort: await formatter.paginate(
await ctx.send('**Aborted**') ctx,
except exc.MissingArgument: added,
await ctx.send('\N{CROSS MARK} **Missing tags**') start=f'\N{WHITE HEAVY CHECK MARK} **Added to {ctx.author.mention}\'s {lst}:**\n')
await ctx.message.add_reaction('\N{CROSS MARK}')
@_add_tags.command(name='me', aliases=['m']) @blacklist.group(
async def __add_user_tags(self, ctx, *args): name='remove',
kwargs = u.get_kwargs(ctx, args) aliases=['rm', 'r'],
tags = kwargs['remaining'] brief='Remove tags from a blacklist',
description='Remove tags from global, channel, or personal blacklists',
try: usage='[blacklist] [tags...]')
async with ctx.channel.typing(): async def remove_tags(self, ctx):
tags = await self._aliases(ctx, tags, self.blacklists['user_blacklist'].setdefault(ctx.author.id, set()))
u.dump(self.blacklists, 'cogs/blacklists.pkl')
await ctx.send('\N{WHITE HEAVY CHECK MARK} {} **added to their blacklist:**\n```\n{}```'.format(ctx.author.mention, ' '.join(tags)))
except exc.Abort:
await ctx.send('**Aborted**')
except exc.MissingArgument:
await ctx.send('\N{CROSS MARK} **Missing tags**')
await ctx.message.add_reaction('\N{CROSS MARK}')
@blacklist.group(name='remove', aliases=['rm', 'r'])
async def _remove_tags(self, ctx):
if not ctx.invoked_subcommand: if not ctx.invoked_subcommand:
await ctx.send('**Invalid blacklist**') await ctx.send('**Invalid blacklist**')
await ctx.message.add_reaction('\N{CROSS MARK}') await ctx.message.add_reaction('\N{CROSS MARK}')
@_remove_tags.command(name='global', aliases=['gl', 'g']) def _remove(self, tags, lst):
removed = []
skipped = []
if tags:
if type(lst) is set:
temp = set()
for tag in tags:
if tag not in tags:
temp.add(tag)
else:
removed.append(tag)
else:
temp = {}
for k, v in lst.items():
temp[k] = set()
for tag in v:
if tag not in tags:
temp[k].add(tag)
else:
removed.append(tag)
lst.update(temp)
u.dump(self.blacklists, 'cogs/blacklists.pkl')
return removed, skipped
@remove_tags.command(
name='global',
aliases=['gl', 'g'],
brief='Remove tags from global blacklist',
description='Remove tags from global blacklist',
usage='[tags...]')
@cmds.is_owner() @cmds.is_owner()
async def __remove_global_tags(self, ctx, *args): async def remove_global_tags(self, ctx, *args):
try: tags, lst = u.kwargs(args)
kwargs = u.get_kwargs(ctx, args)
tags = kwargs['remaining']
for tag in tags: async with ctx.channel.typing():
try: removed, skipped = self._remove(
self.blacklists['global_blacklist'].remove(tag) tags,
self.blacklists['global'].get(lst, set()))
except KeyError: await formatter.paginate(
raise exc.TagError(tag) ctx,
removed,
start=f'\N{WHITE HEAVY CHECK MARK} **Removed from global {lst}:**\n')
if skipped:
await formatter.paginate(
ctx,
skipped,
start=f'\N{CROSS MARK} **Not in global {lst}:**\n')
u.dump(self.blacklists, 'cogs/blacklists.pkl') @remove_tags.command(
name='channel',
await ctx.send('**Removed from global blacklist:**\n```\n{}```'.format(' '.join(tags))) aliases=['ch', 'c'],
brief='Remove tags from channel blacklist',
except exc.TagError as e: description='Remove tags from channel blacklist',
await ctx.send('`{}` **not in blacklist**'.format(e)) usage='[tags...]')
await ctx.message.add_reaction('\N{CROSS MARK}')
@_remove_tags.command(name='channel', aliases=['ch', 'c'])
@cmds.has_permissions(manage_channels=True) @cmds.has_permissions(manage_channels=True)
async def __remove_channel_tags(self, ctx, *args): async def remove_channel_tags(self, ctx, *args):
try: tags, lst = u.kwargs(args)
kwargs = u.get_kwargs(ctx, args)
tags = kwargs['remaining']
guild = ctx.guild if isinstance( async with ctx.channel.typing():
ctx.guild, d.Guild) else ctx.channel removed, skipped = self._remove(
tags,
self.blacklists['channel'].get(ctx.channel.id, {}).get(lst, set()))
for tag in tags: await formatter.paginate(
try: ctx,
self.blacklists['guild_blacklist'][guild.id][ctx.channel.id].remove( removed,
tag) start=f'\N{WHITE HEAVY CHECK MARK} **Removed from {ctx.channel.mention} {lst}:**\n')
if skipped:
await formatter.paginate(
ctx,
skipped,
start=f'\N{CROSS MARK} **Not in {ctx.channel.mention} {lst}:**\n')
except KeyError: @remove_tags.command(
raise exc.TagError(tag) name='me',
aliases=['m'],
brief='Remove tags from personal blacklist',
description='Remove tags from personal blacklist',
usage='[tags...]')
async def remove_user_tags(self, ctx, *args):
tags, lst = u.kwargs(args)
u.dump(self.blacklists, 'cogs/blacklists.pkl') async with ctx.channel.typing():
removed, skipped = self._remove(
tags,
self.blacklists['user'].get(ctx.author.id, {}).get(lst, set()))
await ctx.send('**Removed from** {} **blacklist:**\n```\n{}```'.format(ctx.channel.mention, ' '.join(tags))) await formatter.paginate(
ctx,
removed,
start=f'\N{WHITE HEAVY CHECK MARK} **Removed from {ctx.author.mention}\'s {lst}:**\n')
if skipped:
await formatter.paginate(
ctx,
skipped,
start=f'\N{CROSS MARK} **Not in {ctx.author.mention}\'s {lst}:**\n')
except exc.TagError as e: @blacklist.group(
await ctx.send('`{}` **not in blacklist**'.format(e)) name='clear',
await ctx.message.add_reaction('\N{CROSS MARK}') aliases=['cl', 'c'],
brief='Delete a blacklist',
@_remove_tags.command(name='me', aliases=['m']) description='Delete global, channel, or personal blacklists',
async def __remove_user_tags(self, ctx, *args): usage='[blacklist]')
try: async def clear_blacklist(self, ctx):
kwargs = u.get_kwargs(ctx, args)
tags = kwargs['remaining']
for tag in tags:
try:
self.blacklists['user_blacklist'][ctx.author.id].remove(
tag)
except KeyError:
raise exc.TagError(tag)
u.dump(self.blacklists, 'cogs/blacklists.pkl')
await ctx.send('{} **removed from their blacklist:**\n```\n{}```'.format(ctx.author.mention, ' '.join(tags)))
except exc.TagError as e:
await ctx.send('`{}` **not in blacklist**'.format(e))
await ctx.message.add_reaction('\N{CROSS MARK}')
@blacklist.group(name='clear', aliases=['cl', 'c'])
async def _clear_blacklist(self, ctx):
if not ctx.invoked_subcommand: if not ctx.invoked_subcommand:
await ctx.send('**Invalid blacklist**') await ctx.send('**Invalid blacklist**')
await ctx.message.add_reaction('\N{CROSS MARK}') await ctx.message.add_reaction('\N{CROSS MARK}')
@_clear_blacklist.command(name='global', aliases=['gl', 'g']) @clear_blacklist.command(
name='global',
aliases=['gl', 'g'],
brief='Delete global blacklist',
description='Delete global blacklist')
@cmds.is_owner() @cmds.is_owner()
async def __clear_global_blacklist(self, ctx, *args): async def clear_global_blacklist(self, ctx, *args):
self.blacklists['global_blacklist'].clear() args, lst = u.kwargs(args)
u.dump(self.blacklists, 'cogs/blacklists.pkl')
await ctx.send('**Global blacklist cleared**') async with ctx.channel.typing():
with suppress(KeyError):
del self.blacklists['global'][lst]
@_clear_blacklist.command(name='channel', aliases=['ch', 'c']) u.dump(self.blacklists, 'cogs/blacklists.pkl')
await ctx.send(f'\N{WHITE HEAVY CHECK MARK} **Global {lst} cleared**')
@clear_blacklist.command(
name='channel',
aliases=['ch', 'c'],
brief='Delete channel blacklist',
description='Delete channel blacklist')
@cmds.has_permissions(manage_channels=True) @cmds.has_permissions(manage_channels=True)
async def __clear_channel_blacklist(self, ctx, *args): async def clear_channel_blacklist(self, ctx, *args):
guild = ctx.guild if isinstance( args, lst = u.kwargs(args)
ctx.guild, d.Guild) else ctx.channel
async with ctx.channel.typing():
with suppress(KeyError):
del self.blacklists['channel'][ctx.channel.id][lst]
with suppress(KeyError):
del self.blacklists['guild_blacklist'][guild.id][ctx.channel.id]
u.dump(self.blacklists, 'cogs/blacklists.pkl') u.dump(self.blacklists, 'cogs/blacklists.pkl')
await ctx.send('{} **blacklist cleared**'.format(ctx.channel.mention)) await ctx.send(f'\N{WHITE HEAVY CHECK MARK} **{ctx.channel.mention} {lst} cleared**')
@clear_blacklist.command(
name='me',
aliases=['m'],
brief='Delete your personal blacklist',
description='Delete your personal blacklist')
async def clear_user_blacklist(self, ctx, *args):
args, lst = u.kwargs(args)
async with ctx.channel.typing():
with suppress(KeyError):
del self.blacklists['user'][ctx.author.id][lst]
@_clear_blacklist.command(name='me', aliases=['m'])
async def __clear_user_blacklist(self, ctx, *args):
with suppress(KeyError):
del self.blacklists['user_blacklist'][ctx.author.id]
u.dump(self.blacklists, 'cogs/blacklists.pkl') u.dump(self.blacklists, 'cogs/blacklists.pkl')
await ctx.send('{}**\'s blacklist cleared**'.format(ctx.author.mention)) await ctx.send(f'\N{WHITE HEAVY CHECK MARK} **{ctx.author.mention}\'s {lst} cleared**')

View file

@ -8,7 +8,6 @@ import traceback as tb
from contextlib import redirect_stdout, suppress from contextlib import redirect_stdout, suppress
import discord as d import discord as d
import pyrasite as pyr
from discord.ext import commands as cmds from discord.ext import commands as cmds
from misc import exceptions as exc from misc import exceptions as exc

View file

@ -180,7 +180,7 @@ async def on_command_error(ctx, error):
error), file=sys.stderr) error), file=sys.stderr)
tb.print_exception(type(error), error, error.__traceback__, file=sys.stderr) tb.print_exception(type(error), error, error.__traceback__, file=sys.stderr)
await bot.get_user(u.config['owner_id']).send('**COMMAND ERROR** \N{WARNING SIGN} `{}` from {} in {}\n```\n{}```'.format(ctx.message.content, ctx.author.mention, ctx.channel.mention if isinstance(ctx.channel, d.channel.TextChannel) else 'DMs', error)) await bot.get_user(u.config['owner_id']).send('**COMMAND ERROR** \N{WARNING SIGN} `{}` from {} in {}\n```\n{}```'.format(ctx.message.content, ctx.author.mention, ctx.channel.mention if isinstance(ctx.channel, d.channel.TextChannel) else 'DMs', error))
await bot.get_channel(u.config['info_channel']).send('**COMMAND ERROR** \N{WARNING SIGN} `{}` from {} in {}\n```\n{}```'.format(ctx.message.content, ctx.author.mention, ctx.channel.mention if isinstance(ctx.channel, d.channel.TextChannel) else 'DMs', error)) await bot.get_channel(u.config['info_channel']).send('**COMMAND ERROR** \N{WARNING SIGN} `{}` from {} in {}\n```\n{}```'.format(ctx.message.content, ctx.author.name, ctx.channel.mention if isinstance(ctx.channel, d.channel.TextChannel) else 'DMs', error))
await exc.send_error(ctx, error) await exc.send_error(ctx, error)
await ctx.message.add_reaction('\N{WARNING SIGN}') await ctx.message.add_reaction('\N{WARNING SIGN}')
# u.notify('C O M M A N D E R R O R') # u.notify('C O M M A N D E R R O R')

View file

@ -42,12 +42,11 @@ async def paginate(
paginator.add_line(start) paginator.add_line(start)
if type(i) in (tuple, list, set): if type(i) in (tuple, list, set):
for e in sorted(i): paginator.add_line(eprefix + f'{ejoin}'.join(i) + esuffix)
if e and (e not in i) and (len(i) > 1):
paginator.add_line(eprefix + f'{ejoin}'.join(e) + esuffix)
elif type(i) is dict: elif type(i) is dict:
for k, e in sorted(i.items()): for k, e in sorted(i.items()):
if e and (k not in e) and (len(e) > 1): if e and (k not in e) and (len(e) >= 1):
paginator.add_line(kprefix + k + ksuffix + eprefix + f'{ejoin}'.join(e) + esuffix) paginator.add_line(kprefix + k + ksuffix + eprefix + f'{ejoin}'.join(e) + esuffix)
if end: if end:

View file

@ -131,6 +131,17 @@ def generate_embed(ctx, *, title=d.Embed.Empty, kind='rich', description=d.Embed
return embed return embed
def kwargs(args):
params = list(args)
lst = 'blacklist'
for switch in ('-a', '--aliases'):
if switch in params:
lst = 'aliases'
params.remove(switch)
return params, lst
def get_kwargs(ctx, args, *, limit=False): def get_kwargs(ctx, args, *, limit=False):
remaining = list(args[:]) remaining = list(args[:])
rm = False rm = False