Fixed 267U.pre2
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import { MemorietArchives, Memoriets, Notes, Users } from "../../../models/index.js";
|
||||
import deleteNote from "../../../services/note/delete.js";
|
||||
import { queueLogger } from "../../logger.js";
|
||||
import { genId } from "../../../misc/gen-id.js";
|
||||
const logger = queueLogger.createSubLogger("check-expired-memoriets");
|
||||
export async function checkExpiredMemoriets() {
|
||||
logger.info("Checking expired Memoriets...");
|
||||
const expired = await Memoriets.createQueryBuilder("memoriet").where("memoriet.expiresAt IS NOT NULL").andWhere("memoriet.expiresAt < :now", {
|
||||
now: new Date()
|
||||
}).getMany();
|
||||
for (const memoriet of expired){
|
||||
const note = await Notes.findOneBy({
|
||||
id: memoriet.noteId
|
||||
});
|
||||
if (note != null) {
|
||||
const user = await Users.findOneBy({
|
||||
id: note.userId
|
||||
});
|
||||
if (user != null) {
|
||||
await MemorietArchives.save({
|
||||
id: genId(),
|
||||
createdAt: memoriet.createdAt,
|
||||
deletedAt: new Date(),
|
||||
userId: memoriet.userId,
|
||||
text: note.text?.replace(/\n?#Memoriet\b/gi, "").trim() || null,
|
||||
cw: note.cw,
|
||||
fileIds: note.fileIds,
|
||||
textLayers: memoriet.textLayers,
|
||||
visibility: note.visibility
|
||||
}).catch((err)=>{
|
||||
logger.warn(`Failed to archive expired Memoriet ${memoriet.id}: ${err}`);
|
||||
});
|
||||
await deleteNote(user, note, true).catch((err)=>{
|
||||
logger.warn(`Failed to delete expired Memoriet note ${note.id}: ${err}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
await Memoriets.delete(memoriet.id);
|
||||
}
|
||||
logger.succ("All expired Memoriets checked.");
|
||||
return `done: ${expired.length}`;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { In } from "typeorm";
|
||||
import { Mutings } from "../../../models/index.js";
|
||||
import { queueLogger } from "../../logger.js";
|
||||
import { publishUserEvent } from "../../../services/stream.js";
|
||||
const logger = queueLogger.createSubLogger("check-expired-mutings");
|
||||
export async function checkExpiredMutings() {
|
||||
logger.info("Checking expired mutings...");
|
||||
const expired = await Mutings.createQueryBuilder("muting").where("muting.expiresAt IS NOT NULL").andWhere("muting.expiresAt < :now", {
|
||||
now: new Date()
|
||||
}).innerJoinAndSelect("muting.mutee", "mutee").getMany();
|
||||
if (expired.length > 0) {
|
||||
await Mutings.delete({
|
||||
id: In(expired.map((m)=>m.id))
|
||||
});
|
||||
for (const m of expired){
|
||||
publishUserEvent(m.muterId, "unmute", m.mutee);
|
||||
}
|
||||
}
|
||||
logger.succ("All expired mutings checked.");
|
||||
return "Success";
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { queueLogger } from "../../logger.js";
|
||||
import { activeUsersChart, driveChart, federationChart, hashtagChart, instanceChart, notesChart, perUserDriveChart, perUserFollowingChart, perUserNotesChart, perUserReactionsChart, usersChart, apRequestChart } from "../../../services/chart/index.js";
|
||||
const logger = queueLogger.createSubLogger("clean-charts");
|
||||
export async function cleanCharts() {
|
||||
logger.info("Clean charts...");
|
||||
await Promise.all([
|
||||
federationChart.clean(),
|
||||
notesChart.clean(),
|
||||
usersChart.clean(),
|
||||
activeUsersChart.clean(),
|
||||
instanceChart.clean(),
|
||||
perUserNotesChart.clean(),
|
||||
driveChart.clean(),
|
||||
perUserReactionsChart.clean(),
|
||||
hashtagChart.clean(),
|
||||
perUserFollowingChart.clean(),
|
||||
perUserDriveChart.clean(),
|
||||
apRequestChart.clean()
|
||||
]);
|
||||
logger.succ("All charts successfully cleaned.");
|
||||
return "Success";
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { LessThan } from "typeorm";
|
||||
import { UserIps } from "../../../models/index.js";
|
||||
import { queueLogger } from "../../logger.js";
|
||||
const logger = queueLogger.createSubLogger("clean");
|
||||
export async function clean() {
|
||||
logger.info("Cleaning...");
|
||||
await UserIps.delete({
|
||||
createdAt: LessThan(new Date(Date.now() - 1000 * 60 * 60 * 24 * 90))
|
||||
});
|
||||
logger.succ("Cleaned.");
|
||||
return "Success";
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import { ScheduledNotes } from "../../../models/index.js";
|
||||
import { createQueue, defaultJobOpts } from "../index.js";
|
||||
import { clean } from "./clean.js";
|
||||
import { cleanCharts } from "./clean-charts.js";
|
||||
import { checkExpiredMutings } from "./check-expired-mutings.js";
|
||||
import { checkExpiredMemoriets } from "./check-expired-memoriets.js";
|
||||
import { resyncCharts } from "./resync-charts.js";
|
||||
import { tickCharts } from "./tick-charts.js";
|
||||
import { verifyLinks } from "./verify-links.js";
|
||||
import { publishScheduledNoteJob } from "./publish-scheduled-note.js";
|
||||
import { enqueueScheduledNote } from "./scheduled-note.js";
|
||||
const processors = {
|
||||
clean,
|
||||
cleanCharts,
|
||||
checkExpiredMutings,
|
||||
checkExpiredMemoriets,
|
||||
resyncCharts,
|
||||
tickCharts,
|
||||
verifyLinks,
|
||||
publishScheduledNote: publishScheduledNoteJob
|
||||
};
|
||||
async function process(job) {
|
||||
const processor = processors[job.name];
|
||||
if (processor === undefined) return "skip: unknown job name";
|
||||
return await processor(job);
|
||||
}
|
||||
const [systemQueue_, systemInitQueue] = createQueue("system", process, {
|
||||
concurrency: Object.keys(processors).length
|
||||
});
|
||||
export const systemQueue = systemQueue_;
|
||||
async function enqueuePendingScheduledNotes() {
|
||||
const scheduledNotes = await ScheduledNotes.find({
|
||||
where: {
|
||||
status: "scheduled"
|
||||
}
|
||||
});
|
||||
for (const scheduledNote of scheduledNotes){
|
||||
await enqueueScheduledNote(scheduledNote);
|
||||
}
|
||||
}
|
||||
export async function systemInit() {
|
||||
await systemInitQueue();
|
||||
for (const { name, seconds } of [
|
||||
{
|
||||
name: "clean",
|
||||
seconds: 60 * 60
|
||||
},
|
||||
{
|
||||
name: "cleanCharts",
|
||||
seconds: 60 * 60
|
||||
},
|
||||
{
|
||||
name: "checkExpiredMutings",
|
||||
seconds: 5 * 60
|
||||
},
|
||||
{
|
||||
name: "checkExpiredMemoriets",
|
||||
seconds: 60
|
||||
},
|
||||
{
|
||||
name: "resyncCharts",
|
||||
seconds: 60 * 60
|
||||
},
|
||||
{
|
||||
name: "tickCharts",
|
||||
seconds: 60
|
||||
},
|
||||
{
|
||||
name: "verifyLinks",
|
||||
seconds: 60 * 60 * 24
|
||||
}
|
||||
]){
|
||||
await systemQueue.upsertJobScheduler(name, {
|
||||
every: seconds * 1000
|
||||
}, {
|
||||
opts: defaultJobOpts
|
||||
});
|
||||
}
|
||||
await enqueuePendingScheduledNotes();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { publishScheduledNote } from "../../../services/note/scheduled.js";
|
||||
export async function publishScheduledNoteJob(job) {
|
||||
return await publishScheduledNote(job.data.scheduledNoteId);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { queueLogger } from "../../logger.js";
|
||||
import { driveChart, notesChart, usersChart } from "../../../services/chart/index.js";
|
||||
const logger = queueLogger.createSubLogger("resync-charts");
|
||||
export async function resyncCharts() {
|
||||
logger.info("Resync charts...");
|
||||
// TODO: ユーザーごとのチャートも更新する
|
||||
// TODO: インスタンスごとのチャートも更新する
|
||||
await Promise.all([
|
||||
driveChart.resync(),
|
||||
notesChart.resync(),
|
||||
usersChart.resync()
|
||||
]);
|
||||
logger.succ("All charts successfully resynced.");
|
||||
return "Success";
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { createQueueProducer, defaultJobOpts } from "../index.js";
|
||||
const scheduledNoteSystemQueue = createQueueProducer("system");
|
||||
export async function enqueueScheduledNote(scheduledNote) {
|
||||
await scheduledNoteSystemQueue.add("publishScheduledNote", {
|
||||
scheduledNoteId: scheduledNote.id
|
||||
}, {
|
||||
...defaultJobOpts,
|
||||
delay: Math.max(0, scheduledNote.scheduledAt.getTime() - Date.now()),
|
||||
jobId: `scheduledNote:${scheduledNote.id}`
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { queueLogger } from "../../logger.js";
|
||||
import { activeUsersChart, driveChart, federationChart, hashtagChart, instanceChart, notesChart, perUserDriveChart, perUserFollowingChart, perUserNotesChart, perUserReactionsChart, usersChart, apRequestChart } from "../../../services/chart/index.js";
|
||||
const logger = queueLogger.createSubLogger("tick-charts");
|
||||
export async function tickCharts() {
|
||||
logger.info("Tick charts...");
|
||||
await Promise.all([
|
||||
federationChart.tick(false),
|
||||
notesChart.tick(false),
|
||||
usersChart.tick(false),
|
||||
activeUsersChart.tick(false),
|
||||
instanceChart.tick(false),
|
||||
perUserNotesChart.tick(false),
|
||||
driveChart.tick(false),
|
||||
perUserReactionsChart.tick(false),
|
||||
hashtagChart.tick(false),
|
||||
perUserFollowingChart.tick(false),
|
||||
perUserDriveChart.tick(false),
|
||||
apRequestChart.tick(false)
|
||||
]);
|
||||
logger.succ("All charts successfully ticked.");
|
||||
return "Success";
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { UserProfiles } from "../../../models/index.js";
|
||||
import { Not } from "typeorm";
|
||||
import { queueLogger } from "../../logger.js";
|
||||
import { verifyLink } from "../../../services/fetch-rel-me.js";
|
||||
const logger = queueLogger.createSubLogger("verify-links");
|
||||
export async function verifyLinks() {
|
||||
logger.info("Verifying links...");
|
||||
const usersToVerify = await UserProfiles.findBy({
|
||||
fields: Not(null),
|
||||
userHost: ""
|
||||
});
|
||||
for (const user of usersToVerify){
|
||||
for (const field of user.fields){
|
||||
if (!field || field.name === "" || field.value === "") {
|
||||
continue;
|
||||
}
|
||||
if (field.value.startsWith("http") && user.user?.username) {
|
||||
field.verified = await verifyLink(field.value, user.user.username);
|
||||
}
|
||||
}
|
||||
if (user.fields.length > 0) {
|
||||
try {
|
||||
await UserProfiles.update(user.userId, {
|
||||
fields: user.fields
|
||||
});
|
||||
} catch (e) {
|
||||
logger.error(`Failed to update user ${user.userId} ${e}`);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.succ("All links successfully verified.");
|
||||
return "Success";
|
||||
}
|
||||
Reference in New Issue
Block a user