diff options
Diffstat (limited to 'server/controllers/api/videos/channel.ts')
-rw-r--r-- | server/controllers/api/videos/channel.ts | 153 |
1 files changed, 71 insertions, 82 deletions
diff --git a/server/controllers/api/videos/channel.ts b/server/controllers/api/videos/channel.ts index 630fc4f53..ab54eedee 100644 --- a/server/controllers/api/videos/channel.ts +++ b/server/controllers/api/videos/channel.ts | |||
@@ -4,7 +4,8 @@ import { database as db } from '../../../initializers' | |||
4 | import { | 4 | import { |
5 | logger, | 5 | logger, |
6 | getFormattedObjects, | 6 | getFormattedObjects, |
7 | retryTransactionWrapper | 7 | retryTransactionWrapper, |
8 | resetSequelizeInstance | ||
8 | } from '../../../helpers' | 9 | } from '../../../helpers' |
9 | import { | 10 | import { |
10 | authenticate, | 11 | authenticate, |
@@ -16,7 +17,8 @@ import { | |||
16 | videoChannelsRemoveValidator, | 17 | videoChannelsRemoveValidator, |
17 | videoChannelGetValidator, | 18 | videoChannelGetValidator, |
18 | videoChannelsUpdateValidator, | 19 | videoChannelsUpdateValidator, |
19 | listVideoAuthorChannelsValidator | 20 | listVideoAuthorChannelsValidator, |
21 | asyncMiddleware | ||
20 | } from '../../../middlewares' | 22 | } from '../../../middlewares' |
21 | import { | 23 | import { |
22 | createVideoChannel, | 24 | createVideoChannel, |
@@ -32,18 +34,18 @@ videoChannelRouter.get('/channels', | |||
32 | videoChannelsSortValidator, | 34 | videoChannelsSortValidator, |
33 | setVideoChannelsSort, | 35 | setVideoChannelsSort, |
34 | setPagination, | 36 | setPagination, |
35 | listVideoChannels | 37 | asyncMiddleware(listVideoChannels) |
36 | ) | 38 | ) |
37 | 39 | ||
38 | videoChannelRouter.get('/authors/:authorId/channels', | 40 | videoChannelRouter.get('/authors/:authorId/channels', |
39 | listVideoAuthorChannelsValidator, | 41 | listVideoAuthorChannelsValidator, |
40 | listVideoAuthorChannels | 42 | asyncMiddleware(listVideoAuthorChannels) |
41 | ) | 43 | ) |
42 | 44 | ||
43 | videoChannelRouter.post('/channels', | 45 | videoChannelRouter.post('/channels', |
44 | authenticate, | 46 | authenticate, |
45 | videoChannelsAddValidator, | 47 | videoChannelsAddValidator, |
46 | addVideoChannelRetryWrapper | 48 | asyncMiddleware(addVideoChannelRetryWrapper) |
47 | ) | 49 | ) |
48 | 50 | ||
49 | videoChannelRouter.put('/channels/:id', | 51 | videoChannelRouter.put('/channels/:id', |
@@ -55,12 +57,12 @@ videoChannelRouter.put('/channels/:id', | |||
55 | videoChannelRouter.delete('/channels/:id', | 57 | videoChannelRouter.delete('/channels/:id', |
56 | authenticate, | 58 | authenticate, |
57 | videoChannelsRemoveValidator, | 59 | videoChannelsRemoveValidator, |
58 | removeVideoChannelRetryWrapper | 60 | asyncMiddleware(removeVideoChannelRetryWrapper) |
59 | ) | 61 | ) |
60 | 62 | ||
61 | videoChannelRouter.get('/channels/:id', | 63 | videoChannelRouter.get('/channels/:id', |
62 | videoChannelGetValidator, | 64 | videoChannelGetValidator, |
63 | getVideoChannel | 65 | asyncMiddleware(getVideoChannel) |
64 | ) | 66 | ) |
65 | 67 | ||
66 | // --------------------------------------------------------------------------- | 68 | // --------------------------------------------------------------------------- |
@@ -71,126 +73,113 @@ export { | |||
71 | 73 | ||
72 | // --------------------------------------------------------------------------- | 74 | // --------------------------------------------------------------------------- |
73 | 75 | ||
74 | function listVideoChannels (req: express.Request, res: express.Response, next: express.NextFunction) { | 76 | async function listVideoChannels (req: express.Request, res: express.Response, next: express.NextFunction) { |
75 | db.VideoChannel.listForApi(req.query.start, req.query.count, req.query.sort) | 77 | const resultList = await db.VideoChannel.listForApi(req.query.start, req.query.count, req.query.sort) |
76 | .then(result => res.json(getFormattedObjects(result.data, result.total))) | 78 | |
77 | .catch(err => next(err)) | 79 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
78 | } | 80 | } |
79 | 81 | ||
80 | function listVideoAuthorChannels (req: express.Request, res: express.Response, next: express.NextFunction) { | 82 | async function listVideoAuthorChannels (req: express.Request, res: express.Response, next: express.NextFunction) { |
81 | db.VideoChannel.listByAuthor(res.locals.author.id) | 83 | const resultList = await db.VideoChannel.listByAuthor(res.locals.author.id) |
82 | .then(result => res.json(getFormattedObjects(result.data, result.total))) | 84 | |
83 | .catch(err => next(err)) | 85 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
84 | } | 86 | } |
85 | 87 | ||
86 | // Wrapper to video channel add that retry the function if there is a database error | 88 | // Wrapper to video channel add that retry the async function if there is a database error |
87 | // We need this because we run the transaction in SERIALIZABLE isolation that can fail | 89 | // We need this because we run the transaction in SERIALIZABLE isolation that can fail |
88 | function addVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { | 90 | async function addVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { |
89 | const options = { | 91 | const options = { |
90 | arguments: [ req, res ], | 92 | arguments: [ req, res ], |
91 | errorMessage: 'Cannot insert the video video channel with many retries.' | 93 | errorMessage: 'Cannot insert the video video channel with many retries.' |
92 | } | 94 | } |
93 | 95 | ||
94 | retryTransactionWrapper(addVideoChannel, options) | 96 | await retryTransactionWrapper(addVideoChannel, options) |
95 | .then(() => { | 97 | |
96 | // TODO : include Location of the new video channel -> 201 | 98 | // TODO : include Location of the new video channel -> 201 |
97 | res.type('json').status(204).end() | 99 | return res.type('json').status(204).end() |
98 | }) | ||
99 | .catch(err => next(err)) | ||
100 | } | 100 | } |
101 | 101 | ||
102 | function addVideoChannel (req: express.Request, res: express.Response) { | 102 | async function addVideoChannel (req: express.Request, res: express.Response) { |
103 | const videoChannelInfo: VideoChannelCreate = req.body | 103 | const videoChannelInfo: VideoChannelCreate = req.body |
104 | const author: AuthorInstance = res.locals.oauth.token.User.Author | 104 | const author: AuthorInstance = res.locals.oauth.token.User.Author |
105 | let videoChannelCreated: VideoChannelInstance | ||
105 | 106 | ||
106 | return db.sequelize.transaction(t => { | 107 | await db.sequelize.transaction(async t => { |
107 | return createVideoChannel(videoChannelInfo, author, t) | 108 | videoChannelCreated = await createVideoChannel(videoChannelInfo, author, t) |
108 | }) | ||
109 | .then(videoChannelUUID => logger.info('Video channel with uuid %s created.', videoChannelUUID)) | ||
110 | .catch((err: Error) => { | ||
111 | logger.debug('Cannot insert the video channel.', err) | ||
112 | throw err | ||
113 | }) | 109 | }) |
110 | |||
111 | logger.info('Video channel with uuid %s created.', videoChannelCreated.uuid) | ||
114 | } | 112 | } |
115 | 113 | ||
116 | function updateVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { | 114 | async function updateVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { |
117 | const options = { | 115 | const options = { |
118 | arguments: [ req, res ], | 116 | arguments: [ req, res ], |
119 | errorMessage: 'Cannot update the video with many retries.' | 117 | errorMessage: 'Cannot update the video with many retries.' |
120 | } | 118 | } |
121 | 119 | ||
122 | retryTransactionWrapper(updateVideoChannel, options) | 120 | await retryTransactionWrapper(updateVideoChannel, options) |
123 | .then(() => res.type('json').status(204).end()) | 121 | |
124 | .catch(err => next(err)) | 122 | return res.type('json').status(204).end() |
125 | } | 123 | } |
126 | 124 | ||
127 | function updateVideoChannel (req: express.Request, res: express.Response) { | 125 | async function updateVideoChannel (req: express.Request, res: express.Response) { |
128 | const videoChannelInstance: VideoChannelInstance = res.locals.videoChannel | 126 | const videoChannelInstance: VideoChannelInstance = res.locals.videoChannel |
129 | const videoChannelFieldsSave = videoChannelInstance.toJSON() | 127 | const videoChannelFieldsSave = videoChannelInstance.toJSON() |
130 | const videoChannelInfoToUpdate: VideoChannelUpdate = req.body | 128 | const videoChannelInfoToUpdate: VideoChannelUpdate = req.body |
131 | 129 | ||
132 | return db.sequelize.transaction(t => { | 130 | try { |
133 | const options = { | 131 | await db.sequelize.transaction(async t => { |
134 | transaction: t | 132 | const sequelizeOptions = { |
135 | } | 133 | transaction: t |
134 | } | ||
136 | 135 | ||
137 | if (videoChannelInfoToUpdate.name !== undefined) videoChannelInstance.set('name', videoChannelInfoToUpdate.name) | 136 | if (videoChannelInfoToUpdate.name !== undefined) videoChannelInstance.set('name', videoChannelInfoToUpdate.name) |
138 | if (videoChannelInfoToUpdate.description !== undefined) videoChannelInstance.set('description', videoChannelInfoToUpdate.description) | 137 | if (videoChannelInfoToUpdate.description !== undefined) videoChannelInstance.set('description', videoChannelInfoToUpdate.description) |
139 | 138 | ||
140 | return videoChannelInstance.save(options) | 139 | await videoChannelInstance.save(sequelizeOptions) |
141 | .then(() => { | 140 | const json = videoChannelInstance.toUpdateRemoteJSON() |
142 | const json = videoChannelInstance.toUpdateRemoteJSON() | 141 | |
142 | // Now we'll update the video channel's meta data to our friends | ||
143 | return updateVideoChannelToFriends(json, t) | ||
143 | 144 | ||
144 | // Now we'll update the video channel's meta data to our friends | ||
145 | return updateVideoChannelToFriends(json, t) | ||
146 | }) | ||
147 | }) | ||
148 | .then(() => { | ||
149 | logger.info('Video channel with name %s and uuid %s updated.', videoChannelInstance.name, videoChannelInstance.uuid) | ||
150 | }) | ||
151 | .catch(err => { | ||
152 | logger.debug('Cannot update the video channel.', err) | ||
153 | |||
154 | // Force fields we want to update | ||
155 | // If the transaction is retried, sequelize will think the object has not changed | ||
156 | // So it will skip the SQL request, even if the last one was ROLLBACKed! | ||
157 | Object.keys(videoChannelFieldsSave).forEach(key => { | ||
158 | const value = videoChannelFieldsSave[key] | ||
159 | videoChannelInstance.set(key, value) | ||
160 | }) | ||
161 | |||
162 | throw err | ||
163 | }) | 145 | }) |
146 | |||
147 | logger.info('Video channel with name %s and uuid %s updated.', videoChannelInstance.name, videoChannelInstance.uuid) | ||
148 | } catch (err) { | ||
149 | logger.debug('Cannot update the video channel.', err) | ||
150 | |||
151 | // Force fields we want to update | ||
152 | // If the transaction is retried, sequelize will think the object has not changed | ||
153 | // So it will skip the SQL request, even if the last one was ROLLBACKed! | ||
154 | resetSequelizeInstance(videoChannelInstance, videoChannelFieldsSave) | ||
155 | |||
156 | throw err | ||
157 | } | ||
164 | } | 158 | } |
165 | 159 | ||
166 | function removeVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { | 160 | async function removeVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { |
167 | const options = { | 161 | const options = { |
168 | arguments: [ req, res ], | 162 | arguments: [ req, res ], |
169 | errorMessage: 'Cannot remove the video channel with many retries.' | 163 | errorMessage: 'Cannot remove the video channel with many retries.' |
170 | } | 164 | } |
171 | 165 | ||
172 | retryTransactionWrapper(removeVideoChannel, options) | 166 | await retryTransactionWrapper(removeVideoChannel, options) |
173 | .then(() => res.type('json').status(204).end()) | 167 | |
174 | .catch(err => next(err)) | 168 | return res.type('json').status(204).end() |
175 | } | 169 | } |
176 | 170 | ||
177 | function removeVideoChannel (req: express.Request, res: express.Response) { | 171 | async function removeVideoChannel (req: express.Request, res: express.Response) { |
178 | const videoChannelInstance: VideoChannelInstance = res.locals.videoChannel | 172 | const videoChannelInstance: VideoChannelInstance = res.locals.videoChannel |
179 | 173 | ||
180 | return db.sequelize.transaction(t => { | 174 | await db.sequelize.transaction(async t => { |
181 | return videoChannelInstance.destroy({ transaction: t }) | 175 | await videoChannelInstance.destroy({ transaction: t }) |
182 | }) | ||
183 | .then(() => { | ||
184 | logger.info('Video channel with name %s and uuid %s deleted.', videoChannelInstance.name, videoChannelInstance.uuid) | ||
185 | }) | ||
186 | .catch(err => { | ||
187 | logger.error('Errors when removed the video channel.', err) | ||
188 | throw err | ||
189 | }) | 176 | }) |
177 | |||
178 | logger.info('Video channel with name %s and uuid %s deleted.', videoChannelInstance.name, videoChannelInstance.uuid) | ||
190 | } | 179 | } |
191 | 180 | ||
192 | function getVideoChannel (req: express.Request, res: express.Response, next: express.NextFunction) { | 181 | async function getVideoChannel (req: express.Request, res: express.Response, next: express.NextFunction) { |
193 | db.VideoChannel.loadAndPopulateAuthorAndVideos(res.locals.videoChannel.id) | 182 | const videoChannelWithVideos = await db.VideoChannel.loadAndPopulateAuthorAndVideos(res.locals.videoChannel.id) |
194 | .then(videoChannelWithVideos => res.json(videoChannelWithVideos.toFormattedJSON())) | 183 | |
195 | .catch(err => next(err)) | 184 | return res.json(videoChannelWithVideos.toFormattedJSON()) |
196 | } | 185 | } |