Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cdd5d40236
|
||
|
|
dcd79bb343
|
||
|
|
62e47ea4d0
|
||
|
|
a5924efd91
|
||
|
|
6993cdcee9
|
@@ -1,5 +1,15 @@
|
|||||||
|
{{ if ne .Params.page true }}
|
||||||
<div class="comments-container">
|
<div class="comments-container">
|
||||||
<h5>Comments</h5>
|
<h5>Comments</h5>
|
||||||
|
<noscript>
|
||||||
|
<p class="bg-info" style="text-align: center; padding: 5px;">
|
||||||
|
Comments are only visible with JavaScript enabled. They are
|
||||||
|
dynamically loaded from Mastodon. The code to display the
|
||||||
|
comments is Free Software and <a
|
||||||
|
href="https://src.mehl.mx/mxmehl/hugo-mastodon-comments">completely
|
||||||
|
transparent</a>.
|
||||||
|
</p>
|
||||||
|
</noscript>
|
||||||
<div id="statistics">
|
<div id="statistics">
|
||||||
<div id="like-count-container"></div><div id="reblog-count-container"></div><div id="reply-count-container"></div>
|
<div id="like-count-container"></div><div id="reblog-count-container"></div><div id="reply-count-container"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -8,6 +18,7 @@
|
|||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
<div id="reference"></div>
|
<div id="reference"></div>
|
||||||
</div>
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
<script>var RelPermalink="{{ .RelPermalink }}"</script>
|
<script>var RelPermalink="{{ .RelPermalink }}"</script>
|
||||||
<script>var MastodonUser="{{ .Site.Params.mastodoncomments.user }}"</script>
|
<script>var MastodonUser="{{ .Site.Params.mastodoncomments.user }}"</script>
|
||||||
|
|||||||
@@ -3,5 +3,7 @@ $config = [
|
|||||||
'mastodon-instance' => 'https://mastodon.social',
|
'mastodon-instance' => 'https://mastodon.social',
|
||||||
'user-id' => 379833,
|
'user-id' => 379833,
|
||||||
'search-url' => 'https?://fsfe.org', // please use https?:// as schema
|
'search-url' => 'https?://fsfe.org', // please use https?:// as schema
|
||||||
'threshold' => 300
|
'cache_toots' => 300,
|
||||||
|
'cache_comments' => 300,
|
||||||
|
'debug' => true
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
// check if we show a blog post or not. Regex is defined in site-wide config
|
// check if we show a blog post or not. Regex is defined in site-wide config
|
||||||
var patt = new RegExp(BlogRegex);
|
var patt = new RegExp(BlogRegex);
|
||||||
console.log(patt);
|
|
||||||
var isArticle = patt.test(RelPermalink);
|
var isArticle = patt.test(RelPermalink);
|
||||||
if (isArticle === false) {
|
if (isArticle === false) {
|
||||||
console.log("Not a blog post, no need to search for comments");
|
console.log("Not a blog post, no need to search for comments");
|
||||||
@@ -13,7 +12,7 @@ $(document).ready(function() {
|
|||||||
url: "/comments/getcomments.php",
|
url: "/comments/getcomments.php",
|
||||||
type: "get",
|
type: "get",
|
||||||
data: {
|
data: {
|
||||||
search : "https://fsfe.org/news/2019/news-20190326-01.html"
|
search : RelPermalink
|
||||||
},
|
},
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
var stats = data.stats;
|
var stats = data.stats;
|
||||||
|
|||||||
@@ -5,9 +5,12 @@ $instance = $config['mastodon-instance'];
|
|||||||
$uid = $config['user-id'];
|
$uid = $config['user-id'];
|
||||||
$searchurl = $config['search-url'];
|
$searchurl = $config['search-url'];
|
||||||
$search = isset($_GET['search']) ? $_GET['search'] : '';
|
$search = isset($_GET['search']) ? $_GET['search'] : '';
|
||||||
$debug_on = true;
|
$debug_on = $config['debug'];
|
||||||
/* cache files */
|
/* cache files */
|
||||||
|
$ctt = $config['cache_toots'];
|
||||||
$dbt = "cache-toots.json";
|
$dbt = "cache-toots.json";
|
||||||
|
$ctc = $config['cache_comments'];
|
||||||
|
$dbc = "cache-comments_%id.json";
|
||||||
|
|
||||||
/* Exit if search empty */
|
/* Exit if search empty */
|
||||||
if (empty($search)) {
|
if (empty($search)) {
|
||||||
@@ -25,20 +28,42 @@ function debug($data) {
|
|||||||
|
|
||||||
/* CACHE FUNCTIONS */
|
/* CACHE FUNCTIONS */
|
||||||
/* write data to file */
|
/* write data to file */
|
||||||
function write_db($db, $data) {
|
function write_db($db, $data, $id) {
|
||||||
|
// if $id is given, it's a comments file. Replace placeholder in filename
|
||||||
|
if ($id) {
|
||||||
|
$db = str_replace('%id', $id, $db);
|
||||||
|
}
|
||||||
|
$file['toots'] = $data;
|
||||||
|
$file['timestamp'] = time();
|
||||||
// encode and write file
|
// encode and write file
|
||||||
$encoded = json_encode($data, JSON_PRETTY_PRINT);
|
$encoded = json_encode($file, JSON_PRETTY_PRINT);
|
||||||
file_put_contents($db, $encoded, LOCK_EX);
|
file_put_contents($db, $encoded, LOCK_EX);
|
||||||
}
|
}
|
||||||
/* access data from file */
|
/* access data from file */
|
||||||
function read_db($db, &$data) {
|
function read_db($db, &$data, $cachetime, &$cachebreak, $id) {
|
||||||
|
// if $id is given, it's a comments file. Replace placeholder in filename
|
||||||
|
if ($id) {
|
||||||
|
$db = str_replace('%id', $id, $db);
|
||||||
|
}
|
||||||
// if DB does not exist, create it with empty array
|
// if DB does not exist, create it with empty array
|
||||||
if (! file_exists($db)) {
|
if (! file_exists($db)) {
|
||||||
|
// if $data empty (usually with $toots, not with comment's $result), populate with empty array
|
||||||
|
if (empty($data)) {
|
||||||
|
$data = array();
|
||||||
|
}
|
||||||
touch($db);
|
touch($db);
|
||||||
write_db($db, array());
|
write_db($db, $data, $id);
|
||||||
|
$cachebreak = true;
|
||||||
}
|
}
|
||||||
$file = file_get_contents($db, true);
|
$file = file_get_contents($db, true);
|
||||||
$data = json_decode($file, true);
|
$data = json_decode($file, true);
|
||||||
|
|
||||||
|
// check if timestamp in cache file too old
|
||||||
|
if (empty($data['timestamp']) || ($data['timestamp'] + $cachetime < time())) {
|
||||||
|
$cachebreak = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $data['toots'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TOOT FUNCTIONS */
|
/* TOOT FUNCTIONS */
|
||||||
@@ -53,7 +78,7 @@ function collectToots($instance, $uid, $min_id, $searchurl) {
|
|||||||
}
|
}
|
||||||
/* Find out if a toot contains the searched URL */
|
/* Find out if a toot contains the searched URL */
|
||||||
function analyzeToot($instance, $id, $searchurl) {
|
function analyzeToot($instance, $id, $searchurl) {
|
||||||
debug("Searching for $searchurl in $id");
|
//debug("Searching for $searchurl in $id");
|
||||||
$raw = file_get_contents("$instance/api/v1/statuses/$id");
|
$raw = file_get_contents("$instance/api/v1/statuses/$id");
|
||||||
$json = json_decode($raw, true);
|
$json = json_decode($raw, true);
|
||||||
|
|
||||||
@@ -65,51 +90,7 @@ function analyzeToot($instance, $id, $searchurl) {
|
|||||||
return("");
|
return("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* of context, extract the interesting bits */
|
||||||
|
|
||||||
/* Collect all the toots */
|
|
||||||
/* get id of latest cached toot, and set as $min_id */
|
|
||||||
read_db($dbt, $toots);
|
|
||||||
$toots_cached = $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 */
|
|
||||||
// Search for toots older than the cached latest toot ID ($min_id)
|
|
||||||
$uptodate = false;
|
|
||||||
while ($uptodate === false) {
|
|
||||||
$toots = array_merge(collectToots($instance, $uid, $min_id, $searchurl), $toots);
|
|
||||||
$min_id_new = $toots['0']['id']; // the latest ID of the recent search
|
|
||||||
if ($min_id_new === $min_id) {
|
|
||||||
// min_id is the latest, let's write the new DB and end this loop
|
|
||||||
$uptodate = true;
|
|
||||||
debug("Rewrite cache DB.");
|
|
||||||
write_db($dbt, $toots);
|
|
||||||
} else {
|
|
||||||
// next round looks for toots newer than the newly found ID
|
|
||||||
debug("Newer toots than in cache found. Starting another search for new toots");
|
|
||||||
$min_id = $min_id_new;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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)) {
|
|
||||||
debug("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) {
|
function filterComments($descendants, $root, &$result) {
|
||||||
foreach ($descendants as $d) {
|
foreach ($descendants as $d) {
|
||||||
$result['comments'][$d['id']] = [
|
$result['comments'][$d['id']] = [
|
||||||
@@ -127,13 +108,13 @@ function filterComments($descendants, $root, &$result) {
|
|||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
/* get /context of toot */
|
||||||
function tootContext($instance, $id, &$result) {
|
function tootContext($instance, $id, &$result) {
|
||||||
$raw = file_get_contents("$instance/api/v1/statuses/$id/context");
|
$raw = file_get_contents("$instance/api/v1/statuses/$id/context");
|
||||||
$json = json_decode($raw, true);
|
$json = json_decode($raw, true);
|
||||||
filterComments($json['descendants'], $id, $result);
|
filterComments($json['descendants'], $id, $result);
|
||||||
}
|
}
|
||||||
|
/* extract stats info from toot */
|
||||||
function filterStats($stats) {
|
function filterStats($stats) {
|
||||||
$result = [
|
$result = [
|
||||||
'reblogs' => (int)$stats['reblogs_count'],
|
'reblogs' => (int)$stats['reblogs_count'],
|
||||||
@@ -143,7 +124,7 @@ function filterStats($stats) {
|
|||||||
];
|
];
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
/* for toot, extract interesting statistics */
|
||||||
function tootStats($instance, $id, &$result) {
|
function tootStats($instance, $id, &$result) {
|
||||||
debug("Checking ID $id");
|
debug("Checking ID $id");
|
||||||
$raw = file_get_contents("$instance/api/v1/statuses/$id");
|
$raw = file_get_contents("$instance/api/v1/statuses/$id");
|
||||||
@@ -157,12 +138,79 @@ function tootStats($instance, $id, &$result) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: At the moment the API doesn't return the correct replies count so I count it manually
|
/***************
|
||||||
$result['stats']['replies'] = count($result['comments']);
|
* START PROGRAM
|
||||||
$result['stats']['root'] = $id;
|
***************/
|
||||||
tootContext($instance, $id, $result);
|
|
||||||
tootStats($instance, $id, $result);
|
|
||||||
|
|
||||||
|
/* check whether the cached file containing all toots is older than max. cache time */
|
||||||
|
// this at the same time loads the cached DB, either way
|
||||||
|
$cachebreak = false;
|
||||||
|
read_db($dbt, $toots, $ctt, $cachebreak, false);
|
||||||
|
|
||||||
|
if ($cachebreak) {
|
||||||
|
/* Collect all the toots */
|
||||||
|
/* get id of latest cached toot, and set as $min_id */
|
||||||
|
debug("Toots cache outdated. Checking for new 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 */
|
||||||
|
// Search for toots older than the cached latest toot ID ($min_id)
|
||||||
|
$uptodate = false;
|
||||||
|
while ($uptodate === false) {
|
||||||
|
$toots = array_merge(collectToots($instance, $uid, $min_id, $searchurl), $toots);
|
||||||
|
$min_id_new = $toots['0']['id']; // the latest ID of the recent search
|
||||||
|
|
||||||
|
if ($min_id_new === $min_id) {
|
||||||
|
// min_id is the latest, let's write the new DB and end this loop
|
||||||
|
$uptodate = true;
|
||||||
|
debug("Toots up-to-date. Rewrite cache DB.");
|
||||||
|
write_db($dbt, $toots, false);
|
||||||
|
} else {
|
||||||
|
// next round looks for toots newer than the newly found ID
|
||||||
|
debug("Newer toots than in cache found. Starting another search for new toots");
|
||||||
|
$min_id = $min_id_new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
debug("Toots cache is up-to-date");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prepare $result array */
|
||||||
|
$result = ['comments' => [], 'stats' => ['reblogs' => 0, 'favs' => 0, 'replies' => 0, 'url' => '', 'root' => 0]];
|
||||||
|
|
||||||
|
/* check if URL from $search exists in $toots */
|
||||||
|
$id = array_keys(array_column($toots, 'url'), strtolower($search));
|
||||||
|
if (empty($id)) {
|
||||||
|
debug("Blog URL \"$search\" has not been found");
|
||||||
|
} else {
|
||||||
|
// if multiple exist, take the oldest one (highest array position)
|
||||||
|
$id = $toots[end($id)]['id'];
|
||||||
|
|
||||||
|
/* read cached comments, or reload new comments if cached data too old */
|
||||||
|
$cachebreak = false;
|
||||||
|
read_db($dbc, $result, $ctc, $cachebreak, $id);
|
||||||
|
|
||||||
|
if ($cachebreak) {
|
||||||
|
debug("Comments cache for $id outdated. Checking for new comments");
|
||||||
|
/* 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
|
||||||
|
$result['stats']['replies'] = count($result['comments']);
|
||||||
|
$result['stats']['root'] = $id;
|
||||||
|
|
||||||
|
write_db($dbc, $result, $id);
|
||||||
|
} else {
|
||||||
|
debug("Comments cache for $id up-to-date. Returning cached comments");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// headers for not caching the results
|
// headers for not caching the results
|
||||||
header('Cache-Control: no-cache, must-revalidate');
|
header('Cache-Control: no-cache, must-revalidate');
|
||||||
|
|||||||
Reference in New Issue
Block a user