Compare commits

..

2 Commits

Author SHA1 Message Date
quenousimporte 6a4e578366 Merge branch 'feat/serverside' of https://git.ouvaton.coop/quenousimporte/icstool into feat/serverside 2024-03-18 22:15:19 +01:00
quenousimporte 433f1972b2 move code server side 2024-03-18 17:19:38 +01:00
2 changed files with 173 additions and 153 deletions

319
ics.php
View File

@ -1,161 +1,182 @@
<!DOCTYPE html>
<html>
<head>
<title>Evénements à venir</title>
<meta charset="utf-8">
</head>
<body style="font-family: helvetica; line-height: 24px; font-size: 16px;">
<div id="content">
<header>
<title>Evénements à venir</title>
</header>
<body style="font-family: helvetica; line-height: 24px; font-size: 16px;">
<?php
require 'settings.php';
require 'settings.php';
if ($password && (!isset($_SERVER['PHP_AUTH_PW']) || $_SERVER['PHP_AUTH_PW'] != $password)) {
header('WWW-Authenticate: Basic realm="bbn"');
header('HTTP/1.0 401 Unauthorized');
die('<p>Access denied.</p></body></html>');
}
/*function ics2json($input)
{
$id = 0;
$root = array();
$curr = root;
input.split("\r\n").forEach(l =>
{
var key = l.split(":")[0].split(";")[0];
var val = l.split(":")[1];
if (key == "BEGIN")
{
if (curr[val])
{
val += "_" + (id++);
}
curr[val] = {
parent: curr
};
curr = curr[val];
}
else if (key == "END")
{
var parent = curr.parent;
delete curr.parent;
curr = parent;
}
else
{
curr[key] = key.startsWith("DT") ? dt(val) : val;
}
// authent
if ($password && (!isset($_SERVER['PHP_AUTH_PW']) || $_SERVER['PHP_AUTH_PW'] != $password))
{
header('WWW-Authenticate: Basic realm="bbn"');
header('HTTP/1.0 401 Unauthorized');
echo '<p>Access denied.</p></body></html>';
exit;
}
});
// Enable error reporting for debugging
//error_reporting(E_ALL);
//ini_set('display_errors', 1);
root.VCALENDAR.VEVENTS = [];
Object.keys(root.VCALENDAR)
.filter(k => (k == "VEVENT" || k.startsWith("VEVENT_")))
.forEach(k =>
{
root.VCALENDAR.VEVENTS.push(root.VCALENDAR[k]);
delete root.VCALENDAR[k];
});
function ics2json($input)
{
$id = 0;
$root = [];
$curr = &$root;
$lines = explode("\r\n", $input);
foreach ($lines as $line)
{
$parts = explode(":", $line, 2);
$key = explode(";", $parts[0])[0];
$val = isset($parts[1]) ? $parts[1] : '';
if ($key == "BEGIN")
{
if (isset($curr[$val]))
{
$val .= "_" . ($id++);
}
$curr[$val] = ['parent' => &$curr];
$curr = &$curr[$val];
}
elseif ($key == "END")
{
$parent = &$curr['parent'];
unset($curr['parent']);
$curr = &$parent;
}
else
{
$curr[$key] = (strpos($key, "DT") === 0) ? dt($val) : $val;
}
}
$root['VCALENDAR']['VEVENTS'] = [];
foreach ($root['VCALENDAR'] as $k => $v)
{
if ($k == "VEVENT" || strpos($k, "VEVENT_") === 0)
{
$root['VCALENDAR']['VEVENTS'][] = $v;
unset($root['VCALENDAR'][$k]);
}
}
return $root['VCALENDAR'];
}
return root.VCALENDAR;
}*/
function dt($s)
{
$formatted = substr($s, 0, 4) . "-" . substr($s, 4, 2) . "-" . substr($s, 6, 2);
if (strlen($s) > 8)
{
$formatted .= "T" . substr($s, 9, 2) . ":" . substr($s, 11, 2) . ":" . substr($s, 13, 2);
}
return new DateTime($formatted);
}
// Get ics file
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_USERPWD, $user . ':' . $password);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$result = curl_exec($curl);
function formatdate($d)
{
return strftime('%A, %e %B %Y %H:%M', $d->getTimestamp());
}
if (!$result)
{
die('<p>Error while getting ics file from caldav server.</p></body></html>');
}
curl_close($curl);
function getWeek($date)
{
$dto = new DateTime();
$dto->setISODate($date->format('o'), $date->format('W'));
return $dto->format('W');
}
// port "showresult" js function:
$recent = 7;
if (isset($_GET['recent']))
{
$recent = $_GET['recent'];
}
setlocale(LC_TIME, 'fr_FR.UTF-8');
echo '<h1>Evénements à venir</h1>';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $davurl);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_USERPWD, $davuser . ':' . $davpassword);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$result = curl_exec($curl);
if (!$result)
{
die('error');
}
curl_close($curl);
$params = [];
parse_str($_SERVER['QUERY_STRING'], $params);
$recent = isset($params['recent']) ? (int)$params['recent'] : 7;
$recentonly = isset($params['recentonly']);
$html = "<h1>Evénements à venir</h1>";
$html .= "<div>Récent : $recent derniers jours</div>";
$o = ics2json($result);
$lastmodified = new DateTime();
$lastmodified->modify("-$recent days");
$group = [];
usort($o['VEVENTS'], function($a, $b)
{
return $a['DTSTART'] <=> $b['DTSTART'];
});
foreach ($o['VEVENTS'] as $e)
{
if ($e['DTSTART'] >= new DateTime() && (!$recentonly || $e['DTSTAMP'] >= $lastmodified))
{
$formatteddate = strftime('%A %d %B %Y %H:%M', $e['DTSTART']->getTimestamp());
$splitdate = explode(' ', $formatteddate);
$year = $splitdate[3];
$month = $splitdate[2];
$week = getWeek($e['DTSTART']);
if (!isset($group[$year]))
{
$html .= "<h2>$year</h2>";
$group[$year] = [];
}
if (!isset($group[$year][$month]))
{
$html .= "<h3>". ucfirst($month) ."</h3>";
$group[$year][$month] = [];
}
if (!isset($group[$year][$month][$week]))
{
$html .= "<h4>Semaine $week</h4>";
$group[$year][$month][$week] = true;
}
$line = "<li title=\"modifié le " . strftime('%A, %e %B %Y %H:%M', $e['DTSTAMP']->getTimestamp()) . "\">";
$line .= ucfirst($formatteddate) . ": " . $e['SUMMARY'];
if ($e['DTSTAMP'] >= $lastmodified)
{
$line .= " 🆕";
}
$line .= '</li>';
$html .= $line;
}
}
echo $html;
?>
</div>
</body>
</html>
</body>
</html>
<!-- old -->
<div id="content">Récupération du calendrier...</div>
<script type="text/javascript">
function dt(s)
{
var formatted = s.substr(0,4) + "-" + s.substr(4,2) + "-" + s.substr(6,2);
if (s.length > 8)
{
formatted += "T" + s.substr(9,2) + ":" + s.substr(11,2) + ":" + s.substr(13,2);
}
return new Date(formatted);
}
function formatdate(d)
{
return d.toLocaleString('fr-FR', { timeZone: 'Europe/Paris', dateStyle: "full", timeStyle: "short" });
}
function showresult()
{
if (xhr.status == 200)
{
var params = new URLSearchParams(window.location.search);
var recent = parseInt(params.get("recent"));
if (isNaN(recent))
{
recent = 7;
}
var recentonly = params.get("recentonly");
var html = "<h1>Evénements à venir</h1>";
html += `<h3>${formatdate(new Date)}</h3>`;
html += `<div>En gras: modifié les ${recent} derniers jours</div>`;
var weblink = params.get("weblink");
if (weblink)
{
html += `<div><a target="_blank" href="${weblink}">Lien vers calendrier web</a></div>`;
}
var o = ics2json(xhr.responseText);
var lastmodified = new Date();
lastmodified.setDate(lastmodified.getDate() - recent);
var group = {};
o.VEVENTS
.filter(e => e.DTSTART >= (new Date) && (!recentonly || e.DTSTAMP >= lastmodified))
.sort( (a,b) => a.DTSTART - b.DTSTART)
.forEach(e => {
var formatteddate = formatdate(e.DTSTART);
var splitdate = formatteddate.split(" ");
var year = splitdate[3];
var month = splitdate[2];
if (!group[year])
{
html += `<h2>${year}</h2>`;
group[year] = {};
}
if (!group[year][month])
{
html += `<h3>${month}</h3>`;
group[year][month] = true;
}
var line = `<li title="modifié le ${formatdate(e.DTSTAMP)}"> ${formatteddate}: ${e.SUMMARY}`;
if (e.DTSTAMP >= lastmodified)
{
line = `<b>${line}</b>`;
}
html += line;
});
content.innerHTML = html;
}
}
var password = localStorage.getItem("icspassword");
if (!password)
{
password = prompt("password:");
localStorage.setItem("icspassword", password);
}
var xhr = new XMLHttpRequest();
xhr.onload = showresult;
xhr.open("POST", "ics.php");
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send("password=" + password);
</script>

View File

@ -1,6 +1,5 @@
<?php
$davurl = 'https://caldav.example.com/path/to/calendar';
$davuser = 'caldavuser';
$davpassword = 'caldavpassword';
$password = 'httppassword';
$url = 'https://caldav.example.com/path/to/calendar';
$user = 'caldavuser';
$password = 'caldavpassword';
?>