further cleanup

This commit is contained in:
Namekuji 2023-09-05 10:58:20 -04:00
parent 2570f8a9eb
commit efda68bc64
No known key found for this signature in database
GPG key ID: 1D62332C07FBA532
8 changed files with 178 additions and 40 deletions

View file

@ -1,4 +1,14 @@
user-agent: *
allow: /
User-agent: *
Allow: /
# todo: sitemap
# Uncomment the following to block CommonCrawl
#
# User-agent: CCBot
# User-agent: CCBot/2.0
# User-agent: CCBot/3.1
# Disallow: /
# Uncomment the following to block ChatGPT
#
# User-agent: GPTBot
# Disallow: /

View file

@ -33,6 +33,8 @@ import Following from "./activitypub/following.js";
import Followers from "./activitypub/followers.js";
import Outbox, { packActivity } from "./activitypub/outbox.js";
import { serverLogger } from "./index.js";
import { parseScyllaNote, prepared, scyllaClient } from "@/db/scylla.js";
import type { Note } from "@/models/entities/note.js";
// Init router
const router = new Router();
@ -87,13 +89,32 @@ router.get("/notes/:note", async (ctx, next) => {
return;
}
const note = await Notes.findOneBy({
let note: Note | null = null;
const validVisibilities = ["public", "home", "followers"];
if (scyllaClient) {
const result = await scyllaClient.execute(
prepared.note.select.byId,
[ctx.params.note],
{ prepare: true },
);
if (result.rowLength > 0) {
const candidate = parseScyllaNote(result.first());
if (
!candidate.localOnly &&
validVisibilities.includes(candidate.visibility)
) {
note = candidate;
}
}
} else {
note = await Notes.findOneBy({
id: ctx.params.note,
visibility: In(["public" as const, "home" as const, "followers" as const]),
visibility: In(validVisibilities),
localOnly: false,
});
}
if (note == null) {
if (!note) {
ctx.status = 404;
return;
}
@ -158,14 +179,34 @@ router.get("/notes/:note/activity", async (ctx) => {
return;
}
const note = await Notes.findOneBy({
let note: Note | null = null;
const validVisibilities = ["public", "home"];
if (scyllaClient) {
const result = await scyllaClient.execute(
prepared.note.select.byId,
[ctx.params.note],
{ prepare: true },
);
if (result.rowLength > 0) {
const candidate = parseScyllaNote(result.first());
if (
!candidate.userHost &&
!candidate.localOnly &&
validVisibilities.includes(candidate.visibility)
) {
note = candidate;
}
}
} else {
note = await Notes.findOneBy({
id: ctx.params.note,
userHost: IsNull(),
visibility: In(["public" as const, "home" as const]),
visibility: In(validVisibilities),
localOnly: false,
});
}
if (note == null) {
if (!note) {
ctx.status = 404;
return;
}

View file

@ -8,6 +8,8 @@ import { checkFetch } from "@/remote/activitypub/check-fetch.js";
import { fetchMeta } from "@/misc/fetch-meta.js";
import { setResponseType } from "../activitypub.js";
import type Router from "@koa/router";
import { parseScyllaNote, prepared, scyllaClient } from "@/db/scylla.js";
import { Note } from "@/models/entities/note.js";
export default async (ctx: Router.RouterContext) => {
const verify = await checkFetch(ctx.req);
@ -33,9 +35,17 @@ export default async (ctx: Router.RouterContext) => {
order: { id: "DESC" },
});
const pinnedNotes = await Promise.all(
let pinnedNotes: Note[] = [];
if (scyllaClient) {
const noteIds = pinings.map(({ noteId }) => noteId);
pinnedNotes = await scyllaClient
.execute(prepared.note.select.byIds, [noteIds], { prepare: true })
.then((result) => result.rows.map(parseScyllaNote));
} else {
pinnedNotes = await Promise.all(
pinings.map((pining) => Notes.findOneByOrFail({ id: pining.noteId })),
);
}
const renderedNotes = await Promise.all(
pinnedNotes.map((note) => renderNote(note)),

View file

@ -15,6 +15,7 @@ import { fetchMeta } from "@/misc/fetch-meta.js";
import { makePaginationQuery } from "../api/common/make-pagination-query.js";
import { setResponseType } from "../activitypub.js";
import type Router from "@koa/router";
import { parseScyllaNote, prepared, scyllaClient } from "@/db/scylla.js";
export default async (ctx: Router.RouterContext) => {
const verify = await checkFetch(ctx.req);
@ -136,7 +137,25 @@ export async function packActivity(note: Note): Promise<any> {
!note.hasPoll &&
(note.fileIds == null || note.fileIds.length === 0)
) {
const renote = await Notes.findOneByOrFail({ id: note.renoteId });
let renote: Note | null = null;
if (scyllaClient) {
const result = await scyllaClient.execute(
prepared.note.select.byId,
[note.renoteId],
{ prepare: true },
);
if (result.rowLength > 0) {
renote = parseScyllaNote(result.first());
}
} else {
renote = await Notes.findOneBy({ id: note.renoteId });
}
if (!renote) {
throw new Error("Renote not found");
}
return renderAnnounce(
renote.uri ? renote.uri : `${config.url}/notes/${renote.id}`,
note,

View file

@ -4,6 +4,7 @@ import { Notes, Users } from "@/models/index.js";
import define from "../../define.js";
import { ApiError } from "../../error.js";
import { getUser } from "../../common/getters.js";
import { scyllaClient } from "@/db/scylla.js";
export const meta = {
tags: ["users"],
@ -64,6 +65,10 @@ export default define(meta, paramDef, async (ps, me) => {
throw e;
});
if (scyllaClient) {
return [];
}
// Fetch recent notes
const recentNotes = await Notes.find({
where: {

View file

@ -3,6 +3,8 @@ import { In, IsNull } from "typeorm";
import config from "@/config/index.js";
import type { User } from "@/models/entities/user.js";
import { Notes, DriveFiles, UserProfiles, Users } from "@/models/index.js";
import { parseScyllaNote, prepared, scyllaClient } from "@/db/scylla.js";
import type { Note } from "@/models/entities/note.js";
export default async function (
user: User,
@ -146,17 +148,35 @@ export default async function (
return outstr;
}
async function findById(id) {
async function findById(id: string) {
let text = "";
let next = null;
const findings = await Notes.findOneBy({
let next: string | null = null;
let note: Note | null = null;
const validVisibilities = ["public", "home"];
if (scyllaClient) {
const result = await scyllaClient.execute(
prepared.note.select.byId,
[id],
{ prepare: true },
);
if (result.rowLength > 0) {
const candidate = parseScyllaNote(result.first());
if (validVisibilities.includes(candidate.visibility)) {
note = candidate;
}
}
} else {
note = await Notes.findOneBy({
id: id,
visibility: In(["public", "home"]),
visibility: In(validVisibilities),
});
if (findings) {
text += `<hr>`;
text += await noteToString(findings);
next = findings.renoteId ? findings.renoteId : findings.replyId;
}
if (note) {
text += "<hr>";
text += await noteToString(note);
next = note.renoteId ? note.renoteId : note.replyId;
}
return { text, next };
}

View file

@ -78,7 +78,7 @@ export async function addPinned(
}
/**
* 稿
* Remove pinned note
* @param user
* @param noteId
*/
@ -87,12 +87,27 @@ export async function removePinned(
noteId: Note["id"],
) {
// Fetch unpinee
const note = await Notes.findOneBy({
let note: Note | null = null;
if (scyllaClient) {
const result = await scyllaClient.execute(
prepared.note.select.byId,
[noteId],
{ prepare: true },
);
if (result.rowLength > 0) {
const candidate = parseScyllaNote(result.first());
if (candidate.userId === user.id) {
note = candidate;
}
}
} else {
note = await Notes.findOneBy({
id: noteId,
userId: user.id,
});
}
if (note == null) {
if (!note) {
throw new IdentifiableError(
"b302d4cf-c050-400a-bbb3-be208681f40c",
"No such note.",

View file

@ -5,13 +5,31 @@ import { Users, Notes } from "@/models/index.js";
import type { Note } from "@/models/entities/note.js";
import { deliverToFollowers } from "@/remote/activitypub/deliver-manager.js";
import { deliverToRelays } from "../../relay.js";
import { parseScyllaNote, prepared, scyllaClient } from "@/db/scylla.js";
import { userByIdCache } from "@/services/user-cache.js";
export async function deliverQuestionUpdate(noteId: Note["id"]) {
const note = await Notes.findOneBy({ id: noteId });
if (note == null) throw new Error("note not found");
let note: Note | null = null;
if (scyllaClient) {
const result = await scyllaClient.execute(
prepared.note.select.byId,
[noteId],
{ prepare: true },
);
if (result.rowLength > 0) {
note = parseScyllaNote(result.first());
}
} else {
note = await Notes.findOneBy({ id: noteId });
}
if (!note) throw new Error("note not found");
const user = await Users.findOneBy({ id: note.userId });
if (user == null) throw new Error("note not found");
const user = await userByIdCache.fetchMaybe(note.userId, () =>
Users.findOneBy({ id: (note as Note).userId }).then(
(user) => user ?? undefined,
),
);
if (!user) throw new Error("note not found");
if (Users.isLocalUser(user)) {
const content = renderActivity(