client.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #!/usr/bin/env python
  2. # -*- encoding: utf-8 -*-
  3. """
  4. @Contact : liuyuqi.gov@msn.cn
  5. @Time : 2024/04/09 12:56:07
  6. @License : Copyright © 2017-2022 liuyuqi. All Rights Reserved.
  7. @Desc : client enter point
  8. """
  9. import os,sys,re
  10. import argparse
  11. from fgh.utils.frozen_dir import get_app_path
  12. import requests, subprocess, platform
  13. import dotenv
  14. class Client:
  15. help_str ="""
  16. fgh(fast github) quick clone github repo tools
  17. contact: liuyuqi.gov@msn.cn
  18. Usage: fgh <command> [<args>]
  19. # clone repo
  20. fgh clone https://github.com/xx/yy.git
  21. fgh push https://github.com/xx/yy.git
  22. # download file
  23. fgh wget https://ghproxy.org/https://github.com/microsoft/vscode/archive/refs/tags/1.84.2.zip
  24. fgh wget https://ghproxy.org/https://raw.githubusercontent.com/microsoft/vscode/main/README.md
  25. fgh curl -O https://ghproxy.org/https://github.com/microsoft/vscode/archive/refs/tags/1.84.2.zip
  26. fgh curl -O https://ghproxy.org/https://raw.githubusercontent.com/microsoft/vscode/main/README.md
  27. """
  28. def __init__(self):
  29. self.fgit_host = ''
  30. self.token = ''
  31. self.sess = requests.Session()
  32. self.env_file_path = os.path.join(get_app_path(), '.env')
  33. self.update_host()
  34. self.read_config()
  35. self.args = self.parse_args()
  36. def read_config(self):
  37. """ read config """
  38. dotenv.load_dotenv(self.env_file_path)
  39. fgit_host = os.getenv('FGH_HOST')
  40. print("当前host: " + fgit_host)
  41. try:
  42. if fgit_host[-1] == '/':
  43. self.fgit_host = fgit_host[:-1]
  44. self.token = os.getenv('FGh_TOKEN')
  45. except Exception as e:
  46. print(".env配置错误"+e)
  47. @staticmethod
  48. def ping(host: str) -> None|int:
  49. """ ping host """
  50. if host.startswith('https://') or host.startswith('http://'):
  51. host = host.split('://')[1]
  52. host = host.split(':')[0]
  53. host = host.split('/')[0]
  54. try:
  55. if platform.system().lower() == 'windows':
  56. command = ['ping', '-n', '1', '-w', '1000', host]
  57. else:
  58. command = ['ping', '-c', '1', '-W', '1', host]
  59. output = subprocess.run(command, capture_output=True, text=True)
  60. # 从输出中提取延迟信息
  61. if output.returncode == 0:
  62. # 使用正则表达式从输出中匹配延迟时间
  63. pattern = r"time=(\d+)ms"
  64. match = re.search(pattern, output.stdout)
  65. if match:
  66. return int(match.group(1)) # 返回延迟时间(毫秒)
  67. return None # 如果 ping 失败或延迟时间无法提取,则返回 None
  68. except Exception as e:
  69. print(e)
  70. return None
  71. @staticmethod
  72. def parse_args():
  73. """ parse args """
  74. print("解析参数...")
  75. parser = argparse.ArgumentParser(description='fgit client')
  76. parser.add_argument('command', type=str, help='fgit command',
  77. choices=['git','wget','curl','clone', 'push', 'pull', 'commit', 'add', 'status', 'log', 'diff', 'branch', 'checkout', 'merge', 'rebase', 'reset', 'tag', 'fetch', 'remote', 'init', 'config', 'help'])
  78. # all args behind command
  79. parser.add_argument('args', nargs=argparse.REMAINDER, help='git command args')
  80. return parser.parse_args()
  81. def update_host(self):
  82. """update host"""
  83. print("正在更新host...")
  84. res = []
  85. try:
  86. res = self.sess.get('https://git.yoqi.me/lyq/fgh/raw/master/docs/fgh_host.json')
  87. fgh_hosts= res.json()["hosts"]
  88. fgh_host= self._get_best_host(fgh_hosts)
  89. dotenv.set_key(self.env_file_path, 'FGH_HOST', fgh_host)
  90. except Exception as e:
  91. print(e)
  92. def _get_best_host(self, hosts: list) -> str:
  93. """ 在所有 hosts 中,ping 延迟最短的返回 """
  94. print("即将检测网络延迟...")
  95. res =[]
  96. for host in hosts:
  97. res.append({'host': host, 'delay': self.ping(host) if self.ping(host) else 999999})
  98. print("正在ping "+ host + " 延迟为:" + str(res[-1]['delay']) + "ms")
  99. min_delay = 999999
  100. min_host = res[0]['host']
  101. for item in res:
  102. if item['delay'] and item['delay'] < min_delay:
  103. min_delay = item['delay']
  104. min_host = item['host']
  105. print("选择最佳host: " + min_host + " 延迟为:" + str(min_delay) + "ms")
  106. return min_host
  107. def run(self):
  108. """ run """
  109. args = self.parse_args()
  110. command = args.command
  111. if len(args.args) == 0 and command != 'help':
  112. print('Usage: fgh <command> [<args>]')
  113. sys.exit(1)
  114. if command == "wget":
  115. if len(args.args) > 0:
  116. args.args = [re.sub(r'https://github.com', self.fgit_host+'/https://github.com', arg) for arg in args.args]
  117. # print('wget ' + ' '.join(args.args))
  118. os.system('wget ' + ' '.join(args.args))
  119. elif command =="curl":
  120. if len(args.args) > 0:
  121. args.args = [re.sub(r'https://github.com', self.fgit_host+'/https://github.com', arg) for arg in args.args]
  122. print('curl ' + ' '.join(args.args))
  123. os.system('curl ' + ' '.join(args.args))
  124. elif command == "help":
  125. print(Client.help_str)
  126. else:
  127. if len(args.args) > 0:
  128. args.args = [re.sub(r'https://github.com', self.fgit_host+'/https://github.com', arg) for arg in args.args]
  129. cmd_str = 'git ' + command + ' ' + ' '.join(args.args)
  130. try:
  131. if command == 'git':
  132. cmd_str = command + ' ' + ' '.join(args.args)
  133. os.system(cmd_str)
  134. # print(cmd_str)
  135. except Exception as e:
  136. print(cmd_str + e)
  137. if __name__=='__main__':
  138. client = Client()
  139. client.run()