您不能選擇超過 %s 個話題 話題必須以字母或數字為開頭,可包含連接號 ('-') 且最長為 35 個字
此存儲庫已封存,您能瀏覽檔案及複製此存儲庫,但不能推送、建立問題及拉取請求。
 
 
 
 
 
 

134 行
3.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. result = query.extract(body)
  41. return (query.to_text(result), body["attributionText"])
  42. class Query(metaclass=abc.ABCMeta):
  43. @abc.abstractmethod
  44. def params(self):
  45. pass
  46. @abc.abstractmethod
  47. def path(self):
  48. pass
  49. @abc.abstractmethod
  50. def extract(self, body):
  51. pass
  52. def to_text(self, result):
  53. return result
  54. class CharacterDescription(Query):
  55. path = "/characters"
  56. def __init__(self, name):
  57. self.name = name
  58. def params(self):
  59. return { "name": self.name }
  60. def extract(self, body):
  61. return body["data"]["results"][0]["description"]
  62. class CreatorNumberOfSeries(Query):
  63. path = "/creators"
  64. def __init__(self, first_name, last_name):
  65. self.first_name = first_name
  66. self.last_name = last_name
  67. def params(self):
  68. return { "firstName": self.first_name, "lastName": self.last_name }
  69. def extract(self, body):
  70. return body["data"]["results"][0]["series"]["available"]
  71. def to_text(self, result):
  72. return f"{self.first_name} {self.last_name} worked on {result} series"
  73. class Display:
  74. def __init__(self, width=80):
  75. self.width = width
  76. def display(self, text):
  77. print("\n".join(textwrap.wrap(text, width=self.width)))
  78. def main():
  79. query_type = sys.argv[1]
  80. if query_type == "character-description":
  81. name = sys.argv[2]
  82. query = CharacterDescription(name)
  83. elif query_type == "creator-number-of-series":
  84. first_name = sys.argv[2]
  85. last_name = sys.argv[3]
  86. query = CreatorNumberOfSeries(first_name, last_name)
  87. auth = Authorization("api-keys.txt")
  88. client = Client(auth)
  89. text, attribution = client.make_request(query)
  90. terminal_size = shutil.get_terminal_size()
  91. columns = terminal_size.columns
  92. terminal = Display(width=columns)
  93. terminal.display(text)
  94. terminal.display("---")
  95. terminal.display(attribution)
  96. if __name__ == "__main__":
  97. main()