feat: massive performance and logic improvements
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user