feat: add initial implementation of eSodisce / GURS batch helper extension
Publish Firefox extension / publish (push) Successful in 4m21s
Publish Firefox extension / publish (push) Successful in 4m21s
This commit is contained in:
1 parent
902cf5d813
commit
f1a16ddec0
10 files changed
+769
-1
No files matched your search
@@ -0,0 +1,125 @@
|
||||
(() => {
|
||||
if (window.__eprostorGursHelperLoaded) return;
|
||||
window.__eprostorGursHelperLoaded = true;
|
||||
|
||||
const SELECTORS = {
|
||||
koNumber: 'idZnakNep.katastrskaObcina.idsrcsifrant',
|
||||
parcel: 'idZnakNep.parcelnaStevilka'
|
||||
};
|
||||
const LOG_PREFIX = '[eProstor GURS]';
|
||||
let stopRequested = false;
|
||||
let running = false;
|
||||
|
||||
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
const report = (text) => browser.runtime.sendMessage({ type: 'BATCH_STATUS', text }).catch(() => {});
|
||||
const log = (...args) => console.log(LOG_PREFIX, ...args);
|
||||
const logError = (...args) => console.error(LOG_PREFIX, ...args);
|
||||
|
||||
function findField(selector) {
|
||||
// getElementById avoids CSS escaping issues because the literal IDs contain dots.
|
||||
return document.getElementById(selector);
|
||||
}
|
||||
|
||||
function setNativeValue(element, value) {
|
||||
element.focus();
|
||||
const setter = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(element), 'value')?.set;
|
||||
if (setter) setter.call(element, value); else element.value = value;
|
||||
element.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
element.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
}
|
||||
|
||||
async function processRecord(record, index, total, confirmMode) {
|
||||
if (stopRequested) return false;
|
||||
log(`Začetek zapisa ${index + 1}/${total}`, {
|
||||
koNumber: record.koNumber,
|
||||
parcel: record.parcel
|
||||
});
|
||||
const koNumber = findField(SELECTORS.koNumber);
|
||||
const parcel = findField(SELECTORS.parcel);
|
||||
log('Polji najdeni', {
|
||||
koField: SELECTORS.koNumber,
|
||||
koFieldFound: Boolean(koNumber),
|
||||
parcelField: SELECTORS.parcel,
|
||||
parcelFieldFound: Boolean(parcel)
|
||||
});
|
||||
if (!koNumber || !parcel) throw new Error('Polj z ID-jema ni mogoče najti; preverite selectorje v content-script.js.');
|
||||
|
||||
if (confirmMode === 'manual' && !window.confirm(`Obdelam ${index + 1}/${total}: KO ${record.koNumber} / parcela ${record.parcel}?`)) {
|
||||
log(`Zapis ${index + 1}/${total} preskočen na ročno zahtevo`);
|
||||
return true;
|
||||
}
|
||||
log('Neposreden vnos KO', { recordNumber: index + 1, koNumber: record.koNumber });
|
||||
setNativeValue(koNumber, record.koNumber);
|
||||
log('Neposreden vnos parcele', { recordNumber: index + 1, parcel: record.parcel });
|
||||
setNativeValue(parcel, record.parcel);
|
||||
|
||||
const button = document.getElementById('btn_pdf');
|
||||
log('btn_pdf preverjen', { recordNumber: index + 1, found: Boolean(button) });
|
||||
if (!button) throw new Error('Gumba z ID-jem »btn_pdf« ni mogoče najti.');
|
||||
button.click();
|
||||
log('btn_pdf kliknjen', { recordNumber: index + 1 });
|
||||
report(`Zapis ${index + 1}/${total}: vrednosti vnesene in potrjene z gumbom btn_pdf.`);
|
||||
log(`Zapis ${index + 1}/${total} uspešno obdelan`);
|
||||
return true;
|
||||
}
|
||||
|
||||
function describeError(error) {
|
||||
const isObject = error !== null && (typeof error === 'object' || typeof error === 'function');
|
||||
return {
|
||||
message: isObject && error.message !== undefined ? String(error.message) : String(error),
|
||||
name: isObject && error.name !== undefined ? String(error.name) : typeof error,
|
||||
cause: isObject ? error.cause : undefined,
|
||||
stack: isObject ? error.stack : undefined
|
||||
};
|
||||
}
|
||||
|
||||
function getDomDiagnostics() {
|
||||
return {
|
||||
koFieldPresent: Boolean(findField(SELECTORS.koNumber)),
|
||||
parcelFieldPresent: Boolean(findField(SELECTORS.parcel)),
|
||||
btnPdfPresent: Boolean(document.getElementById('btn_pdf'))
|
||||
};
|
||||
}
|
||||
|
||||
browser.runtime.onMessage.addListener(async (message) => {
|
||||
if (message.type === 'STOP_BATCH') {
|
||||
stopRequested = true;
|
||||
log('Zahtev za ustavitev prejet', { state: 'stop-requested' });
|
||||
return { message: 'Ustavljanje…' };
|
||||
}
|
||||
if (message.type !== 'START_BATCH') return undefined;
|
||||
if (running) return { message: 'Obdelava že teče.' };
|
||||
running = true;
|
||||
stopRequested = false;
|
||||
const { records, confirmMode = 'manual', delayMs = 1500 } = message;
|
||||
log('Batch začet', { total: records.length, confirmMode, delayMs });
|
||||
try {
|
||||
for (let i = 0; i < records.length && !stopRequested; i += 1) {
|
||||
try {
|
||||
await processRecord(records[i], i, records.length, confirmMode);
|
||||
} catch (error) {
|
||||
const errorDetails = describeError(error);
|
||||
logError(`Napaka pri zapisu ${i + 1}/${records.length}`, {
|
||||
recordNumber: i + 1,
|
||||
total: records.length,
|
||||
record: records[i],
|
||||
error: errorDetails,
|
||||
dom: getDomDiagnostics()
|
||||
});
|
||||
report(`Zapis ${i + 1}: ${errorDetails.message}`);
|
||||
if (confirmMode === 'manual' && !window.confirm(`Napaka pri zapisu ${i + 1}: ${errorDetails.message}\nNadaljujem?`)) break;
|
||||
}
|
||||
await sleep(delayMs);
|
||||
}
|
||||
const messageText = stopRequested ? 'Obdelava ustavljena.' : 'Obdelava končana.';
|
||||
log(messageText, {
|
||||
state: stopRequested ? 'stopped' : 'completed',
|
||||
total: records.length
|
||||
});
|
||||
report(messageText);
|
||||
return { message: messageText };
|
||||
} finally {
|
||||
running = false;
|
||||
}
|
||||
});
|
||||
})();
|
||||
Reference in new issue
Block a user