From bc6fcc02c26d0896ea3efea78857caa6cb95c888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD=20=D0=A2=D1=80=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Sun, 18 Oct 2026 00:05:21 +0300 Subject: [PATCH] Command filter: two presets, and a "Selected: N" summary (v2.7.2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - the 'Proactive + events' preset is gone: the proactive one (FETCH, TERMINAL PROFILE and the SW 91xx initiators) plus the individual ENVELOPE entry cover it, and its Russian key is removed with it - with several entries checked the filter button now reads "Selected: N" («Выбрано: N») instead of "N commands"; a single entry keeps showing its name and an empty selection stays "All commands" - tests: the removed preset's case is replaced by an absence pin in the menu test, and the summary case follows the new wording; 527 Python + 72 Node tests - README/README_RUS list two presets; PWA_VERSION/pyproject/version.py 2.7.2, SW cache simtrace-analyser-v82 --- README.md | 7 +++---- README_RUS.md | 2 +- frontend/index.html | 12 +++--------- frontend/sw.js | 2 +- frontend/tests/filter.test.js | 13 +++---------- pyproject.toml | 2 +- simtrace_analyser/version.py | 2 +- tests/test_pcap_import.py | 2 +- 8 files changed, 14 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 9c9cb45..7f339ad 100644 --- a/README.md +++ b/README.md @@ -73,10 +73,9 @@ GSMTAP into this analyser. COMPRION trace import (the Device Manager *ISO Protocol Layer* text export), search and a **multi-select command filter** — pick any number of commands and/or the conversation presets (*Proactive sessions*: FETCH, TERMINAL - PROFILE and every command answered with SW 91xx; *Proactive + events*: the - same plus ENVELOPE; *File operations*: SELECT, READ/UPDATE BINARY and - READ/UPDATE RECORD, with the GET RESPONSE carrying a selected command's - data) + PROFILE and every command answered with SW 91xx; *File operations*: SELECT, + READ/UPDATE BINARY and READ/UPDATE RECORD, with the GET RESPONSE carrying a + selected command's data) - Installable PWA, dark theme, English/Russian UI ## Prerequisites diff --git a/README_RUS.md b/README_RUS.md index 8b80907..4532486 100644 --- a/README_RUS.md +++ b/README_RUS.md @@ -76,7 +76,7 @@ SIM/UICC из UDP-потока GSMTAP (или импортирует файлы «ISO Protocol Layer» из Device Manager), поиск и **фильтр команд с множественным выбором** — любые команды и/или готовые пресеты («Проактивные сессии»: FETCH, TERMINAL PROFILE и все команды с ответом SW 91xx; - «Проактивные + события»: то же плюс ENVELOPE; «Файловые операции»: SELECT, + «Файловые операции»: SELECT, READ/UPDATE BINARY и READ/UPDATE RECORD, вместе с GET RESPONSE, несущим данные выбранной команды) - Устанавливаемая PWA, тёмная тема, интерфейс на английском/русском diff --git a/frontend/index.html b/frontend/index.html index ee873da..f43d277 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -2353,11 +2353,6 @@ const FILTER_PRESETS = [ labels: ['FETCH', 'TERMINAL PROFILE'], test: m => _sw1(m) === 0x91, }, - { - id: 'preset:proactive-events', name: 'Proactive + events', - labels: ['FETCH', 'TERMINAL PROFILE', 'ENVELOPE'], - test: m => _sw1(m) === 0x91, - }, { id: 'preset:files', name: 'File operations', labels: ['SELECT', 'READ BINARY', 'READ RECORD', 'UPDATE BINARY', @@ -2383,7 +2378,7 @@ function filterEntryName(entry) { function filterSummary() { if (!STATE.filter.size) return t('All commands'); if (STATE.filter.size === 1) return filterEntryName([...STATE.filter][0]); - return t('{n} commands').replace('{n}', STATE.filter.size); + return t('Selected: {n}').replace('{n}', STATE.filter.size); } let _filterMenuSig = null; @@ -3346,7 +3341,7 @@ function onSearchChange() { } // ──────────────────── Versioning ──────────────────── -const PWA_VERSION = '2.7.1'; +const PWA_VERSION = '2.7.2'; const MIN_SERVER_VERSION = '2.3.0'; function parseVersion(v) { @@ -3384,9 +3379,8 @@ const LANG_RU = { 'Presets': 'Пресеты', 'Commands': 'Команды', 'Proactive sessions': 'Проактивные сессии', - 'Proactive + events': 'Проактивные + события', 'File operations': 'Файловые операции', - '{n} commands': 'команд: {n}', + 'Selected: {n}': 'Выбрано: {n}', 'Filter': 'Фильтр', 'Start Capture': 'Начать захват', 'Stop Capture': 'Остановить захват', diff --git a/frontend/sw.js b/frontend/sw.js index 7b0fe97..4ba80a4 100644 --- a/frontend/sw.js +++ b/frontend/sw.js @@ -1,4 +1,4 @@ -const CACHE = 'simtrace-analyser-v81'; +const CACHE = 'simtrace-analyser-v82'; const PRECACHE = [ 'index.html', diff --git a/frontend/tests/filter.test.js b/frontend/tests/filter.test.js index 6748d56..101124c 100644 --- a/frontend/tests/filter.test.js +++ b/frontend/tests/filter.test.js @@ -100,13 +100,6 @@ test('FETCH and TERMINAL RESPONSE are separate commands now', () => { assert.equal(matchesFilter(gr, 1, set), true); }); -test('the proactive+events preset adds ENVELOPE', () => { - const set = new Set(['preset:proactive-events']); - assert.equal(matchesFilter(msg('ENVELOPE'), 0, set), true); - assert.equal(matchesFilter(msg('FETCH'), 0, set), true); - assert.equal(matchesFilter(msg('SELECT'), 0, set), false); -}); - test('the file-operations preset covers the five commands and their replies', () => { const set = new Set(['preset:files']); for (const name of ['SELECT', 'READ BINARY', 'READ RECORD', 'UPDATE BINARY', @@ -137,7 +130,7 @@ test('the summary follows the selection', () => { STATE.filter.add('preset:files'); assert.equal(filterSummary(), 'File operations'); STATE.filter.add('cmd:FETCH'); - assert.equal(filterSummary(), '2 commands'); + assert.equal(filterSummary(), 'Selected: 2'); }); test('the menu lists the presets and the commands with their counts', () => { @@ -150,8 +143,8 @@ test('the menu lists the presets and the commands with their counts', () => { el = id => (id === 'filter-menu' ? menu : btn); renderFilterMenu(true); assert.match(menu.innerHTML, /data-filter="preset:proactive"/); - assert.match(menu.innerHTML, /data-filter="preset:proactive-events"/); assert.match(menu.innerHTML, /data-filter="preset:files"/); + assert.doesNotMatch(menu.innerHTML, /preset:proactive-events/); assert.match(menu.innerHTML, /data-filter="cmd:SELECT"/); assert.match(menu.innerHTML, /2<\/span>/); assert.match(menu.innerHTML, /data-filter="all" checked>/); @@ -171,7 +164,7 @@ test('the filter strings carry Russian translations', () => { keys.add(m[1].replace(/\\(['\\])/g, '$1')); } for (const s of ['All commands', 'Presets', 'Commands', 'Proactive sessions', - 'Proactive + events', 'File operations', '{n} commands']) { + 'File operations', 'Selected: {n}']) { assert.ok(keys.has(s), 'no LANG_RU entry for: ' + s); } }); diff --git a/pyproject.toml b/pyproject.toml index 19a70ce..25fb775 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.backends._legacy:_Backend" [project] name = "simtrace-analyser" -version = "2.7.1" +version = "2.7.2" description = "SIMtrace Analyser — APDU trace analyser for GSMTAP/PCAP captures (bundles the simtrace2-pysniff utility)" readme = {file = "README.md", content-type = "text/markdown"} license = {text = "GPL-2.0-or-later"} diff --git a/simtrace_analyser/version.py b/simtrace_analyser/version.py index ab1dba1..b20be22 100644 --- a/simtrace_analyser/version.py +++ b/simtrace_analyser/version.py @@ -1,3 +1,3 @@ """Single source of truth for the SIMtrace Analyser version.""" -__version__ = '2.7.1' +__version__ = '2.7.2' diff --git a/tests/test_pcap_import.py b/tests/test_pcap_import.py index ea50f0a..d205187 100644 --- a/tests/test_pcap_import.py +++ b/tests/test_pcap_import.py @@ -224,7 +224,7 @@ class TestImportEndpoint(unittest.TestCase): class TestVersion(unittest.TestCase): def test_package_version(self): from simtrace2_pysniff import __version__ - self.assertEqual(__version__, '2.7.1') + self.assertEqual(__version__, '2.7.2') def test_status_includes_version(self): import os