| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | async function query(sql, args) { | 
					
						
							|  |  |  | 	let rows = []; | 
					
						
							| 
									
										
										
										
											2024-11-27 12:07:00 -05:00
										 |  |  | 	await ssb.sqlAsync(sql, args ?? [], function (row) { | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | 		rows.push(row); | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2024-11-27 12:07:00 -05:00
										 |  |  | 	return rows; | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | async function get_biggest() { | 
					
						
							|  |  |  | 	return query(`
 | 
					
						
							| 
									
										
										
										
											2025-04-16 19:21:57 -04:00
										 |  |  | 		select author, size from messages_stats group by author order by size desc limit 10; | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | 	`);
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-26 16:05:28 -05:00
										 |  |  | async function get_total() { | 
					
						
							| 
									
										
										
										
											2024-11-27 12:07:00 -05:00
										 |  |  | 	return ( | 
					
						
							|  |  |  | 		await query(`
 | 
					
						
							| 
									
										
										
										
											2024-11-26 16:05:28 -05:00
										 |  |  | 		select sum(length(content)) as size, count(distinct author) as count from messages; | 
					
						
							| 
									
										
										
										
											2024-11-27 12:07:00 -05:00
										 |  |  | 	`)
 | 
					
						
							|  |  |  | 	)[0]; | 
					
						
							| 
									
										
										
										
											2024-11-26 16:05:28 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | async function get_names(identities) { | 
					
						
							| 
									
										
										
										
											2024-11-27 12:07:00 -05:00
										 |  |  | 	return query( | 
					
						
							|  |  |  | 		`
 | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | 		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 | 
					
						
							| 
									
										
										
										
											2024-11-27 12:07:00 -05:00
										 |  |  | 	`,
 | 
					
						
							|  |  |  | 		[JSON.stringify(identities)] | 
					
						
							|  |  |  | 	); | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-26 16:25:15 -05:00
										 |  |  | 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; | 
					
						
							|  |  |  | 	`);
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | 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() { | 
					
						
							| 
									
										
										
										
											2025-04-16 19:27:24 -04:00
										 |  |  | 	await app.setDocument('<p style="color: #fff">Analyzing feeds...</p>'); | 
					
						
							| 
									
										
										
										
											2025-04-16 19:21:57 -04:00
										 |  |  | 	let most_follows = get_most_follows(); | 
					
						
							| 
									
										
										
										
											2024-11-26 16:05:28 -05:00
										 |  |  | 	let total = await get_total(); | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | 	let identities = await ssb.getAllIdentities(); | 
					
						
							|  |  |  | 	let following1 = await ssb.following(identities, 1); | 
					
						
							|  |  |  | 	let following2 = await ssb.following(identities, 2); | 
					
						
							|  |  |  | 	let biggest = await get_biggest(); | 
					
						
							| 
									
										
										
										
											2025-04-16 19:21:57 -04:00
										 |  |  | 	most_follows = await most_follows; | 
					
						
							| 
									
										
										
										
											2024-11-27 12:07:00 -05:00
										 |  |  | 	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])); | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | 	for (let item of biggest) { | 
					
						
							|  |  |  | 		item.name = names[item.author]; | 
					
						
							|  |  |  | 		item.following = | 
					
						
							| 
									
										
										
										
											2024-11-27 12:07:00 -05:00
										 |  |  | 			identities.indexOf(item.author) != -1 | 
					
						
							|  |  |  | 				? 0 | 
					
						
							|  |  |  | 				: following1[item.author] !== undefined | 
					
						
							|  |  |  | 					? 1 | 
					
						
							|  |  |  | 					: following2[item.author] !== undefined | 
					
						
							|  |  |  | 						? 2 | 
					
						
							|  |  |  | 						: undefined; | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-11-26 16:25:15 -05:00
										 |  |  | 	for (let item of most_follows) { | 
					
						
							|  |  |  | 		item.name = names[item.author]; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | 	let html = `<body style="color: #000; background-color: #ddd">\n
 | 
					
						
							| 
									
										
										
										
											2024-11-26 16:25:15 -05:00
										 |  |  | 		<h1>Storage Summary</h1> | 
					
						
							| 
									
										
										
										
											2025-04-16 19:21:57 -04:00
										 |  |  | 		<h2>Top Accounts by Size</h2> | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | 		<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> | 
					
						
							| 
									
										
										
										
											2024-11-26 16:05:28 -05:00
										 |  |  | 		</li> | 
					
						
							|  |  |  | 		\n`;
 | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-11-26 16:25:15 -05:00
										 |  |  | 	html += `
 | 
					
						
							|  |  |  | 		</ol> | 
					
						
							| 
									
										
										
										
											2025-04-16 19:21:57 -04:00
										 |  |  | 		<h2>Top Accounts by Follows</h2> | 
					
						
							| 
									
										
										
										
											2024-11-26 16:25:15 -05:00
										 |  |  | 		<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`;
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-11-26 16:05:28 -05:00
										 |  |  | 	html += `
 | 
					
						
							|  |  |  | 		</ol> | 
					
						
							|  |  |  | 		<p>Total <span style="color: #888">${nice_size(total.size)}</span> in ${total.count} accounts.</p> | 
					
						
							|  |  |  | 	`;
 | 
					
						
							| 
									
										
										
										
											2024-11-26 15:59:02 -05:00
										 |  |  | 	await app.setDocument(html); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-27 12:07:00 -05:00
										 |  |  | main().catch(function (e) { | 
					
						
							|  |  |  | 	print(e); | 
					
						
							|  |  |  | }); |