feat: massive performance and logic improvements

This commit is contained in:
2026-02-23 17:17:53 +01:00
parent 96db0131ad
commit a749a6b6aa
2 changed files with 46 additions and 49 deletions

View File

@@ -4,6 +4,7 @@
SPDX-FileCopyrightText: 2019 Björn Schießle
-->
{{ if ne .Params.page true }}
<hr />
<div class="comments-container">
<h5>Comments</h5>
<noscript>

View File

@@ -40,8 +40,8 @@ function write_db($db, $data, $id) {
}
$file['toots'] = $data;
$file['timestamp'] = time();
// encode and write file
$encoded = json_encode($file, JSON_PRETTY_PRINT);
// encode and write file (no pretty print for performance)
$encoded = json_encode($file);
file_put_contents($db, $encoded, LOCK_EX);
}
/* delete file */
@@ -81,22 +81,25 @@ function read_db($db, &$data, $cachetime, &$cachebreak, $id) {
/* TOOT FUNCTIONS */
function collectToots($instance, $uid, $min_id, $searchurl) {
$raw = file_get_contents("$instance/api/v1/accounts/$uid/statuses?exclude_reblogs=true&exclude_replies=true&limit=50&min_id=$min_id");
$raw = @file_get_contents("$instance/api/v1/accounts/$uid/statuses?exclude_reblogs=true&exclude_replies=true&limit=50&min_id=$min_id");
if ($raw === false) {
debug("Failed to fetch toots from API");
return array();
}
$json_complete = json_decode($raw, true);
$json = array();
foreach ($json_complete as $toot) {
$json[] = array('id' => $toot['id'], 'date' => $toot['created_at'] ,'url' => analyzeToot($instance, $toot['id'], $searchurl));
$url = analyzeToot($toot['content'], $toot['id'], $searchurl);
$json[] = array('id' => $toot['id'], 'date' => $toot['created_at'] ,'url' => $url);
}
return($json);
}
/* Find out if a toot contains the searched URL */
function analyzeToot($instance, $id, $searchurl) {
function analyzeToot($content, $id, $searchurl) {
debug("Searching for $searchurl in $id");
$raw = file_get_contents("$instance/api/v1/statuses/$id");
$json = json_decode($raw, true);
// search for $searchurl inside of <a> tags, until (and excluding) a "
preg_match("|$searchurl.+?(?=\")|i", $json['content'], $matches);
preg_match("|$searchurl.+?(?=\")|i", $content, $matches);
if(!empty($matches)) {
return(strtolower($matches[0])); // take first match inside toot
@@ -123,33 +126,29 @@ function filterComments($descendants, $root, &$result) {
}
return $result;
}
/* get /context of toot */
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);
}
/* extract stats info from toot */
function filterStats($stats) {
$result = [
'reblogs' => (int)$stats['reblogs_count'],
'favs' => (int)$stats['favourites_count'],
'replies' => (int)$stats['replies_count'],
'url' => $stats['url']
];
return $result;
}
/* for toot, extract interesting statistics */
function tootStats($instance, $id, &$result) {
debug("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'];
/* get /context of toot and extract stats - combined to reduce API calls */
function tootContextAndStats($instance, $id, &$result) {
debug("Fetching context and stats for ID $id");
// Fetch context (descendants/replies)
$raw_context = @file_get_contents("$instance/api/v1/statuses/$id/context");
if ($raw_context !== false) {
$json_context = json_decode($raw_context, true);
filterComments($json_context['descendants'], $id, $result);
} else {
debug("Failed to fetch context for $id");
}
// Fetch stats
$raw_stats = @file_get_contents("$instance/api/v1/statuses/$id");
if ($raw_stats !== false) {
$json_stats = json_decode($raw_stats, true);
$result['stats']['reblogs'] = (int)$json_stats['reblogs_count'];
$result['stats']['favs'] = (int)$json_stats['favourites_count'];
$result['stats']['replies'] = (int)$json_stats['replies_count'];
$result['stats']['url'] = $json_stats['url'];
} else {
debug("Failed to fetch stats for $id");
}
}
@@ -202,19 +201,17 @@ $result_empty = ['comments' => [], 'stats' => ['reblogs' => 0, 'favs' => 0, 'rep
$result = $result_empty;
/* check if URL from $search exists in $toots */
$id = array_keys(
array_filter(
array_column($toots, 'url'),
function ($value) use ($search) {
return (strpos($value, $search) !== false);
}
)
);
if (empty($id)) {
$found_id = null;
foreach ($toots as $toot) {
if (!empty($toot['url']) && strpos($toot['url'], $search) !== false) {
$found_id = $toot['id']; // will keep the oldest (last in array)
}
}
if ($found_id === null) {
debug("Blog URL \"$search\" has not been found");
} else {
// if multiple toots with the searched URL exist, take the oldest one (largest array index)
$id = $toots[end($id)]['id'];
$id = $found_id;
/* read cached comments, or reload new comments if cached data too old */
$cachebreak = false;
@@ -228,9 +225,8 @@ if (empty($id)) {
$result = $result_empty;
read_db($dbc, $result, $ctc, $cachebreak, $id);
/* Extract comments and stats from toot */
tootContext($instance, $id, $result);
tootStats($instance, $id, $result);
// FIXME: At the moment the API doesn't return the correct replies count so I count it manually
tootContextAndStats($instance, $id, $result);
// Always count replies manually for accuracy
$result['stats']['replies'] = count($result['comments']);
$result['stats']['root'] = $id;