|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- import abc
- import hashlib
- import json
- import shutil
- import time
- import urllib.parse
- import urllib.request
- import textwrap
- import sys
-
-
- class Authorization:
- def __init__(self, filename):
- with open(filename, "r") as file:
- lines = file.readlines()
-
- if len(lines) != 2:
- sys.exit("Incorrect api-keys file")
-
- self.public_key = lines[0].strip()
- self.private_key = lines[1].strip()
-
- def generate_params(self):
- params = dict()
- params["apikey"] = self.public_key
- ts = str(time.time())
- to_hash = ts + self.private_key + self.public_key
- hasher = hashlib.md5()
- hasher.update(to_hash.encode())
- digest = hasher.hexdigest()
- params["ts"] = ts
- params["hash"] = digest
- return params
-
-
- class Client:
- base_url = "http://gateway.marvel.com/v1/public"
-
- def __init__(self, auth):
- self.auth = auth
-
- def make_request(self, query):
- params = self.auth.generate_params()
- params.update(query.params())
- query_string = urllib.parse.urlencode(params)
- full_url = Client.base_url + query.path() + "?" + query_string
- with urllib.request.urlopen(full_url) as response:
- status_code = response.getcode()
- if status_code != 200:
- sys.exit("got status: " + str(status_code))
- body = json.loads(response.read())
- attribution = body["attributionText"]
- response = query.extract(body)
- return (response, attribution)
-
-
- class Display:
- def __init__(self, width=80):
- self.width = width
-
- def display(self, text):
- print("\n".join(textwrap.wrap(text, width=self.width)))
-
-
- class Query(metaclass=abc.ABCMeta):
- @abc.abstractmethod
- def params(self):
- pass
-
- @abc.abstractmethod
- def path(self):
- pass
-
- @abc.abstractmethod
- def extract(self, body):
- pass
-
- @abc.abstractmethod
- def text(self, response):
- pass
-
-
- class CharacterDescription(Query):
- def __init__(self, name):
- self.name = name
-
- def params(self):
- return {"name": self.name}
-
- def path(self):
- return "/characters"
-
- def extract(self, body):
- first_result = body["data"]["results"][0]
- description = first_result["description"]
- return description
-
- def text(self, response):
- return response
-
-
- class CreatorNumberOfSeries(Query):
- def __init__(self, first_name, last_name):
- self.first_name = first_name
- self.last_name = last_name
-
- def params(self):
- return {"firstName": self.first_name, "lastName": self.last_name}
-
- def path(self):
- return "/creators"
-
- def extract(self, body):
- first_result = body["data"]["results"][0]
- return first_result["series"]["available"]
-
- def text(self, response):
- return "{} {} worked on {} series".format(
- self.first_name, self.last_name, response
- )
-
-
- def main():
- auth = Authorization("api-keys.txt")
-
- query_type = sys.argv[1]
- if query_type == "character-description":
- name = sys.argv[2]
- query = CharacterDescription(name)
-
- elif query_type == "creator-number-of-series":
- first_name = sys.argv[2]
- last_name = sys.argv[3]
- query = CreatorNumberOfSeries(first_name, last_name)
- else:
- sys.exit("Unkwnon query type: {}".format(query_type))
-
- client = Client(auth)
- response, attribution = client.make_request(query)
- text = query.text(response)
-
- terminal_size = shutil.get_terminal_size()
- columns = terminal_size.columns
- terminal = Display(width=columns)
-
- terminal.display(text)
- terminal.display("---")
- terminal.display(attribution)
-
-
- if __name__ == "__main__":
- main()
|