aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--discord_ban_list/__init__.py2
-rw-r--r--discord_ban_list/api.py25
-rw-r--r--discord_ban_list/exceptions.py14
-rw-r--r--discord_ban_list/result.py12
-rw-r--r--tests/test_login.py72
5 files changed, 111 insertions, 14 deletions
diff --git a/discord_ban_list/__init__.py b/discord_ban_list/__init__.py
index a0fbd5c..98af9c6 100644
--- a/discord_ban_list/__init__.py
+++ b/discord_ban_list/__init__.py
@@ -3,6 +3,7 @@ Module for looking up entries/users on the bans.discord.id
"""
from .api import DiscordBanList
+from .exceptions import TooManyUsers
from .result import BanABC, NoBan, Ban
from .version import VersionInfo, VERSION
@@ -10,4 +11,5 @@ __all__ = (
'VersionInfo', 'VERSION',
'DiscordBanList',
'BanABC', 'Ban', 'NoBan',
+ 'TooManyUsers',
)
diff --git a/discord_ban_list/api.py b/discord_ban_list/api.py
index 35e8c8a..25b46a2 100644
--- a/discord_ban_list/api.py
+++ b/discord_ban_list/api.py
@@ -3,11 +3,12 @@ Central API module. Most action taskes place here
"""
from asyncio import Lock
-from typing import Union
+from typing import Union, List
from aiohttp import ClientSession
-from .result import Ban, NoBan, BanABC
+from .exceptions import TooManyUsers
+from .result import BanABC
CHECK_URL = 'https://bans.discord.id/api/check.php'
@@ -36,17 +37,21 @@ class DiscordBanList(object):
"""
await self._guarantee_client()
- async def check(self, user_id: Union[int, str]) -> BanABC:
+ async def check(self, *user_ids: Union[int, str]) -> List[BanABC]:
"""
- Check if a user is banned on DBans
+ Check if some users are banned on DBans
- :param user_id: id of the user to be checked
- :return: a :class:`BanABC`
+ :param user_ids: ids of the users to be checked
+ :return: a list of :class:`BanABC`
"""
- resp = await self._get('{base}?user_id={user_id}'.format(base=CHECK_URL, user_id=user_id))
- if resp['banned'] == "0":
- return NoBan(user_id)
- return Ban(user_id, resp['reason'], resp['case_id'], resp['proof'])
+ user_ids = list(set(user_ids))
+ if len(user_ids) < 1:
+ return []
+ if len(user_ids) > 99:
+ raise TooManyUsers(len(user_ids))
+ resp = await self._get(CHECK_URL + '?' + '&'.join('user_id=' +
+ str(user_id) for user_id in user_ids))
+ return [BanABC.parse(ban) for ban in resp]
async def _get(self, url):
async with self._client.get(url,
diff --git a/discord_ban_list/exceptions.py b/discord_ban_list/exceptions.py
new file mode 100644
index 0000000..c47e163
--- /dev/null
+++ b/discord_ban_list/exceptions.py
@@ -0,0 +1,14 @@
+"""
+Module containing exceptions for the discord_ban_list module
+"""
+
+
+class TooManyUsers(Exception):
+ """
+ Risen if more users than possible are requested.
+
+ """
+
+ def __init__(self, count):
+ super(TooManyUsers, self).__init__(
+ "You may at most request 99 users at once. 99 < %s" % count)
diff --git a/discord_ban_list/result.py b/discord_ban_list/result.py
index 9d1a685..3d734c5 100644
--- a/discord_ban_list/result.py
+++ b/discord_ban_list/result.py
@@ -11,6 +11,18 @@ class BanABC(ABC):
"""
__slots__ = ()
+ @staticmethod
+ def parse(obj: dict) -> 'BanABC':
+ """
+ Parse a response from DBans into an apropiate :class:`BanABC` subclass object.
+
+ :param obj: json response to be parsed
+ :return: the parsed ban
+ """
+ if obj['banned'] == "0":
+ return NoBan(obj['user_id'])
+ return Ban(obj['user_id'], obj['reason'], obj['case_id'], obj['proof'])
+
@abstractproperty
def user_id(self) -> int:
"""
diff --git a/tests/test_login.py b/tests/test_login.py
index 79b1747..3c211dc 100644
--- a/tests/test_login.py
+++ b/tests/test_login.py
@@ -2,13 +2,13 @@ import os
from asyncio import get_event_loop
from unittest import TestCase
-from discord_ban_list import DiscordBanList
+from discord_ban_list import DiscordBanList, TooManyUsers
async def a_test_valid_login():
ban_list = DiscordBanList(os.environ['token'])
await ban_list.login()
- ban = await ban_list.check(123)
+ ban = (await ban_list.check(123))[0]
assert not ban.banned
@@ -16,7 +16,7 @@ async def a_test_banned():
user = 123456789123456789
ban_list = DiscordBanList(os.environ['token'])
await ban_list.login()
- ban = await ban_list.check(user)
+ ban = (await ban_list.check(user))[0]
assert ban.banned
assert ban.user_id == user
assert ban.case_id == 9999
@@ -24,9 +24,73 @@ async def a_test_banned():
assert ban.proof
+async def a_test_multiple_bans():
+ ban_list = DiscordBanList(os.environ['token'])
+ await ban_list.login()
+ bans = await ban_list.check(
+ 0,
+ 1,
+ 2,
+ 123456789123456789,
+ )
+ for ban in bans:
+ if ban.user_id == 123456789123456789:
+ assert ban.banned
+ assert ban.case_id == 9999
+ assert ban.proof
+ assert ban.reason
+ else:
+ assert not ban.banned
+ assert len(bans) == 4
+
+
+async def a_test_no_ids_provided():
+ ban_list = DiscordBanList(os.environ['token'])
+ await ban_list.login()
+ bans = await ban_list.check()
+ assert bans == []
+
+
+async def a_test_id_de_duplication():
+ ban_list = DiscordBanList(os.environ['token'])
+ await ban_list.login()
+ bans = await ban_list.check(*([123456789123456789] * 100 + [0] * 100))
+ for ban in bans:
+ if ban.user_id == 123456789123456789:
+ assert ban.banned
+ assert ban.case_id == 9999
+ assert ban.proof
+ assert ban.reason
+ else:
+ assert not ban.banned
+ assert len(bans) == 2
+
+
+async def a_test_too_many_ids_provided():
+ ban_list = DiscordBanList(os.environ['token'])
+ await ban_list.login()
+ try:
+ await ban_list.check(*list(range(1000)))
+ except TooManyUsers:
+ return
+ assert False
+
+
class TestSomething(TestCase):
- def test_not_banned(self):
+ def test_valid_login(self):
get_event_loop().run_until_complete(a_test_valid_login())
def test_banned(self):
get_event_loop().run_until_complete(a_test_banned())
+
+ def test_multiple_bans(self):
+ get_event_loop().run_until_complete(a_test_multiple_bans())
+
+ def test_no_ids_provided(self):
+ get_event_loop().run_until_complete(a_test_no_ids_provided())
+
+ def test_id_de_duplication(self):
+ get_event_loop().run_until_complete(a_test_id_de_duplication())
+
+ def test_too_many_ids_provided(self):
+ get_event_loop().run_until_complete(a_test_too_many_ids_provided())