ソースを参照

clash 工具增加已选节点检测

jack 8 ヶ月 前
コミット
bfc2e89eee
3 ファイル変更92 行追加28 行削除
  1. 64 23
      models/clash_tools.py
  2. 2 1
      security/ir.model.access.csv
  3. 26 4
      views/view_clash_tools.xml

+ 64 - 23
models/clash_tools.py

@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 from concurrent.futures import ThreadPoolExecutor, as_completed
-from odoo import fields, models
+from odoo import fields, models, api
 from odoo.exceptions import UserError
 from urllib.parse import quote
 import httpx
@@ -19,8 +19,6 @@ class ClashTools(models.Model):
 
     current_node = fields.Char('Current Node')
 
-    skip_node = fields.Char('Skip Node', help='Use semicolons to separate')
-
     total_nodes = fields.Integer('Total Nodes')
 
     use_type = fields.Selection([
@@ -28,8 +26,12 @@ class ClashTools(models.Model):
         ('depin', 'Depin'),
     ], string='Use Type', default='')
 
+    current_node_state = fields.Char('Current Node State')
+
     line_ids = fields.One2many('clash.tools.line', 'clash_tools_id', string='Line')
 
+    clash_no_skip_config_id = fields.Many2one('clash.no_skip.config', string='Clash Skip Config')
+
     def btn_init_data(self):
         # 一键创建所有局域网中的 clash 连接, 因为懒
         data_dict = {
@@ -175,25 +177,29 @@ class ClashTools(models.Model):
             line_delay_min = self.line_ids.search([('clash_tools_id', '=', rec.id), ('node_state', '=', 'ok')], order='delay asc')
 
             for line in line_delay_min:
-                if rec.skip_node:
+                if rec.clash_no_skip_config_id:
                     try:
-                        skip_node_list = rec.skip_node.split(';')
+                        no_skip_node_list = rec.clash_no_skip_config_id.no_skip_domains.split(';')
                     except:
                         raise UserError('Please enter the node name to skip, separated by semicolons.')
 
-                    # 查看是否存在需要跳过的节点, 如果是, 则跳过
-                    for skip_node in skip_node_list:
-                        if skip_node in line.name:
-                            continue
-                        else:
-                            # 这里不是跳过, 然后检查一下有没使用过这个节点
-                            if line.name in selected_node_list:
-                                continue
-                            else:
-                                # 这里是既不是跳过, 有没有使用过, 就使用这个节点
-                                self._use_select_node(line)
-                                selected_node_list.append(line.name)
-                                break
+                    # 查看是否存在不需要跳过的节点, 如果是, 查看有没有使用过这个节点, 如果使用过, 就跳过
+                    # 如果没有使用过, 则使用这个节点, 之后将这个节点添加到已使用列表中
+                    # 判定节点的时候, 部分节点是英文, 所以需要统一一下大小写
+                    selected = False
+                    for no_skip_node in no_skip_node_list:
+                        if line.name in selected_node_list:
+                            break
+
+                        if no_skip_node.strip().lower() in line.name.lower():
+                            self._use_select_node(line)
+                            selected_node_list.append(line.name)
+                            selected = True
+                            break
+
+                    if selected:
+                        break
+
                 else:
                     # 如果跳过节点的条件为空, 则判断是否使用过这个节点, 没有就使用
                     if line.name in selected_node_list:
@@ -203,6 +209,23 @@ class ClashTools(models.Model):
                     selected_node_list.append(line.name)
                     break
 
+    def btn_check_current_node(self):
+        for rec in self:
+            if not rec.localhost_ip or not rec.line_ids or not rec.current_node:
+                continue
+
+            url = rec.localhost_ip
+            if 'https' in url:
+                raise UserError('Local network services do not require HTTPS.')
+            if 'http' not in url:
+                url = 'http://' + url
+
+            result = self._check_node(quote(rec.current_node, safe=""), url)
+            if result != 9999:
+                rec.current_node_state = ';'.join([f'{k}:{v}' for k, v in result.items()])
+            else:
+                rec.current_node_state = 'error'
+
     def _set_global_proxy(self, url, rec):
         setting_url = url + '/api/configs'
 
@@ -246,12 +269,17 @@ class ClashTools(models.Model):
         }
 
         response = httpx.get(proxies_list_url, headers=headers)
-
-        result = []
-
         proxies_list = response.json()
-        for proxies in proxies_list.get('proxies'):
-            result.append(proxies)
+
+        if self.clash_no_skip_config_id:
+            try:
+                skip_node_list = self.clash_no_skip_config_id.no_skip_domains.split(';')
+                skip_node_set = {node.lower() for node in skip_node_list}
+                result = [proxies for proxies in proxies_list.get('proxies') if any(skip_node in proxies.lower() for skip_node in skip_node_set)]
+            except Exception as e:
+                raise UserError(f'{self.name} Please enter the node name to skip, separated by semicolons.\nerror: {e}')
+        else:
+            result = proxies_list.get('proxies', [])
 
         return result
 
@@ -405,3 +433,16 @@ class ClashToolsLine(models.Model):
                 'mean_delay': res,
                 'node_state': 'error'
             })
+
+
+class ClashSkipConfig(models.Model):
+    _name = 'clash.no_skip.config'
+    _description = 'Clash No Skip Config'
+
+    name = fields.Char('Name')
+    no_skip_domains = fields.Char('No Skip Domains')
+
+    @api.depends('name', 'no_skip_domains')
+    def _compute_display_name(self):
+        for record in self:
+            record.display_name = f'{record.name} - {record.no_skip_domains}'

+ 2 - 1
security/ir.model.access.csv

@@ -5,4 +5,5 @@ access_home_page_access,"Home Page",model_home_page,base.group_user,1,1,1,1
 access_codes_access,"Home Codes Access",model_codes,base.group_user,1,1,1,1
 
 access_clash_tools_access,"Home Clash Tools Access",model_clash_tools,base.group_user,1,1,1,1
-access_clash_tools_line_access,"Home Clash Tools Line Access",model_clash_tools_line,base.group_user,1,1,1,1
+access_clash_tools_line_access,"Home Clash Tools Line Access",model_clash_tools_line,base.group_user,1,1,1,1
+access_clash_no_skip_config_access,"Home Clash NO Skip Config Access",model_clash_no_skip_config,base.group_user,1,1,1,1

+ 26 - 4
views/view_clash_tools.xml

@@ -10,13 +10,15 @@
                     <button name="btn_get_all_node" type="object" string="Get All Proxy" class="oe_highlight"/>
                     <button name="btn_check_all_node" type="object" string="Check All Proxy" class="oe_highlight"/>
                     <button name="btn_select_node" type="object" string="Select Node" class="oe_highlight"/>
+                    <button name="btn_check_current_node" type="object" string="Check Current Node" class="oe_highlight"/>
                 </header>
                 <field name="name"/>
                 <field name="localhost_ip"/>
                 <field name="api_ip"/>
                 <field name="total_nodes"/>
                 <field name="current_node"/>
-                <field name="skip_node"/>
+                <field name="current_node_state"/>
+                <field name="clash_no_skip_config_id"/>
                 <field name="use_type"/>
             </list>
         </field>
@@ -31,6 +33,7 @@
                     <button name="btn_get_all_node" type="object" string="Get All Node" class="oe_highlight"/>
                     <button name="btn_check_all_node" type="object" string="Check All Node" class="oe_highlight"/>
                     <button name="btn_select_node" type="object" string="Select Node" class="oe_highlight"/>
+                    <button name="btn_check_current_node" type="object" string="Check Current Node" class="oe_highlight"/>
                 </header>
                 <sheet>
                     <group>
@@ -38,12 +41,13 @@
                             <field name="name"/>
                             <field name="total_nodes" readonly="True"/>
                             <field name="current_node" readonly="True"/>
+                            <field name="current_node_state" readonly="True"/>
                             <field name="use_type" widget="selection"/>
                         </group>
                         <group>
                             <field name="localhost_ip"/>
                             <field name="api_ip"/>
-                            <field name="skip_node"/>
+                            <field name="clash_no_skip_config_id" options="{'no_create': True, 'no_create_edit': True}"/>
                         </group>
                     </group>
                     <notebook>
@@ -79,6 +83,24 @@
         </field>
     </record>
 
+    <record id="view_clash_no_skip_config" model="ir.ui.view">
+        <field name="name">clash.no_skip.config</field>
+        <field name="model">clash.no_skip.config</field>
+        <field name="arch" type="xml">
+            <list string="Clash No Skip Config" editable="bottom" create="true" delete="true">
+                <field name="name"/>
+                <field name="no_skip_domains"/>
+            </list>
+        </field>
+    </record>
+
+    <record id="action_clash_no_skip_config" model="ir.actions.act_window">
+        <field name="name">No Skip Config</field>
+        <field name="res_model">clash.no_skip.config</field>
+        <field name="view_mode">list</field>
+    </record>
+
+
     <record id="action_clash_tools" model="ir.actions.act_window">
         <field name="name">Clash Tools</field>
         <field name="res_model">clash.tools</field>
@@ -87,7 +109,7 @@
     </record>
 
     <menuitem id="menu_clash_tools" name="Clash Tools" parent="menu_home_page" sequence="9"/>
-    <menuitem id="menu_clash_tools_clash_tools" name="Clash Tools" parent="menu_clash_tools" action="action_clash_tools"
-              sequence="1"/>
+    <menuitem id="menu_clash_tools_clash_tools" name="Clash Tools" parent="menu_clash_tools" action="action_clash_tools" sequence="1"/>
+    <menuitem id="menu_clash_no_skip_config" name="No Skip Config" parent="menu_clash_tools" action="action_clash_no_skip_config" sequence="2"/>
 
 </odoo>