Fixed 267U.pre2
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { PromoNotes } from "../../../../models/index.js";
|
||||
import define from "../../define.js";
|
||||
import { ApiError } from "../../error.js";
|
||||
import { getNote } from "../../common/getters.js";
|
||||
import { readPromo } from "../../common/read-promo.js";
|
||||
export const meta = {
|
||||
tags: [
|
||||
"notes"
|
||||
],
|
||||
requireCredential: true,
|
||||
errors: {
|
||||
noSuchNote: {
|
||||
message: "No such note.",
|
||||
code: "NO_SUCH_NOTE",
|
||||
id: "d785b897-fcd3-4fe9-8fc3-b85c26e6c932"
|
||||
}
|
||||
}
|
||||
};
|
||||
export const paramDef = {
|
||||
type: "object",
|
||||
properties: {
|
||||
noteId: {
|
||||
type: "string",
|
||||
format: "misskey:id"
|
||||
}
|
||||
},
|
||||
required: [
|
||||
"noteId"
|
||||
]
|
||||
};
|
||||
export default define(meta, paramDef, async (ps, user)=>{
|
||||
const [note, promo] = await Promise.all([
|
||||
getNote(ps.noteId, user, {
|
||||
allowAdservice: true
|
||||
}).catch((err)=>{
|
||||
if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24") throw new ApiError(meta.errors.noSuchNote);
|
||||
throw err;
|
||||
}),
|
||||
PromoNotes.findOneBy({
|
||||
noteId: ps.noteId
|
||||
})
|
||||
]);
|
||||
if (note == null || promo == null || promo.expiresAt.getTime() <= Date.now() || promo.remainingCredits <= 0) {
|
||||
throw new ApiError(meta.errors.noSuchNote);
|
||||
}
|
||||
await readPromo(note, promo, user);
|
||||
});
|
||||
@@ -0,0 +1,115 @@
|
||||
import rndstr from "rndstr";
|
||||
import { Notes, PromoNotes, PromoReads, Users } from "../../../../models/index.js";
|
||||
import define from "../../define.js";
|
||||
import { shouldHideEUsersFor } from "../../common/generate-minor-badge-visibility-query.js";
|
||||
import { readPromo } from "../../common/read-promo.js";
|
||||
const serviceTags = {
|
||||
video: "videoservice",
|
||||
audio: "audioservice",
|
||||
image: "imageservice",
|
||||
karaoke: "karaokeservice",
|
||||
lua4frozen: "lua4frozen"
|
||||
};
|
||||
const systemTags = new Set([
|
||||
"adservice",
|
||||
"videoservice",
|
||||
"audioservice",
|
||||
"imageservice",
|
||||
"karaokeservice",
|
||||
"lua4frozen"
|
||||
]);
|
||||
function isExplicitAd(note) {
|
||||
return note.tags.includes("explicit") || note.user?.minorBadges?.includes("E") === true;
|
||||
}
|
||||
function canShowExplicit(note, user, hideExplicit) {
|
||||
if (!isExplicitAd(note)) return true;
|
||||
if (hideExplicit) return false;
|
||||
return !(user && shouldHideEUsersFor(user));
|
||||
}
|
||||
function hasPollOr(note, fn) {
|
||||
return note.hasPoll || fn();
|
||||
}
|
||||
function hasFileType(note, prefix) {
|
||||
return note.attachedFileTypes.some((type)=>type.startsWith(prefix));
|
||||
}
|
||||
function matchesService(note, service) {
|
||||
if (service == null) return true;
|
||||
if (!note.tags.includes(serviceTags[service])) return false;
|
||||
switch(service){
|
||||
case "video":
|
||||
return hasPollOr(note, ()=>hasFileType(note, "video/"));
|
||||
case "audio":
|
||||
return hasPollOr(note, ()=>hasFileType(note, "audio/"));
|
||||
case "image":
|
||||
return hasPollOr(note, ()=>hasFileType(note, "image/"));
|
||||
case "karaoke":
|
||||
return hasFileType(note, "video/") || hasFileType(note, "audio/") && hasFileType(note, "image/");
|
||||
case "lua4frozen":
|
||||
return hasPollOr(note, ()=>hasFileType(note, "image/"));
|
||||
}
|
||||
}
|
||||
export const meta = {
|
||||
tags: [
|
||||
"notes"
|
||||
],
|
||||
requireCredential: false,
|
||||
requireCredentialPrivateMode: true
|
||||
};
|
||||
export const paramDef = {
|
||||
type: "object",
|
||||
properties: {
|
||||
service: {
|
||||
type: "string",
|
||||
enum: [
|
||||
"video",
|
||||
"audio",
|
||||
"image",
|
||||
"karaoke",
|
||||
"lua4frozen"
|
||||
],
|
||||
nullable: true
|
||||
},
|
||||
tag: {
|
||||
type: "string",
|
||||
nullable: true
|
||||
},
|
||||
hideExplicit: {
|
||||
type: "boolean",
|
||||
default: false
|
||||
}
|
||||
},
|
||||
required: []
|
||||
};
|
||||
export default define(meta, paramDef, async (ps, user)=>{
|
||||
const readDay = new Date().toISOString().slice(0, 10);
|
||||
const reads = user ? await PromoReads.findBy({
|
||||
userId: user.id,
|
||||
readDay
|
||||
}) : [];
|
||||
const readNoteIds = new Set(reads.map((read)=>read.noteId));
|
||||
const promos = (await PromoNotes.find()).filter((promo)=>promo.expiresAt.getTime() > Date.now() && promo.remainingCredits > 0 && !readNoteIds.has(promo.noteId));
|
||||
const candidates = [];
|
||||
for (const promo of promos){
|
||||
const note = await Notes.findOneBy({
|
||||
id: promo.noteId
|
||||
});
|
||||
if (!note?.tags.includes("adservice")) continue;
|
||||
note.user = await Users.findOneByOrFail({
|
||||
id: note.userId
|
||||
});
|
||||
if (!canShowExplicit(note, user, ps.hideExplicit)) continue;
|
||||
if (!matchesService(note, ps.service ?? null)) continue;
|
||||
candidates.push(note);
|
||||
}
|
||||
if (candidates.length === 0) return null;
|
||||
const requestedTag = ps.tag?.trim().toLowerCase().replace(/^#/, "");
|
||||
const priority = requestedTag && !systemTags.has(requestedTag) ? candidates.filter((note)=>note.tags.includes(requestedTag)) : [];
|
||||
const pool = priority.length > 0 ? priority : candidates;
|
||||
const note = pool[Math.floor(Math.random() * pool.length)];
|
||||
const promo = promos.find((promo)=>promo.noteId === note.id);
|
||||
note._prId_ = rndstr("a-z0-9", 8);
|
||||
if (user && promo) {
|
||||
await readPromo(note, promo, user);
|
||||
}
|
||||
return Notes.pack(note, user);
|
||||
});
|
||||
Reference in New Issue
Block a user