You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 
 
 
 

166 lines
4.2 KiB

  1. import abc
  2. import hashlib
  3. import requests
  4. import shutil
  5. import time
  6. import textwrap
  7. import sys
  8. class Authorization:
  9. def __init__(self, filename):
  10. with open(filename, "r") as file:
  11. lines = file.readlines()
  12. if len(lines) != 2:
  13. sys.exit("Incorrect api-keys file")
  14. self.public_key = lines[0].strip()
  15. self.private_key = lines[1].strip()
  16. def generate_params(self):
  17. params = dict()
  18. params["apikey"] = self.public_key
  19. ts = str(time.time())
  20. to_hash = ts + self.private_key + self.public_key
  21. hasher = hashlib.md5()
  22. hasher.update(to_hash.encode())
  23. digest = hasher.hexdigest()
  24. params["ts"] = ts
  25. params["hash"] = digest
  26. return params
  27. class Client:
  28. base_url = "http://gateway.marvel.com/v1/public"
  29. def __init__(self, auth):
  30. self.auth = auth
  31. def make_request(self, query):
  32. params = self.auth.generate_params()
  33. params.update(query.params())
  34. url = Client.base_url + query.path()
  35. response = requests.get(url, params=params)
  36. status_code = response.status_code
  37. if status_code != 200:
  38. sys.exit("got status: " + str(status_code))
  39. body = response.json()
  40. attribution = body["attributionText"]
  41. response = query.extract(body)
  42. return (response, attribution)
  43. class Display:
  44. def __init__(self, width=80):
  45. self.width = width
  46. def display(self, text):
  47. print("\n".join(textwrap.wrap(text, width=self.width)))
  48. class Query(metaclass=abc.ABCMeta):
  49. @abc.abstractmethod
  50. def params(self):
  51. pass
  52. @abc.abstractmethod
  53. def path(self):
  54. pass
  55. @abc.abstractmethod
  56. def extract(self, body):
  57. pass
  58. @abc.abstractmethod
  59. def text(self, response):
  60. pass
  61. class CharacterDescription(Query):
  62. def __init__(self, name):
  63. self.name = name
  64. def get_character_description(self, name):
  65. params = {"name": name}
  66. body, attribution = self.make_request("/characters",
  67. params)
  68. first_result = body["data"]["results"][0]
  69. description = first_result["description"]
  70. return (description, attribution)
  71. def params(self):
  72. return {"name": self.name}
  73. def path(self):
  74. return "/characters"
  75. def extract(self, body):
  76. first_result = body["data"]["results"][0]
  77. description = first_result["description"]
  78. return description
  79. def text(self, response):
  80. return response
  81. class CreatorNumberOfSeries(Query):
  82. def __init__(self, first_name, last_name):
  83. self.first_name = first_name
  84. self.last_name = last_name
  85. def get_number_of_series(self, first_name, last_name):
  86. params = {
  87. "firstName": first_name,
  88. "lastName": last_name,
  89. }
  90. body, attribution = self.make_request("/creators",
  91. params)
  92. first_result = body["data"]["results"][0]
  93. return (first_result["series"]["available"], attribution)
  94. def params(self):
  95. return { "firstName": self.first_name, "lastName": self.last_name }
  96. def path(self):
  97. return "/creators"
  98. def extract(self, body):
  99. first_result = body["data"]["results"][0]
  100. return first_result["series"]["available"]
  101. def text(self, response):
  102. return f"{self.first_name} {self.last_name} worked on {response} series"
  103. def main():
  104. auth = Authorization("api-keys.txt")
  105. query_type = sys.argv[1]
  106. if query_type == "character-description":
  107. name = sys.argv[2]
  108. query = CharacterDescription(name)
  109. elif query_type == "creator-number-of-series":
  110. first_name = sys.argv[2]
  111. last_name = sys.argv[3]
  112. query = CreatorNumberOfSeries(first_name, last_name)
  113. client = Client(auth)
  114. response,attribution = client.make_request(query)
  115. text = query.text(response)
  116. terminal_size = shutil.get_terminal_size()
  117. columns = terminal_size.columns
  118. terminal = Display(width=columns)
  119. terminal.display(text)
  120. terminal.display("---")
  121. terminal.display(attribution)
  122. if __name__ == "__main__":
  123. main()