aboutsummaryrefslogtreecommitdiffstats
path: root/routes
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-10-10 12:16:41 -0700
committerAdam Soltys <[email protected]>2024-10-10 12:17:05 -0700
commit0de0e3ba3719333f3884aeff26992adf1688c6ec (patch)
treec0ed293eb942ca34c412f952cb20f049e4b50300 /routes
parentd734c424f19bbec89274d828c3a2b70dd3ef221a (diff)
downloadcoinos-server-0de0e3ba3719333f3884aeff26992adf1688c6ec.tar.gz
coinos-server-0de0e3ba3719333f3884aeff26992adf1688c6ec.zip
2s maxwait
Diffstat (limited to 'routes')
-rw-r--r--routes/nostr.ts108
-rw-r--r--routes/users.ts4
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);