175 lines
4.8 KiB
PHP
175 lines
4.8 KiB
PHP
<?php
|
|
|
|
require_once 'config.php';
|
|
$instance = $config['mastodon-instance'];
|
|
$uid = $config['user-id'];
|
|
$searchurl = $config['search-url'];
|
|
$search = isset($_GET['search']) ? $_GET['search'] : '';
|
|
/* cache files */
|
|
$dbt = "cache-toots.json";
|
|
|
|
/* Exit if search empty */
|
|
if (empty($search)) {
|
|
out("No proper search given");
|
|
die();
|
|
}
|
|
|
|
/* MISC FUNCTIONS */
|
|
function out($data) {
|
|
error_log("[getcomments.php] " . print_r($data, TRUE));
|
|
}
|
|
|
|
/* CACHE FUNCTIONS */
|
|
/* write data to file */
|
|
function write_db($db, $data) {
|
|
// encode and write file
|
|
$encoded = json_encode($data, JSON_PRETTY_PRINT);
|
|
file_put_contents($db, $encoded, LOCK_EX);
|
|
}
|
|
/* access data from file */
|
|
function read_db($db, &$data) {
|
|
if (! file_exists($db)) {
|
|
touch($db);
|
|
}
|
|
$file = file_get_contents($db, true);
|
|
$data = json_decode($file, true);
|
|
}
|
|
|
|
/* TOOT FUNCTIONS */
|
|
function collectToots($instance, $uid, $min_id) {
|
|
$raw = file_get_contents("$instance/api/v1/accounts/$uid/statuses?exclude_reblogs=true&exclude_replies=true&limit=50&min_id=$min_id");
|
|
$json = json_decode($raw, true);
|
|
return($json);
|
|
}
|
|
|
|
|
|
/* Collect all the toots */
|
|
$toots = array();
|
|
/* get id of latest cached toot, and set as $min_id */
|
|
read_db($dbt, $toots);
|
|
if (!empty($toots['0']['id'])) {
|
|
$min_id_cached = $toots['0']['id'];
|
|
$min_id = $min_id_cached;
|
|
} else {
|
|
/* if cached toots do not exist, start from oldest toot */
|
|
$min_id = "0";
|
|
$min_id_cached = "0";
|
|
}
|
|
|
|
|
|
/* test whether there are new toots available */
|
|
$min_id_new = "1";
|
|
while ($min_id_new !== $min_id) {
|
|
$min_id_new = $min_id;
|
|
|
|
$toots = array_merge(collectToots($instance, $uid, $min_id), $toots);
|
|
$min_id = $toots['0']['id'];
|
|
}
|
|
|
|
/* if newer toot has been found, find new URLs */
|
|
// TODO: only look up newly found toots
|
|
if ($min_id !== $min_id_cached) {
|
|
out("New toots found");
|
|
$ids = array_column($toots, 'id');
|
|
|
|
/* Find out if a toot contains the searched URL */
|
|
function analyzeToot($instance, $id, $searchurl) {
|
|
$raw = file_get_contents("$instance/api/v1/statuses/$id");
|
|
$json = json_decode($raw, true);
|
|
|
|
preg_match("|$searchurl.+?(?=\")|i", $json['content'], $matches);
|
|
|
|
if(!empty($matches)) {
|
|
return(strtolower($matches[0]));
|
|
} else {
|
|
return("");
|
|
}
|
|
}
|
|
|
|
$toots = array();
|
|
foreach ($ids as $id) {
|
|
$toots[] = array('id' => $id, 'url' => analyzeToot($instance, $id, $searchurl));
|
|
}
|
|
|
|
write_db($dbt, $toots);
|
|
} else {
|
|
out("No new toots found");
|
|
}
|
|
|
|
/* check if URL from $search exists in $toots */
|
|
// if multiple exist, take the oldest one (highest array position)
|
|
$id = array_keys(array_column($toots, 'url'), strtolower($search));
|
|
if (empty($id)) {
|
|
out("Blog URL \"$search\" has not been found");
|
|
die();
|
|
}
|
|
$id = $toots[end($id)]['id'];
|
|
|
|
/* Extract comments and stats from toot */
|
|
$result = ['comments' => [], 'stats' => ['reblogs' => 0, 'favs' => 0, 'replies' => 0, 'url' => '', 'root' => 0]];
|
|
|
|
function filterComments($descendants, $root, &$result) {
|
|
foreach ($descendants as $d) {
|
|
$result['comments'][$d['id']] = [
|
|
'author' => [
|
|
'display_name' => $d['account']['display_name'] ? $d['account']['display_name'] : $d['account']['username'],
|
|
'avatar' => $d['account']['avatar_static'],
|
|
'url' => $d['account']['url']
|
|
],
|
|
'toot' => $d['content'],
|
|
'date' => $d['created_at'],
|
|
'url' => $d['uri'],
|
|
'reply_to' => $d['in_reply_to_id'],
|
|
'root' => $root,
|
|
];
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
function tootContext($instance, $id, &$result) {
|
|
$raw = file_get_contents("$instance/api/v1/statuses/$id/context");
|
|
$json = json_decode($raw, true);
|
|
filterComments($json['descendants'], $id, $result);
|
|
}
|
|
|
|
function filterStats($stats) {
|
|
$result = [
|
|
'reblogs' => (int)$stats['reblogs_count'],
|
|
'favs' => (int)$stats['favourites_count'],
|
|
'replies' => (int)$stats['replies_count'],
|
|
'url' => $stats['url']
|
|
];
|
|
return $result;
|
|
}
|
|
|
|
function tootStats($instance, $id, &$result) {
|
|
out("Checking ID $id");
|
|
$raw = file_get_contents("$instance/api/v1/statuses/$id");
|
|
$json = json_decode($raw, true);
|
|
$newStats = filterStats($json);
|
|
$result['stats']['reblogs'] += $newStats['reblogs'];
|
|
$result['stats']['favs'] += $newStats['favs'];
|
|
$result['stats']['replies'] += $newStats['replies'];
|
|
if (empty($result['stats']['url'])) {
|
|
$result['stats']['url'] = $newStats['url'];
|
|
}
|
|
}
|
|
|
|
// FIXME: At the moment the API doesn't return the correct replies count so I count it manually
|
|
$result['stats']['replies'] = count($result['comments']);
|
|
$result['stats']['root'] = $id;
|
|
tootContext($instance, $id, $result);
|
|
tootStats($instance, $id, $result);
|
|
|
|
|
|
// headers for not caching the results
|
|
header('Cache-Control: no-cache, must-revalidate');
|
|
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
|
|
|
|
// headers to tell that result is JSON
|
|
header('Content-type: application/json');
|
|
|
|
echo json_encode($result);
|
|
|
|
?>
|