forked from cory/tildefriends
		
	
		
			
				
	
	
		
			127 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			127 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, size from messages_stats 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">Analyzing feeds...</p>');
 | 
						|
	let most_follows = 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();
 | 
						|
	most_follows = await most_follows;
 | 
						|
	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 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 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);
 | 
						|
});
 |