pull.php 10.2 KB
Newer Older
MatrixCrawler's avatar
MatrixCrawler committed
1
<?php
2
//* Copyright (c) 2011, David Morley. This file is licensed under the Affero General Public License version 3 or later. See the COPYRIGHT file. */
3

David Morley's avatar
David Morley committed
4 5 6
$debug   = isset($_GET['debug']) || (isset($argv) && in_array('debug', $argv, true));
$newline = PHP_SAPI === 'cli' ? "\n" : '<br>';

7 8
$_domain = $_GET['domain'] ?? '';

9
require_once __DIR__ . '/../config.php';
dmorley's avatar
dmorley committed
10

11 12
$dbh = pg_connect("dbname=$pgdb user=$pguser password=$pgpass");
$dbh || die('Error in connection: ' . pg_last_error());
MatrixCrawler's avatar
MatrixCrawler committed
13

14
if ($_domain) {
15
  $sql = 'SELECT domain,score,date_created,adminrating,weight,hidden,podmin_notify,email FROM pods WHERE domain = $1';
16 17
  $result = pg_query_params($dbh, $sql, [$_domain]);
} elseif (PHP_SAPI === 'cli') {
18
  $sql = 'SELECT domain,score,date_created,adminrating,weight,hidden,podmin_notify,email FROM pods';
dmorley's avatar
dmorley committed
19
  $result = pg_query($dbh, $sql);
20 21
} else {
  die('No valid input');
dmorley's avatar
dmorley committed
22
}
23 24
$result || die('Error in SQL query1: ' . pg_last_error());

David Morley's avatar
David Morley committed
25 26 27 28 29 30
while ($row = pg_fetch_assoc($result)) {
  $domain    = $row['domain'];
  $score     = (int) $row['score'];
  $dateadded = $row['date_created'];
  $admindb   = (int) $row['adminrating'];
  $weight    = $row['weight'];
31 32 33
  $hiddennow = $row['hidden'];
  $email     = $row['email'];
  $notify    = $row['podmin_notify'];
David Morley's avatar
David Morley committed
34 35 36
  $sqlforr   = 'SELECT admin,rating FROM rating_comments WHERE domain = $1';
  $ratings   = pg_query_params($dbh, $sqlforr, [$domain]);
  $ratings || die('Error in SQL query2: ' . pg_last_error());
37

David Morley's avatar
David Morley committed
38
  _debug('Domain', $domain);
noplanman's avatar
noplanman committed
39

David Morley's avatar
David Morley committed
40 41 42 43 44 45 46
  $user_ratings  = [];
  $admin_ratings = [];
  while ($rating = pg_fetch_assoc($ratings)) {
    if ($rating['admin'] == 0) {
      $user_ratings[] = $rating['rating'];
    } elseif ($rating['admin'] == 1) {
      $admin_ratings[] = $rating['rating'];
47
    }
David Morley's avatar
David Morley committed
48 49 50
  }
  $user_rating  = empty($user_ratings) ? 0 : max(10, round(array_sum($user_ratings) / count($user_ratings), 2));
  $admin_rating = empty($admin_ratings) ? 0 : max(10, round(array_sum($admin_ratings) / count($admin_ratings), 2));
noplanman's avatar
noplanman committed
51

David Morley's avatar
David Morley committed
52 53 54
  if ($admindb == -1) {
    $admin_rating = -1;
  }
55

David Morley's avatar
David Morley committed
56 57
  $chss = curl_init();
  curl_setopt($chss, CURLOPT_URL, 'https://' . $domain . '/nodeinfo/1.0');
58 59
  curl_setopt($chss, CURLOPT_CONNECTTIMEOUT, 10);
  curl_setopt($chss, CURLOPT_TIMEOUT, 30);
David Morley's avatar
David Morley committed
60 61
  curl_setopt($chss, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($chss, CURLOPT_CERTINFO, 1);
dmorley's avatar
dmorley committed
62
  curl_setopt($chss, CURLOPT_CAINFO, $cafullpath);
David Morley's avatar
David Morley committed
63 64 65
  $outputssl      = curl_exec($chss);
  $outputsslerror = curl_error($chss);
  $info           = curl_getinfo($chss, CURLINFO_CERTINFO);
66
  $latency        = curl_getinfo($chss, CURLINFO_TOTAL_TIME);
dmorley's avatar
dmorley committed
67
  $sslexpire      = $info[0]['Expire date'] ?? null;
David Morley's avatar
David Morley committed
68
  curl_close($chss);
69

David Morley's avatar
David Morley committed
70 71
  _debug('Nodeinfo output', $outputssl, true);
  _debug('Nodeinfo output error', $outputsslerror, true);
72
  _debug('Cert expire date', $sslexpire);
dmorley's avatar
dmorley committed
73
  _debug('Latency', $latency);
74
  
David Morley's avatar
David Morley committed
75
  $jsonssl = json_decode($outputssl);
noplanman's avatar
noplanman committed
76

77 78 79 80 81
  $xdver                 = $jsonssl->software->version ?? 0;
  $dverr                 = explode('-', trim($xdver));
  $shortversion          = $dverr[0];
  $signup                = ($jsonssl->openRegistrations ?? false) === true;
  $softwarename          = $jsonssl->software->name ?? 'unknown';
David Morley's avatar
David Morley committed
82
  $name                  = $jsonssl->metadata->nodeName ?? $softwarename;
83 84 85 86 87 88
  $total_users           = $jsonssl->usage->users->total ?? 0;
  $active_users_halfyear = $jsonssl->usage->users->activeHalfyear ?? 0;
  $active_users_monthly  = $jsonssl->usage->users->activeMonth ?? 0;
  $local_posts           = $jsonssl->usage->localPosts ?? 0;
  $comment_counts        = $jsonssl->usage->localComments ?? 0;
  $service_xmpp          = ($jsonssl->metadata->xmppChat ?? false) === true;
dmorley's avatar
dmorley committed
89 90 91 92
  $service_facebook      = false;
  $service_twitter       = false;
  $service_tumblr        = false;
  $service_wordpress     = false;
93
  if (json_last_error() === 0) {
dmorley's avatar
dmorley committed
94
    (!$jsonssl->software->version) || $score += 1;
David Morley's avatar
David Morley committed
95 96 97 98
    $service_facebook      = in_array('facebook', $jsonssl->services->outbound, true);
    $service_twitter       = in_array('twitter', $jsonssl->services->outbound, true);
    $service_tumblr        = in_array('tumblr', $jsonssl->services->outbound, true);
    $service_wordpress     = in_array('wordpress', $jsonssl->services->outbound, true);
99
  }
David Morley's avatar
David Morley committed
100
    
101 102
  if ($jsonssl !== null) {
    $status        = 'Up';
dmorley's avatar
dmorley committed
103 104
    $sql_checks    = 'INSERT INTO checks (domain, online, latency, total_users, local_posts, comment_counts, shortversion) VALUES ($1, $2, $3, $4, $5, $6, $7)';
    $result_checks = pg_query_params($dbh, $sql_checks, [$domain, 1, $latency, $total_users, $local_posts, $comment_counts, $shortversion]);
David Morley's avatar
David Morley committed
105
    $result_checks || die('Error in SQL query: ' . pg_last_error());
David Morley's avatar
David Morley committed
106
  }
107 108 109
  
  if (!$jsonssl) {    
    _debug('Connection', 'Can not connect to pod');
dmorley's avatar
dmorley committed
110 111
    $sql_errors    = 'INSERT INTO checks (domain, online, error, latency) VALUES ($1, $2, $3, $4)';
    $result_errors = pg_query_params($dbh, $sql_errors, [$domain, 0, $outputsslerror, $latency]);
112 113 114 115 116 117 118
    $result_errors || die('Error in SQL query: ' . pg_last_error());
    $score         -= 1;
    $shortversion  = '0.error';
    $status        = 'Down';
  }
  
  _debug('Version code', $shortversion);
David Morley's avatar
David Morley committed
119
  _debug('Signup Open', $signup);
David Morley's avatar
David Morley committed
120

121
  $iplookupv4 = [];
122
  $ip         = '';
David Morley's avatar
David Morley committed
123
  exec(escapeshellcmd('delv @' . $dnsserver . ' ' . $domain . ' 2>&1'), $iplookupv4);
124
  $dnssec   = in_array('; fully validated', $iplookupv4, true) ?? false;
David Morley's avatar
David Morley committed
125
  $getaonly = array_values(preg_grep('/\s+IN\s+A\s+.*/', $iplookupv4));
126
  if ($getaonly) {
127
    preg_match('/A\s(.*)/', $getaonly[0], $aversion);
128
    $ip = trim($aversion[1]) ?? '';
129 130
  }
  $iplookupv6 = [];
David Morley's avatar
David Morley committed
131
  $ipv6 = null;
David Morley's avatar
David Morley committed
132
  exec(escapeshellcmd('delv @' . $dnsserver . ' ' . $domain . ' AAAA 2>&1'), $iplookupv6);
David Morley's avatar
David Morley committed
133 134 135 136
  $getaaaaonly = array_values(preg_grep('/\s+IN\s+AAAA\s+.*/', $iplookupv6));
  if ($getaaaaonly) {
    preg_match('/AAAA\s(.*)/', $getaaaaonly[0], $aaaaversion);
    $ipv6   = trim($aaaaversion[1]) ?? '';
dmorley's avatar
dmorley committed
137
  }
dmorley's avatar
dmorley committed
138
  $ip || $score -= 2;
David Morley's avatar
David Morley committed
139 140

  _debug('IPv4', $ip);
141
  _debug('Iplookupv4', $iplookupv4, true);
David Morley's avatar
David Morley committed
142
  _debug('IPv6', $ipv6);
143
  _debug('Iplookupv6', $iplookupv6, true);
David Morley's avatar
David Morley committed
144 145 146

  $location = geoip_record_by_name($ip);
  _debug('Location', $location, true);
147 148 149 150 151
  $country  = !empty($location['country_code']) ? iconv('UTF-8', 'UTF-8//IGNORE', $location['country_code']) : null;
  $city     = !empty($location['city']) ? iconv('UTF-8', 'UTF-8//IGNORE', $location['city']) : null;
  $state    = !empty($location['region']) ? iconv('UTF-8', 'UTF-8//IGNORE', $location['region']) : null;
  $lat      = !empty($location['latitude']) ? $location['latitude'] : 0;
  $long     = !empty($location['longitude']) ? $location['longitude'] : 0;
dmorley's avatar
dmorley committed
152
  
David Morley's avatar
David Morley committed
153 154
  echo $newline;
  $statslastdate = date('Y-m-d H:i:s');
David Morley's avatar
David Morley committed
155

156 157
  $diff         = (new DateTime())->diff(new DateTime($dateadded));
  $months       = $diff->m + ($diff->y * 12);
David Morley's avatar
David Morley committed
158
    
dmorley's avatar
dmorley committed
159 160 161 162 163
  $avglatency     = 0;
  $sqllatency     = 'SELECT round(avg(latency) * 1000) AS latency FROM checks WHERE domain = $1';
  $resultlatency  = pg_query_params($dbh, $sqllatency, [$domain]);
  $resultlatency  || die('Error in SQL query resultchecks: ' . pg_last_error());
  $avglatency     = pg_fetch_result($resultlatency, 0);
David Morley's avatar
David Morley committed
164 165

  $uptime       = 0;
166
  $sqlonline    = 'SELECT avg(online::int) * 100 AS online FROM checks WHERE domain = $1';
David Morley's avatar
David Morley committed
167 168
  $resultonline = pg_query_params($dbh, $sqlonline, [$domain]);
  $resultonline || die('Error in SQL query resultchecks: ' . pg_last_error());
169 170 171
  $uptime       = round(pg_fetch_result($resultonline, 0),2);
  
  _debug('Uptime', $uptime);
David Morley's avatar
David Morley committed
172 173 174 175 176 177 178 179

  $sqlmasters    = 'SELECT version FROM masterversions WHERE software = $1 ORDER BY date_checked LIMIT 1';
  $resultmasters = pg_query_params($dbh, $sqlmasters, [$softwarename]);
  $resultmasters || die('Error in SQL query: ' . pg_last_error());
  $masterversion = pg_fetch_result($resultmasters, 0);

  _debug('Masterversion', $masterversion);
  
David Morley's avatar
David Morley committed
180 181
  $hidden = $score <= 70;
  _debug('Hidden', $hidden ? 'yes' : 'no');
182 183 184 185 186 187 188 189 190

  if ($hiddennow === 'f' && $hidden && $notify === 't') {
    $to      = $email;
    $headers = ['From: ' . $adminemail, 'Bcc: ' . $adminemail];
    $subject = 'Monitoring notice from poduptime';
    $message = 'Notice for ' . $domain . '. Your score fell to ' . $score . ' and your pod is now marked as hidden.';
    @mail($to, $subject, $message, implode("\r\n", $headers));
    _debug('Mail Notice', 'sent to '.$email);
  }
David Morley's avatar
David Morley committed
191 192 193 194 195
  if ($score > 100) {
    $score = 100;
  } elseif ($score < 0) {
    $score = 0;
  }
196 197
  $weightedscore = ($uptime + $score - (10 - $weight)) / 2;
  _debug('Weighted Score', $weightedscore);
noplanman's avatar
noplanman committed
198

David Morley's avatar
David Morley committed
199
  $timenow    = date('Y-m-d H:i:s');
dmorley's avatar
dmorley committed
200 201
  $sql_set    = 'UPDATE pods SET secure = $2, hidden = $3, ip = $4, ipv6 = $5, monthsmonitored = $6, uptime_alltime = $7, status = $8, date_laststats = $9, date_updated = $10, latency = $11, score = $12, adminrating = $13, country = $14, city = $15, state = $16, lat = $17, long = $18, userrating = $19, shortversion = $20, masterversion = $21, signup = $22, total_users = $23, active_users_halfyear = $24, active_users_monthly = $25, local_posts = $26, name = $27, comment_counts = $28, service_facebook = $29, service_tumblr = $30, service_twitter = $31, service_wordpress = $32, weightedscore = $33, service_xmpp = $34, softwarename = $35, sslvalid = $36, dnssec = $37, sslexpire = $38 WHERE domain = $1';
  $result_set = pg_query_params($dbh, $sql_set, [$domain, 1, (int) $hidden, $ip, (int) ($ipv6 !== null), $months, $uptime, $status, $statslastdate, $timenow, $avglatency, $score, $admin_rating, $country, $city, $state, $lat, $long, $user_rating, $shortversion, $masterversion, (int) $signup, $total_users, $active_users_halfyear, $active_users_monthly, $local_posts, $name, $comment_counts, (int) $service_facebook, (int) $service_tumblr, (int) $service_twitter, (int) $service_wordpress, $weightedscore, (int) $service_xmpp, $softwarename, $outputsslerror, (int) $dnssec, $sslexpire]);
David Morley's avatar
David Morley committed
202 203 204
  $result_set || die('Error in SQL query3: ' . pg_last_error());

  _debug('Score out of 100', $score);
MatrixCrawler's avatar
MatrixCrawler committed
205

206
  echo 'Success '.$domain;
dmorley's avatar
dmorley committed
207
  
David Morley's avatar
David Morley committed
208 209 210
  echo $newline;
  echo $newline;
}
211

David Morley's avatar
David Morley committed
212 213 214 215 216 217 218 219 220
/**
 * Output a debug message and variable value
 * 
 * @param string $label
 * @param mixed  $var
 * @param bool   $dump
 */
function _debug($label, $var = null, $dump = false) {
  global $debug, $newline;
221

David Morley's avatar
David Morley committed
222 223
  if (!$debug) {
    return;
dmorley's avatar
dmorley committed
224
  }
David Morley's avatar
David Morley committed
225 226 227 228 229 230 231 232 233 234
  
  if ($dump || is_array($var)) {
    $output = print_r($var, true); 
  } elseif (is_bool($var)) {
    $output = $var ? 'true' : 'false';
  } else {
    $output = (string) $var;
  }
  
  printf('%s: %s%s', $label, $output, $newline);
235
}