aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2020-05-14 16:56:15 +0200
committerChocobozzz <chocobozzz@cpy.re>2020-05-29 09:21:26 +0200
commit444c0a0e017824fb4ce526281a22c4abe0a13c50 (patch)
tree6a3c1ea8c4995361c582176257d1e1315287411d /server/controllers
parent99139e7753e20ab0fba8eae5638d3dd3e792fe43 (diff)
downloadPeerTube-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.ts41
-rw-r--r--server/controllers/api/index.ts20
-rw-r--r--server/controllers/api/videos/comment.ts35
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 @@
1import * as express from 'express'
2import { asyncMiddleware, authenticate } from '../../middlewares'
3import { bulkRemoveCommentsOfValidator } from '@server/middlewares/validators/bulk'
4import { VideoCommentModel } from '@server/models/video/video-comment'
5import { BulkRemoveCommentsOfBody } from '@shared/models/bulk/bulk-remove-comments-of-body.model'
6import { removeComment } from '@server/lib/video-comment'
7
8const bulkRouter = express.Router()
9
10bulkRouter.post('/remove-comments-of',
11 authenticate,
12 asyncMiddleware(bulkRemoveCommentsOfValidator),
13 asyncMiddleware(bulkRemoveCommentsOf)
14)
15
16// ---------------------------------------------------------------------------
17
18export {
19 bulkRouter
20}
21
22// ---------------------------------------------------------------------------
23
24async 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 @@
1import * as cors from 'cors'
1import * as express from 'express' 2import * as express from 'express'
3import * as RateLimit from 'express-rate-limit'
4import { badRequest } from '../../helpers/express-utils'
5import { CONFIG } from '../../initializers/config'
6import { accountsRouter } from './accounts'
7import { bulkRouter } from './bulk'
2import { configRouter } from './config' 8import { configRouter } from './config'
3import { jobsRouter } from './jobs' 9import { jobsRouter } from './jobs'
4import { oauthClientsRouter } from './oauth-clients' 10import { oauthClientsRouter } from './oauth-clients'
11import { overviewsRouter } from './overviews'
12import { pluginRouter } from './plugins'
13import { searchRouter } from './search'
5import { serverRouter } from './server' 14import { serverRouter } from './server'
6import { usersRouter } from './users' 15import { usersRouter } from './users'
7import { accountsRouter } from './accounts'
8import { videosRouter } from './videos'
9import { badRequest } from '../../helpers/express-utils'
10import { videoChannelRouter } from './video-channel' 16import { videoChannelRouter } from './video-channel'
11import * as cors from 'cors'
12import { searchRouter } from './search'
13import { overviewsRouter } from './overviews'
14import { videoPlaylistRouter } from './video-playlist' 17import { videoPlaylistRouter } from './video-playlist'
15import { CONFIG } from '../../initializers/config' 18import { videosRouter } from './videos'
16import { pluginRouter } from './plugins'
17import * as RateLimit from 'express-rate-limit'
18 19
19const apiRouter = express.Router() 20const apiRouter = express.Router()
20 21
@@ -31,6 +32,7 @@ const apiRateLimiter = RateLimit({
31apiRouter.use(apiRateLimiter) 32apiRouter.use(apiRateLimiter)
32 33
33apiRouter.use('/server', serverRouter) 34apiRouter.use('/server', serverRouter)
35apiRouter.use('/bulk', bulkRouter)
34apiRouter.use('/oauth-clients', oauthClientsRouter) 36apiRouter.use('/oauth-clients', oauthClientsRouter)
35apiRouter.use('/config', configRouter) 37apiRouter.use('/config', configRouter)
36apiRouter.use('/users', usersRouter) 38apiRouter.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 @@
1import * as express from 'express' 1import * as express from 'express'
2import { cloneDeep } from 'lodash'
3import { ResultList } from '../../../../shared/models' 2import { ResultList } from '../../../../shared/models'
4import { VideoCommentCreate } from '../../../../shared/models/videos/video-comment.model' 3import { VideoCommentCreate } from '../../../../shared/models/videos/video-comment.model'
5import { logger } from '../../../helpers/logger' 4import { auditLoggerFactory, CommentAuditView, getAuditIdFromRes } from '../../../helpers/audit-logger'
6import { getFormattedObjects } from '../../../helpers/utils' 5import { getFormattedObjects } from '../../../helpers/utils'
7import { sequelizeTypescript } from '../../../initializers/database' 6import { sequelizeTypescript } from '../../../initializers/database'
8import { buildFormattedCommentTree, createVideoComment, markCommentAsDeleted } from '../../../lib/video-comment' 7import { Notifier } from '../../../lib/notifier'
8import { Hooks } from '../../../lib/plugins/hooks'
9import { buildFormattedCommentTree, createVideoComment, removeComment } from '../../../lib/video-comment'
9import { 10import {
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'
26import { VideoCommentModel } from '../../../models/video/video-comment'
27import { auditLoggerFactory, CommentAuditView, getAuditIdFromRes } from '../../../helpers/audit-logger'
28import { AccountModel } from '../../../models/account/account' 27import { AccountModel } from '../../../models/account/account'
29import { Notifier } from '../../../lib/notifier' 28import { VideoCommentModel } from '../../../models/video/video-comment'
30import { Hooks } from '../../../lib/plugins/hooks'
31import { sendDeleteVideoComment } from '../../../lib/activitypub/send'
32 29
33const auditLogger = auditLoggerFactory('comments') 30const auditLogger = auditLoggerFactory('comments')
34const videoCommentRouter = express.Router() 31const 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
157async function addVideoCommentReply (req: express.Request, res: express.Response) { 152async 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
179async function removeVideoComment (req: express.Request, res: express.Response) { 174async 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}