Refactor article fetching

* Apply different limits to profile and feed
* Ensure the limit is the returned amount
* Pre-sort articles
This commit is contained in:
Râu Cao 2024-10-26 12:04:06 +02:00
parent 0b1eca87b2
commit 010eb3f291
Signed by: raucao
GPG Key ID: 37036C356E56CC51
4 changed files with 13 additions and 11 deletions

View File

@ -2,7 +2,6 @@ import { Context } from "@oak/oak";
import { lookupPubkeyByUsername } from "../directory.ts"; import { lookupPubkeyByUsername } from "../directory.ts";
import { fetchArticlesByAuthor, fetchProfileEvent } from "../nostr.ts"; import { fetchArticlesByAuthor, fetchProfileEvent } from "../nostr.ts";
import { profileAtomFeed } from "../feeds.ts"; import { profileAtomFeed } from "../feeds.ts";
import Article from "../models/article.ts";
import Profile from "../models/profile.ts"; import Profile from "../models/profile.ts";
import { notFoundHandler } from "../handlers/errors.ts"; import { notFoundHandler } from "../handlers/errors.ts";
@ -21,8 +20,7 @@ const userAtomFeedHandler = async function (ctx: Context) {
const profile = new Profile(profileEvent, username); const profile = new Profile(profileEvent, username);
if (profile.nip05) { if (profile.nip05) {
const articleEvents = await fetchArticlesByAuthor(pubkey); const articles = await fetchArticlesByAuthor(pubkey, 10);
const articles = articleEvents.map((a) => new Article(a));
const atom = await profileAtomFeed(profile, articles); const atom = await profileAtomFeed(profile, articles);
ctx.response.headers.set("Content-Type", "application/atom+xml"); ctx.response.headers.set("Content-Type", "application/atom+xml");

View File

@ -1,7 +1,6 @@
import { Context } from "@oak/oak"; import { Context } from "@oak/oak";
import { lookupPubkeyByUsername } from "../directory.ts"; import { lookupPubkeyByUsername } from "../directory.ts";
import { fetchArticlesByAuthor, fetchProfileEvent } from "../nostr.ts"; import { fetchArticlesByAuthor, fetchProfileEvent } from "../nostr.ts";
import Article from "../models/article.ts";
import Profile from "../models/profile.ts"; import Profile from "../models/profile.ts";
import { profilePageHtml } from "../html.ts"; import { profilePageHtml } from "../html.ts";
import { notFoundHandler } from "../handlers/errors.ts"; import { notFoundHandler } from "../handlers/errors.ts";
@ -20,8 +19,7 @@ const userProfileHandler = async function (ctx: Context) {
if (profileEvent) { if (profileEvent) {
const profile = new Profile(profileEvent, username); const profile = new Profile(profileEvent, username);
const articleEvents = await fetchArticlesByAuthor(pubkey); const articles = await fetchArticlesByAuthor(pubkey, 210);
const articles = articleEvents.map((a) => new Article(a));
const html = await profilePageHtml(profile, articles); const html = await profilePageHtml(profile, articles);
generateOgProfileImage(profile); generateOgProfileImage(profile);

View File

@ -92,10 +92,9 @@ function articleListItemHtml(article: Article): string {
export function articleListHtml(articles: Article[]): string { export function articleListHtml(articles: Article[]): string {
if (articles.length === 0) return ""; if (articles.length === 0) return "";
const sortedArticles = articles.sort((a, b) => b.publishedAt - a.publishedAt);
let html = ""; let html = "";
for (const article of sortedArticles) { for (const article of articles) {
html += articleListItemHtml(article); html += articleListItemHtml(article);
} }

View File

@ -2,6 +2,7 @@ import { NostrEvent, NostrFilter, NPool, NRelay1 } from "@nostrify/nostrify";
import { nip19 } from "@nostr/tools"; import { nip19 } from "@nostr/tools";
import { lookupUsernameByPubkey } from "./directory.ts"; import { lookupUsernameByPubkey } from "./directory.ts";
import config from "./config.ts"; import config from "./config.ts";
import Article from "./models/article.ts";
const relayPool = new NPool({ const relayPool = new NPool({
open: (url) => new NRelay1(url), open: (url) => new NRelay1(url),
@ -49,14 +50,20 @@ export async function fetchReplaceableEvent(
} }
} }
export async function fetchArticlesByAuthor(pubkey: string) { export async function fetchArticlesByAuthor(
pubkey: string,
limit: number = 10,
) {
const events = await fetchWithTimeout([{ const events = await fetchWithTimeout([{
authors: [pubkey], authors: [pubkey],
kinds: [30023], kinds: [30023],
limit: 210, limit: limit,
}]) as NostrEvent[]; }]) as NostrEvent[];
return events; const articles = events.map((a) => new Article(a));
const sortedArticles = articles.sort((a, b) => b.publishedAt - a.publishedAt);
// The limit seems to apply per relay, not per pool query
return sortedArticles.slice(0, limit);
} }
export async function fetchProfileEvent(pubkey: string) { export async function fetchProfileEvent(pubkey: string) {