forked from cory/tildefriends
128 lines
3.2 KiB
JavaScript
128 lines
3.2 KiB
JavaScript
async function query(sql, args) {
|
|
let rows = [];
|
|
await ssb.sqlAsync(sql, args ?? [], function (row) {
|
|
rows.push(row);
|
|
});
|
|
return rows;
|
|
}
|
|
|
|
async function get_biggest() {
|
|
return query(`
|
|
select author, sum(length(content)) as size from messages group by author order by size desc limit 10;
|
|
`);
|
|
}
|
|
|
|
async function get_total() {
|
|
return (
|
|
await query(`
|
|
select sum(length(content)) as size, count(distinct author) as count from messages;
|
|
`)
|
|
)[0];
|
|
}
|
|
|
|
async function get_names(identities) {
|
|
return query(
|
|
`
|
|
SELECT author, name FROM (
|
|
SELECT
|
|
messages.author,
|
|
RANK() OVER (PARTITION BY messages.author ORDER BY messages.sequence DESC) AS author_rank,
|
|
messages.content ->> 'name' AS name
|
|
FROM messages
|
|
JOIN json_each(?) AS identities ON identities.value = messages.author
|
|
WHERE
|
|
json_extract(messages.content, '$.type') = 'about' AND
|
|
content ->> 'about' = messages.author AND name IS NOT NULL)
|
|
WHERE author_rank = 1
|
|
`,
|
|
[JSON.stringify(identities)]
|
|
);
|
|
}
|
|
|
|
async function get_most_follows() {
|
|
return query(`
|
|
select author, count(*) as count
|
|
from messages
|
|
where content ->> 'type' = 'contact' and content ->> 'following' = true
|
|
group by author
|
|
order by count desc
|
|
limit 10;
|
|
`);
|
|
}
|
|
|
|
function nice_size(bytes) {
|
|
let value = bytes;
|
|
let index = 0;
|
|
let units = ['B', 'kB', 'MB', 'GB'];
|
|
while (value > 1024 && index < units.length - 1) {
|
|
value /= 1024;
|
|
index++;
|
|
}
|
|
return `${Math.round(value * 10) / 10} ${units[index]}`;
|
|
}
|
|
|
|
async function main() {
|
|
await app.setDocument(
|
|
'<p style="color: #fff">Finding the top 10 largest feeds...</p>'
|
|
);
|
|
let most_follows = await get_most_follows();
|
|
let total = await get_total();
|
|
let identities = await ssb.getAllIdentities();
|
|
let following1 = await ssb.following(identities, 1);
|
|
let following2 = await ssb.following(identities, 2);
|
|
let biggest = await get_biggest();
|
|
let names = await get_names(
|
|
[].concat(
|
|
biggest.map((x) => x.author),
|
|
most_follows.map((x) => x.author)
|
|
)
|
|
);
|
|
names = Object.fromEntries(names.map((x) => [x.author, x.name]));
|
|
for (let item of biggest) {
|
|
item.name = names[item.author];
|
|
item.following =
|
|
identities.indexOf(item.author) != -1
|
|
? 0
|
|
: following1[item.author] !== undefined
|
|
? 1
|
|
: following2[item.author] !== undefined
|
|
? 2
|
|
: undefined;
|
|
}
|
|
for (let item of most_follows) {
|
|
item.name = names[item.author];
|
|
}
|
|
let html = `<body style="color: #000; background-color: #ddd">\n
|
|
<h1>Storage Summary</h1>
|
|
<h2>Top 10 Accounts by Size</h2>
|
|
<ol>`;
|
|
for (let item of biggest) {
|
|
html += `<li>
|
|
<span style="color: #888">${nice_size(item.size)}</span>
|
|
<a target="_top" href="/~core/ssb/#${encodeURI(item.author)}">${item.name ?? item.author}</a>
|
|
</li>
|
|
\n`;
|
|
}
|
|
html += `
|
|
</ol>
|
|
<h2>Top 10 Accounts by Follows</h2>
|
|
<ol>`;
|
|
for (let item of most_follows) {
|
|
html += `<li>
|
|
<span style="color: #888">${item.count}</span>
|
|
${following2[item.author] ? '✅' : '🚫'}
|
|
<a target="_top" href="/~core/ssb/#${encodeURI(item.author)}">${item.name ?? item.author}</a>
|
|
</li>
|
|
\n`;
|
|
}
|
|
html += `
|
|
</ol>
|
|
<p>Total <span style="color: #888">${nice_size(total.size)}</span> in ${total.count} accounts.</p>
|
|
`;
|
|
await app.setDocument(html);
|
|
}
|
|
|
|
main().catch(function (e) {
|
|
print(e);
|
|
});
|