-
OTAMan SIM OTA with a Human Face v1.9.2
+
OTAMan SIM OTA with a Human Face v1.9.3
github
@@ -921,8 +921,12 @@
-
+
+
+
+
+
@@ -997,9 +1001,13 @@
-
-
-
+
+
+
+
+
+
+
@@ -4291,9 +4299,22 @@ function cardsExport() {
el.select();
}
-async function cardsImport() {
+function downloadJson(name, obj) {
+ const blob = new Blob([JSON.stringify(obj, null, 2)], {type: 'application/json'});
+ const a = document.createElement('a');
+ a.href = URL.createObjectURL(blob);
+ a.download = name;
+ a.click();
+ URL.revokeObjectURL(a.href);
+}
+
+function cardsExportFile() {
+ downloadJson('otaman-cards.json', cards);
+}
+
+async function cardsImport(text) {
try {
- const text = await navigator.clipboard.readText();
+ if (text == null) text = await navigator.clipboard.readText();
const imported = JSON.parse(text);
if (!Array.isArray(imported)) throw new Error('Expected an array');
let added = 0;
@@ -4324,6 +4345,25 @@ async function cardsImport() {
}
}
+function cardsImportFile(input) {
+ const file = input.files && input.files[0];
+ input.value = '';
+ if (!file) return;
+ const reader = new FileReader();
+ reader.onload = () => cardsImport(reader.result);
+ reader.readAsText(file);
+}
+
+function cardsImportField() {
+ const el = document.getElementById('cards-io');
+ const val = el.value.trim();
+ if (!el.classList.contains('hidden') && val.startsWith('[')) { cardsImport(val); return; }
+ el.value = '';
+ el.placeholder = 'Paste JSON array here, then press Paste & import again';
+ el.classList.remove('hidden');
+ el.focus();
+}
+
// ===== pysim sub-tabs =====
let pysimCmdHistory = [];
let pysimCmdHistIdx = -1;
@@ -5706,9 +5746,13 @@ function pysimCustomExport() {
el.select();
}
-async function pysimCustomImport() {
+function pysimCustomExportFile() {
+ downloadJson('otaman-custom-files.json', pysimCustomFiles);
+}
+
+async function pysimCustomImport(text) {
try {
- const text = await navigator.clipboard.readText();
+ if (text == null) text = await navigator.clipboard.readText();
const imported = JSON.parse(text);
if (!Array.isArray(imported)) throw new Error('Expected an array');
let added = 0;
@@ -5736,6 +5780,25 @@ async function pysimCustomImport() {
}
}
+function pysimCustomImportFile(input) {
+ const file = input.files && input.files[0];
+ input.value = '';
+ if (!file) return;
+ const reader = new FileReader();
+ reader.onload = () => pysimCustomImport(reader.result);
+ reader.readAsText(file);
+}
+
+function pysimCustomImportField() {
+ const el = document.getElementById('pysim-cf-io');
+ const val = el.value.trim();
+ if (!el.classList.contains('hidden') && val.startsWith('[')) { pysimCustomImport(val); return; }
+ el.value = '';
+ el.placeholder = 'Paste JSON array here, then press Paste & import again';
+ el.classList.remove('hidden');
+ el.focus();
+}
+
// Init custom files
pysimCustomLoad();
@@ -5833,6 +5896,9 @@ const LANG_RU = {
'Card presets are stored locally in your browser. JSON export/import buttons are below the card list.': 'Данные карт хранятся локально в браузере. Кнопки экспорта/импорта JSON — под списком карт.',
'Add': 'Добавить',
'Export as JSON': 'Экспорт в JSON',
+ 'Export to file': 'Экспорт в файл',
+ 'Import from file': 'Импорт из файла',
+ 'Paste & import': 'Вставить и импортировать',
'Import JSON from clipboard': 'Импорт JSON из буфера',
'Name': 'Имя',
'ICCID': 'ICCID',
diff --git a/frontend/sw.js b/frontend/sw.js
index 3c9fcbd..4af3d94 100644
--- a/frontend/sw.js
+++ b/frontend/sw.js
@@ -1,4 +1,4 @@
-const CACHE = 'otaman-v13';
+const CACHE = 'otaman-v14';
const URLS = [
'index.html',
'help.html',
diff --git a/pyproject.toml b/pyproject.toml
index 553e1b7..d14e4bb 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "pysim-otaman-server"
-version = "1.9.2"
+version = "1.9.3"
description = "HTTP REST server wrapping pysim for the OTAMan PWA"
requires-python = ">=3.8"
# pysim is a git-only dependency installed explicitly by setup.bat/setup.sh.
diff --git a/pysim_otaman_server/server.py b/pysim_otaman_server/server.py
index 9a3e24d..363b149 100644
--- a/pysim_otaman_server/server.py
+++ b/pysim_otaman_server/server.py
@@ -18,7 +18,7 @@ from osmocom.construct import GsmOrUcs2Adapter
from osmocom.tlv import BER_TLV_IE
-VERSION = '1.9.2'
+VERSION = '1.9.3'
# Static file serving (the PWA lives in
/frontend, served by this server