Skip to content

Commit d6d4cfe

Browse files
committed
fix(automation): robust company name extraction and filename sanitization
1 parent facc926 commit d6d4cfe

2 files changed

Lines changed: 33 additions & 8 deletions

File tree

src/automation/screenshot.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,20 @@ const { delay } = require('./utils');
1414
function formatFilename(pattern, nationalId, company) {
1515
if (!pattern) pattern = '{id}_{code}';
1616

17-
// Sanitize company name for filesystem (remove \/:*?"<>| and control characters)
18-
const safeName = (company.name || '').replace(/[\\\\/:*?"<>|\\x00-\\x1F\\x7F]/g, '_');
17+
// Sanitize company name: replace forbidden chars and whitespace with underscores
18+
let safeName = (company.name || '')
19+
.trim()
20+
.replace(/[\\/:*?"<>| \t\n\r\f\v\x00-\x1F\x7F]/g, '_');
21+
22+
// Replace multiple internal underscores with a single one for cleaner names
23+
safeName = safeName.replace(/_+/g, '_').replace(/^_+|_+$/g, '');
24+
25+
const nameToUse = safeName || 'noname';
1926

2027
return pattern
21-
.replace(/{id}/g, nationalId)
22-
.replace(/{code}/g, company.code)
23-
.replace(/{name}/g, safeName);
28+
.replace(/{id}/g, nationalId || 'unknown')
29+
.replace(/{code}/g, company.code || 'unknown')
30+
.replace(/{name}/g, nameToUse);
2431
}
2532

2633
/**

src/automation/voting.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,27 @@ async function getCompanyList(webContents, sendLog) {
2626
const cells = row.querySelectorAll('td');
2727
if (cells.length < 1) return null;
2828
29-
const companyInfo = cells[0].innerText.trim().split(/\\s+/);
30-
const code = companyInfo[0];
31-
const name = companyInfo.length > 1 ? companyInfo.slice(1).join(' ') : '未知公司';
29+
// Prefer hidden input for accuracy (handles English names better)
30+
// Search row-wide for the input
31+
const nameInput = row.querySelector('input[id^="stockName_"]');
32+
let code, name;
33+
34+
if (nameInput) {
35+
name = nameInput.value.trim();
36+
code = nameInput.id.replace('stockName_', '');
37+
} else {
38+
const text = cells[0].innerText.trim();
39+
// Match at least 4 digits at start, then optional separator, then name
40+
const match = text.match(/^(\\d{4,})(?:\\s+|(?=[^\\d]))(.*)$/s);
41+
if (match) {
42+
code = match[1];
43+
name = match[2].trim() || '未知公司';
44+
} else {
45+
const companyInfo = text.split(/\\s+/);
46+
code = companyInfo[0];
47+
name = companyInfo.length > 1 ? companyInfo.slice(1).join(' ') : '未知公司';
48+
}
49+
}
3250
3351
const links = Array.from(row.querySelectorAll('a.c-actLink, a.u-link'));
3452
const hasVote = links.some(a => ['投票', 'Vote'].some(kw => a.innerText.includes(kw)));

0 commit comments

Comments
 (0)