jerry 3 kuukautta sitten
vanhempi
sitoutus
ad23d844b2
6 muutettua tiedostoa jossa 158 lisäystä ja 110 poistoa
  1. 17 17
      config/groups.json
  2. 64 71
      config/proxies.json
  3. 2 1
      gco.py
  4. 60 20
      plugins/tls_plugin.py
  5. 14 0
      requirements.txt
  6. 1 1
      toolkit/vs_cloud_api.py

+ 17 - 17
config/groups.json

@@ -2,7 +2,7 @@
     {
         "identifier": "VFS_IE_NL",
         "debug": false,
-        "enable": false,
+        "enable": true,
         "need_account": true,
         "local_account_pool": "ie_nl",
         "need_proxy": true,
@@ -57,7 +57,7 @@
         "need_account": true,
         "local_account_pool": "sg_fr",
         "need_proxy": true,
-        "proxy_pool": "ireland_proxies",
+        "proxy_pool": "global_proxies",
         "target_instances": 1,
         "account_login_interval": 30,
         "order_account_routing": "",
@@ -109,7 +109,7 @@
         "need_account": true,
         "local_account_pool": "au_fr",
         "need_proxy": true,
-        "proxy_pool": "ireland_proxies",
+        "proxy_pool": "global_proxies",
         "target_instances": 1,
         "account_login_interval": 30,
         "order_account_routing": "",
@@ -174,7 +174,7 @@
         "need_account": true,
         "local_account_pool": "gb_it",
         "need_proxy": true,
-        "proxy_pool": "ireland_proxies",
+        "proxy_pool": "global_proxies",
         "target_instances": 1,
         "account_login_interval": 30,
         "order_account_routing": "",
@@ -239,7 +239,7 @@
         "need_account": true,
         "local_account_pool": "gb_nl",
         "need_proxy": true,
-        "proxy_pool": "ireland_proxies",
+        "proxy_pool": "global_proxies",
         "target_instances": 1,
         "account_login_interval": 30,
         "order_account_routing": "",
@@ -304,7 +304,7 @@
         "need_account": true,
         "local_account_pool": "gb_no",
         "need_proxy": true,
-        "proxy_pool": "ireland_proxies",
+        "proxy_pool": "global_proxies",
         "target_instances": 1,
         "account_login_interval": 30,
         "order_account_routing": "",
@@ -352,7 +352,7 @@
     {
         "identifier": "VFS_IE_AT",
         "debug": false,
-        "enable": false,
+        "enable": true,
         "need_account": true,
         "local_account_pool": "ie_at",
         "need_proxy": true,
@@ -408,7 +408,7 @@
         "need_account": true,
         "local_account_pool": "ie_dk",
         "need_proxy": true,
-        "proxy_pool": "ireland_proxies",
+        "proxy_pool": "global_proxies",
         "target_instances": 1,
         "account_login_interval": 30,
         "order_account_routing": "",
@@ -460,7 +460,7 @@
         "need_account": true,
         "local_account_pool": "ie_fi",
         "need_proxy": true,
-        "proxy_pool": "ireland_proxies",
+        "proxy_pool": "global_proxies",
         "target_instances": 1,
         "account_login_interval": 30,
         "order_account_routing": "",
@@ -512,7 +512,7 @@
         "need_account": true,
         "local_account_pool": "ie_hu",
         "need_proxy": true,
-        "proxy_pool": "ireland_proxies",
+        "proxy_pool": "global_proxies",
         "target_instances": 1,
         "account_login_interval": 30,
         "order_account_routing": "",
@@ -564,7 +564,7 @@
         "need_account": true,
         "local_account_pool": "ie_is",
         "need_proxy": true,
-        "proxy_pool": "ireland_proxies",
+        "proxy_pool": "global_proxies",
         "target_instances": 1,
         "account_login_interval": 30,
         "order_account_routing": "",
@@ -612,11 +612,11 @@
     {
         "identifier": "BLS_IE_ES",
         "debug": false,
-        "enable": true,
+        "enable": false,
         "need_account": true,
         "local_account_pool": "ie_es",
         "need_proxy": true,
-        "proxy_pool": "local",
+        "proxy_pool": "spain_proxies",
         "target_instances": 1,
         "account_login_interval": 30,
         "order_account_routing": "",
@@ -661,7 +661,7 @@
         "need_account": true,
         "local_account_pool": "gb_es",
         "need_proxy": true,
-        "proxy_pool": "local",
+        "proxy_pool": "spain_proxies",
         "target_instances": 1,
         "account_login_interval": 30,
         "order_account_routing": "",
@@ -702,11 +702,11 @@
     {
         "identifier": "TLS_GB_FR",
         "debug": false,
-        "enable": true,
+        "enable": false,
         "need_account": true,
         "local_account_pool": "gb_fr",
         "need_proxy": true,
-        "proxy_pool": "ireland_proxies",
+        "proxy_pool": "global_proxies",
         "target_instances": 1,
         "account_login_interval": 30,
         "order_account_routing": "auto.slot.lon.fr.tourist",
@@ -748,7 +748,7 @@
     {
         "identifier": "VISAMETRIC_IE_DE",
         "debug": false,
-        "enable": true,
+        "enable": false,
         "need_account": false,
         "local_account_pool": "",
         "need_proxy": true,

+ 64 - 71
config/proxies.json

@@ -1,112 +1,96 @@
 {
-    "global_proxy": [
+    "global_proxies": [
         {
             "id": 100003,
-            "ip": "82.152.15.37",
+            "ip": "disp.oxylabs.io",
             "lock_until": 0,
-            "password": "idzlar",
-            "port": 7778,
+            "password": "jYubEsw6~g3z1Uh",
+            "port": 8001,
             "scheme": "http",
-            "username": "4scepfs03sh920"
+            "username": "user-visafly_zFNdf"
         },
         {
-            "id": 100005,
-            "ip": "82.152.19.246",
-            "lock_until": 0,
-            "password": "idzlar",
-            "port": 7778,
-            "scheme": "http",
-            "username": "4scepfmv4gp9c"
-        },
-        {
-            "id": 100014,
-            "ip": "82.152.15.33",
-            "lock_until": 0,
-            "password": "idzlar",
-            "port": 7778,
-            "scheme": "http",
-            "username": "4scepfpclja918"
-        },
-        {
-            "id": 100018,
-            "ip": "82.152.19.4",
+            "id": 100004,
+            "ip": "disp.oxylabs.io",
             "lock_until": 0,
-            "password": "idzlar",
-            "port": 7778,
+            "password": "jYubEsw6~g3z1Uh",
+            "port": 8002,
             "scheme": "http",
-            "username": "4scepfmv4gp914"
+            "username": "user-visafly_zFNdf"
         },
         {
-            "id": 100019,
-            "ip": "82.152.15.8",
+            "id": 100005,
+            "ip": "disp.oxylabs.io",
             "lock_until": 0,
-            "password": "idzlar",
-            "port": 7778,
+            "password": "jYubEsw6~g3z1Uh",
+            "port": 8003,
             "scheme": "http",
-            "username": "4scepfmv4gp913"
+            "username": "user-visafly_zFNdf"
         },
         {
-            "id": 100020,
-            "ip": "82.152.19.141",
+            "id": 110029,
+            "ip": "disp.oxylabs.io",
             "lock_until": 0,
-            "password": "idzlar",
-            "port": 7778,
+            "password": "jYubEsw6~g3z1Uh",
+            "port": 8004,
             "scheme": "http",
-            "username": "4scepfmv4gp912"
+            "username": "user-visafly_zFNdf"
         },
         {
-            "id": 100023,
-            "ip": "82.152.19.2",
+            "id": 110030,
+            "ip": "disp.oxylabs.io",
             "lock_until": 0,
-            "password": "idzlar",
-            "port": 7778,
+            "password": "jYubEsw6~g3z1Uh",
+            "port": 8005,
             "scheme": "http",
-            "username": "4scepfmv4gp9e"
+            "username": "user-visafly_zFNdf"
         },
         {
-            "id": 100025,
-            "ip": "163.5.40.236",
+            "id": 100029,
+            "ip": "95.135.130.175",
             "lock_until": 0,
-            "password": "idzlar",
-            "port": 7778,
+            "password": "hmuROCk1FDebCnL",
+            "port": 46247,
             "scheme": "http",
-            "username": "4scekff9u6j9a"
+            "username": "GB6o2vBrXFjz4ya"
         },
         {
-            "id": 100026,
-            "ip": "45.196.65.44",
+            "id": 100030,
+            "ip": "95.135.130.29",
             "lock_until": 0,
-            "password": "idzlar",
-            "port": 7778,
+            "password": "WmqFTSvRvtxChIT",
+            "port": 43740,
             "scheme": "http",
-            "username": "4sj3agscn8592cf"
+            "username": "JUcjydi0HKZzWC6"
         },
         {
-            "id": 100027,
-            "ip": "154.82.173.108",
+            "id": 100031,
+            "ip": "95.135.130.45",
             "lock_until": 0,
-            "password": "M8v0m9b1p4b3",
-            "port": 9856,
-            "scheme": "http",
-            "username": "l9w3z3c4B4O2"
-        },
+            "password": "QSve9BePC91VxjO",
+            "port": 41537,
+            "scheme": "socks5",
+            "username": "XmigvOGAseidkxG"
+        }
+    ],
+    "spain_proxies": [
         {
-            "id": 100028,
-            "ip": "45.196.65.25",
+            "id": 110029,
+            "ip": "disp.oxylabs.io",
             "lock_until": 0,
-            "password": "idzlar",
-            "port": 7778,
+            "password": "jYubEsw6~g3z1Uh",
+            "port": 8004,
             "scheme": "http",
-            "username": "4sio3rdic7m9184"
+            "username": "user-visafly_zFNdf"
         },
         {
-            "id": 100029,
-            "ip": "45.196.65.109",
+            "id": 110030,
+            "ip": "disp.oxylabs.io",
             "lock_until": 0,
-            "password": "idzlar",
-            "port": 7778,
+            "password": "jYubEsw6~g3z1Uh",
+            "port": 8005,
             "scheme": "http",
-            "username": "4sibp4qi26n93c"
+            "username": "user-visafly_zFNdf"
         }
     ],
     "ireland_proxies": [
@@ -120,13 +104,22 @@
             "username": "GB6o2vBrXFjz4ya"
         },
         {
-            "id": 100029,
+            "id": 100030,
             "ip": "95.135.130.29",
             "lock_until": 0,
             "password": "WmqFTSvRvtxChIT",
             "port": 43740,
             "scheme": "http",
             "username": "JUcjydi0HKZzWC6"
+        },
+        {
+            "id": 100031,
+            "ip": "95.135.130.45",
+            "lock_until": 0,
+            "password": "QSve9BePC91VxjO",
+            "port": 41537,
+            "scheme": "socks5",
+            "username": "XmigvOGAseidkxG"
         }
     ],
     "local": [

+ 2 - 1
gco.py

@@ -368,7 +368,8 @@ class GCO:
                             VSCloudApi.Instance().return_vas_task_to_queue(task_ref['id'])
                             return None
                 except Exception as e:
-                    self._log(f"Get Order task exception, e={e}")
+                    pass
+                    #self._log(f"Get Order task exception, e={e}")
 
         if not config_ready:
             return None

+ 60 - 20
plugins/tls_plugin.py

@@ -226,7 +226,7 @@ class TlsPlugin(IVSPlg):
         return res
 
 
-    def book(self, slot_info: VSQueryResult, user_input: Dict = None) -> VSBookResult:
+    def book(self, slot_info: VSQueryResult, user_inputs: Dict = None) -> VSBookResult:
         res = VSBookResult()
         res.success = False
         
@@ -234,24 +234,38 @@ class TlsPlugin(IVSPlg):
         embassy = self.free_config.get('center', {})
         group_num = self.travel_group['group_number']
         
-        target_slot = slot_info.availability[0]
-        target_date = target_slot.date
-        target_time = target_slot.times[0].time
+        available_dates = [da.date for da in slot_info.availability]
+        exp_start = user_inputs.get('expected_start_date', '')
+        exp_end = user_inputs.get('expected_end_date', '')
         
+        support_pta = user_inputs.get('support_pta', True)
+
+        target_labels = ['']
+        
+        if support_pta:
+            target_labels.append('pta')
+        
+        valid_dates = self._filter_dates(available_dates, exp_start, exp_end)
+        if not valid_dates:
+            raise NotFoundError(message="No dates match user constraints")
+        
+        selected_date = None
+        selected_time = None
+        selected_label = None
         # [关键修正] Label 处理
-        # 根据你的 dump,如果是 Prime Time,这里是 "pta"。
-        # 如果是普通号,通常是 "regular" 或者空字符串。
-        # 我们优先取 slot_info 里的 label,如果没有则默认为空
-        raw_labels = getattr(target_slot.times[0], 'labels', [])
-        if isinstance(raw_labels, list) and len(raw_labels) > 0:
-            # 取第一个标签,例如 "pta" 或 "regular"
-            target_label = raw_labels[0] 
-        else:
-            target_label = "" # 或者试试 "regular"
+        for d in valid_dates:
+            for da in slot_info.availability:
+                if da.date == d:
+                    for t in da.times:
+                        if t.label in target_labels:
+                            selected_date = d
+                            selected_time = t
+                            selected_label = t.label
+                            break
 
         # 2. 解决 ReCaptcha V3
         # 动作必须是 "book"
-        page_url = f'https://visas-fr.tlscontact.com/en-us/{group_num}/workflow/appointment-booking?location={embassy["code"]}&month={target_date[:7]}'
+        page_url = f'https://visas-fr.tlscontact.com/en-us/{group_num}/workflow/appointment-booking?location={embassy["code"]}&month={selected_date[:7]}'
         
         api_token = self.free_config.get("capsolver_key", "")
         rc_params = {
@@ -273,9 +287,9 @@ class TlsPlugin(IVSPlg):
             '1_lang': 'en-us',
             '1_process': 'APPOINTMENT',
             '1_location': embassy["code"],        # 例如 gbLON2fr
-            '1_date': target_date,
-            '1_time': target_time,
-            '1_appointmentLabel': target_label,   # 修正:单数 Label,值为字符串 "pta" 或 "regular"
+            '1_date': selected_date,
+            '1_time': selected_time,
+            '1_appointmentLabel': selected_label,   # 修正:单数 Label,值为字符串 "pta" 或 "regular"
             '1_captcha_token': g_token,           # 修正:下划线格式
             '0': '[{"status":"IDLE"},"$K1"]'      # 对应 Next.js Action 的状态位
         }
@@ -307,8 +321,8 @@ class TlsPlugin(IVSPlg):
             location = resp.headers.get('Location', '')
             self._log(f"Booking Success! Redirecting to: {location}")
             res.success = True
-            res.book_date = target_date
-            res.book_time = target_time
+            res.book_date = selected_date
+            res.book_time = selected_time
             return res
             
         elif resp.status_code == 200:
@@ -520,4 +534,30 @@ class TlsPlugin(IVSPlg):
                 raise SessionExpiredOrInvalidError()
             if 'temporarily blocked!' in html.lower() and 'Your session has been temporarily suspended due to the high number of your access to this page.' in html.lower() and 'You can try to access your account again in 2 hours.' in html.lower():
                 self.is_healthy = False
-                raise SessionExpiredOrInvalidError()
+                raise SessionExpiredOrInvalidError()
+            
+    def _filter_dates(self, dates: List[str], start_str: str, end_str: str) -> List[str]:
+        """
+        根据用户的期望范围筛选可用日期
+        
+        :param dates: API 返回的可用日期列表 (YYYY-MM-DD)
+        :param start_str: 用户期望开始日期 (YYYY-MM-DD)
+        :param end_str: 用户期望结束日期 (YYYY-MM-DD)
+        :return: 符合要求的日期列表
+        """
+        # 如果没有设置范围,则不过滤,返回所有日期
+        if not start_str or not end_str:
+            return dates
+            
+        valid_dates = []
+        # 截取前10位以防带有时分秒
+        s_date = datetime.strptime(start_str[:10], "%Y-%m-%d")
+        e_date = datetime.strptime(end_str[:10], "%Y-%m-%d")
+        
+        for date_str in dates:
+            curr_date = datetime.strptime(date_str, "%Y-%m-%d")
+            # 比较范围 (闭区间)
+            if s_date <= curr_date <= e_date:
+                valid_dates.append(date_str)
+        random.shuffle(valid_dates)
+        return valid_dates

+ 14 - 0
requirements.txt

@@ -0,0 +1,14 @@
+DrissionPage==4.1.0.12
+PIL==UNKNOWN
+bs4==0.0.2
+cryptography==38.0.4
+curl-cffi==0.10.0
+ddddocr==1.5.3
+fastapi==0.128.0
+numpy==1.24.2
+pydantic==2.12.5
+requests-toolbelt==1.0.0
+requests==2.31.0
+torch==2.1.0.dev20230404
+torchvision==0.16.0.dev20230404
+uvicorn==0.39.0

+ 1 - 1
toolkit/vs_cloud_api.py

@@ -17,7 +17,7 @@ class VSCloudApi:
         if cls._instance is None:
             cls._instance = super(VSCloudApi, cls).__new__(cls)
             # 初始化默认配置
-            cls._instance.base_url = "http://45.137.220.138:8888"
+            cls._instance.base_url = "https://visafly.top"
             cls._instance.api_token = "Bearer tok_e946329a60ff45ba807f3f41b0e8b7fc"
             cls._instance.session = requests.Session()
         return cls._instance