mastodonCzStats/mastodonCzStats.js

70 lines
3.0 KiB
JavaScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env -S npx nodejsscript
/* jshint esversion: 11,-W097, -W040, module: true, node: true, expr: true, undef: true *//* global echo, $, pipe, s, fetch, cyclicLoop */
const store= "./mastodonCzStats.json";
const instances_cz_pre= new Set(s.cat(store).xargs(JSON.parse).instances_cz.map(i=> i.instance));
const { version, description }= s.cat("package.json").xargs(JSON.parse);
const timeOut= (l= 500)=> AbortSignal.timeout(l);
$.api("", true)
.version(version)
.describe(description)
.option("--git", "Commit changes to git")
.action(async function main({ git: is_git }){
let stats= [];
for(const instance of instances_cz_pre){
echo.use("-R", "Shromažďuji instance: " + instance);
const peers= await fetch("https://"+instance+"/api/v1/instance/peers", { signal: timeOut() })
.then(res=> res.json()).catch(()=> []);
if(peers && Array.isArray(peers))
peers.filter(i=> i.endsWith(".cz")).forEach(i=> instances_cz_pre.add(i));
}
const instances_cz= Array.from(instances_cz_pre);
const { length }= instances_cz;
for await(const data of collectStats(instances_cz, 4)){
echo.use("-R", "Shromažďuji data za instance: " + instances_cz.indexOf(data.instance)+"/"+length+": "+data.instance);
stats.push(data);
}
const out= {
instances_cz: stats.sort((a, b)=> b.registrations-a.registrations),
sum: stats.reduce((acc, stats) => sumStats([acc, stats]), { statuses: 0, logins: 0, registrations: 0, mau: 0, user_count: 0 })
};
if(is_git) s.run`git pull --rebase`;
echo(JSON.stringify(out, null, " ")).to(store);
if(is_git) gitCommit([ store ], "cron");
$.exit(0);
})
.parse();
function gitCommit(files, des= "not specified"){
if(!files.length || !s.run`git diff --numstat`.trim())
return echo("Nothig todo");
echo("Diff to save");
s.run`git config user.name "Bot"`;
s.run`git config user.email "${"zc.murtnec@naj.elrdna".split("").reverse().join("")}"`;
s.run`git add ${files}`;
s.run`git commit -m "Updated by bot ${des}"`;
s.run`git push`;
s.run`git config --remove-section user`;
}
async function* collectStats(instances, weeks = 1) {
for(const instance of instances){
const { stats, mau, user_count }= await fetchInstanceStats(instance).catch(e=> ({}));
if(!stats || !Array.isArray(stats)) continue;
yield { instance, mau, user_count, ...sumStats(stats.slice(0, weeks + 1)) };
}
}
function sumStats(arr) {
const out= Object.keys(arr[0]).reduce((acc, curr)=> (acc[curr]= 0, acc), {});
for (const key of Object.keys(out))
for (const s of arr) out[key]+= Number(s[key]);
return out;
}
async function fetchInstanceStats(instance) {
const url_main= "https://" + instance + "/api/";
const stats= await fetch(url_main+"v1/instance/activity", { signal: timeOut() }).then(res=> res.json());
const { usage: { users } }= await fetch(url_main+"v2/instance", { signal: timeOut() }).then(res=> res.json());
const { stats: { user_count } }= await fetch(url_main+"v1/instance", { signal: timeOut() }).then(res=> res.json());
return { instance, stats, mau: users.active_month, user_count };
}