Угрозы: список сортируется по возрастанию кода УБИ (УБИ.001 → УБИ.211) во всех местах — подбор программой, ИИ, автозаполнение, импорт, добавление недостающих

This commit is contained in:
LocoAgent
2026-08-05 14:14:06 +04:00
parent c9dffdd4ca
commit 52b4ee6f1a
2 changed files with 50 additions and 13 deletions
+21 -3
View File
@@ -11,6 +11,24 @@
import os import os
import json import json
import re
def _ubi_num(text):
"""Код УБИ из строки → int: «УБИ.069 Название» → 69. None, если кода нет."""
m = re.search(r'уби\.?\s*(\d+)', str(text), re.IGNORECASE)
return int(m.group(1)) if m else None
def sort_threats_by_ubi(items):
"""Сортировка угроз по возрастанию кода УБИ (УБИ.001, УБИ.002, …).
Строки без кода УБИ уходят в конец (по алфавиту).
"""
def _key(t):
n = _ubi_num(t)
return (0, n) if n is not None else (1, str(t).lower())
return sorted(items, key=_key)
def load_threats(dict_dir=None): def load_threats(dict_dir=None):
@@ -244,9 +262,9 @@ def suggest_threats_program(isys, threats=None, limit=None):
sc = sum(1 for kw in pos if kw in tl) sc = sum(1 for kw in pos if kw in tl)
scored.append((sc, t)) scored.append((sc, t))
# Сортируем по релевантности (сначала — с наибольшим совпадением) # Сортируем по возрастанию кода УБИ (УБИ.001 → УБИ.211…)
scored.sort(key=lambda x: -x[0]) scored = [t for sc, t in scored if sc > 0]
result = [t for sc, t in scored if sc > 0] result = sort_threats_by_ubi(scored)
if limit and len(result) > limit: if limit and len(result) > limit:
result = result[:limit] result = result[:limit]
+29 -10
View File
@@ -1908,9 +1908,12 @@ class DokoGenApp:
w.set(val) w.set(val)
elif isinstance(w, tk.Listbox): elif isinstance(w, tk.Listbox):
w.delete(0, tk.END) w.delete(0, tk.END)
for line in str(val).split('\n'): lines = [ln.strip() for ln in str(val).split('\n') if ln.strip()]
if line.strip(): if model_field == 'threats':
w.insert(tk.END, line.strip()) from .threat_rules import sort_threats_by_ubi
lines = sort_threats_by_ubi(lines)
for line in lines:
w.insert(tk.END, line)
elif isinstance(w, tk.Text): elif isinstance(w, tk.Text):
w.delete('1.0', tk.END) w.delete('1.0', tk.END)
w.insert('1.0', val) w.insert('1.0', val)
@@ -2873,9 +2876,12 @@ class DokoGenApp:
if key in fill and hasattr(self, attr): if key in fill and hasattr(self, attr):
lb = getattr(self, attr) lb = getattr(self, attr)
lb.delete(0, tk.END) lb.delete(0, tk.END)
for line in fill[key].split('\n'): lines = [ln.strip() for ln in fill[key].split('\n') if ln.strip()]
if line.strip(): if key == 'threats':
lb.insert(tk.END, line.strip()) from .threat_rules import sort_threats_by_ubi
lines = sort_threats_by_ubi(lines)
for line in lines:
lb.insert(tk.END, line)
self._collect_is() # сохранить в модель self._collect_is() # сохранить в модель
filled = ', '.join({ filled = ', '.join({
@@ -2911,7 +2917,8 @@ class DokoGenApp:
return return
lb = self.is_threats_listbox lb = self.is_threats_listbox
lb.delete(0, tk.END) lb.delete(0, tk.END)
for t in threats: from .threat_rules import sort_threats_by_ubi
for t in sort_threats_by_ubi(threats):
lb.insert(tk.END, t) lb.insert(tk.END, t)
self._collect_is() # сохранить в модель — галочки в словаре будут стоять self._collect_is() # сохранить в модель — галочки в словаре будут стоять
self.log(f"⚙️ Угрозы подобраны программой: {len(threats)} шт.") self.log(f"⚙️ Угрозы подобраны программой: {len(threats)} шт.")
@@ -3286,6 +3293,12 @@ class DokoGenApp:
existing.add(key) existing.add(key)
added += 1 added += 1
if added: if added:
# сортируем по возрастанию кода УБИ
from .threat_rules import sort_threats_by_ubi
items = [str(lb.get(i)) for i in range(lb.size())]
lb.delete(0, tk.END)
for t in sort_threats_by_ubi(items):
lb.insert(tk.END, t)
self._collect_is() self._collect_is()
self.log(f"➕ Добавлено недостающих угроз (по словарю): {added}") self.log(f"➕ Добавлено недостающих угроз (по словарю): {added}")
else: else:
@@ -3462,15 +3475,21 @@ class DokoGenApp:
e = entries.get(key) e = entries.get(key)
return e.get('1.0', 'end-1c').strip() if e else '' return e.get('1.0', 'end-1c').strip() if e else ''
def _fill_listbox(lb, text): def _fill_listbox(lb, text, sort_ubi=False):
if not lb: if not lb:
return return
lb.delete(0, tk.END) lb.delete(0, tk.END)
import re as _re3 import re as _re3
lines = []
for line in _re3.split(r'[\n,;]+', text or ''): for line in _re3.split(r'[\n,;]+', text or ''):
line = line.strip().lstrip('•-–— ') line = line.strip().lstrip('•-–— ')
if line: if line:
lb.insert(tk.END, line) lines.append(line)
if sort_ubi:
from .threat_rules import sort_threats_by_ubi
lines = sort_threats_by_ubi(lines)
for line in lines:
lb.insert(tk.END, line)
try: try:
if _wanted('attacker_category'): if _wanted('attacker_category'):
@@ -3480,7 +3499,7 @@ class DokoGenApp:
exact = next((v for v in values if v.lower() == val.lower()), None) exact = next((v for v in values if v.lower() == val.lower()), None)
self.is_attacker_category_combo.set(exact or val) self.is_attacker_category_combo.set(exact or val)
if _wanted('threats'): if _wanted('threats'):
_fill_listbox(getattr(self, 'is_threats_listbox', None), _text('threats')) _fill_listbox(getattr(self, 'is_threats_listbox', None), _text('threats'), sort_ubi=True)
if _wanted('incidents'): if _wanted('incidents'):
_fill_listbox(getattr(self, 'is_incidents_listbox', None), _text('incidents')) _fill_listbox(getattr(self, 'is_incidents_listbox', None), _text('incidents'))
if _wanted('criteria_values'): if _wanted('criteria_values'):