wip: adding featured
This commit is contained in:
parent
c11a1bc110
commit
317d5df5f3
3 changed files with 85 additions and 12 deletions
|
@ -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 (
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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":
|
||||||
|
|
Loading…
Reference in a new issue