Inital Commit
This commit is contained in:
215
html/rechner/server.js
Normal file
215
html/rechner/server.js
Normal file
@@ -0,0 +1,215 @@
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const sqlite3 = require('sqlite3').verbose();
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const cron = require('node-cron');
|
||||
const app = express();
|
||||
const port = 3000;
|
||||
|
||||
// Serve static files from the current directory
|
||||
app.use(express.static(__dirname));
|
||||
app.use(bodyParser.json());
|
||||
|
||||
// Create backups directory if it doesn't exist
|
||||
const backupDir = path.join(__dirname, 'backups');
|
||||
if (!fs.existsSync(backupDir)) {
|
||||
fs.mkdirSync(backupDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Database setup
|
||||
const db = new sqlite3.Database('./rechner.db', (err) => {
|
||||
if (err) {
|
||||
console.error('Error opening database:', err.message);
|
||||
} else {
|
||||
console.log('Connected to the SQLite database.');
|
||||
// Create tables if they don't exist
|
||||
db.run(`CREATE TABLE IF NOT EXISTS coin_trackers (
|
||||
id TEXT PRIMARY KEY,
|
||||
data TEXT NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`);
|
||||
}
|
||||
});
|
||||
|
||||
// API route to save coin trackers
|
||||
app.post('/api/coinTrackers', (req, res) => {
|
||||
const data = req.body.data;
|
||||
if (!data) {
|
||||
return res.status(400).json({ error: 'No data provided' });
|
||||
}
|
||||
|
||||
// Save data to database
|
||||
db.run('DELETE FROM coin_trackers', [], function(err) {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: err.message });
|
||||
}
|
||||
|
||||
const stmt = db.prepare('INSERT INTO coin_trackers (id, data) VALUES (?, ?)');
|
||||
data.forEach(tracker => {
|
||||
stmt.run(tracker.id, JSON.stringify(tracker));
|
||||
});
|
||||
stmt.finalize();
|
||||
|
||||
res.json({ success: true, message: 'Data saved successfully' });
|
||||
});
|
||||
});
|
||||
|
||||
// API route to get coin trackers
|
||||
app.get('/api/coinTrackers', (req, res) => {
|
||||
db.all('SELECT id, data FROM coin_trackers', [], (err, rows) => {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: err.message });
|
||||
}
|
||||
|
||||
const data = rows.map(row => JSON.parse(row.data));
|
||||
res.json({ data });
|
||||
});
|
||||
});
|
||||
|
||||
// API route to create a backup
|
||||
app.get('/api/backup/create', (req, res) => {
|
||||
const name = req.query.name || `Backup_${new Date().toISOString()}`;
|
||||
const timestamp = Date.now();
|
||||
const fileName = `backup_${timestamp}_name_${name}.json`;
|
||||
const filePath = path.join(backupDir, fileName);
|
||||
|
||||
// Get all data from database
|
||||
db.all('SELECT id, data FROM coin_trackers', [], (err, rows) => {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: err.message });
|
||||
}
|
||||
|
||||
const data = rows.map(row => JSON.parse(row.data));
|
||||
const backupData = {
|
||||
date: new Date().toISOString(),
|
||||
name: name,
|
||||
data: data
|
||||
};
|
||||
|
||||
// Write backup file
|
||||
fs.writeFile(filePath, JSON.stringify(backupData, null, 2), (err) => {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: err.message });
|
||||
}
|
||||
|
||||
res.json({ success: true, message: 'Backup created successfully', file: fileName });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// API route to list backups
|
||||
app.get('/api/backup/list', (req, res) => {
|
||||
fs.readdir(backupDir, (err, files) => {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: err.message });
|
||||
}
|
||||
|
||||
const backups = [];
|
||||
|
||||
// Process each file synchronously
|
||||
for (const file of files) {
|
||||
if (!file.startsWith('backup_') || !file.endsWith('.json')) continue;
|
||||
|
||||
const filePath = path.join(backupDir, file);
|
||||
const stats = fs.statSync(filePath);
|
||||
|
||||
let name = file;
|
||||
if (file.includes('_name_')) {
|
||||
name = file.split('_name_')[1].split('.json')[0];
|
||||
}
|
||||
|
||||
const timestamp = file.split('_')[1];
|
||||
|
||||
backups.push({
|
||||
file: file,
|
||||
date: new Date(parseInt(timestamp)).toISOString(),
|
||||
size: stats.size,
|
||||
name: name
|
||||
});
|
||||
}
|
||||
|
||||
res.json({ backups });
|
||||
});
|
||||
});
|
||||
|
||||
// API route to restore from a backup
|
||||
app.get('/api/backup/restore/:file', (req, res) => {
|
||||
const fileName = req.params.file;
|
||||
const filePath = path.join(backupDir, fileName);
|
||||
|
||||
if (!fs.existsSync(filePath)) {
|
||||
return res.status(404).json({ error: 'Backup file not found' });
|
||||
}
|
||||
|
||||
fs.readFile(filePath, 'utf8', (err, data) => {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: err.message });
|
||||
}
|
||||
|
||||
try {
|
||||
const backupData = JSON.parse(data);
|
||||
|
||||
// Clear existing data
|
||||
db.run('DELETE FROM coin_trackers', [], function(err) {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: err.message });
|
||||
}
|
||||
|
||||
// Insert backup data
|
||||
if (backupData.data && Array.isArray(backupData.data)) {
|
||||
const stmt = db.prepare('INSERT INTO coin_trackers (id, data) VALUES (?, ?)');
|
||||
backupData.data.forEach(tracker => {
|
||||
stmt.run(tracker.id, JSON.stringify(tracker));
|
||||
});
|
||||
stmt.finalize();
|
||||
}
|
||||
|
||||
res.json({ success: true, message: 'Backup restored successfully' });
|
||||
});
|
||||
} catch (e) {
|
||||
res.status(500).json({ error: 'Invalid backup file format' });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Add a status endpoint for testing
|
||||
app.get('/api/status', (req, res) => {
|
||||
res.json({ status: 'ok', version: '1.0', timestamp: new Date().toISOString() });
|
||||
});
|
||||
|
||||
// Start the server
|
||||
app.listen(port, () => {
|
||||
console.log(`Server running at http://localhost:${port}`);
|
||||
});
|
||||
|
||||
// Schedule automatic backups daily at midnight
|
||||
cron.schedule('0 0 * * *', () => {
|
||||
console.log('Creating automatic daily backup');
|
||||
const name = `Auto_${new Date().toLocaleDateString()}`;
|
||||
const timestamp = Date.now();
|
||||
const fileName = `backup_${timestamp}_name_${name}.json`;
|
||||
const filePath = path.join(backupDir, fileName);
|
||||
|
||||
db.all('SELECT id, data FROM coin_trackers', [], (err, rows) => {
|
||||
if (err) {
|
||||
console.error('Auto backup error:', err);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = rows.map(row => JSON.parse(row.data));
|
||||
const backupData = {
|
||||
date: new Date().toISOString(),
|
||||
name: name,
|
||||
data: data
|
||||
};
|
||||
|
||||
fs.writeFile(filePath, JSON.stringify(backupData, null, 2), (err) => {
|
||||
if (err) {
|
||||
console.error('Error writing auto backup:', err);
|
||||
return;
|
||||
}
|
||||
console.log('Automatic backup created successfully');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user