This commit is contained in:
2023-06-11 22:44:25 +02:00
parent cafb6bc755
commit a38909babd
10 changed files with 1735 additions and 88 deletions

53
src/getCalendar.py Normal file
View File

@@ -0,0 +1,53 @@
import datetime
from caldav.davclient import DAVClient
import argparse
import html
# Parse command-line arguments
parser = argparse.ArgumentParser(description='Retrieve events from a CalDAV calendar.')
parser.add_argument('url', type=str, help='Server URL')
parser.add_argument('user', type=str, help='Username')
parser.add_argument('password', type=str, help='Password')
parser.add_argument('calendar', type=str, help='Calendar name')
parser.add_argument('start_date', type=str, help='Start date (dd.mm.yyyy)')
parser.add_argument('end_date', type=str, help='End date (dd.mm.yyyy)')
args = parser.parse_args()
# Create a DAV client
client = DAVClient(args.url, username=args.user, password=args.password)
# Find the calendar by its name ('myCalendar' in this case)
principal = client.principal()
calendars = principal.calendars()
calendar = None
for cal in calendars:
if cal.name == args.calendar:
calendar = cal
break
if calendar:
# Set the start and end timestamps
start = datetime.datetime.strptime(args.start_date, "%d.%m.%Y")
end = datetime.datetime.strptime(args.end_date, "%d.%m.%Y")
start = start.replace(hour=0, minute=0, second=0)
end = end.replace(hour=23, minute=59, second=59)
results = calendar.date_search(start, end)
# Store events in a list
events = []
for result in results:
event = result.instance.vevent
summary = event.summary.value if event.summary else None
start_time = event.dtstart.value.strftime("%d.%m.%Y %H:%M:%S")
events.append((start_time, summary))
# Sort the events by start time
events.sort(key=lambda x: datetime.datetime.strptime(x[0], "%d.%m.%Y %H:%M:%S"))
# Print the sorted events
for summary in events:
print('-', summary[1])
else:
print('Calendar not found.')

1
src/requirements.txt Normal file
View File

@@ -0,0 +1 @@
caldav

86
src/server.js Normal file
View File

@@ -0,0 +1,86 @@
const express = require('express');
const path = require('path');
const app = express();
const { spawnSync } = require('child_process');
const moment = require('moment');
// Befehl für die Skriptausführung
const command = process.platform === 'win32' ? 'python' : 'python3';
// Pfad zum Kalender-Skript
const scriptPath = path.resolve(__dirname, 'getCalendar.py');
// Definiere den Port, auf dem der Webserver lauschen soll
const webPort = process.env.WEB_PORT || 3000;
const templates = path.join(__dirname, 'templates');
// Stelle den Pfad zum "views" Verzeichnis ein
app.set('views', templates);
// Verwende EJS als Vorlagen-Engine
app.set('view engine', 'ejs');
// Funktion zum Formatieren des Datums
function formatDate(date) {
const day = date.getDate().toString().padStart(2, '0');
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const year = date.getFullYear();
return `${day}.${month}.${year}`;
}
// Funktion zum Erstellen der Liste der letzten 50 Wochen
function getLast50Weeks() {
let currentWeek = moment().startOf('isoWeek');
const last50Weeks = [];
for (let i = 0; i < 50; i++) {
const startOfWeek = currentWeek.clone().format('DD.MM.YYYY');
const endOfWeek = currentWeek.clone().add(6, 'days').format('DD.MM.YYYY');
last50Weeks.push(startOfWeek + " - " + endOfWeek);
currentWeek.subtract(7, 'days');
}
return last50Weeks;
}
function convertToJsEscape(str) {
return str.replace(/[\u00A0-\u9999]/g, function (match) {
return '\\u' + ('0000' + match.charCodeAt(0).toString(16)).slice(-4);
});
}
function getCalendarEntries(week) {
const weekDate = getLast50Weeks()[week];
const [startDateStr, endDateStr] = weekDate.split(" - ");
// Argumente für das Kalender-Skript
const args = [
process.env.CALDAV_URL,
process.env.CALDAV_USER,
process.env.CALDAV_PASSWORD,
process.env.CALDAV_CALENDAR,
startDateStr,
endDateStr
];
// Skript ausführen und Output in einer Variable speichern
const result = spawnSync(command, [scriptPath, ...args], { encoding: 'utf-8' });
console.log(convertToJsEscape(result.stdout.toString('utf-8')));
return result.stdout;
}
// Definiere eine Route für die Startseite
app.get('/', (req, res) => {
res.render('index', { options:getLast50Weeks() });
});
// Definiere eine Route für die Ausgabe der Daten
app.get('/getreport', (req, res) => {
res.send(getCalendarEntries(req.query.week));
});
// Starte den Server und lass ihn auf Port 3000 lauschen
app.listen(webPort, () => {
console.log('Webserver läuft auf Port', webPort);
});

75
src/templates/index.ejs Normal file
View File

@@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BerichtExporter</title>
<style>
body {
font-family: 'Roboto', sans-serif;
font-size: 16px;
background-color: #f5f5f5;
}
.selector {
margin-top: 10px;
margin-bottom: 10px;
}
.selector select {
height: 30px;
font-size: 16px;
}
.selector button {
font-size: 16px;
height: 30px;
margin-left: 10px;
}
#export-textarea {
font-size: 16px;
width: 90%;
resize: none;
overflow-y: hidden;
}
</style>
</head>
<body>
<h1>BerichtExporter</h1>
<div class="selector">
<select id="week-list">
<% options.forEach((element, index) => { %>
<option value="<%= index %>"><%= element %></option>
<% }); %>
</select>
<button id="export-button" onclick="exportReport()">Export</button>
</div>
<textarea id="export-textarea" readonly></textarea>
<script>
const exportTextarea = document.getElementById('export-textarea');
const weekList = document.getElementById('week-list');
function exportReport() {
const week = weekList.value;
fetch('/getreport?week=' + week)
.then(response => {
if (response.ok) {
return response.text();
} else {
exportTextarea.value = 'Error while fetching report';
throw new Error('Error while fetching report');
}
}).then(text => {
exportTextarea.value = text;
exportTextarea.style.height = exportTextarea.scrollHeight + "px";
}).catch(error => {
exportTextarea.value = 'Error while fetching report';
console.error(error);
});
}
</script>
</body>
</html>