Browse Source

检测host

liuyuqi-dellpc 1 year ago
parent
commit
d81d1755cd
1 changed files with 61 additions and 7 deletions
  1. 61 7
      client.py

+ 61 - 7
client.py

@@ -10,8 +10,11 @@
 import os,sys,re
 import argparse
 from fgh.utils.frozen_dir import get_app_path
+import requests, subprocess, platform
+import dotenv
 
 class Client:
+
     help_str ="""
     fgh(fast github) quick clone github repo tools
         contact: liuyuqi.gov@msn.cn
@@ -35,13 +38,16 @@ fgh curl -O https://ghproxy.org/https://raw.githubusercontent.com/microsoft/vsco
     def __init__(self):
         self.fgit_host = ''
         self.token = ''
+        self.update_host()
         self.read_config()
         self.args = self.parse_args()
+        self.sess = requests.Session()
+        self.env_file_path = os.path.join(get_app_path(), '.env')
 
     def read_config(self):
-        import dotenv
+        """ read config """
         current_dir = get_app_path()
-        dotenv.load_dotenv(os.path.join(current_dir, '.env'))
+        dotenv.load_dotenv(self.env_file_path)
         fgit_host = os.getenv('FGH_HOST')
         try:
             if fgit_host[-1] == '/':
@@ -50,8 +56,32 @@ fgh curl -O https://ghproxy.org/https://raw.githubusercontent.com/microsoft/vsco
         except Exception as e:
             print(".env配置错误"+e)
 
+    @staticmethod
+    def ping(host: str) -> None|int:
+        """ ping host """
+        try:
+            if platform.system().lower() == 'windows':
+                command = ['ping', '-n', '1', '-w', '1000', host]
+            else:
+                command = ['ping', '-c', '1', '-W', '1', host]
+        
+            output = subprocess.run(command, capture_output=True, text=True)
+
+            # 从输出中提取延迟信息
+            if output.returncode == 0:
+                # 使用正则表达式从输出中匹配延迟时间
+                pattern = r"time=(\d+)ms"
+                match = re.search(pattern, output.stdout)
+                if match:
+                    return int(match.group(1))  # 返回延迟时间(毫秒)
+            return None  # 如果 ping 失败或延迟时间无法提取,则返回 None
+        except Exception as e:
+            print(e)
+        return None
+
     @staticmethod
     def parse_args():
+        """ parse args """
         parser = argparse.ArgumentParser(description='fgit client')
         parser.add_argument('command', type=str, help='fgit command', 
                             choices=['git','wget','curl','clone', 'push', 'pull', 'commit', 'add', 'status', 'log', 'diff', 'branch', 'checkout', 'merge', 'rebase', 'reset', 'tag', 'fetch', 'remote', 'init', 'config', 'help'])
@@ -59,11 +89,35 @@ fgh curl -O https://ghproxy.org/https://raw.githubusercontent.com/microsoft/vsco
         parser.add_argument('args', nargs=argparse.REMAINDER, help='git command args')
         return parser.parse_args()
 
-    def choose_host(self):
-        """choose host"""
-        pass
-
-    def run(self):   
+    def update_host(self):
+        """update host"""
+        res = []
+        try:
+            res = self.sess.get(self.fgit_host+'/update_host')
+            fgh_hosts= res.json()["hosts"]
+            fgh_host= self._get_best_host()
+            dotenv.set_key(self.env_file_path, 'FGH_HOST', fgh_host)
+        except Exception as e:
+            print(e)
+        
+    def _get_best_host(self, hosts: list) -> str:
+        """ 在所有 hosts 中,ping 延迟最短的返回 """
+        print("即将检测网络延迟...")
+        res =[]
+        for host in hosts:
+            res.append({'host': host, 'delay': self.ping(host) if self.ping(host) else 999999})
+            print("正在ping "+ host + " 延迟为:" + str(res[-1]['delay']) + "ms")
+        min_delay = 999999
+        min_host = ''
+        for item in res:
+            if item['delay'] and item['delay'] < min_delay:
+                min_delay = item['delay']
+                min_host = item['host']
+        print("选择最佳host: " + min_host + " 延迟为:" + str(min_delay) + "ms")
+        return min_host
+    
+    def run(self):
+        """ run """
         args = self.parse_args()
         command = args.command
         if len(args.args) == 0 and command != 'help':