main.py 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. # main.py
  2. import time
  3. import os
  4. import json
  5. import logging
  6. # 导入必要模块
  7. from vs_types import GroupConfig, QueryWaitMode, PluginConfig, QueryWaitConfig
  8. from group_coordinator import GroupCoordinator
  9. from vs_log_macros import VSC_INFO, VSC_ERROR
  10. def vfs_test():
  11. # 0. 检查目录结构
  12. if not os.path.exists("plugins/vfs_plugin.py"):
  13. print("[ERROR] 找不到插件文件 'plugins/vfs_plugin.py'")
  14. print("请将上一条回答中的代码保存为该文件。")
  15. return
  16. # 1. 准备 VFS 业务配置 (free_config)
  17. # 这部分 JSON 对应 VfsPlugin 中读取的配置
  18. vfs_config = {
  19. "verbose": 0,
  20. "missionCode": "fra",
  21. "missionName": "France",
  22. "countryCode": "sgp",
  23. "countryName": "Singapore",
  24. "cultureCode": "en-US",
  25. "language": "en",
  26. "website": "https://visa.vfsglobal.com/sgp/en/fra/login",
  27. "appointmentType": [
  28. {
  29. "id": 538,
  30. "routing_key": "slot.vfs.sin.fr.tourist",
  31. "centerName": "France Visa Application Center, Singapore",
  32. "city": "Singapore",
  33. "country": "France",
  34. "visa_type": "Tourist",
  35. "address": "79 Anson Road #15-01 Singapore 079906",
  36. "vacCode": "FRSN",
  37. "categoryName": "Short Stay",
  38. "categoryCode": "02",
  39. "subcategoryName": "Short Stay Tourist, Family Visit",
  40. "subcategoryCode": "Six",
  41. "fee": None,
  42. "currency": None
  43. }
  44. ]
  45. }
  46. # 2. 构造查询策略配置
  47. query_wait_config = QueryWaitConfig(
  48. mode=QueryWaitMode.Random,
  49. random_min=5, # 最小间隔 5秒
  50. random_max=10 # 最大间隔 10秒
  51. )
  52. # 3. 构造插件加载配置
  53. # 注意:plugin_name="vfs_plugin" 会被自动推导为类名 "VfsPlugin"
  54. plugin_config = PluginConfig(
  55. lib_path="plugins",
  56. plugin_name="vfs_plugin",
  57. plugin_bin="vfs_plugin.py",
  58. plugin_proto="IVSPlg"
  59. )
  60. # 4. 构造任务组配置
  61. group_config = GroupConfig(
  62. identifier="Singapore_France_Visas", # 组名
  63. enable=True, # 启用
  64. need_account=True, # 需要登录账号
  65. account_pool="ie_nl", # 使用 AccountManager 中的 fr_pool (在 account_manager.py 中预设)
  66. need_proxy=True, # 需要代理
  67. proxy_pool="global_proxy", # 使用 ProxyManager 中的 global_proxy
  68. need_ip_bind=False, # 不强制 IP 绑定
  69. account_login_interval=10, # 登录失败/成功后锁定账号 10 分钟
  70. target_instances=1, # 启动 2 个并发实例 (线程)
  71. query_wait=query_wait_config,
  72. plugin_config=plugin_config,
  73. free_config=json.dumps(vfs_config) # 将业务配置转为 JSON 字符串
  74. )
  75. # 5. 创建协调器
  76. coordinator = GroupCoordinator(group_config)
  77. # 6. 设置回调 (模拟 WebSocket 推送或日志记录)
  78. def my_push_callback(type_code: int, data: bytes, size: int):
  79. msg = data.decode('utf-8')
  80. VSC_INFO("main", ">>> [PUSH CALLBACK] Type: %d, Message: %s", type_code, msg)
  81. coordinator.set_push_callback(my_push_callback)
  82. # 7. 启动
  83. try:
  84. VSC_INFO("main", "========================================")
  85. VSC_INFO("main", " VFS Python Plugin Tester ")
  86. VSC_INFO("main", "========================================")
  87. coordinator.start()
  88. time.sleep(3600)
  89. except KeyboardInterrupt:
  90. VSC_INFO("main", "Ctrl+C detected. Stopping...")
  91. except Exception as e:
  92. VSC_ERROR("main", "Unexpected Error: %s", str(e))
  93. finally:
  94. # 8. 停止
  95. coordinator.stop()
  96. VSC_INFO("main", "Program finished.")
  97. def tls_test():
  98. # 0. 检查目录结构
  99. if not os.path.exists("plugins/tls_plugin.py"):
  100. print("[ERROR] 找不到插件文件 'plugins/tls_plugin.py'")
  101. print("请将上一条回答中的代码保存为该文件。")
  102. return
  103. # 1. 准备 VFS 业务配置 (free_config)
  104. # 这部分 JSON 对应 TlsPlugin 中读取的配置
  105. tls_config = {
  106. "verbose": 0,
  107. "embassy_code": "gbLON2fr",
  108. "country_code": "gb",
  109. "mission_code": "fr",
  110. "city": "london",
  111. "capsolver_key": "CAP-5441DD341DD3CC2FAEF0BE6FE493EE9A",
  112. "interest_month": "01-2026",
  113. "target_labels": ["", "pta"],
  114. 'website': 'https://visas-fr.tlscontact.com/country/gb/vac/gbLON2fr/'
  115. }
  116. # 2. 构造查询策略配置
  117. query_wait_config = QueryWaitConfig(
  118. mode=QueryWaitMode.Random,
  119. random_min=60, # 最小间隔 5秒
  120. random_max=300 # 最大间隔 10秒
  121. )
  122. # 3. 构造插件加载配置
  123. # 注意:plugin_name="tls_plugin" 会被自动推导为类名 "TlsPlugin"
  124. plugin_config = PluginConfig(
  125. lib_path="plugins",
  126. plugin_name="tls_plugin",
  127. plugin_bin="tls_plugin.py",
  128. plugin_proto="IVSPlg"
  129. )
  130. # 4. 构造任务组配置
  131. group_config = GroupConfig(
  132. identifier="London_France_Visas", # 组名
  133. enable=True, # 启用
  134. need_account=True, # 需要登录账号
  135. account_pool="gb_fr", # 使用 AccountManager 中的 uk_pool (在 account_manager.py 中预设)
  136. need_proxy=True, # 需要代理
  137. proxy_pool="global_proxy", # 使用 ProxyManager 中的 global_proxy
  138. need_ip_bind=False, # 不强制 IP 绑定
  139. account_login_interval=10, # 登录失败/成功后锁定账号 10 分钟
  140. target_instances=1, # 启动 2 个并发实例 (线程)
  141. query_wait=query_wait_config,
  142. plugin_config=plugin_config,
  143. free_config=json.dumps(tls_config) # 将业务配置转为 JSON 字符串
  144. )
  145. # 5. 创建协调器
  146. coordinator = GroupCoordinator(group_config)
  147. # 6. 设置回调 (模拟 WebSocket 推送或日志记录)
  148. def my_push_callback(type_code: int, data: bytes, size: int):
  149. msg = data.decode('utf-8')
  150. VSC_INFO("main", ">>> [PUSH CALLBACK] Type: %d, Message: %s", type_code, msg)
  151. coordinator.set_push_callback(my_push_callback)
  152. # 7. 启动
  153. try:
  154. VSC_INFO("main", "========================================")
  155. VSC_INFO("main", " TLS Python Plugin Tester ")
  156. VSC_INFO("main", "========================================")
  157. coordinator.start()
  158. time.sleep(3600)
  159. except KeyboardInterrupt:
  160. VSC_INFO("main", "Ctrl+C detected. Stopping...")
  161. except Exception as e:
  162. VSC_ERROR("main", "Unexpected Error: %s", str(e))
  163. finally:
  164. # 8. 停止
  165. coordinator.stop()
  166. VSC_INFO("main", "Program finished.")
  167. def bls_test():
  168. # 0. 环境检查
  169. if not os.path.exists("plugins/bls_plugin.py"):
  170. print("[ERROR] 找不到插件文件 'plugins/bls_plugin.py'")
  171. return
  172. # 2. 准备 BLS 业务配置 (Free Config)
  173. # 这些字段会被 BlsPlugin 读取并用于填表和逻辑判断
  174. bls_config = {
  175. "domain": "ireland.blsspainglobal.com", # 目标域名
  176. "ocr_service_url": "http://127.0.0.1:8085/predict/vfcode?model=pytorch", # OCR 服务地址
  177. # 签证参数 (根据实际网站下拉框的值填写)
  178. "location": "Dublin",
  179. "jurisdiction": None,
  180. "visaType": "Schengen Visa/ Short Term Visa",
  181. "visaSubType": "Tourist Visa",
  182. "appointmentCategory": "Normal",
  183. # 申请人信息 (用于 book 阶段)
  184. "user_info": {
  185. "first_name": "John",
  186. "last_name": "Doe",
  187. "passport_no": "E12345678",
  188. "passport_issue_date": "2020-01-01",
  189. "passport_expiry_date": "2030-01-01",
  190. "birthday": "1990-01-01",
  191. "phone_no": "447700900000",
  192. "nationality": "India",
  193. "gender": "Male",
  194. "passport_image_url": "https://via.placeholder.com/600x400.jpg" # 模拟图片URL
  195. }
  196. }
  197. # 3. 构造查询策略
  198. query_wait_config = QueryWaitConfig(
  199. mode=QueryWaitMode.Fixed,
  200. fixed_wait=10 # 每次查询间隔 10 秒
  201. )
  202. # 4. 构造插件配置
  203. # plugin_name="bls_plugin" -> 自动推导类名 "BlsPlugin"
  204. plugin_config = PluginConfig(
  205. lib_path="plugins",
  206. plugin_name="bls_plugin",
  207. plugin_bin="bls_plugin.py",
  208. plugin_proto="IVSPlg"
  209. )
  210. # 5. 构造任务组配置
  211. group_config = GroupConfig(
  212. identifier="Dublin_Spain_Visas", # 任务组 ID
  213. enable=True,
  214. need_account=True,
  215. account_pool="ie_es", # 使用刚才注入的池子
  216. need_proxy=True,
  217. proxy_pool="local", # 使用默认代理池
  218. target_instances=1, # 启动 1 个实例
  219. account_login_interval=5, # 登录间隔/锁定时间
  220. query_wait=query_wait_config,
  221. plugin_config=plugin_config,
  222. free_config=json.dumps(bls_config)
  223. )
  224. # 6. 创建协调器
  225. coordinator = GroupCoordinator(group_config)
  226. # 7. 设置回调 (监听抢票成功消息)
  227. def push_callback(type_code, data, size):
  228. msg = data.decode('utf-8')
  229. VSC_INFO("CALLBACK", f"Received Push: Type={type_code}, Msg={msg}")
  230. coordinator.set_push_callback(push_callback)
  231. # 8. 启动运行
  232. try:
  233. VSC_INFO("main", ">>> Starting BLS Plugin Test...")
  234. coordinator.start()
  235. time.sleep(3600)
  236. except KeyboardInterrupt:
  237. VSC_INFO("main", "Ctrl+C detected.")
  238. except Exception as e:
  239. VSC_ERROR("main", f"Unexpected Error: {e}")
  240. finally:
  241. coordinator.stop()
  242. VSC_INFO("main", "Test Finished.")
  243. if __name__ == "__main__":
  244. vfs_test()