134 lines
5.1 KiB
JavaScript
134 lines
5.1 KiB
JavaScript
const pool = require('../config/db');
|
|
const cheerio = require('cheerio');
|
|
const { logActivity } = require('../services/activityLog');
|
|
|
|
const MONTHS_FR = {
|
|
'janv': '01', 'janvier': '01', 'févr': '02', 'février': '02', 'fevrier': '02',
|
|
'mars': '03', 'avr': '04', 'avril': '04', 'mai': '05', 'juin': '06',
|
|
'juil': '07', 'juillet': '07', 'août': '08', 'aout': '08',
|
|
'sept': '09', 'septembre': '09', 'oct': '10', 'octobre': '10',
|
|
'nov': '11', 'novembre': '11', 'déc': '12', 'décembre': '12', 'decembre': '12'
|
|
};
|
|
|
|
function parseFrenchDate(str) {
|
|
const m = str.trim().match(/^(\d+)\s+(\S+)\s+(\d{4})$/);
|
|
if (!m) return null;
|
|
const month = MONTHS_FR[m[2].toLowerCase().replace(/\.$/, '')];
|
|
if (!month) return null;
|
|
return `${m[3]}-${month}-${m[1].padStart(2, '0')}`;
|
|
}
|
|
|
|
exports.list = async (req, res) => {
|
|
try {
|
|
const [rows] = await pool.query('SELECT * FROM evenements ORDER BY date ASC');
|
|
res.json(rows);
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Server error' });
|
|
}
|
|
};
|
|
|
|
exports.create = async (req, res) => {
|
|
try {
|
|
const { date, nom_evenement, lieu, horaire } = req.body;
|
|
if (!date || !nom_evenement) {
|
|
return res.status(400).json({ error: 'Date and name required' });
|
|
}
|
|
const [result] = await pool.query(
|
|
'INSERT INTO evenements (date, nom_evenement, lieu, horaire) VALUES (?, ?, ?, ?)',
|
|
[date, nom_evenement, lieu || null, horaire || null]
|
|
);
|
|
res.status(201).json({ id: result.insertId, message: 'Event created' });
|
|
logActivity(req, 'evenement_ajout', { date, nom_evenement });
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Server error' });
|
|
}
|
|
};
|
|
|
|
exports.update = async (req, res) => {
|
|
try {
|
|
const { date, nom_evenement, lieu, horaire } = req.body;
|
|
await pool.query(
|
|
'UPDATE evenements SET date = ?, nom_evenement = ?, lieu = ?, horaire = ? WHERE id = ?',
|
|
[date, nom_evenement, lieu || null, horaire || null, req.params.id]
|
|
);
|
|
res.json({ message: 'Updated' });
|
|
logActivity(req, 'evenement_modification', { id: req.params.id, date, nom_evenement });
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Server error' });
|
|
}
|
|
};
|
|
|
|
exports.remove = async (req, res) => {
|
|
try {
|
|
await pool.query('DELETE FROM evenements WHERE id = ?', [req.params.id]);
|
|
res.json({ message: 'Deleted' });
|
|
logActivity(req, 'evenement_suppression', { id: req.params.id });
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Server error' });
|
|
}
|
|
};
|
|
|
|
exports.deletePast = async (req, res) => {
|
|
try {
|
|
const [result] = await pool.query('DELETE FROM evenements WHERE date < CURDATE()');
|
|
res.json({ message: `${result.affectedRows} événement(s) supprimé(s)` });
|
|
logActivity(req, 'evenements_passes_supprimes', { count: result.affectedRows });
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Server error' });
|
|
}
|
|
};
|
|
|
|
exports.scrape = async (req, res) => {
|
|
try {
|
|
const url = 'https://www.rencontres-dirigeants.com/nos-rencontres?region=11&startAt=&endAt=&dateRange=&format=&agency%5B%5D=289&department=';
|
|
const resp = await fetch(url);
|
|
const html = await resp.text();
|
|
const $ = cheerio.load(html);
|
|
|
|
const candidates = [];
|
|
|
|
$('article, [class*="card"], [class*="event"], [class*="rencontre"]').each((i, el) => {
|
|
const text = $(el).text();
|
|
const lines = text.split('\n').map(l => l.trim()).filter(Boolean);
|
|
|
|
let location = '', dateStr = '', timeStr = '';
|
|
for (const line of lines) {
|
|
if (!location && line.length > 3 && line[0] === line[0].toUpperCase() && !line.includes('€') && !line.includes('Participation') && !line.includes('places')) {
|
|
location = line;
|
|
}
|
|
const dateMatch = line.match(/(\d{1,2}\s+\S+\s+\d{4})/);
|
|
if (dateMatch && !dateStr) dateStr = dateMatch[1];
|
|
const timeMatch = line.match(/(\d{2}h\d{2})\s*[àa]\s*(\d{2}h\d{2})/);
|
|
if (timeMatch && !timeStr) timeStr = `${timeMatch[1]} - ${timeMatch[2]}`;
|
|
}
|
|
|
|
if (!dateStr) return;
|
|
const isoDate = parseFrenchDate(dateStr);
|
|
if (!isoDate) return;
|
|
candidates.push({ isoDate, location, timeStr });
|
|
});
|
|
|
|
const imported = [];
|
|
for (const c of candidates) {
|
|
const [existing] = await pool.query('SELECT id FROM evenements WHERE date = ? AND nom_evenement LIKE ?', [c.isoDate, `%Rencontre%`]);
|
|
if (existing.length > 0) continue;
|
|
const title = c.location ? `Rencontre dirigeants - ${c.location}` : 'Rencontre dirigeants Dynabuy';
|
|
await pool.query(
|
|
'INSERT INTO evenements (date, nom_evenement, lieu, horaire) VALUES (?, ?, ?, ?)',
|
|
[c.isoDate, title, c.location || null, c.timeStr || null]
|
|
);
|
|
imported.push({ date: c.isoDate, title, location: c.location, time: c.timeStr });
|
|
}
|
|
|
|
res.json({ message: `${imported.length} événement(s) importé(s)`, events: imported });
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Erreur lors de l\'import: ' + err.message });
|
|
}
|
|
};
|