Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

179 linhas
5.7 KiB

3 anos atrás
3 anos atrás
3 anos atrás
3 anos atrás
3 anos atrás
3 anos atrás
3 anos atrás
3 anos atrás
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. #
  4. # Author : XueWeiHan
  5. # E-mail : 595666367@qq.com
  6. # Date : 2020-05-19 15:27
  7. # Desc : 获取最新的 GitHub 相关域名对应 IP
  8. import os
  9. import re
  10. import json
  11. import traceback
  12. from datetime import datetime, timezone, timedelta
  13. from collections import Counter
  14. import requests
  15. from retry import retry
  16. RAW_URL = [
  17. "alive.github.com",
  18. "live.github.com",
  19. "github.githubassets.com",
  20. "central.github.com",
  21. "desktop.githubusercontent.com",
  22. "assets-cdn.github.com",
  23. "camo.githubusercontent.com",
  24. "github.map.fastly.net",
  25. "github.global.ssl.fastly.net",
  26. "gist.github.com",
  27. "github.io",
  28. "github.com",
  29. "api.github.com",
  30. "raw.githubusercontent.com",
  31. "user-images.githubusercontent.com",
  32. "favicons.githubusercontent.com",
  33. "avatars5.githubusercontent.com",
  34. "avatars4.githubusercontent.com",
  35. "avatars3.githubusercontent.com",
  36. "avatars2.githubusercontent.com",
  37. "avatars1.githubusercontent.com",
  38. "avatars0.githubusercontent.com",
  39. "avatars.githubusercontent.com",
  40. "codeload.github.com",
  41. "github-cloud.s3.amazonaws.com",
  42. "github-com.s3.amazonaws.com",
  43. "github-production-release-asset-2e65be.s3.amazonaws.com",
  44. "github-production-user-asset-6210df.s3.amazonaws.com",
  45. "github-production-repository-file-5c1aeb.s3.amazonaws.com",
  46. "githubstatus.com",
  47. "github.community",
  48. "media.githubusercontent.com"]
  49. IPADDRESS_PREFIX = ".ipaddress.com"
  50. HOSTS_TEMPLATE = """# GitHub520 Host Start
  51. {content}
  52. # Update time: {update_time}
  53. # Star me GitHub url: https://github.com/521xueweihan/GitHub520
  54. # GitHub520 Host End\n"""
  55. def write_file(hosts_content: str, update_time: str):
  56. output_doc_file_path = os.path.join(os.path.dirname(__file__), "README.md")
  57. template_path = os.path.join(os.path.dirname(__file__),
  58. "README_template.md")
  59. write_host_file(hosts_content)
  60. with open(output_doc_file_path, "r") as old_readme_fb:
  61. old_content = old_readme_fb.read()
  62. old_hosts = old_content.split("```bash")[1].split("```")[0].strip()
  63. old_hosts = old_hosts.split("# Update time:")[0]
  64. if old_hosts == hosts_content:
  65. print("host not change")
  66. return False
  67. with open(template_path, "r") as temp_fb:
  68. template_str = temp_fb.read()
  69. hosts_content = template_str.format(hosts_str=hosts_content,
  70. update_time=update_time)
  71. with open(output_doc_file_path, "w") as output_fb:
  72. output_fb.write(hosts_content)
  73. return True
  74. def write_host_file(hosts_content: str):
  75. output_file_path = os.path.join(os.path.dirname(__file__), 'hosts')
  76. with open(output_file_path, "w") as output_fb:
  77. output_fb.write(hosts_content)
  78. def write_json_file(hosts_dict: dict):
  79. output_file_path = os.path.join(os.path.dirname(__file__), 'hosts.json')
  80. with open(output_file_path, "w") as output_fb:
  81. json.dump(hosts_dict, output_fb)
  82. def make_ipaddress_url(raw_url: str):
  83. """
  84. ipaddress url
  85. :param raw_url: url
  86. :return: ipaddress url
  87. """
  88. dot_count = raw_url.count(".")
  89. if dot_count > 1:
  90. raw_url_list = raw_url.split(".")
  91. tmp_url = raw_url_list[-2] + "." + raw_url_list[-1]
  92. ipaddress_url = "https://" + tmp_url + IPADDRESS_PREFIX + "/" + raw_url
  93. else:
  94. ipaddress_url = "https://" + raw_url + IPADDRESS_PREFIX
  95. return ipaddress_url
  96. @retry(tries=3)
  97. def get_ip(session: requests.session, raw_url: str):
  98. url = make_ipaddress_url(raw_url)
  99. try:
  100. rs = session.get(url, timeout=5)
  101. pattern = r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b"
  102. ip_list = re.findall(pattern, rs.text)
  103. ip_counter_obj = Counter(ip_list).most_common(1)
  104. if ip_counter_obj:
  105. return raw_url, ip_counter_obj[0][0]
  106. raise Exception("ip address empty")
  107. except Exception as ex:
  108. print("get: {}, error: {}".format(url, ex))
  109. raise Exception
  110. @retry(tries=3)
  111. def update_gitee_gist(session: requests.session, host_content):
  112. gitee_token = os.getenv("gitee_token")
  113. gitee_gist_id = os.getenv("gitee_gist_id")
  114. gist_file_name = os.getenv("gitee_gist_file_name")
  115. url = "https://gitee.com/api/v5/gists/{}".format(gitee_gist_id)
  116. headers = {
  117. "Content-Type": "application/json"}
  118. data = {
  119. "access_token": gitee_token,
  120. "files": {gist_file_name: {"content": host_content}},
  121. "public": "true"}
  122. json_data = json.dumps(data)
  123. try:
  124. response = session.patch(url, data=json_data, headers=headers,
  125. timeout=20)
  126. if response.status_code == 200:
  127. print("update gitee gist success")
  128. else:
  129. print("update gitee gist fail: {} {}".format(response.status_code,
  130. response.content))
  131. except Exception as e:
  132. traceback.print_exc(e)
  133. raise Exception(e)
  134. def main():
  135. session = requests.session()
  136. content = ""
  137. content_dict = {}
  138. for raw_url in RAW_URL:
  139. try:
  140. host_name, ip = get_ip(session, raw_url)
  141. content += ip.ljust(30) + host_name + "\n"
  142. content_dict[ip] = host_name
  143. except Exception:
  144. continue
  145. if not content:
  146. return
  147. update_time = datetime.utcnow().astimezone(
  148. timezone(timedelta(hours=8))).replace(microsecond=0).isoformat()
  149. hosts_content = HOSTS_TEMPLATE.format(content=content, update_time=update_time)
  150. has_change = write_file(hosts_content, update_time)
  151. if has_change:
  152. write_json_file(content_dict)
  153. print(hosts_content)
  154. if __name__ == '__main__':
  155. main()