From 0e4a111f81cceed275d9bec2695f6e401fb654d8 Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 12 Nov 2021 02:02:25 +0900 Subject: refactoring Resolve #7779 --- .../api/endpoints/notes/polls/recommendation.ts | 77 ---------- src/server/api/endpoints/notes/polls/vote.ts | 170 --------------------- 2 files changed, 247 deletions(-) delete mode 100644 src/server/api/endpoints/notes/polls/recommendation.ts delete mode 100644 src/server/api/endpoints/notes/polls/vote.ts (limited to 'src/server/api/endpoints/notes/polls') diff --git a/src/server/api/endpoints/notes/polls/recommendation.ts b/src/server/api/endpoints/notes/polls/recommendation.ts deleted file mode 100644 index 0763f0c8fd..0000000000 --- a/src/server/api/endpoints/notes/polls/recommendation.ts +++ /dev/null @@ -1,77 +0,0 @@ -import $ from 'cafy'; -import define from '../../../define'; -import { Polls, Mutings, Notes, PollVotes } from '@/models/index'; -import { Brackets, In } from 'typeorm'; - -export const meta = { - tags: ['notes'], - - requireCredential: true as const, - - params: { - limit: { - validator: $.optional.num.range(1, 100), - default: 10 - }, - - offset: { - validator: $.optional.num.min(0), - default: 0 - } - }, - - res: { - type: 'array' as const, - optional: false as const, nullable: false as const, - items: { - type: 'object' as const, - optional: false as const, nullable: false as const, - ref: 'Note' - } - } -}; - -export default define(meta, async (ps, user) => { - const query = Polls.createQueryBuilder('poll') - .where('poll.userHost IS NULL') - .andWhere(`poll.userId != :meId`, { meId: user.id }) - .andWhere(`poll.noteVisibility = 'public'`) - .andWhere(new Brackets(qb => { qb - .where('poll.expiresAt IS NULL') - .orWhere('poll.expiresAt > :now', { now: new Date() }); - })); - - //#region exclude arleady voted polls - const votedQuery = PollVotes.createQueryBuilder('vote') - .select('vote.noteId') - .where('vote.userId = :meId', { meId: user.id }); - - query - .andWhere(`poll.noteId NOT IN (${ votedQuery.getQuery() })`); - - query.setParameters(votedQuery.getParameters()); - //#endregion - - //#region mute - const mutingQuery = Mutings.createQueryBuilder('muting') - .select('muting.muteeId') - .where('muting.muterId = :muterId', { muterId: user.id }); - - query - .andWhere(`poll.userId NOT IN (${ mutingQuery.getQuery() })`); - - query.setParameters(mutingQuery.getParameters()); - //#endregion - - const polls = await query.take(ps.limit!).skip(ps.offset).getMany(); - - if (polls.length === 0) return []; - - const notes = await Notes.find({ - id: In(polls.map(poll => poll.noteId)) - }); - - return await Notes.packMany(notes, user, { - detail: true - }); -}); diff --git a/src/server/api/endpoints/notes/polls/vote.ts b/src/server/api/endpoints/notes/polls/vote.ts deleted file mode 100644 index f670501385..0000000000 --- a/src/server/api/endpoints/notes/polls/vote.ts +++ /dev/null @@ -1,170 +0,0 @@ -import $ from 'cafy'; -import { ID } from '@/misc/cafy-id'; -import { publishNoteStream } from '@/services/stream'; -import { createNotification } from '@/services/create-notification'; -import define from '../../../define'; -import { ApiError } from '../../../error'; -import { getNote } from '../../../common/getters'; -import { deliver } from '@/queue/index'; -import { renderActivity } from '@/remote/activitypub/renderer/index'; -import renderVote from '@/remote/activitypub/renderer/vote'; -import { deliverQuestionUpdate } from '@/services/note/polls/update'; -import { PollVotes, NoteWatchings, Users, Polls, Blockings } from '@/models/index'; -import { Not } from 'typeorm'; -import { IRemoteUser } from '@/models/entities/user'; -import { genId } from '@/misc/gen-id'; - -export const meta = { - tags: ['notes'], - - requireCredential: true as const, - - kind: 'write:votes', - - params: { - noteId: { - validator: $.type(ID), - }, - - choice: { - validator: $.num - }, - }, - - errors: { - noSuchNote: { - message: 'No such note.', - code: 'NO_SUCH_NOTE', - id: 'ecafbd2e-c283-4d6d-aecb-1a0a33b75396' - }, - - noPoll: { - message: 'The note does not attach a poll.', - code: 'NO_POLL', - id: '5f979967-52d9-4314-a911-1c673727f92f' - }, - - invalidChoice: { - message: 'Choice ID is invalid.', - code: 'INVALID_CHOICE', - id: 'e0cc9a04-f2e8-41e4-a5f1-4127293260cc' - }, - - alreadyVoted: { - message: 'You have already voted.', - code: 'ALREADY_VOTED', - id: '0963fc77-efac-419b-9424-b391608dc6d8' - }, - - alreadyExpired: { - message: 'The poll is already expired.', - code: 'ALREADY_EXPIRED', - id: '1022a357-b085-4054-9083-8f8de358337e' - }, - - youHaveBeenBlocked: { - message: 'You cannot vote this poll because you have been blocked by this user.', - code: 'YOU_HAVE_BEEN_BLOCKED', - id: '85a5377e-b1e9-4617-b0b9-5bea73331e49' - }, - } -}; - -export default define(meta, async (ps, user) => { - const createdAt = new Date(); - - // Get votee - const note = await getNote(ps.noteId).catch(e => { - if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); - throw e; - }); - - if (!note.hasPoll) { - throw new ApiError(meta.errors.noPoll); - } - - // Check blocking - if (note.userId !== user.id) { - const block = await Blockings.findOne({ - blockerId: note.userId, - blockeeId: user.id, - }); - if (block) { - throw new ApiError(meta.errors.youHaveBeenBlocked); - } - } - - const poll = await Polls.findOneOrFail({ noteId: note.id }); - - if (poll.expiresAt && poll.expiresAt < createdAt) { - throw new ApiError(meta.errors.alreadyExpired); - } - - if (poll.choices[ps.choice] == null) { - throw new ApiError(meta.errors.invalidChoice); - } - - // if already voted - const exist = await PollVotes.find({ - noteId: note.id, - userId: user.id - }); - - if (exist.length) { - if (poll.multiple) { - if (exist.some(x => x.choice == ps.choice)) - throw new ApiError(meta.errors.alreadyVoted); - } else { - throw new ApiError(meta.errors.alreadyVoted); - } - } - - // Create vote - const vote = await PollVotes.insert({ - id: genId(), - createdAt, - noteId: note.id, - userId: user.id, - choice: ps.choice - }).then(x => PollVotes.findOneOrFail(x.identifiers[0])); - - // Increment votes count - const index = ps.choice + 1; // In SQL, array index is 1 based - await Polls.query(`UPDATE poll SET votes[${index}] = votes[${index}] + 1 WHERE "noteId" = '${poll.noteId}'`); - - publishNoteStream(note.id, 'pollVoted', { - choice: ps.choice, - userId: user.id - }); - - // Notify - createNotification(note.userId, 'pollVote', { - notifierId: user.id, - noteId: note.id, - choice: ps.choice - }); - - // Fetch watchers - NoteWatchings.find({ - noteId: note.id, - userId: Not(user.id), - }).then(watchers => { - for (const watcher of watchers) { - createNotification(watcher.userId, 'pollVote', { - notifierId: user.id, - noteId: note.id, - choice: ps.choice - }); - } - }); - - // リモート投票の場合リプライ送信 - if (note.userHost != null) { - const pollOwner = await Users.findOneOrFail(note.userId) as IRemoteUser; - - deliver(user, renderActivity(await renderVote(user, vote, note, poll, pollOwner)), pollOwner.inbox); - } - - // リモートフォロワーにUpdate配信 - deliverQuestionUpdate(note.id); -}); -- cgit v1.2.3-freya