···1111from core.constellation import get_board_activity, get_replies, get_root_posts
1212from core.filters import filter_moderated
1313from core.models import AtUri, AuthError, BBS, Board, MiniDoc, Post, Record
1414-from core.slingshot import get_records_batch, get_records_by_uri, resolve_identities_batch
1414+from core.slingshot import (
1515+ get_records_batch,
1616+ get_records_by_uri,
1717+ resolve_identities_batch,
1818+)
1519from core.util import now_iso
16201721···65696670 records = await get_records_batch(client, backlinks.records)
6771 if banned_dids or hidden_posts:
6868- records = filter_moderated(records, banned_dids or set(), hidden_posts or set())
7272+ records = filter_moderated(
7373+ records, banned_dids or set(), hidden_posts or set()
7474+ )
69757076 for record in records:
7177 thread_uri = record.value.get("root") or record.uri
···8187 root_records = await get_records_by_uri(client, thread_uris)
8288 root_records = [record for record in root_records if not record.value.get("root")]
8389 if banned_dids or hidden_posts:
8484- root_records = filter_moderated(root_records, banned_dids or set(), hidden_posts or set())
9090+ root_records = filter_moderated(
9191+ root_records, banned_dids or set(), hidden_posts or set()
9292+ )
85938694 # Phase 3: Resolve authors and build Post objects
8795 uri_to_did = {record.uri: AtUri.parse(record.uri).did for record in root_records}
···96104 # Set last_activity_at and sort by it (bump order)
97105 for thread in threads:
98106 thread.last_activity_at = last_activity.get(thread.uri, thread.created_at)
9999- threads.sort(key=lambda thread: thread.last_activity_at or thread.created_at, reverse=True)
107107+ threads.sort(
108108+ key=lambda thread: thread.last_activity_at or thread.created_at, reverse=True
109109+ )
100110101111 return threads, scan_cursor
102112···553563 backlinks = await get_replies(client, post_uri, limit=BACKLINK_LIMIT)
554564 records = await get_records_batch(client, backlinks.records)
555565 parsed = {record.uri: AtUri.parse(record.uri) for record in records}
556556- records = [record for record in records if parsed[record.uri].did != did]
566566+ records = [
567567+ record for record in records if parsed[record.uri].did != did
568568+ ]
557569 if not records:
558570 return []
559571···598610599611 records = await get_records_batch(client, backlinks.records)
600612 parsed = {record.uri: AtUri.parse(record.uri) for record in records}
601601- records = [record for record in records if parsed[record.uri].did != did]
613613+ records = [
614614+ record for record in records if parsed[record.uri].did != did
615615+ ]
602616 if not records:
603617 return []
604618
+5-8
core/resolver.py
···5858 board_tasks = []
5959 for uri in board_uris:
6060 parsed = AtUri.parse(uri)
6161- board_tasks.append(get_record(client, parsed.did, parsed.collection, parsed.rkey))
6161+ board_tasks.append(
6262+ get_record(client, parsed.did, parsed.collection, parsed.rkey)
6363+ )
6264 news_task = get_root_posts(client, site_uri)
63656464- results = await asyncio.gather(
6565- *board_tasks, news_task, return_exceptions=True
6666- )
6666+ results = await asyncio.gather(*board_tasks, news_task, return_exceptions=True)
6767 board_records = results[: len(board_uris)]
6868 news_result = results[len(board_uris)]
6969···8888 else:
8989 sysop_news = [ref for ref in news_result.records if ref.did == identity.did]
9090 news_records = await get_records_batch(client, sysop_news)
9191- news = [
9292- post_from_record(record, identity)
9393- for record in news_records
9494- ]
9191+ news = [post_from_record(record, identity) for record in news_records]
9592 news.sort(key=lambda post: post.created_at, reverse=True)
96939794 site = Site(
+4-1
core/slingshot.py
···7171) -> list[Record]:
7272 """Fetch multiple records by AT-URI, skipping failures."""
7373 parsed = [AtUri.parse(uri) for uri in uris]
7474- tasks = [get_record(client, at_uri.did, at_uri.collection, at_uri.rkey) for at_uri in parsed]
7474+ tasks = [
7575+ get_record(client, at_uri.did, at_uri.collection, at_uri.rkey)
7676+ for at_uri in parsed
7777+ ]
7578 results = await asyncio.gather(*tasks, return_exceptions=True)
7679 return [result for result in results if isinstance(result, Record)]
7780
+4-2
telnet/server.py
···126126 for index, thread in enumerate(threads, 1):
127127 date = format_datetime_utc(thread.last_activity_at or thread.created_at)
128128 await write(
129129- writer, f" {index}. {thread.title} · {thread.author.handle} · {date}\r\n"
129129+ writer,
130130+ f" {index}. {thread.title} · {thread.author.handle} · {date}\r\n",
130131 )
131132132133 cmds = ["[#] open thread"]
···151152async def show_replies(writer, replies):
152153 for reply in replies:
153154 await write(
154154- writer, f" {reply.author.handle} · {format_datetime_utc(reply.created_at)}\r\n"
155155+ writer,
156156+ f" {reply.author.handle} · {format_datetime_utc(reply.created_at)}\r\n",
155157 )
156158 for line in reply.body.splitlines():
157159 await write(writer, f" {line}\r\n")
···8080 """Check the user doesn't already have a BBS, then open the create screen."""
8181 session = self.app.user_session
8282 try:
8383- await get_record(
8484- self.app.http_client, session["did"], lexicon.SITE, "self"
8585- )
8383+ await get_record(self.app.http_client, session["did"], lexicon.SITE, "self")
8684 # If we got here the record exists — they already have a BBS.
8785 self.notify(
8886 "You already have a BBS. Dial your handle to manage it.",
···11111212from core import lexicon
1313from core.models import BBS, AtUri, AuthError, Post as PostModel
1414-from core.records import delete_record, hydrate_replies as fetch_replies, post_from_record
1414+from core.records import (
1515+ delete_record,
1616+ hydrate_replies as fetch_replies,
1717+ post_from_record,
1818+)
1519from core.slingshot import get_record, resolve_identity
1620from tui.screens.compose import ComposeReplyScreen
1721from tui.util import ban_user, hide_post, require_session, require_sysop
···171175 )
172176173177 # Focus first reply
174174- replies = [
175175- post for post in self.query(Post) if self._is_reply_widget(post)
176176- ]
178178+ replies = [post for post in self.query(Post) if self._is_reply_widget(post)]
177179 if replies:
178180 replies[0].focus()
179181
+6-2
web/src/components/ErrorPage.tsx
···991010 let title = "Something went wrong.";
1111 let detail: string | null = null;
1212- let action: { to: string; label: string } = { to: "/", label: "← back to home" };
1212+ let action: { to: string; label: string } = {
1313+ to: "/",
1414+ label: "← back to home",
1515+ };
13161417 if (error instanceof BBSNotFoundError) {
1518 title = "BBS not found.";
···1922 if (user) {
2023 detail = "This account isn't running a BBS yet.";
2124 } else {
2222- detail = "This account isn't running a BBS yet. Is this you? Log in to start one.";
2525+ detail =
2626+ "This account isn't running a BBS yet. Is this you? Log in to start one.";
2327 action = { to: "/login", label: "log in" };
2428 }
2529 } else if (error instanceof NetworkError) {
···1515import { mainSchema as siteSchema } from "../lexicons/types/xyz/atbbs/site";
1616import { mainSchema as boardSchema } from "../lexicons/types/xyz/atbbs/board";
1717import { mainSchema as postSchema } from "../lexicons/types/xyz/atbbs/post";
1818-import type {
1919- XyzAtbbsSite,
2020- XyzAtbbsBoard,
2121- XyzAtbbsPost,
2222-} from "../lexicons";
1818+import type { XyzAtbbsSite, XyzAtbbsBoard, XyzAtbbsPost } from "../lexicons";
23192420export class BBSNotFoundError extends Error {}
2521export class NoBBSError extends Error {}
+1-2
web/src/lib/profile.ts
···4242 profileResult.status === "fulfilled" &&
4343 is(profileSchema, profileResult.value.value)
4444 ) {
4545- const value = profileResult.value
4646- .value as unknown as XyzAtbbsProfile.Main;
4545+ const value = profileResult.value.value as unknown as XyzAtbbsProfile.Main;
4746 profile.name = value.name;
4847 profile.pronouns = value.pronouns;
4948 profile.bio = value.bio;