]>
Commit | Line | Data |
---|---|---|
72c7248b | 1 | import * as express from 'express' |
571389d4 C |
2 | import { VideoChannelCreate, VideoChannelUpdate } from '../../../../shared' |
3 | import { getFormattedObjects, logger, resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers' | |
3fd3ab2d | 4 | import { sequelizeTypescript } from '../../../initializers' |
571389d4 | 5 | import { createVideoChannel } from '../../../lib' |
a2431b7d | 6 | import { sendUpdateVideoChannel } from '../../../lib/activitypub/send/send-update' |
72c7248b | 7 | import { |
571389d4 | 8 | asyncMiddleware, |
72c7248b | 9 | authenticate, |
571389d4 | 10 | listVideoAccountChannelsValidator, |
72c7248b | 11 | paginationValidator, |
72c7248b | 12 | setPagination, |
571389d4 | 13 | setVideoChannelsSort, |
571389d4 | 14 | videoChannelsAddValidator, |
a2431b7d | 15 | videoChannelsGetValidator, |
571389d4 C |
16 | videoChannelsRemoveValidator, |
17 | videoChannelsSortValidator, | |
18 | videoChannelsUpdateValidator | |
72c7248b | 19 | } from '../../../middlewares' |
3fd3ab2d C |
20 | import { AccountModel } from '../../../models/account/account' |
21 | import { VideoChannelModel } from '../../../models/video/video-channel' | |
72c7248b C |
22 | |
23 | const videoChannelRouter = express.Router() | |
24 | ||
25 | videoChannelRouter.get('/channels', | |
26 | paginationValidator, | |
27 | videoChannelsSortValidator, | |
28 | setVideoChannelsSort, | |
29 | setPagination, | |
eb080476 | 30 | asyncMiddleware(listVideoChannels) |
72c7248b C |
31 | ) |
32 | ||
38fa2065 | 33 | videoChannelRouter.get('/accounts/:accountId/channels', |
a2431b7d | 34 | asyncMiddleware(listVideoAccountChannelsValidator), |
38fa2065 | 35 | asyncMiddleware(listVideoAccountChannels) |
72c7248b C |
36 | ) |
37 | ||
38 | videoChannelRouter.post('/channels', | |
39 | authenticate, | |
40 | videoChannelsAddValidator, | |
eb080476 | 41 | asyncMiddleware(addVideoChannelRetryWrapper) |
72c7248b C |
42 | ) |
43 | ||
44 | videoChannelRouter.put('/channels/:id', | |
45 | authenticate, | |
a2431b7d | 46 | asyncMiddleware(videoChannelsUpdateValidator), |
72c7248b C |
47 | updateVideoChannelRetryWrapper |
48 | ) | |
49 | ||
50 | videoChannelRouter.delete('/channels/:id', | |
51 | authenticate, | |
a2431b7d | 52 | asyncMiddleware(videoChannelsRemoveValidator), |
eb080476 | 53 | asyncMiddleware(removeVideoChannelRetryWrapper) |
72c7248b C |
54 | ) |
55 | ||
56 | videoChannelRouter.get('/channels/:id', | |
a2431b7d | 57 | asyncMiddleware(videoChannelsGetValidator), |
eb080476 | 58 | asyncMiddleware(getVideoChannel) |
72c7248b C |
59 | ) |
60 | ||
61 | // --------------------------------------------------------------------------- | |
62 | ||
63 | export { | |
64 | videoChannelRouter | |
65 | } | |
66 | ||
67 | // --------------------------------------------------------------------------- | |
68 | ||
eb080476 | 69 | async function listVideoChannels (req: express.Request, res: express.Response, next: express.NextFunction) { |
3fd3ab2d | 70 | const resultList = await VideoChannelModel.listForApi(req.query.start, req.query.count, req.query.sort) |
eb080476 C |
71 | |
72 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | |
72c7248b C |
73 | } |
74 | ||
38fa2065 | 75 | async function listVideoAccountChannels (req: express.Request, res: express.Response, next: express.NextFunction) { |
3fd3ab2d | 76 | const resultList = await VideoChannelModel.listByAccount(res.locals.account.id) |
eb080476 C |
77 | |
78 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | |
72c7248b C |
79 | } |
80 | ||
eb080476 | 81 | // Wrapper to video channel add that retry the async function if there is a database error |
72c7248b | 82 | // We need this because we run the transaction in SERIALIZABLE isolation that can fail |
eb080476 | 83 | async function addVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { |
72c7248b C |
84 | const options = { |
85 | arguments: [ req, res ], | |
86 | errorMessage: 'Cannot insert the video video channel with many retries.' | |
87 | } | |
88 | ||
eb080476 C |
89 | await retryTransactionWrapper(addVideoChannel, options) |
90 | ||
91 | // TODO : include Location of the new video channel -> 201 | |
92 | return res.type('json').status(204).end() | |
72c7248b C |
93 | } |
94 | ||
eb080476 | 95 | async function addVideoChannel (req: express.Request, res: express.Response) { |
72c7248b | 96 | const videoChannelInfo: VideoChannelCreate = req.body |
3fd3ab2d C |
97 | const account: AccountModel = res.locals.oauth.token.User.Account |
98 | let videoChannelCreated: VideoChannelModel | |
72c7248b | 99 | |
3fd3ab2d | 100 | await sequelizeTypescript.transaction(async t => { |
38fa2065 | 101 | videoChannelCreated = await createVideoChannel(videoChannelInfo, account, t) |
72c7248b | 102 | }) |
eb080476 C |
103 | |
104 | logger.info('Video channel with uuid %s created.', videoChannelCreated.uuid) | |
72c7248b C |
105 | } |
106 | ||
eb080476 | 107 | async function updateVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { |
72c7248b C |
108 | const options = { |
109 | arguments: [ req, res ], | |
110 | errorMessage: 'Cannot update the video with many retries.' | |
111 | } | |
112 | ||
eb080476 C |
113 | await retryTransactionWrapper(updateVideoChannel, options) |
114 | ||
115 | return res.type('json').status(204).end() | |
72c7248b C |
116 | } |
117 | ||
eb080476 | 118 | async function updateVideoChannel (req: express.Request, res: express.Response) { |
3fd3ab2d | 119 | const videoChannelInstance = res.locals.videoChannel as VideoChannelModel |
72c7248b | 120 | const videoChannelFieldsSave = videoChannelInstance.toJSON() |
3fd3ab2d | 121 | const videoChannelInfoToUpdate = req.body as VideoChannelUpdate |
72c7248b | 122 | |
eb080476 | 123 | try { |
3fd3ab2d | 124 | await sequelizeTypescript.transaction(async t => { |
eb080476 C |
125 | const sequelizeOptions = { |
126 | transaction: t | |
127 | } | |
72c7248b | 128 | |
eb080476 C |
129 | if (videoChannelInfoToUpdate.name !== undefined) videoChannelInstance.set('name', videoChannelInfoToUpdate.name) |
130 | if (videoChannelInfoToUpdate.description !== undefined) videoChannelInstance.set('description', videoChannelInfoToUpdate.description) | |
72c7248b | 131 | |
54141398 | 132 | const videoChannelInstanceUpdated = await videoChannelInstance.save(sequelizeOptions) |
72c7248b | 133 | |
54141398 | 134 | await sendUpdateVideoChannel(videoChannelInstanceUpdated, t) |
72c7248b | 135 | }) |
eb080476 C |
136 | |
137 | logger.info('Video channel with name %s and uuid %s updated.', videoChannelInstance.name, videoChannelInstance.uuid) | |
138 | } catch (err) { | |
139 | logger.debug('Cannot update the video channel.', err) | |
140 | ||
141 | // Force fields we want to update | |
142 | // If the transaction is retried, sequelize will think the object has not changed | |
143 | // So it will skip the SQL request, even if the last one was ROLLBACKed! | |
144 | resetSequelizeInstance(videoChannelInstance, videoChannelFieldsSave) | |
145 | ||
146 | throw err | |
147 | } | |
72c7248b C |
148 | } |
149 | ||
eb080476 | 150 | async function removeVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { |
72c7248b C |
151 | const options = { |
152 | arguments: [ req, res ], | |
153 | errorMessage: 'Cannot remove the video channel with many retries.' | |
154 | } | |
155 | ||
eb080476 C |
156 | await retryTransactionWrapper(removeVideoChannel, options) |
157 | ||
158 | return res.type('json').status(204).end() | |
72c7248b C |
159 | } |
160 | ||
eb080476 | 161 | async function removeVideoChannel (req: express.Request, res: express.Response) { |
3fd3ab2d | 162 | const videoChannelInstance: VideoChannelModel = res.locals.videoChannel |
72c7248b | 163 | |
3fd3ab2d | 164 | await sequelizeTypescript.transaction(async t => { |
eb080476 | 165 | await videoChannelInstance.destroy({ transaction: t }) |
72c7248b | 166 | }) |
eb080476 C |
167 | |
168 | logger.info('Video channel with name %s and uuid %s deleted.', videoChannelInstance.name, videoChannelInstance.uuid) | |
72c7248b C |
169 | } |
170 | ||
eb080476 | 171 | async function getVideoChannel (req: express.Request, res: express.Response, next: express.NextFunction) { |
3fd3ab2d | 172 | const videoChannelWithVideos = await VideoChannelModel.loadAndPopulateAccountAndVideos(res.locals.videoChannel.id) |
eb080476 C |
173 | |
174 | return res.json(videoChannelWithVideos.toFormattedJSON()) | |
72c7248b | 175 | } |