diff options
author | Chocobozzz <me@florianbigard.com> | 2020-05-14 16:56:15 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2020-05-29 09:21:26 +0200 |
commit | 444c0a0e017824fb4ce526281a22c4abe0a13c50 (patch) | |
tree | 6a3c1ea8c4995361c582176257d1e1315287411d /server/controllers | |
parent | 99139e7753e20ab0fba8eae5638d3dd3e792fe43 (diff) | |
download | PeerTube-444c0a0e017824fb4ce526281a22c4abe0a13c50.tar.gz PeerTube-444c0a0e017824fb4ce526281a22c4abe0a13c50.tar.zst PeerTube-444c0a0e017824fb4ce526281a22c4abe0a13c50.zip |
Add ability to bulk delete comments
Diffstat (limited to 'server/controllers')
-rw-r--r-- | server/controllers/api/bulk.ts | 41 | ||||
-rw-r--r-- | server/controllers/api/index.ts | 20 | ||||
-rw-r--r-- | server/controllers/api/videos/comment.ts | 35 |
3 files changed, 61 insertions, 35 deletions
diff --git a/server/controllers/api/bulk.ts b/server/controllers/api/bulk.ts new file mode 100644 index 000000000..1fe139c92 --- /dev/null +++ b/server/controllers/api/bulk.ts | |||
@@ -0,0 +1,41 @@ | |||
1 | import * as express from 'express' | ||
2 | import { asyncMiddleware, authenticate } from '../../middlewares' | ||
3 | import { bulkRemoveCommentsOfValidator } from '@server/middlewares/validators/bulk' | ||
4 | import { VideoCommentModel } from '@server/models/video/video-comment' | ||
5 | import { BulkRemoveCommentsOfBody } from '@shared/models/bulk/bulk-remove-comments-of-body.model' | ||
6 | import { removeComment } from '@server/lib/video-comment' | ||
7 | |||
8 | const bulkRouter = express.Router() | ||
9 | |||
10 | bulkRouter.post('/remove-comments-of', | ||
11 | authenticate, | ||
12 | asyncMiddleware(bulkRemoveCommentsOfValidator), | ||
13 | asyncMiddleware(bulkRemoveCommentsOf) | ||
14 | ) | ||
15 | |||
16 | // --------------------------------------------------------------------------- | ||
17 | |||
18 | export { | ||
19 | bulkRouter | ||
20 | } | ||
21 | |||
22 | // --------------------------------------------------------------------------- | ||
23 | |||
24 | async function bulkRemoveCommentsOf (req: express.Request, res: express.Response) { | ||
25 | const account = res.locals.account | ||
26 | const body = req.body as BulkRemoveCommentsOfBody | ||
27 | const user = res.locals.oauth.token.User | ||
28 | |||
29 | const filter = body.scope === 'my-videos' | ||
30 | ? { onVideosOfAccount: user.Account } | ||
31 | : {} | ||
32 | |||
33 | const comments = await VideoCommentModel.listForBulkDelete(account, filter) | ||
34 | |||
35 | // Don't wait result | ||
36 | res.sendStatus(204) | ||
37 | |||
38 | for (const comment of comments) { | ||
39 | await removeComment(comment) | ||
40 | } | ||
41 | } | ||
diff --git a/server/controllers/api/index.ts b/server/controllers/api/index.ts index 7bec6c527..c334a26b4 100644 --- a/server/controllers/api/index.ts +++ b/server/controllers/api/index.ts | |||
@@ -1,20 +1,21 @@ | |||
1 | import * as cors from 'cors' | ||
1 | import * as express from 'express' | 2 | import * as express from 'express' |
3 | import * as RateLimit from 'express-rate-limit' | ||
4 | import { badRequest } from '../../helpers/express-utils' | ||
5 | import { CONFIG } from '../../initializers/config' | ||
6 | import { accountsRouter } from './accounts' | ||
7 | import { bulkRouter } from './bulk' | ||
2 | import { configRouter } from './config' | 8 | import { configRouter } from './config' |
3 | import { jobsRouter } from './jobs' | 9 | import { jobsRouter } from './jobs' |
4 | import { oauthClientsRouter } from './oauth-clients' | 10 | import { oauthClientsRouter } from './oauth-clients' |
11 | import { overviewsRouter } from './overviews' | ||
12 | import { pluginRouter } from './plugins' | ||
13 | import { searchRouter } from './search' | ||
5 | import { serverRouter } from './server' | 14 | import { serverRouter } from './server' |
6 | import { usersRouter } from './users' | 15 | import { usersRouter } from './users' |
7 | import { accountsRouter } from './accounts' | ||
8 | import { videosRouter } from './videos' | ||
9 | import { badRequest } from '../../helpers/express-utils' | ||
10 | import { videoChannelRouter } from './video-channel' | 16 | import { videoChannelRouter } from './video-channel' |
11 | import * as cors from 'cors' | ||
12 | import { searchRouter } from './search' | ||
13 | import { overviewsRouter } from './overviews' | ||
14 | import { videoPlaylistRouter } from './video-playlist' | 17 | import { videoPlaylistRouter } from './video-playlist' |
15 | import { CONFIG } from '../../initializers/config' | 18 | import { videosRouter } from './videos' |
16 | import { pluginRouter } from './plugins' | ||
17 | import * as RateLimit from 'express-rate-limit' | ||
18 | 19 | ||
19 | const apiRouter = express.Router() | 20 | const apiRouter = express.Router() |
20 | 21 | ||
@@ -31,6 +32,7 @@ const apiRateLimiter = RateLimit({ | |||
31 | apiRouter.use(apiRateLimiter) | 32 | apiRouter.use(apiRateLimiter) |
32 | 33 | ||
33 | apiRouter.use('/server', serverRouter) | 34 | apiRouter.use('/server', serverRouter) |
35 | apiRouter.use('/bulk', bulkRouter) | ||
34 | apiRouter.use('/oauth-clients', oauthClientsRouter) | 36 | apiRouter.use('/oauth-clients', oauthClientsRouter) |
35 | apiRouter.use('/config', configRouter) | 37 | apiRouter.use('/config', configRouter) |
36 | apiRouter.use('/users', usersRouter) | 38 | apiRouter.use('/users', usersRouter) |
diff --git a/server/controllers/api/videos/comment.ts b/server/controllers/api/videos/comment.ts index 5070bb3c0..bdd3cf9e2 100644 --- a/server/controllers/api/videos/comment.ts +++ b/server/controllers/api/videos/comment.ts | |||
@@ -1,11 +1,12 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { cloneDeep } from 'lodash' | ||
3 | import { ResultList } from '../../../../shared/models' | 2 | import { ResultList } from '../../../../shared/models' |
4 | import { VideoCommentCreate } from '../../../../shared/models/videos/video-comment.model' | 3 | import { VideoCommentCreate } from '../../../../shared/models/videos/video-comment.model' |
5 | import { logger } from '../../../helpers/logger' | 4 | import { auditLoggerFactory, CommentAuditView, getAuditIdFromRes } from '../../../helpers/audit-logger' |
6 | import { getFormattedObjects } from '../../../helpers/utils' | 5 | import { getFormattedObjects } from '../../../helpers/utils' |
7 | import { sequelizeTypescript } from '../../../initializers/database' | 6 | import { sequelizeTypescript } from '../../../initializers/database' |
8 | import { buildFormattedCommentTree, createVideoComment, markCommentAsDeleted } from '../../../lib/video-comment' | 7 | import { Notifier } from '../../../lib/notifier' |
8 | import { Hooks } from '../../../lib/plugins/hooks' | ||
9 | import { buildFormattedCommentTree, createVideoComment, removeComment } from '../../../lib/video-comment' | ||
9 | import { | 10 | import { |
10 | asyncMiddleware, | 11 | asyncMiddleware, |
11 | asyncRetryTransactionMiddleware, | 12 | asyncRetryTransactionMiddleware, |
@@ -23,12 +24,8 @@ import { | |||
23 | removeVideoCommentValidator, | 24 | removeVideoCommentValidator, |
24 | videoCommentThreadsSortValidator | 25 | videoCommentThreadsSortValidator |
25 | } from '../../../middlewares/validators' | 26 | } from '../../../middlewares/validators' |
26 | import { VideoCommentModel } from '../../../models/video/video-comment' | ||
27 | import { auditLoggerFactory, CommentAuditView, getAuditIdFromRes } from '../../../helpers/audit-logger' | ||
28 | import { AccountModel } from '../../../models/account/account' | 27 | import { AccountModel } from '../../../models/account/account' |
29 | import { Notifier } from '../../../lib/notifier' | 28 | import { VideoCommentModel } from '../../../models/video/video-comment' |
30 | import { Hooks } from '../../../lib/plugins/hooks' | ||
31 | import { sendDeleteVideoComment } from '../../../lib/activitypub/send' | ||
32 | 29 | ||
33 | const auditLogger = auditLoggerFactory('comments') | 30 | const auditLogger = auditLoggerFactory('comments') |
34 | const videoCommentRouter = express.Router() | 31 | const videoCommentRouter = express.Router() |
@@ -149,9 +146,7 @@ async function addVideoCommentThread (req: express.Request, res: express.Respons | |||
149 | 146 | ||
150 | Hooks.runAction('action:api.video-thread.created', { comment }) | 147 | Hooks.runAction('action:api.video-thread.created', { comment }) |
151 | 148 | ||
152 | return res.json({ | 149 | return res.json({ comment: comment.toFormattedJSON() }) |
153 | comment: comment.toFormattedJSON() | ||
154 | }).end() | ||
155 | } | 150 | } |
156 | 151 | ||
157 | async function addVideoCommentReply (req: express.Request, res: express.Response) { | 152 | async function addVideoCommentReply (req: express.Request, res: express.Response) { |
@@ -173,27 +168,15 @@ async function addVideoCommentReply (req: express.Request, res: express.Response | |||
173 | 168 | ||
174 | Hooks.runAction('action:api.video-comment-reply.created', { comment }) | 169 | Hooks.runAction('action:api.video-comment-reply.created', { comment }) |
175 | 170 | ||
176 | return res.json({ comment: comment.toFormattedJSON() }).end() | 171 | return res.json({ comment: comment.toFormattedJSON() }) |
177 | } | 172 | } |
178 | 173 | ||
179 | async function removeVideoComment (req: express.Request, res: express.Response) { | 174 | async function removeVideoComment (req: express.Request, res: express.Response) { |
180 | const videoCommentInstance = res.locals.videoCommentFull | 175 | const videoCommentInstance = res.locals.videoCommentFull |
181 | const videoCommentInstanceBefore = cloneDeep(videoCommentInstance) | ||
182 | |||
183 | await sequelizeTypescript.transaction(async t => { | ||
184 | if (videoCommentInstance.isOwned() || videoCommentInstance.Video.isOwned()) { | ||
185 | await sendDeleteVideoComment(videoCommentInstance, t) | ||
186 | } | ||
187 | 176 | ||
188 | markCommentAsDeleted(videoCommentInstance) | 177 | await removeComment(videoCommentInstance) |
189 | |||
190 | await videoCommentInstance.save() | ||
191 | }) | ||
192 | 178 | ||
193 | auditLogger.delete(getAuditIdFromRes(res), new CommentAuditView(videoCommentInstance.toFormattedJSON())) | 179 | auditLogger.delete(getAuditIdFromRes(res), new CommentAuditView(videoCommentInstance.toFormattedJSON())) |
194 | logger.info('Video comment %d deleted.', videoCommentInstance.id) | ||
195 | |||
196 | Hooks.runAction('action:api.video-comment.deleted', { comment: videoCommentInstanceBefore }) | ||
197 | 180 | ||
198 | return res.type('json').status(204).end() | 181 | return res.type('json').status(204) |
199 | } | 182 | } |