diff options
| author | Adam Soltys <[email protected]> | 2024-10-10 12:16:41 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-10-10 12:17:05 -0700 |
| commit | 0de0e3ba3719333f3884aeff26992adf1688c6ec (patch) | |
| tree | c0ed293eb942ca34c412f952cb20f049e4b50300 /routes | |
| parent | d734c424f19bbec89274d828c3a2b70dd3ef221a (diff) | |
| download | coinos-server-0de0e3ba3719333f3884aeff26992adf1688c6ec.tar.gz coinos-server-0de0e3ba3719333f3884aeff26992adf1688c6ec.zip | |
2s maxwait
Diffstat (limited to 'routes')
| -rw-r--r-- | routes/nostr.ts | 108 | ||||
| -rw-r--r-- | routes/users.ts | 4 |
2 files changed, 92 insertions, 20 deletions
diff --git a/routes/nostr.ts b/routes/nostr.ts index 573424e3..fa20aa43 100644 --- a/routes/nostr.ts +++ b/routes/nostr.ts @@ -1,7 +1,16 @@ import config from "$config"; -import { bail, chunk, getUser, uniq } from "$lib/utils"; +import { bail, fail, getUser } from "$lib/utils"; import { g, s, db } from "$lib/db"; -import { anon, send, getRelays, serverPubkey, pool } from "$lib/nostr"; +import { + anon, + send, + getCount, + getRelays, + serverPubkey, + pool, +} from "$lib/nostr"; + +let opts = { maxWait: 2000 }; export default { async event(req, res) { @@ -18,6 +27,32 @@ export default { res.send(event); }, + async publish(req, res) { + try { + let { event } = req.body; + let { pubkey } = req.user; + let { write: relays } = await getRelays(pubkey); + if (!relays.includes(config.nostr)) relays.push(config.nostr); + + let ok; + for (let url of relays) { + try { + await send(event, url); + ok = true; + } catch (e) { + console.log("failed to publish to", url); + } + } + + if (!ok) fail("failed to publish"); + if (event.kind === 3) db.del(`${pubkey}:follows`); + + res.send({}); + } catch (e) { + bail(res, e.message); + } + }, + async follows(req, res) { let { params: { pubkey }, @@ -25,38 +60,42 @@ export default { } = req; try { let filter = { kinds: [3], authors: [pubkey] }; - let ev = await pool.get([config.nostr], filter); + let ev = await pool.get([config.nostr], filter, opts); - if (!ev) { + if (!ev || tagsonly) { let { relays } = config; ({ write: relays } = await getRelays(pubkey)); filter = { kinds: [3], authors: [pubkey] }; - pool.get(relays, filter).then(send); + ev = await pool.get(relays, filter, opts); + send(ev); } let created_at; let follows = []; let tags = []; + if (ev) ({ created_at, tags } = ev); if (!tags.length || tagsonly) return res.send(tags); let cache = await g(`${pubkey}:follows`); if (cache && cache.t >= created_at) ({ follows } = cache); else { - let pubkeys = tags.map((t) => t[1]).filter((p) => p.length === 64); + let pubkeys = tags + .map((t) => t[0] === "p" && t[1]) + .filter((p) => p && p.length === 64); let filter: any = { cache: ["user_infos", { pubkeys }] }; - let infos = await pool.querySync([config.cache], filter); + let infos = await pool.querySync([config.cache], filter, opts); let profiles = infos.filter((e) => e.kind === 0); let f = infos.find((e) => e.kind === 10000133); - let followers = {}; - if (f) followers = JSON.parse(f.content); + let counts = {}; + if (f) counts = JSON.parse(f.content); for (let p of profiles) { let { content, pubkey } = p; let user = JSON.parse(content); - user.followers = followers[pubkey]; + user.count = counts[pubkey]; user.pubkey = pubkey; follows.push(user); } @@ -66,7 +105,7 @@ export default { .filter((p) => !followKeys.includes(p)) .map((pubkey) => anon(pubkey)); - follows.sort((a: any, b: any) => b.followers - a.followers); + follows.sort((a: any, b: any) => b.count - a.count); follows.push(...missing); s(`${pubkey}:follows`, { follows, t: created_at }); @@ -84,20 +123,51 @@ export default { params: { pubkey }, } = req; try { - let pubkeys: any = await q({ "#p": [pubkey] }); - pubkeys = pubkeys.map((e) => e.pubkey); + let filter: any = { kinds: [3], "#p": [pubkey] }; + let ev = await pool.get([config.nostr], filter, opts); + let created_at; + if (ev) ({ created_at } = ev); - let followers: any = await q({ authors: [pubkeys], kinds: [0] }); + let followers = []; + let cache = await g(`${pubkey}:followers`); + if (cache && cache.t >= created_at) ({ followers } = cache); + else { + filter = { cache: ["user_followers", { pubkey }] }; + let data = await pool.querySync([config.cache], filter, opts); + for (let ev of data.filter((f) => f.kind === 0)) { + let { content, pubkey } = ev; + let user = JSON.parse(content); + user.pubkey = pubkey; + followers.push(user); + } + + let pubkeys = followers.map((f) => f.pubkey); + filter = { cache: ["user_infos", { pubkeys }] }; + let infos = await pool.querySync([config.cache], filter, opts); - followers = uniq(followers, (e) => e.pubkey); - followers.sort( - (a, b) => a.username && a.username.localeCompare(b.username), - ); + let counts = {}; + let f = infos.find((e) => e.kind === 10000133); + if (f) counts = JSON.parse(f.content); + followers.map((f) => (f.count = counts[f.pubkey])); + followers.sort((a: any, b: any) => b.count - a.count); + + await s(`${pubkey}:followers`, { followers, t: created_at }); + } res.send(followers); } catch (e) { console.log(e); - res.code(500).send(e && e.message); + bail(res, e.message); + } + }, + + async count(req, res) { + try { + let { pubkey } = req.params; + let count = await getCount(pubkey); + res.send(count); + } catch (e) { + bail(res, e.message); } }, diff --git a/routes/users.ts b/routes/users.ts index e1971e78..06eb75ab 100644 --- a/routes/users.ts +++ b/routes/users.ts @@ -15,7 +15,7 @@ import { mail, templates } from "$lib/mail"; import upload from "$lib/upload"; import rpc from "@coinos/rpc"; import { nip19 } from "nostr-tools"; -import { getProfile } from "$lib/nostr"; +import { getCount, getProfile } from "$lib/nostr"; export default { upload, @@ -111,6 +111,7 @@ export default { if (!user) return res.code(500).send("User not found"); let whitelist = [ + "about", "address", "anon", "banner", @@ -127,6 +128,7 @@ export default { "prompt", "pubkey", "username", + "website" ]; if (user.pubkey) user.npub = nip19.npubEncode(user.pubkey); |
