wip: adding featured

This commit is contained in:
Namekuji 2023-08-22 10:10:43 -04:00
parent c11a1bc110
commit 317d5df5f3
No known key found for this signature in database
GPG key ID: 1D62332C07FBA532
3 changed files with 85 additions and 12 deletions

View file

@ -76,7 +76,7 @@ CREATE TABLE note ( -- Store all posts
"reactions" map<text, int>, -- Reactions "reactions" map<text, int>, -- Reactions
"noteEdit" set<frozen<note_edit_history>>, -- Edit History "noteEdit" set<frozen<note_edit_history>>, -- Edit History
"updatedAt" timestamp, "updatedAt" timestamp,
PRIMARY KEY ("createdAtDate", "createdAt", "userId", "userHost", "visibility") PRIMARY KEY ("createdAtDate", "createdAt", "userId", "userHost", "visibility", "score")
) WITH CLUSTERING ORDER BY ("createdAt" DESC); ) WITH CLUSTERING ORDER BY ("createdAt" DESC);
CREATE INDEX note_by_uri ON note ("uri"); CREATE INDEX note_by_uri ON note ("uri");
@ -91,7 +91,8 @@ CREATE MATERIALIZED VIEW note_by_id AS
AND "userId" IS NOT NULL AND "userId" IS NOT NULL
AND "userHost" IS NOT NULL AND "userHost" IS NOT NULL
AND "visibility" IS NOT NULL AND "visibility" IS NOT NULL
PRIMARY KEY ("id", "createdAt", "createdAtDate", "userId", "userHost", "visibility") AND "score" IS NOT NULL
PRIMARY KEY ("id", "createdAt", "createdAtDate", "userId", "userHost", "visibility", "score")
WITH CLUSTERING ORDER BY ("createdAt" DESC); WITH CLUSTERING ORDER BY ("createdAt" DESC);
CREATE MATERIALIZED VIEW note_by_user_id AS CREATE MATERIALIZED VIEW note_by_user_id AS
@ -101,7 +102,8 @@ CREATE MATERIALIZED VIEW note_by_user_id AS
AND "createdAtDate" IS NOT NULL AND "createdAtDate" IS NOT NULL
AND "userHost" IS NOT NULL AND "userHost" IS NOT NULL
AND "visibility" IS NOT NULL AND "visibility" IS NOT NULL
PRIMARY KEY ("userId", "createdAt", "createdAtDate", "userHost", "visibility") AND "score" IS NOT NULL
PRIMARY KEY ("userId", "createdAt", "createdAtDate", "userHost", "visibility", "score")
WITH CLUSTERING ORDER BY ("createdAt" DESC); WITH CLUSTERING ORDER BY ("createdAt" DESC);
CREATE MATERIALIZED VIEW note_by_renote_id AS CREATE MATERIALIZED VIEW note_by_renote_id AS
@ -112,7 +114,8 @@ CREATE MATERIALIZED VIEW note_by_renote_id AS
AND "userId" IS NOT NULL AND "userId" IS NOT NULL
AND "userHost" IS NOT NULL AND "userHost" IS NOT NULL
AND "visibility" IS NOT NULL AND "visibility" IS NOT NULL
PRIMARY KEY ("renoteId", "createdAt", "createdAtDate", "userId", "userHost", "visibility") AND "score" IS NOT NULL
PRIMARY KEY ("renoteId", "createdAt", "createdAtDate", "userId", "userHost", "visibility", "score")
WITH CLUSTERING ORDER BY ("createdAt" DESC); WITH CLUSTERING ORDER BY ("createdAt" DESC);
CREATE MATERIALIZED VIEW note_by_renote_id_and_user_id AS CREATE MATERIALIZED VIEW note_by_renote_id_and_user_id AS
@ -123,7 +126,8 @@ CREATE MATERIALIZED VIEW note_by_renote_id_and_user_id AS
AND "userId" IS NOT NULL AND "userId" IS NOT NULL
AND "userHost" IS NOT NULL AND "userHost" IS NOT NULL
AND "visibility" IS NOT NULL AND "visibility" IS NOT NULL
PRIMARY KEY (("renoteId", "userId"), "createdAt", "createdAtDate", "userHost", "visibility") AND "score" IS NOT NULL
PRIMARY KEY (("renoteId", "userId"), "createdAt", "createdAtDate", "userHost", "visibility", "score")
WITH CLUSTERING ORDER BY ("createdAt" DESC); WITH CLUSTERING ORDER BY ("createdAt" DESC);
CREATE MATERIALIZED VIEW note_by_channel_id AS CREATE MATERIALIZED VIEW note_by_channel_id AS
@ -134,7 +138,8 @@ CREATE MATERIALIZED VIEW note_by_channel_id AS
AND "userId" IS NOT NULL AND "userId" IS NOT NULL
AND "userHost" IS NOT NULL AND "userHost" IS NOT NULL
AND "visibility" IS NOT NULL AND "visibility" IS NOT NULL
PRIMARY KEY ("channelId", "createdAt", "createdAtDate", "userId", "userHost", "visibility") AND "score" IS NOT NULL
PRIMARY KEY ("channelId", "createdAt", "createdAtDate", "userId", "userHost", "visibility", "score")
WITH CLUSTERING ORDER BY ("createdAt" DESC); WITH CLUSTERING ORDER BY ("createdAt" DESC);
CREATE MATERIALIZED VIEW global_timeline AS CREATE MATERIALIZED VIEW global_timeline AS
@ -143,8 +148,9 @@ CREATE MATERIALIZED VIEW global_timeline AS
AND "createdAt" IS NOT NULL AND "createdAt" IS NOT NULL
AND "userId" IS NOT NULL AND "userId" IS NOT NULL
AND "userHost" IS NOT NULL AND "userHost" IS NOT NULL
AND "score" IS NOT NULL
AND "visibility" = 'public' AND "visibility" = 'public'
PRIMARY KEY ("createdAtDate", "createdAt", "userId", "userHost", "visibility") PRIMARY KEY ("createdAtDate", "createdAt", "userId", "userHost", "visibility", "score")
WITH CLUSTERING ORDER BY ("createdAt" DESC); WITH CLUSTERING ORDER BY ("createdAt" DESC);
CREATE MATERIALIZED VIEW local_timeline AS CREATE MATERIALIZED VIEW local_timeline AS
@ -154,7 +160,8 @@ CREATE MATERIALIZED VIEW local_timeline AS
AND "userId" IS NOT NULL AND "userId" IS NOT NULL
AND "userHost" = 'local' AND "userHost" = 'local'
AND "visibility" = 'public' AND "visibility" = 'public'
PRIMARY KEY ("createdAtDate", "createdAt", "userId", "userHost", "visibility") AND "score" IS NOT NULL
PRIMARY KEY ("createdAtDate", "createdAt", "userId", "userHost", "visibility", "score")
WITH CLUSTERING ORDER BY ("createdAt" DESC); WITH CLUSTERING ORDER BY ("createdAt" DESC);
CREATE MATERIALIZED VIEW score_feed AS CREATE MATERIALIZED VIEW score_feed AS
@ -165,7 +172,8 @@ CREATE MATERIALIZED VIEW score_feed AS
AND "userHost" IS NOT NULL AND "userHost" IS NOT NULL
AND "score" IS NOT NULL AND "score" IS NOT NULL
AND "visibility" = 'public' AND "visibility" = 'public'
PRIMARY KEY ("createdAtDate", "score", "createdAt", "userId", "userHost", "visibility") AND "score" > 0
PRIMARY KEY ("createdAtDate", "score", "userHost", "createdAt", "userId" "visibility")
WITH CLUSTERING ORDER BY ("score" DESC, "createdAt" DESC); WITH CLUSTERING ORDER BY ("score" DESC, "createdAt" DESC);
CREATE TABLE home_timeline ( CREATE TABLE home_timeline (

View file

@ -143,6 +143,9 @@ export const scyllaQueries = {
byDate: `SELECT * FROM global_timeline WHERE "createdAtDate" = ?`, byDate: `SELECT * FROM global_timeline WHERE "createdAtDate" = ?`,
}, },
}, },
scoreFeed: {
select: `SELECT * FROM score_feed WHERE "createdAtDate" = ?`,
},
reaction: { reaction: {
insert: `INSERT INTO reaction insert: `INSERT INTO reaction
("id", "noteId", "userId", "reaction", "emoji", "createdAt") ("id", "noteId", "userId", "reaction", "emoji", "createdAt")

View file

@ -1,7 +1,23 @@
import { Notes } from "@/models/index.js"; import { Notes, UserProfiles } from "@/models/index.js";
import define from "../../define.js"; import define from "../../define.js";
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js"; import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js"; import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import {
type ScyllaNote,
scyllaClient,
prepared,
parseScyllaNote,
filterMutedNote,
filterMutedUser,
filterBlockUser,
} from "@/db/scylla.js";
import {
InstanceMutingsCache,
UserBlockedCache,
UserBlockingCache,
UserMutingsCache,
userWordMuteCache,
} from "@/misc/cache.js";
export const meta = { export const meta = {
tags: ["notes"], tags: ["notes"],
@ -37,15 +53,61 @@ export const paramDef = {
required: [], required: [],
} as const; } as const;
const ONEDAY = 1000 * 60 * 60 * 24;
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const max = 30; const max = 30;
const day = 1000 * 60 * 60 * 24 * ps.days; const day = ONEDAY * ps.days;
if (scyllaClient) {
let [mutedUserIds, mutedInstances, blockerIds, blockingIds]: string[][] =
[];
let mutedWords: string[][] = [];
const foundNotes: ScyllaNote[] = [];
let searchedDays = 0;
let targetDay = new Date();
if (user) {
[mutedUserIds, mutedInstances, mutedWords, blockerIds, blockingIds] =
await Promise.all([
UserMutingsCache.init(user.id).then((cache) => cache.getAll()),
InstanceMutingsCache.init(user.id).then((cache) => cache.getAll()),
userWordMuteCache
.fetchMaybe(user.id, () =>
UserProfiles.findOne({
select: ["mutedWords"],
where: { userId: user.id },
}).then((profile) => profile?.mutedWords),
)
.then((words) => words ?? []),
UserBlockedCache.init(user.id).then((cache) => cache.getAll()),
UserBlockingCache.init(user.id).then((cache) => cache.getAll()),
]);
}
while (foundNotes.length < max && searchedDays < ps.days) {
searchedDays++;
let notes = await scyllaClient
.execute(prepared.scoreFeed.select, [targetDay], { prepare: true })
.then((result) => result.rows.map(parseScyllaNote));
if (user) {
notes = await filterMutedUser(notes, user, mutedUserIds, mutedInstances);
notes = await filterMutedNote(notes, user, mutedWords);
notes = await filterBlockUser(notes, user, [...blockerIds, ...blockingIds]);
}
foundNotes.push(...notes);
targetDay = new Date(targetDay.getTime() - ONEDAY);
}
}
const query = Notes.createQueryBuilder("note") const query = Notes.createQueryBuilder("note")
.addSelect("note.score") .addSelect("note.score")
.andWhere("note.score > 0") .andWhere("note.score > 0")
.andWhere("note.createdAt > :date", { date: new Date(Date.now() - day) }) .andWhere("note.createdAt > :date", { date: new Date(Date.now() - day) })
.andWhere("note.visibility = 'public'") .andWhere("note.visibility = 'public'");
switch (ps.origin) { switch (ps.origin) {
case "local": case "local":