commit
94b441caac
@ -0,0 +1 @@
|
|||||||
|
config.php
|
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$CFG = [
|
||||||
|
'api_key' => '',
|
||||||
|
'web_context' => ''
|
||||||
|
];
|
@ -0,0 +1,68 @@
|
|||||||
|
<?php if (!defined('INIT')) exit; ?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Phedder</title>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1><?=e($DATA['city'])?></h1>
|
||||||
|
<h2><small><?=e($DATA['sunrise'])?> / <?=e($DATA['sunset'])?></small></h2>
|
||||||
|
|
||||||
|
<table class="forecast">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Datum</th>
|
||||||
|
<th>Regen</th>
|
||||||
|
<th colspan="3"></th>
|
||||||
|
<th>Wind</th>
|
||||||
|
<th>Temp</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<?php foreach($grouped as $group): ?>
|
||||||
|
<tbody>
|
||||||
|
<?php $first = true; ?>
|
||||||
|
<?php foreach($group as $line): ?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<?php if ($first): ?>
|
||||||
|
<?=e(substr($line['date'], 0, 11))?>
|
||||||
|
<?php $first = false; ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<?=e(substr($line['date'], 12, 5))?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
<td><?=e(round($line['rain'], 1))?>mm</td>
|
||||||
|
<td class="pictogram"><?=($line['icon'])?></td>
|
||||||
|
<td class="pictogram">
|
||||||
|
<?php $class = $line['riding'] === 'Y' ? 'flying-weather'
|
||||||
|
: $line['riding'] === 'M' ? 'maybe-flying-weather'
|
||||||
|
: '' ?>
|
||||||
|
<span class="<?=$class?>"><?=e($line['ridingIcon'])?></span>
|
||||||
|
</td>
|
||||||
|
<td class="pictogram">
|
||||||
|
<?php $class = $line['flying'] === 'Y' ? 'flying-weather'
|
||||||
|
: $line['flying'] === 'M' ? 'maybe-flying-weather'
|
||||||
|
: '' ?>
|
||||||
|
<span class="<?=$class?>"><?=e($line['flyingIcon'])?></span>
|
||||||
|
</td>
|
||||||
|
<td><?=e($line['wind'])?>m/s</td>
|
||||||
|
<td><?=e(round($line['temp'], 1))?>°C</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<form action="<?=wc()?>">
|
||||||
|
<label>
|
||||||
|
Ort
|
||||||
|
<input name="location" required value="<?=e($_GET['location'] ?? '')?>">
|
||||||
|
</label>
|
||||||
|
<button type="submit">
|
||||||
|
Suche
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,121 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
define('INIT', true);
|
||||||
|
require_once 'config.php';
|
||||||
|
|
||||||
|
function e($s) {
|
||||||
|
return htmlspecialchars($s);
|
||||||
|
}
|
||||||
|
|
||||||
|
function wc() {
|
||||||
|
global $CFG;
|
||||||
|
return $CFG['web_context'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_GET['location'])) {
|
||||||
|
require_once 'search.html.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$location = $_GET['location'];
|
||||||
|
$apicall = 'https://api.openweathermap.org/data/2.5/forecast?'
|
||||||
|
. 'q=' . urlencode($location)
|
||||||
|
. '&appid=' . urlencode($CFG['api_key']);
|
||||||
|
|
||||||
|
$ch = curl_init();
|
||||||
|
curl_setopt($ch, CURLOPT_URL, $apicall);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
$body = curl_exec($ch);
|
||||||
|
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
|
||||||
|
if ($httpcode !== 200) {
|
||||||
|
$CFG['failure'] = $httpcode;
|
||||||
|
require_once 'search.html.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = json_decode($body);
|
||||||
|
|
||||||
|
$DATA = [
|
||||||
|
'city' => $data->city->name . ', ' . $data->city->country,
|
||||||
|
'population' => $data->city->population,
|
||||||
|
'sunrise' => date('H:i:s', $data->city->sunrise),
|
||||||
|
'sunset' => date('H:i:s', $data->city->sunset)
|
||||||
|
];
|
||||||
|
|
||||||
|
$icons = [
|
||||||
|
//'01d' => "&#D83C;&#DF1E;",
|
||||||
|
'01d' => '🌞',
|
||||||
|
'01n' => '🌚',
|
||||||
|
'02d' => "🌤",
|
||||||
|
'02n' => "🌤",
|
||||||
|
'03d' => "🌥",
|
||||||
|
'03n' => "🌥",
|
||||||
|
'04d' => "☁",
|
||||||
|
'04n' => "☁",
|
||||||
|
'09d' => "🌦",
|
||||||
|
'09n' => "🌦",
|
||||||
|
'10d' => "🌧",
|
||||||
|
'10n' => "🌧",
|
||||||
|
'11d' => "🌩",
|
||||||
|
'11n' => "🌩",
|
||||||
|
'13d' => "⛄",
|
||||||
|
'13n' => "⛄",
|
||||||
|
'50d' => "🌫",
|
||||||
|
'50n' => "🌫"
|
||||||
|
];
|
||||||
|
|
||||||
|
$list = [];
|
||||||
|
foreach ($data->list as $line) {
|
||||||
|
$temp = $line->main->temp - 273.15;
|
||||||
|
$date = date('D. d.m. H:i', $line->dt);
|
||||||
|
$icon = $icons[$line->weather[0]->icon];
|
||||||
|
|
||||||
|
$rainArr = (array) ($line->rain ?? []);
|
||||||
|
$snowArr = (array) ($line->snow ?? []);
|
||||||
|
$rain = ($rainArr['3h'] ?? 0) + ($snowArr['3h'] ?? 0);
|
||||||
|
|
||||||
|
$wind = $line->wind->speed;
|
||||||
|
$flying = $rain === 0 && $wind < 2.5 ? 'Y'
|
||||||
|
: $rain <= 0.3 && $wind < 3.1 ? 'M'
|
||||||
|
: 'N';
|
||||||
|
$flyingIcon = $flying === 'Y' ? "🛩"
|
||||||
|
: $flying === 'M' ? "🛩"
|
||||||
|
: '⏚';
|
||||||
|
|
||||||
|
$riding = $rain === 0 && $temp > 15 ? 'Y'
|
||||||
|
: $rain <= 0.3 && $temp > 10 ? 'M'
|
||||||
|
: 'N';
|
||||||
|
$ridingIcon = $riding === 'Y' ? "🏍"
|
||||||
|
: $riding === 'M' ? "🏍"
|
||||||
|
: "🚳";
|
||||||
|
|
||||||
|
$list[] = [
|
||||||
|
'temp' => $temp,
|
||||||
|
'date' => $date,
|
||||||
|
'icon' => $icon,
|
||||||
|
'rain' => $rain,
|
||||||
|
'wind' => $wind,
|
||||||
|
'flying' => $flying,
|
||||||
|
'flyingIcon' => $flyingIcon,
|
||||||
|
'riding' => $riding,
|
||||||
|
'ridingIcon' => $ridingIcon
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastDay = substr($list[0]['date'], 0, 11);
|
||||||
|
$dayGroup = [];
|
||||||
|
$grouped = [];
|
||||||
|
foreach($list as $line) {
|
||||||
|
$dayStr = substr($line['date'], 0, 11);
|
||||||
|
if ($dayStr === $lastDay) {
|
||||||
|
$dayGroup[] = $line;
|
||||||
|
} else {
|
||||||
|
$grouped[] = $dayGroup;
|
||||||
|
$dayGroup = [];
|
||||||
|
$lastDay = $dayStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$grouped[] = $dayGroup;
|
||||||
|
|
||||||
|
require_once 'display.html.php';
|
@ -0,0 +1,28 @@
|
|||||||
|
<?php if (!defined('INIT')) exit; ?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Phedder</title>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Phedder</h1>
|
||||||
|
<form action="<?=wc()?>">
|
||||||
|
<label>
|
||||||
|
Ort
|
||||||
|
<input name="location" required value="<?=e($_GET['location'] ?? '')?>">
|
||||||
|
</label>
|
||||||
|
<button type="submit">
|
||||||
|
Suche
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<?php
|
||||||
|
if (isset($CFG['failure'])) {
|
||||||
|
?>
|
||||||
|
<p>Http Code: <?=$CFG['failure']?></p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,45 @@
|
|||||||
|
body {
|
||||||
|
max-width: 50rem;
|
||||||
|
margin: auto;
|
||||||
|
font-family: sans-serif;
|
||||||
|
padding: .2rem;
|
||||||
|
}
|
||||||
|
body .search form * {
|
||||||
|
margin-right: 1rem;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
body .forecast {
|
||||||
|
border-spacing: 0;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
body .forecast tbody::after {
|
||||||
|
display: block;
|
||||||
|
height: 2rem;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
body .forecast img {
|
||||||
|
height: 2rem;
|
||||||
|
}
|
||||||
|
body .forecast th {
|
||||||
|
border-bottom: .2rem solid #ccc;
|
||||||
|
background-color: #aaa;
|
||||||
|
padding: .8rem 0rem;
|
||||||
|
}
|
||||||
|
body .forecast td {
|
||||||
|
padding: .5rem 0rem;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
body .forecast td:not(:first-child) {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
body .forecast .pictogram {
|
||||||
|
width: 0;
|
||||||
|
padding: .5rem .5rem;
|
||||||
|
}
|
||||||
|
body .forecast .flying-weather {
|
||||||
|
border-bottom: 3px solid green;
|
||||||
|
}
|
||||||
|
body .forecast .maybe-flying-weather {
|
||||||
|
border-bottom: 3px solid darkorange;
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
body {
|
||||||
|
max-width: 50rem;
|
||||||
|
margin: auto;
|
||||||
|
font-family: sans-serif;
|
||||||
|
padding: .2rem;
|
||||||
|
|
||||||
|
.search form * {
|
||||||
|
margin-right: 1rem;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forecast {
|
||||||
|
border-spacing: 0;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
|
||||||
|
tbody::after {
|
||||||
|
display: block;
|
||||||
|
height: 2rem;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
border-bottom: .2rem solid #ccc;
|
||||||
|
background-color: #aaa;
|
||||||
|
padding: .8rem 0rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: .5rem 0rem;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
|
||||||
|
&:not(:first-child) {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pictogram {
|
||||||
|
width: 0;
|
||||||
|
padding: .5rem .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flying-weather {
|
||||||
|
border-bottom: 3px solid green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maybe-flying-weather {
|
||||||
|
border-bottom: 3px solid darkorange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue