jokeapi
This commit is contained in:
parent
c835dd3592
commit
72ed7aa4ff
Binary file not shown.
|
@ -0,0 +1,292 @@
|
||||||
|
import urllib3
|
||||||
|
import urllib
|
||||||
|
import urllib.request
|
||||||
|
import simplejson as json
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class CategoryError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BlacklistError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ResponseTypeError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class JokeTypeError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Jokes:
|
||||||
|
def __init__(self):
|
||||||
|
self.http = urllib3.PoolManager()
|
||||||
|
self.info = self.http.request("GET", "https://sv443.net/jokeapi/v2/info")
|
||||||
|
self.info = json.loads(self.info.data.decode("utf-8"))["jokes"]
|
||||||
|
|
||||||
|
def build_request(
|
||||||
|
self,
|
||||||
|
category=[],
|
||||||
|
blacklist=[],
|
||||||
|
response_format="json",
|
||||||
|
joke_type="Any",
|
||||||
|
search_string="",
|
||||||
|
id_range=[],
|
||||||
|
amount=1,
|
||||||
|
safe_mode=False,
|
||||||
|
lang="en",
|
||||||
|
):
|
||||||
|
r = "https://sv443.net/jokeapi/v2/joke/"
|
||||||
|
|
||||||
|
if len(category):
|
||||||
|
for c in category:
|
||||||
|
if not c.title() in self.info["categories"]:
|
||||||
|
raise CategoryError(
|
||||||
|
f'''Invalid category selected.
|
||||||
|
You selected {c}.
|
||||||
|
Available categories are:
|
||||||
|
{"""
|
||||||
|
""".join(self.info["categories"])}
|
||||||
|
Leave blank for any.'''
|
||||||
|
)
|
||||||
|
|
||||||
|
cats = ",".join(category)
|
||||||
|
else:
|
||||||
|
cats = "Any"
|
||||||
|
|
||||||
|
if type(blacklist) in [list, tuple]:
|
||||||
|
if len(blacklist) > 0:
|
||||||
|
for b in blacklist:
|
||||||
|
if b not in self.info["flags"]:
|
||||||
|
raise BlacklistError(
|
||||||
|
f'''
|
||||||
|
You have blacklisted flags which are not available.
|
||||||
|
Available flags are:
|
||||||
|
{"""
|
||||||
|
""".join(self.info["flags"])}
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
return
|
||||||
|
blacklistFlags = ",".join(blacklist)
|
||||||
|
else:
|
||||||
|
blacklistFlags = None
|
||||||
|
else:
|
||||||
|
raise BlacklistError(f"""blacklist must be a list or tuple.""")
|
||||||
|
|
||||||
|
if response_format not in ["json", "xml", "yaml", "txt"]:
|
||||||
|
raise ResponseTypeError(
|
||||||
|
"Response format must be either json, xml, txt or yaml."
|
||||||
|
)
|
||||||
|
if joke_type:
|
||||||
|
if joke_type not in ["single", "twopart", "Any"]:
|
||||||
|
raise JokeTypeError(
|
||||||
|
"""Invalid joke type.
|
||||||
|
Available options are "single" or "twopart"."""
|
||||||
|
)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
joke_type = "Any"
|
||||||
|
|
||||||
|
if search_string:
|
||||||
|
if not isinstance(search_string, str):
|
||||||
|
raise ValueError("search_string must be a string.")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
search_string = urllib.parse.quote(search_string)
|
||||||
|
range_limit = self.info["totalCount"]
|
||||||
|
|
||||||
|
if len(id_range) and (id_range[1] - id_range[0] > range_limit):
|
||||||
|
raise ValueError(
|
||||||
|
"id_range must be no longer than 2 items, \
|
||||||
|
id_range[0] must be greater than or equal to 0 and \
|
||||||
|
id_range[1] must be less than or equal to {range_limit-1}."
|
||||||
|
)
|
||||||
|
|
||||||
|
if amount > 10:
|
||||||
|
raise ValueError(
|
||||||
|
f"amount parameter must be no greater than 10. \
|
||||||
|
you passed {amount}."
|
||||||
|
)
|
||||||
|
|
||||||
|
r += cats
|
||||||
|
|
||||||
|
r += f"?format={response_format}"
|
||||||
|
|
||||||
|
if blacklistFlags:
|
||||||
|
r += f"&blacklistFlags={blacklistFlags}"
|
||||||
|
|
||||||
|
r += f"&type={joke_type}"
|
||||||
|
|
||||||
|
if search_string:
|
||||||
|
r += f"&contains={search_string}"
|
||||||
|
if id_range:
|
||||||
|
r += f"i&dRange={id_range[0]}-{id_range[1]}"
|
||||||
|
if amount > 10:
|
||||||
|
raise ValueError(
|
||||||
|
f"amount parameter must be no greater than 10. you passed {amount}."
|
||||||
|
)
|
||||||
|
r += f"&amount={amount}"
|
||||||
|
|
||||||
|
r += f"&lang={lang}"
|
||||||
|
|
||||||
|
r += f"{'&safe-mode'*safe_mode}"
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
def send_request(
|
||||||
|
self, request, response_format, return_headers, auth_token, user_agent
|
||||||
|
):
|
||||||
|
returns = []
|
||||||
|
|
||||||
|
if auth_token:
|
||||||
|
r = self.http.request(
|
||||||
|
"GET",
|
||||||
|
request,
|
||||||
|
headers={
|
||||||
|
"Authorization": str(auth_token),
|
||||||
|
"user-agent": str(user_agent),
|
||||||
|
"accept-encoding": "gzip",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
r = self.http.request(
|
||||||
|
"GET",
|
||||||
|
request,
|
||||||
|
headers={"user-agent": str(user_agent), "accept-encoding": "gzip"},
|
||||||
|
)
|
||||||
|
|
||||||
|
data = r.data.decode("utf-8")
|
||||||
|
|
||||||
|
if response_format == "json":
|
||||||
|
try:
|
||||||
|
data = json.loads(data)
|
||||||
|
except:
|
||||||
|
print(data)
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
if (
|
||||||
|
len(
|
||||||
|
" ".join(re.split("error", data.lower())[0:][1:])
|
||||||
|
.replace("<", "")
|
||||||
|
.replace("/", "")
|
||||||
|
.replace(" ", "")
|
||||||
|
.replace(":", "")
|
||||||
|
.replace(">", "")
|
||||||
|
)
|
||||||
|
== 4
|
||||||
|
):
|
||||||
|
raise Exception(
|
||||||
|
f"API returned an error. \
|
||||||
|
Full response: \n\n {data}"
|
||||||
|
)
|
||||||
|
|
||||||
|
headers = (
|
||||||
|
str(r.headers)
|
||||||
|
.replace(r"\n", "")
|
||||||
|
.replace("\n", "")
|
||||||
|
.replace(r"\\", "")
|
||||||
|
.replace(r"\'", "")[15:-1]
|
||||||
|
)
|
||||||
|
|
||||||
|
returns.append(data)
|
||||||
|
if return_headers:
|
||||||
|
returns.append(headers)
|
||||||
|
|
||||||
|
if auth_token:
|
||||||
|
returns.append(
|
||||||
|
{"Token-Valid": bool(int(re.split(r"Token-Valid", headers)[1][4]))}
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(returns) > 1:
|
||||||
|
return returns
|
||||||
|
return returns[0]
|
||||||
|
|
||||||
|
def get_joke(
|
||||||
|
self,
|
||||||
|
category=[],
|
||||||
|
blacklist=[],
|
||||||
|
response_format="json",
|
||||||
|
joke_type="Any",
|
||||||
|
search_string="",
|
||||||
|
id_range=[],
|
||||||
|
amount=1,
|
||||||
|
safe_mode=False,
|
||||||
|
lang="en",
|
||||||
|
auth_token=None,
|
||||||
|
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) \
|
||||||
|
Gecko/20100101 Firefox/77.0",
|
||||||
|
return_headers=False,
|
||||||
|
):
|
||||||
|
r = self.build_request(
|
||||||
|
category,
|
||||||
|
blacklist,
|
||||||
|
response_format,
|
||||||
|
joke_type,
|
||||||
|
search_string,
|
||||||
|
id_range,
|
||||||
|
amount,
|
||||||
|
safe_mode,
|
||||||
|
lang,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self.send_request(
|
||||||
|
r, response_format, return_headers, auth_token, user_agent
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
|
||||||
|
def submit_joke(self, category, joke, flags, lang="en", dry_run=False):
|
||||||
|
request = {"formatVersion": 3}
|
||||||
|
|
||||||
|
if category not in self.info["categories"]:
|
||||||
|
raise CategoryError(
|
||||||
|
f'''Invalid category selected.
|
||||||
|
You selected {category}.
|
||||||
|
Available categories are:
|
||||||
|
{"""
|
||||||
|
""".join(self.info["categories"])}'''
|
||||||
|
)
|
||||||
|
request["category"] = category
|
||||||
|
|
||||||
|
if type(joke) in [list, tuple]:
|
||||||
|
if len(joke) > 1:
|
||||||
|
request["type"] = "twopart"
|
||||||
|
request["setup"] = joke[0]
|
||||||
|
request["delivery"] = joke[1]
|
||||||
|
else:
|
||||||
|
request["type"] = "single"
|
||||||
|
request["joke"] = joke[0]
|
||||||
|
else:
|
||||||
|
request["type"] = "single"
|
||||||
|
request["joke"] = joke
|
||||||
|
|
||||||
|
for key in flags.keys():
|
||||||
|
if key not in self.info["flags"]:
|
||||||
|
raise BlacklistError(
|
||||||
|
f'''
|
||||||
|
You have blacklisted flags which are not available.
|
||||||
|
Available flags are:
|
||||||
|
{"""
|
||||||
|
""".join(self.info["flags"])}
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
request["flags"] = flags
|
||||||
|
request["lang"] = lang
|
||||||
|
|
||||||
|
data = str(request).replace("'", '"')
|
||||||
|
data = data.replace(": True", ": true").replace(": False", ": false")
|
||||||
|
data = data.encode("ascii")
|
||||||
|
url = f"https://sv443.net/jokeapi/v2/submit{'?dry-run'*dry_run}"
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = urllib.request.urlopen(url, data=data)
|
||||||
|
data = response.getcode()
|
||||||
|
|
||||||
|
return data
|
||||||
|
except urllib.error.HTTPError as e:
|
||||||
|
body = e.read().decode() # Read the body of the error response
|
||||||
|
|
||||||
|
_json = json.loads(body)
|
||||||
|
return _json
|
|
@ -0,0 +1,10 @@
|
||||||
|
from jokeapi import Jokes # Import the Jokes class
|
||||||
|
|
||||||
|
j = Jokes() # Initialise the class
|
||||||
|
joke = j.get_joke(category=['programming', 'dark']) # Retrieve a random joke
|
||||||
|
if joke["type"] == "single": # Print the joke
|
||||||
|
print(joke["joke"])
|
||||||
|
else:
|
||||||
|
print(joke["setup"])
|
||||||
|
print(joke["delivery"])
|
||||||
|
|
Loading…
Reference in New Issue