Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

189 rader
6.1 KiB

3 år sedan
3 år sedan
2 år sedan
2 år sedan
3 år sedan
3 år sedan
3 år sedan
3 år sedan
3 år sedan
3 år sedan
3 år sedan
3 år sedan
3 år sedan
  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. "github.blog",
  30. "api.github.com",
  31. "raw.githubusercontent.com",
  32. "user-images.githubusercontent.com",
  33. "favicons.githubusercontent.com",
  34. "avatars5.githubusercontent.com",
  35. "avatars4.githubusercontent.com",
  36. "avatars3.githubusercontent.com",
  37. "avatars2.githubusercontent.com",
  38. "avatars1.githubusercontent.com",
  39. "avatars0.githubusercontent.com",
  40. "avatars.githubusercontent.com",
  41. "codeload.github.com",
  42. "github-cloud.s3.amazonaws.com",
  43. "github-com.s3.amazonaws.com",
  44. "github-production-release-asset-2e65be.s3.amazonaws.com",
  45. "github-production-user-asset-6210df.s3.amazonaws.com",
  46. "github-production-repository-file-5c1aeb.s3.amazonaws.com",
  47. "githubstatus.com",
  48. "github.community",
  49. "github.dev",
  50. "collector.github.com",
  51. "pipelines.actions.githubusercontent.com",
  52. "media.githubusercontent.com",
  53. "cloud.githubusercontent.com",
  54. "objects.githubusercontent.com",
  55. "vscode.dev"]
  56. IPADDRESS_PREFIX = ".ipaddress.com"
  57. HOSTS_TEMPLATE = """# GitHub520 Host Start
  58. {content}
  59. # Update time: {update_time}
  60. # Update url: https://raw.hellogithub.com/hosts
  61. # Star me: https://github.com/521xueweihan/GitHub520
  62. # GitHub520 Host End\n"""
  63. def write_file(hosts_content: str, update_time: str):
  64. output_doc_file_path = os.path.join(os.path.dirname(__file__), "README.md")
  65. template_path = os.path.join(os.path.dirname(__file__),
  66. "README_template.md")
  67. write_host_file(hosts_content)
  68. if os.path.exists(output_doc_file_path):
  69. with open(output_doc_file_path, "r") as old_readme_fb:
  70. old_content = old_readme_fb.read()
  71. old_hosts = old_content.split("```bash")[1].split("```")[0].strip()
  72. old_hosts = old_hosts.split("# Update time:")[0].strip()
  73. hosts_content_hosts = hosts_content.split("# Update time:")[0].strip()
  74. if old_hosts == hosts_content_hosts:
  75. print("host not change")
  76. return False
  77. with open(template_path, "r") as temp_fb:
  78. template_str = temp_fb.read()
  79. hosts_content = template_str.format(hosts_str=hosts_content,
  80. update_time=update_time)
  81. with open(output_doc_file_path, "w") as output_fb:
  82. output_fb.write(hosts_content)
  83. return True
  84. def write_host_file(hosts_content: str):
  85. output_file_path = os.path.join(os.path.dirname(__file__), 'hosts')
  86. with open(output_file_path, "w") as output_fb:
  87. output_fb.write(hosts_content)
  88. def write_json_file(hosts_list: list):
  89. output_file_path = os.path.join(os.path.dirname(__file__), 'hosts.json')
  90. with open(output_file_path, "w") as output_fb:
  91. json.dump(hosts_list, output_fb)
  92. def make_ipaddress_url(raw_url: str):
  93. """
  94. ipaddress url
  95. :param raw_url: url
  96. :return: ipaddress url
  97. """
  98. dot_count = raw_url.count(".")
  99. if dot_count > 1:
  100. raw_url_list = raw_url.split(".")
  101. tmp_url = raw_url_list[-2] + "." + raw_url_list[-1]
  102. ipaddress_url = "https://" + tmp_url + IPADDRESS_PREFIX + "/" + raw_url
  103. else:
  104. ipaddress_url = "https://" + raw_url + IPADDRESS_PREFIX
  105. return ipaddress_url
  106. @retry(tries=3)
  107. def get_ip(session: requests.session, raw_url: str):
  108. url = make_ipaddress_url(raw_url)
  109. try:
  110. rs = session.get(url, timeout=5)
  111. pattern = r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b"
  112. ip_list = re.findall(pattern, rs.text)
  113. ip_counter_obj = Counter(ip_list).most_common(1)
  114. if ip_counter_obj:
  115. return raw_url, ip_counter_obj[0][0]
  116. raise Exception("ip address empty")
  117. except Exception as ex:
  118. print("get: {}, error: {}".format(url, ex))
  119. raise Exception
  120. @retry(tries=3)
  121. def update_gitee_gist(session: requests.session, host_content):
  122. gitee_token = os.getenv("gitee_token")
  123. gitee_gist_id = os.getenv("gitee_gist_id")
  124. gist_file_name = os.getenv("gitee_gist_file_name")
  125. url = "https://gitee.com/api/v5/gists/{}".format(gitee_gist_id)
  126. headers = {
  127. "Content-Type": "application/json"}
  128. data = {
  129. "access_token": gitee_token,
  130. "files": {gist_file_name: {"content": host_content}},
  131. "public": "true"}
  132. json_data = json.dumps(data)
  133. try:
  134. response = session.patch(url, data=json_data, headers=headers,
  135. timeout=20)
  136. if response.status_code == 200:
  137. print("update gitee gist success")
  138. else:
  139. print("update gitee gist fail: {} {}".format(response.status_code,
  140. response.content))
  141. except Exception as e:
  142. traceback.print_exc(e)
  143. raise Exception(e)
  144. def main():
  145. session = requests.session()
  146. content = ""
  147. content_list = []
  148. for raw_url in RAW_URL:
  149. try:
  150. host_name, ip = get_ip(session, raw_url)
  151. content += ip.ljust(30) + host_name + "\n"
  152. content_list.append((ip, host_name,))
  153. except Exception:
  154. continue
  155. if not content:
  156. return
  157. update_time = datetime.utcnow().astimezone(
  158. timezone(timedelta(hours=8))).replace(microsecond=0).isoformat()
  159. hosts_content = HOSTS_TEMPLATE.format(content=content, update_time=update_time)
  160. has_change = write_file(hosts_content, update_time)
  161. if has_change:
  162. write_json_file(content_list)
  163. print(hosts_content)
  164. if __name__ == '__main__':
  165. main()