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)]); } 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('
Finding the top 10 largest feeds...
'); 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(biggest.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; } let html = `\nTotal ${nice_size(total.size)} in ${total.count} accounts.
`; await app.setDocument(html); } main().catch(function(e) { print(e); });