Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

176 wiersze
5.7 KiB

  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. from retry import retry
  15. import requests
  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 yaml file,改成 gitee gist 地址同步(国内访问流畅)
  60. write_yaml_file(hosts_content)
  61. with open(output_doc_file_path, "r") as old_readme_fb:
  62. old_content = old_readme_fb.read()
  63. old_hosts = old_content.split("```bash")[1].split("```")[0].strip()
  64. old_hosts = old_hosts.split("# Update time:")[0]
  65. if old_hosts == hosts_content:
  66. print("host not change")
  67. return False
  68. with open(template_path, "r") as temp_fb:
  69. template_str = temp_fb.read()
  70. hosts_content = template_str.format(hosts_str=hosts_content,
  71. update_time=update_time)
  72. with open(output_doc_file_path, "w") as output_fb:
  73. output_fb.write(hosts_content)
  74. return True
  75. def write_yaml_file(hosts_content: str, ):
  76. output_yaml_file_path = os.path.join(os.path.dirname(__file__), 'hosts')
  77. with open(output_yaml_file_path, "w") as output_yaml_fb:
  78. output_yaml_fb.write(hosts_content)
  79. def make_ipaddress_url(raw_url: str):
  80. """
  81. ipaddress url
  82. :param raw_url: url
  83. :return: ipaddress url
  84. """
  85. dot_count = raw_url.count(".")
  86. if dot_count > 1:
  87. raw_url_list = raw_url.split(".")
  88. tmp_url = raw_url_list[-2] + "." + raw_url_list[-1]
  89. ipaddress_url = "https://" + tmp_url + IPADDRESS_PREFIX + "/" + raw_url
  90. else:
  91. ipaddress_url = "https://" + raw_url + IPADDRESS_PREFIX
  92. return ipaddress_url
  93. @retry(tries=3)
  94. def get_ip(session: requests.session, raw_url: str):
  95. url = make_ipaddress_url(raw_url)
  96. try:
  97. rs = session.get(url, timeout=5)
  98. pattern = r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b"
  99. ip_list = re.findall(pattern, rs.text)
  100. ip_counter_obj = Counter(ip_list).most_common(1)
  101. if ip_counter_obj:
  102. return raw_url, ip_counter_obj[0][0]
  103. raise Exception("ip address empty")
  104. except Exception as ex:
  105. print("get: {}, error: {}".format(url, ex))
  106. raise Exception
  107. @retry(tries=3)
  108. def update_gitee_gist(session: requests.session, host_content):
  109. gitee_token = os.getenv("gitee_token")
  110. gitee_gist_id = os.getenv("gitee_gist_id")
  111. gist_file_name = os.getenv("gitee_gist_file_name")
  112. url = "https://gitee.com/api/v5/gists/{}".format(gitee_gist_id)
  113. headers = {
  114. "Content-Type": "application/json"}
  115. data = {
  116. "access_token": gitee_token,
  117. "files": {gist_file_name: {"content": host_content}},
  118. "public": "true"}
  119. json_data = json.dumps(data)
  120. try:
  121. response = session.patch(url, data=json_data, headers=headers,
  122. timeout=20)
  123. if response.status_code == 200:
  124. print("update gitee gist success")
  125. else:
  126. print("update gitee gist fail: {} {}".format(response.status_code,
  127. response.content))
  128. except Exception as e:
  129. traceback.print_exc(e)
  130. raise Exception(e)
  131. def main():
  132. session = requests.session()
  133. content = ""
  134. for raw_url in RAW_URL:
  135. try:
  136. host_name, ip = get_ip(session, raw_url)
  137. content += ip.ljust(30) + host_name + "\n"
  138. except Exception:
  139. continue
  140. if not content:
  141. return
  142. update_time = datetime.utcnow().astimezone(
  143. timezone(timedelta(hours=8))).replace(microsecond=0).isoformat()
  144. hosts_content = HOSTS_TEMPLATE.format(content=content, update_time=update_time)
  145. has_change = write_file(hosts_content, update_time)
  146. if has_change:
  147. try:
  148. update_gitee_gist(session, hosts_content)
  149. except Exception as e:
  150. print("update gitee gist fail:{}".format(e))
  151. print(hosts_content)
  152. if __name__ == '__main__':
  153. main()