153 lines
4.2 KiB
JavaScript
153 lines
4.2 KiB
JavaScript
const { readFileSync, writeFileSync, readdirSync, existsSync } = require('node:fs');
|
|
const { resolve } = require('node:path');
|
|
|
|
const VAULT_ROOT = resolve(__dirname, '..', '..');
|
|
const PERSONS_DIR = resolve(VAULT_ROOT, '00 Kontext/Personen');
|
|
const COMPANIES_DIR = resolve(VAULT_ROOT, '00 Kontext/Firmen');
|
|
|
|
function parseFrontmatter(content) {
|
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
if (!match) return {};
|
|
|
|
const fm = {};
|
|
for (const line of match[1].split('\n')) {
|
|
const colonIdx = line.indexOf(':');
|
|
if (colonIdx === -1) continue;
|
|
const key = line.substring(0, colonIdx).trim();
|
|
let value = line.substring(colonIdx + 1).trim();
|
|
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
(value.startsWith("'") && value.endsWith("'"))) {
|
|
value = value.slice(1, -1);
|
|
}
|
|
if (value.startsWith('[') || value.startsWith('{')) continue;
|
|
fm[key] = value;
|
|
}
|
|
return fm;
|
|
}
|
|
|
|
function loadPersons() {
|
|
if (!existsSync(PERSONS_DIR)) return [];
|
|
return readdirSync(PERSONS_DIR)
|
|
.filter(f => f.endsWith('.md'))
|
|
.map(file => {
|
|
const content = readFileSync(resolve(PERSONS_DIR, file), 'utf-8');
|
|
return { file, fm: parseFrontmatter(content) };
|
|
});
|
|
}
|
|
|
|
function loadCompanies() {
|
|
if (!existsSync(COMPANIES_DIR)) return [];
|
|
return readdirSync(COMPANIES_DIR)
|
|
.filter(f => f.endsWith('.md'))
|
|
.map(file => {
|
|
const content = readFileSync(resolve(COMPANIES_DIR, file), 'utf-8');
|
|
return { file, fm: parseFrontmatter(content) };
|
|
});
|
|
}
|
|
|
|
function matchAttendeeToPersons(attendee, persons) {
|
|
const emailMatch = persons.find(p =>
|
|
p.fm.email && p.fm.email.toLowerCase() === attendee.email.toLowerCase()
|
|
);
|
|
if (emailMatch) {
|
|
return { matched: true, file: emailMatch.file, matchType: 'email' };
|
|
}
|
|
|
|
const nameMatch = persons.find(p => {
|
|
const fullName = `${p.fm.vorname || ''} ${p.fm.nachname || ''}`.trim().toLowerCase();
|
|
return fullName && fullName === attendee.name.toLowerCase();
|
|
});
|
|
if (nameMatch) {
|
|
return { matched: true, file: nameMatch.file, matchType: 'name' };
|
|
}
|
|
|
|
return { matched: false };
|
|
}
|
|
|
|
function resolveCompanyFromDomain(email, companies) {
|
|
const domain = email.split('@')[1]?.toLowerCase();
|
|
if (!domain) return '';
|
|
|
|
const match = companies.find(c =>
|
|
c.fm.domain && c.fm.domain.toLowerCase() === domain
|
|
);
|
|
if (match) {
|
|
const name = match.file.replace('.md', '');
|
|
return `[[00 Kontext/Firmen/${name}]]`;
|
|
}
|
|
|
|
return domain;
|
|
}
|
|
|
|
function splitName(displayName) {
|
|
const parts = displayName.trim().split(/\s+/);
|
|
if (parts.length === 1) {
|
|
return { vorname: parts[0], nachname: '' };
|
|
}
|
|
const nachname = parts.pop();
|
|
return { vorname: parts.join(' '), nachname };
|
|
}
|
|
|
|
function buildNewPersonNote({ name, email, firma }) {
|
|
const { vorname, nachname } = splitName(name);
|
|
|
|
return `---
|
|
tags: [person]
|
|
vorname: ${vorname}
|
|
nachname: ${nachname ? nachname : '""'}
|
|
email: ${email}
|
|
kategorie: Extern
|
|
firma: "${firma}"
|
|
status: ungeprüft
|
|
---
|
|
|
|
# ${name}
|
|
|
|
## Zur Person
|
|
|
|
- **E-Mail:** ${email}
|
|
- **Firma:** ${firma}
|
|
|
|
## Notizen
|
|
|
|
`;
|
|
}
|
|
|
|
function createPersonNote({ name, email }, companies) {
|
|
const firma = resolveCompanyFromDomain(email, companies);
|
|
const content = buildNewPersonNote({ name, email, firma });
|
|
const { vorname, nachname } = splitName(name);
|
|
const fileName = nachname ? `${vorname} ${nachname}.md` : `${vorname}.md`;
|
|
const filePath = resolve(PERSONS_DIR, fileName);
|
|
|
|
if (!existsSync(filePath)) {
|
|
writeFileSync(filePath, content, 'utf-8');
|
|
}
|
|
|
|
return fileName;
|
|
}
|
|
|
|
function resolveAttendees(attendees) {
|
|
const persons = loadPersons();
|
|
const companies = loadCompanies();
|
|
|
|
return attendees.map(attendee => {
|
|
const match = matchAttendeeToPersons(attendee, persons);
|
|
|
|
if (match.matched) {
|
|
const personName = match.file.replace('.md', '');
|
|
return { wikilink: `[[${personName}]]`, name: attendee.name, isNew: false };
|
|
}
|
|
|
|
const fileName = createPersonNote(attendee, companies);
|
|
const personName = fileName.replace('.md', '');
|
|
return { wikilink: `[[${personName}]]`, name: attendee.name, isNew: true };
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
parseFrontmatter, loadPersons, loadCompanies,
|
|
matchAttendeeToPersons, resolveCompanyFromDomain,
|
|
buildNewPersonNote, createPersonNote, resolveAttendees
|
|
};
|