Commit c576dcf5 authored by dmorley's avatar dmorley

Merge branch 'misc' into 'develop'

Misc Updates

See merge request diasporg/Poduptime!273
parents 68f33b19 593966da
stages:
- test
- test7.4
- test8.0
- deploy
test:
stage: test
test7.4:
stage: test7.4
cache:
key: poduptime
paths:
......@@ -17,6 +18,21 @@ test:
script:
- php composer.phar check-code
test8.0:
stage: test8.0
cache:
key: poduptime
paths:
- vendor/
image: php:8.0-cli-alpine
before_script:
- apk add -U git
- docker-php-ext-install -j$(nproc) bcmath
- curl -sS https://getcomposer.org/installer | php
- php composer.phar install
script:
- php composer.phar check-code
deploy:
stage: deploy
environment:
......
......@@ -9,6 +9,19 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic
### Fixed
### Security
## [2.8.1]
### Added
- Allow filter on domain name in config.php
### Changed
- Update map tiles to match theme
- Filter bad domains and software from sitemap.xml
- User charts on singleview
- Link to singleview from table
### Deprecated
### Removed
### Fixed
### Security
## [2.8.0]
:exclamation: DB migrations required! (see [SQL migration script][2.8.0-sql-migration])
:exclamation: `config.php` changed - requires updates
......
......@@ -75,9 +75,9 @@ psql -U podupuser podupdb < db/migrations/xxx.sql (see db/migrations/README.md f
============================
Source for Diaspora Pod Uptime
Source for Podpptime
Poduptime is software to get live stats and data on listed Diaspora Pods.
Poduptime is software to get live stats and data on federated network hosts.
Copyright (C) 2011 David Morley
This program is free software: you can redistribute it and/or modify
......
......@@ -88,6 +88,9 @@ return [
//hidden software word strings from view - %(one)% OR %(one|two|three)%
'hidden-softwares' => '%(relay|n/q)%',
//hidden domain word strings from view - %(one)% OR %(one|two|three)%
'hidden-domains' => '%(xxx|porn|fuck)%',
//softwares and git repos we support
'softwares' => [
......
......@@ -29,7 +29,7 @@ try {
}
try {
// remove diasp.org heck in 2022
// remove diasp.org heck in 2022 if you remove some older 2017 check data
$monthly_totals_all = R::getAll("
SELECT
to_char(date_checked, 'yyyy-mm') AS yymm,
......@@ -58,7 +58,7 @@ foreach ($monthly_totals_all as $monthly) {
break;
}
}
if ($total === 0) {
if ($total == 0) {
$total = 1;
}
......@@ -83,7 +83,7 @@ foreach ($monthly_totals_all as $monthly) {
try {
// remove diasp.org heck in 2022
// remove diasp.org heck in 2022 if you remove some older 2017 check data
$monthly_totals_bypod = R::getAll("
SELECT
to_char(checks.date_checked, 'yyyy-mm') AS yymm,
......@@ -112,7 +112,7 @@ foreach ($monthly_totals_bypod as $monthly) {
break;
}
}
if ($total === 0) {
if ($total == 0) {
$total = 1;
}
......@@ -123,8 +123,10 @@ foreach ($monthly_totals_bypod as $monthly) {
$p['total_posts'] = round($monthly['posts'] / $total);
$p['total_comments'] = round($monthly['comments'] / $total);
$p['total_pods'] = round($monthly['pods'] / $total);
if ($monthly['downtime']) {
if ($monthly['downtime'] && $monthly['uptime']) {
$p['total_uptime'] = round($monthly['downtime'] / $monthly['uptime'] * 100);
} elseif ($monthly['downtime']) {
$p['total_uptime'] = round($monthly['downtime'] / 1 * 100);
} else {
$p['total_uptime'] = 100;
}
......
......@@ -10,13 +10,18 @@ use RedBeanPHP\R;
require_once __DIR__ . '/../boot.php';
$hiddensoftwares = c('hidden-softwares');
$hiddendomains = c('hidden-domains');
try {
$pods = R::getAll('
SELECT softwarename, domain, date_updated::TIMESTAMP::DATE
FROM pods
WHERE date_updated IS NOT NULL
AND softwarename NOT SIMILAR TO ?
AND domain NOT SIMILAR TO ?
ORDER BY date_updated DESC
');
', [$hiddensoftwares, $hiddendomains]);
$xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
......
......@@ -110,7 +110,7 @@ foreach ($pods as $pod) {
$user_rating = round(array_sum($user_ratings) / count($user_ratings), 2);
}
$nodeinfo_meta = curl("https://{$domain}/.well-known/nodeinfo", false, 25);
$nodeinfo_meta = curl("https://{$domain}/.well-known/nodeinfo", false, 30);
// Default link to fetch node info.
$nodeinfo_url = "https://{$domain}/nodeinfo/1.0";
......@@ -127,7 +127,7 @@ foreach ($pods as $pod) {
debug('Nodeinfo link', $nodeinfo_url);
$nodeinfo = curl($nodeinfo_url, false, 25);
$nodeinfo = curl($nodeinfo_url, false, 30);
$outputssl = $nodeinfo['body'];
$outputsslerror = $nodeinfo['error'];
$info = $nodeinfo['info'];
......
......@@ -67,6 +67,7 @@ $software_all = !empty($subdomain) ? ucwords($subdomain) : 'All';
<script defer src="node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script defer src="node_modules/featherlight/release/featherlight.min.js"></script>
<script defer src="node_modules/ion-rangeslider/js/ion.rangeSlider.min.js"></script>
<script src="node_modules/chart.js/dist/Chart.min.js"></script>
<meta property="og:url" content="https://<?php echo $_SERVER['HTTP_HOST'] ?>/<?php echo $input ?>"/>
<meta property="og:title" content="<?php echo $software ?> Uptime Status"/>
<meta property="og:type" content="website"/>
......@@ -200,7 +201,7 @@ foreach ($csoftwares as $csoftware => $details) {
</footer>
<input type="hidden" name="software" value="<?php echo lcfirst($softwarejs) ?>">
<script src="node_modules/chart.js/dist/Chart.min.js"></script>
<?php
$statsview && include_once __DIR__ . '/statsviewjs.php';
$fullview && printf('<script defer src="js/podup.min.js"></script>');
......
......@@ -24,9 +24,6 @@ if ($country_code) {
define('PODUPTIME', microtime(true));
// CloudFlare country code pull.
$country_code = $_SERVER['HTTP_CF_IPCOUNTRY'] ?? '';
if ($country_code) {
$lat = country(strtolower($country_code))->getLatitudeDesc();
$long = country(strtolower($country_code))->getLongitudeDesc();
......@@ -119,7 +116,7 @@ try {
);
}
$pod_name = htmlentities($pod['name'] ?? '', ENT_QUOTES);
$pod_name = htmlentities($pod['domain'] ?? '', ENT_QUOTES);
$signup = $pod['signup'] ? 'yes' : 'no';
echo <<<EOF
{
......@@ -140,7 +137,7 @@ EOF;
};
var tiles = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=<?php echo c('mapboxkey'); ?>', {
maxZoom: 18,
id: 'mapbox/streets-v11',
id: 'mapbox/dark-v10',
accessToken: '<?php echo c('mapboxkey'); ?>',
attribution: '<a href="https://www.mapbox.com/about/maps/" target="_blank">&copy; Mapbox &copy; OpenStreetMap</a> <a class="mapbox-improve-map" href="https://www.mapbox.com/map-feedback/" target="_blank">Improve this map</a>'
});
......
......@@ -7,6 +7,7 @@
declare(strict_types=1);
use RedBeanPHP\R;
use Carbon\Carbon;
// Required parameters.
($_domain = $input ?? null) || die('no domain given');
......@@ -17,7 +18,7 @@ $iso = new Matriphe\ISO639\ISO639;
try {
$pod = R::getRow('
SELECT domain, podmin_statement, shortversion, softwarename, monthsmonitored, score, name, countryname, city, state, detectedlanguage, uptime_alltime, active_users_halfyear, services, service_xmpp, latency, total_users, local_posts, comment_counts, userrating, status, lat, long
SELECT domain, podmin_statement, shortversion, softwarename, monthsmonitored, daysmonitored, score, name, countryname, city, state, detectedlanguage, uptime_alltime, active_users_halfyear, services, service_xmpp, latency, total_users, local_posts, comment_counts, userrating, status, lat, long
FROM pods
WHERE domain = ?
', [$_domain]);
......@@ -25,23 +26,88 @@ try {
die('Error in SQL query: ' . $e->getMessage());
}
echo 'Poduptime report for <a href="/go.php?domain=' . $pod['domain'] . '">' . idn_to_utf8($pod['domain']) . '</a><br>';
echo 'This ' . $pod['softwarename'] . ' pod runs software version ' . $pod['shortversion'] . ' <br>';
try {
$domain_clicks = R::getAll("
SELECT
to_char(date_clicked, 'yyyy-mm') AS yymm,
SUM(manualclick) AS manualclick,
SUM(autoclick) AS autoclick
FROM clicks
WHERE domain = ?
GROUP BY yymm
", [$_domain]);
} catch (\RedBeanPHP\RedException $e) {
die('Error in SQL query: ' . $e->getMessage());
}
$humanmonitored = Carbon::now()->subDays($pod['daysmonitored'])->diffForHumans(null, true);
echo '<h4>' . c('title') . ' report for <a href="/go.php?domain=' . $pod['domain'] . '">' . idn_to_utf8($pod['domain']) . '</a></h4><br>';
echo 'This ' . $pod['softwarename'] . ' pod/node runs software version ' . $pod['shortversion'] . ' <br>';
echo 'This pod/node has been monitored for ' . $humanmonitored . '<br>';
echo 'Score for this pod is ' . $pod['score'] . ' out of 100<br>';
echo 'Detected language of this pod is ' . ($pod['detectedlanguage'] ? $iso->languageByCode1($pod['detectedlanguage']) : '') . '<br>';
echo '<br>';
echo 'Uptime over the last ' . $pod['monthsmonitored'] . ' months is <a href="#" class="green" data-featherlight="/podstat-uptime.php?domain=' . $pod['domain'] . '">' . $pod['uptime_alltime'] . '</a> %<br>';
echo 'Response Time from ' . c('serverlocation') . ' is ' . $pod['latency'] . ' ms<br>';
echo '<br>This pod has <a href="#" class="green" data-featherlight="podstat-counts.php?domain=' . $pod['domain'] . '">' . $pod['total_users'] . '</a> total users with ' . $pod['active_users_halfyear'] . ' active the last 6 months, users have posted ' . $pod['local_posts'] . ' times and commented ' . $pod['comment_counts'] . ' times<br><br>';
echo 'Services this pod offers are: ';
$services = json_decode($pod['services'] ?? '[]') ?: [];
($pod['service_xmpp'] ?? false) && $services[] = 'xmpp';
echo implode(', ', $services);
echo '<br><br>';
echo 'Server Country: ' . $pod['countryname'] . '<br>';
echo 'Server State: ' . $pod['state'] . '<br>';
echo 'Server City: ' . $pod['city'] . '<br>';
if ($services) {
echo 'Services this pod/node offers are: ';
($pod['service_xmpp'] ?? false) && $services[] = 'xmpp';
echo implode(', ', $services);
echo '<br><br>';
}
echo 'Servers IP address shows: ' . $pod['countryname'];
echo ' ' . $pod['state'];
echo ' ' . $pod['city'] . '<br>';
echo '<br>';
if ($pod['podmin_statement']) {
echo 'The host of the pod would like you to know<br><b><i> ' . $pod['podmin_statement'] . ' </i></b><br>';
echo 'The host of the pod would like you to know<br><b><i> ' . $pod['podmin_statement'] . ' </i></b><br><br>';
}
$_GET['domain'] = $pod['domain'];
echo "<h4>Uptime & Latency</h4><br>";
include 'podstat-uptime.php';
echo "<h4>User Stats</h4><br>";
include 'podstat-counts.php';
?>
<h4>Clicks Out</h4><br>
<div class="chart-container p-1 table-responsive" style="height:400px; width:700px">
<canvas id="clicks"></canvas>
</div>
<script>
new Chart(document.getElementById('clicks'), {
type: "bar",
data: {
labels: <?php echo json_encode(array_column($domain_clicks, 'yymm')); ?>,
datasets: [{
data: <?php echo json_encode(array_column($domain_clicks, 'manualclick')); ?>,
label: 'Manual',
fill: false,
yAxisID: "l2",
borderColor: "#A07614",
backgroundColor: "#A07614",
borderWidth: 4,
pointHoverRadius: 6
}, {
data: <?php echo json_encode(array_column($domain_clicks, 'autoclick')); ?>,
label: 'Auto',
fill: false,
yAxisID: "l2",
borderColor: "#4b6588",
backgroundColor: "#4b6588",
borderWidth: 4,
pointHoverRadius: 6
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
scales: {
yAxes: [{
position: "left",
"id": "l2"
}]
}
}
});
</script>
......@@ -15,6 +15,7 @@ require_once __DIR__ . '/boot.php';
$iso = new Matriphe\ISO639\ISO639;
$hiddensoftwares = c('hidden-softwares');
$hiddendomains = c('hidden-domains');
try {
if ($_GET['software']) {
......@@ -25,8 +26,9 @@ try {
AND score > 0
AND softwarename NOT SIMILAR TO ?
AND softwarename = ?
AND domain NOT SIMILAR TO ?
ORDER BY weightedscore DESC
', [PodStatus::RECHECK, $hiddensoftwares, $_GET['software']]);
', [PodStatus::RECHECK, $hiddensoftwares, $_GET['software'], $hiddendomains]);
} else {
$pods = R::getAll('
SELECT domain, dnssec, podmin_statement, masterversion, shortversion, softwarename, daysmonitored, monthsmonitored, score, signup, protocols, name, country, countryname, city, state, detectedlanguage, uptime_alltime, active_users_halfyear, active_users_monthly, services, service_xmpp, latency, date_updated, ipv6, total_users, local_posts, comment_counts, userrating, status, date_laststats
......@@ -34,8 +36,9 @@ try {
WHERE status < ?
AND score > 0
AND softwarename NOT SIMILAR TO ?
AND domain NOT SIMILAR TO ?
ORDER BY weightedscore DESC
', [PodStatus::RECHECK, $hiddensoftwares]);
', [PodStatus::RECHECK, $hiddensoftwares, $hiddendomains]);
}
} catch (\RedBeanPHP\RedException $e) {
die('Error in SQL query: ' . $e->getMessage());
......@@ -51,9 +54,9 @@ foreach ($pods as $pod) {
$tip = "{$pod['domain']} last checked {$last_podcheck} ago, over the last {$humanmonitored} uptime was {$pod['uptime_alltime']}%";
if (($_COOKIE['domain'] ?? null) === $pod['domain']) {
echo '<tr><td title="This is the last pod you visited from this site. ' . $tip . '" data-placement="bottom" data-toggle="tooltip" class="bg-blue"><a class="text-white url" target="_pod" href="/go.php?domain=' . $pod['domain'] . '">' . idn_to_utf8($pod['domain']) . '</a><a href="/' . $pod['domain'] . '"><span style="font-size: 1.7em; opacity: 0.5;" class="fa fa-info-circle align-top pl-3 d-lg-none"></span></a></td>';
echo '<tr><td title="This is the last pod you visited from this site. ' . $tip . '" data-placement="bottom" data-toggle="tooltip" class="bg-blue"><a class="text-white url" target="_pod" href="/go.php?domain=' . $pod['domain'] . '">' . idn_to_utf8($pod['domain']) . '</a><a href="/' . $pod['domain'] . '"><span style="font-size: 1.4em; opacity: 0.2;" class="fa fa-info-circle align-top pl-3"></span></a></td>';
} else {
echo '<tr><td data-placement="bottom" title="' . $tip . '" data-toggle="tooltip"><a class="url" target="_pod" href="/go.php?domain=' . $pod['domain'] . '">' . idn_to_utf8($pod['domain']) . '</a><a href="/' . $pod['domain'] . '"><span style="font-size: 1.7em; opacity: 0.5;" class="fa fa-info-circle align-top pl-3 d-lg-none"></span></a></td>';
echo '<tr><td data-placement="bottom" title="' . $tip . '" data-toggle="tooltip"><a class="url" target="_pod" href="/go.php?domain=' . $pod['domain'] . '">' . idn_to_utf8($pod['domain']) . '</a><a href="/' . $pod['domain'] . '"><span style="font-size: 1.4em; opacity: 0.2;" class="fa fa-info-circle align-top pl-3"></span></a></td>';
}
if ($pod['shortversion'] > $pod['masterversion']) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment