diff options
Diffstat (limited to 'server/models')
35 files changed, 445 insertions, 589 deletions
diff --git a/server/models/application/application-interface.ts b/server/models/application/application-interface.ts index c03513db1..33254ba2d 100644 --- a/server/models/application/application-interface.ts +++ b/server/models/application/application-interface.ts | |||
@@ -1,11 +1,13 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
3 | export namespace ApplicationMethods { | 4 | export namespace ApplicationMethods { |
4 | export type LoadMigrationVersionCallback = (err: Error, version: number) => void | 5 | export type LoadMigrationVersion = () => Promise<number> |
5 | export type LoadMigrationVersion = (callback: LoadMigrationVersionCallback) => void | ||
6 | 6 | ||
7 | export type UpdateMigrationVersionCallback = (err: Error, applicationInstance: ApplicationAttributes) => void | 7 | export type UpdateMigrationVersion = ( |
8 | export type UpdateMigrationVersion = (newVersion: number, transaction: Sequelize.Transaction, callback: UpdateMigrationVersionCallback) => void | 8 | newVersion: number, |
9 | transaction: Sequelize.Transaction | ||
10 | ) => Promise<[ number, ApplicationInstance[] ]> | ||
9 | } | 11 | } |
10 | 12 | ||
11 | export interface ApplicationClass { | 13 | export interface ApplicationClass { |
diff --git a/server/models/application/application.ts b/server/models/application/application.ts index 0e9a1ebb3..507b7a843 100644 --- a/server/models/application/application.ts +++ b/server/models/application/application.ts | |||
@@ -2,7 +2,6 @@ import * as Sequelize from 'sequelize' | |||
2 | 2 | ||
3 | import { addMethodsToModel } from '../utils' | 3 | import { addMethodsToModel } from '../utils' |
4 | import { | 4 | import { |
5 | ApplicationClass, | ||
6 | ApplicationAttributes, | 5 | ApplicationAttributes, |
7 | ApplicationInstance, | 6 | ApplicationInstance, |
8 | 7 | ||
@@ -35,23 +34,19 @@ export default function defineApplication (sequelize: Sequelize.Sequelize, DataT | |||
35 | 34 | ||
36 | // --------------------------------------------------------------------------- | 35 | // --------------------------------------------------------------------------- |
37 | 36 | ||
38 | loadMigrationVersion = function (callback: ApplicationMethods.LoadMigrationVersionCallback) { | 37 | loadMigrationVersion = function () { |
39 | const query = { | 38 | const query = { |
40 | attributes: [ 'migrationVersion' ] | 39 | attributes: [ 'migrationVersion' ] |
41 | } | 40 | } |
42 | 41 | ||
43 | return Application.findOne(query).asCallback(function (err, data) { | 42 | return Application.findOne(query).then(data => data ? data.migrationVersion : null) |
44 | const version = data ? data.migrationVersion : null | ||
45 | |||
46 | return callback(err, version) | ||
47 | }) | ||
48 | } | 43 | } |
49 | 44 | ||
50 | updateMigrationVersion = function (newVersion: number, transaction: Sequelize.Transaction, callback: ApplicationMethods.UpdateMigrationVersionCallback) { | 45 | updateMigrationVersion = function (newVersion: number, transaction: Sequelize.Transaction) { |
51 | const options: Sequelize.UpdateOptions = { | 46 | const options: Sequelize.UpdateOptions = { |
52 | where: {}, | 47 | where: {}, |
53 | transaction: transaction | 48 | transaction: transaction |
54 | } | 49 | } |
55 | 50 | ||
56 | return Application.update({ migrationVersion: newVersion }, options).asCallback(callback) | 51 | return Application.update({ migrationVersion: newVersion }, options) |
57 | } | 52 | } |
diff --git a/server/models/job/job-interface.ts b/server/models/job/job-interface.ts index 31b377367..ba5622977 100644 --- a/server/models/job/job-interface.ts +++ b/server/models/job/job-interface.ts | |||
@@ -1,10 +1,10 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
3 | import { JobState } from '../../../shared/models/job.model' | 4 | import { JobState } from '../../../shared/models/job.model' |
4 | 5 | ||
5 | export namespace JobMethods { | 6 | export namespace JobMethods { |
6 | export type ListWithLimitCallback = (err: Error, jobInstances: JobInstance[]) => void | 7 | export type ListWithLimit = (limit: number, state: JobState) => Promise<JobInstance[]> |
7 | export type ListWithLimit = (limit: number, state: JobState, callback: ListWithLimitCallback) => void | ||
8 | } | 8 | } |
9 | 9 | ||
10 | export interface JobClass { | 10 | export interface JobClass { |
diff --git a/server/models/job/job.ts b/server/models/job/job.ts index 38e4e8f30..968f9d71d 100644 --- a/server/models/job/job.ts +++ b/server/models/job/job.ts | |||
@@ -5,7 +5,6 @@ import { JOB_STATES } from '../../initializers' | |||
5 | 5 | ||
6 | import { addMethodsToModel } from '../utils' | 6 | import { addMethodsToModel } from '../utils' |
7 | import { | 7 | import { |
8 | JobClass, | ||
9 | JobInstance, | 8 | JobInstance, |
10 | JobAttributes, | 9 | JobAttributes, |
11 | 10 | ||
@@ -49,7 +48,7 @@ export default function defineJob (sequelize: Sequelize.Sequelize, DataTypes: Se | |||
49 | 48 | ||
50 | // --------------------------------------------------------------------------- | 49 | // --------------------------------------------------------------------------- |
51 | 50 | ||
52 | listWithLimit = function (limit: number, state: JobState, callback: JobMethods.ListWithLimitCallback) { | 51 | listWithLimit = function (limit: number, state: JobState) { |
53 | const query = { | 52 | const query = { |
54 | order: [ | 53 | order: [ |
55 | [ 'id', 'ASC' ] | 54 | [ 'id', 'ASC' ] |
@@ -60,5 +59,5 @@ listWithLimit = function (limit: number, state: JobState, callback: JobMethods.L | |||
60 | } | 59 | } |
61 | } | 60 | } |
62 | 61 | ||
63 | return Job.findAll(query).asCallback(callback) | 62 | return Job.findAll(query) |
64 | } | 63 | } |
diff --git a/server/models/oauth/oauth-client-interface.ts b/server/models/oauth/oauth-client-interface.ts index 3b4325740..3526e4159 100644 --- a/server/models/oauth/oauth-client-interface.ts +++ b/server/models/oauth/oauth-client-interface.ts | |||
@@ -1,13 +1,12 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
3 | export namespace OAuthClientMethods { | 4 | export namespace OAuthClientMethods { |
4 | export type CountTotalCallback = (err: Error, total: number) => void | 5 | export type CountTotal = () => Promise<number> |
5 | export type CountTotal = (callback: CountTotalCallback) => void | ||
6 | 6 | ||
7 | export type LoadFirstClientCallback = (err: Error, client: OAuthClientInstance) => void | 7 | export type LoadFirstClient = () => Promise<OAuthClientInstance> |
8 | export type LoadFirstClient = (callback: LoadFirstClientCallback) => void | ||
9 | 8 | ||
10 | export type GetByIdAndSecret = (clientId, clientSecret) => void | 9 | export type GetByIdAndSecret = (clientId: string, clientSecret: string) => Promise<OAuthClientInstance> |
11 | } | 10 | } |
12 | 11 | ||
13 | export interface OAuthClientClass { | 12 | export interface OAuthClientClass { |
diff --git a/server/models/oauth/oauth-client.ts b/server/models/oauth/oauth-client.ts index fbc2a3393..9cc68771d 100644 --- a/server/models/oauth/oauth-client.ts +++ b/server/models/oauth/oauth-client.ts | |||
@@ -2,7 +2,6 @@ import * as Sequelize from 'sequelize' | |||
2 | 2 | ||
3 | import { addMethodsToModel } from '../utils' | 3 | import { addMethodsToModel } from '../utils' |
4 | import { | 4 | import { |
5 | OAuthClientClass, | ||
6 | OAuthClientInstance, | 5 | OAuthClientInstance, |
7 | OAuthClientAttributes, | 6 | OAuthClientAttributes, |
8 | 7 | ||
@@ -67,12 +66,12 @@ function associate (models) { | |||
67 | }) | 66 | }) |
68 | } | 67 | } |
69 | 68 | ||
70 | countTotal = function (callback: OAuthClientMethods.CountTotalCallback) { | 69 | countTotal = function () { |
71 | return OAuthClient.count().asCallback(callback) | 70 | return OAuthClient.count() |
72 | } | 71 | } |
73 | 72 | ||
74 | loadFirstClient = function (callback: OAuthClientMethods.LoadFirstClientCallback) { | 73 | loadFirstClient = function () { |
75 | return OAuthClient.findOne().asCallback(callback) | 74 | return OAuthClient.findOne() |
76 | } | 75 | } |
77 | 76 | ||
78 | getByIdAndSecret = function (clientId: string, clientSecret: string) { | 77 | getByIdAndSecret = function (clientId: string, clientSecret: string) { |
diff --git a/server/models/oauth/oauth-token-interface.ts b/server/models/oauth/oauth-token-interface.ts index 815ad5eef..f2ddafa54 100644 --- a/server/models/oauth/oauth-token-interface.ts +++ b/server/models/oauth/oauth-token-interface.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Bluebird from 'bluebird' | 2 | import * as Promise from 'bluebird' |
3 | 3 | ||
4 | import { UserModel } from '../user' | 4 | import { UserModel } from '../user' |
5 | 5 | ||
@@ -15,12 +15,11 @@ export type OAuthTokenInfo = { | |||
15 | } | 15 | } |
16 | 16 | ||
17 | export namespace OAuthTokenMethods { | 17 | export namespace OAuthTokenMethods { |
18 | export type GetByRefreshTokenAndPopulateClient = (refreshToken: string) => Bluebird<OAuthTokenInfo> | 18 | export type GetByRefreshTokenAndPopulateClient = (refreshToken: string) => Promise<OAuthTokenInfo> |
19 | export type GetByTokenAndPopulateUser = (bearerToken: string) => Bluebird<OAuthTokenInstance> | 19 | export type GetByTokenAndPopulateUser = (bearerToken: string) => Promise<OAuthTokenInstance> |
20 | export type GetByRefreshTokenAndPopulateUser = (refreshToken: string) => Bluebird<OAuthTokenInstance> | 20 | export type GetByRefreshTokenAndPopulateUser = (refreshToken: string) => Promise<OAuthTokenInstance> |
21 | 21 | ||
22 | export type RemoveByUserIdCallback = (err: Error) => void | 22 | export type RemoveByUserId = (userId) => Promise<number> |
23 | export type RemoveByUserId = (userId, callback) => void | ||
24 | } | 23 | } |
25 | 24 | ||
26 | export interface OAuthTokenClass { | 25 | export interface OAuthTokenClass { |
diff --git a/server/models/oauth/oauth-token.ts b/server/models/oauth/oauth-token.ts index eab9cf858..8c6883465 100644 --- a/server/models/oauth/oauth-token.ts +++ b/server/models/oauth/oauth-token.ts | |||
@@ -4,7 +4,6 @@ import { logger } from '../../helpers' | |||
4 | 4 | ||
5 | import { addMethodsToModel } from '../utils' | 5 | import { addMethodsToModel } from '../utils' |
6 | import { | 6 | import { |
7 | OAuthTokenClass, | ||
8 | OAuthTokenInstance, | 7 | OAuthTokenInstance, |
9 | OAuthTokenAttributes, | 8 | OAuthTokenAttributes, |
10 | 9 | ||
@@ -149,12 +148,12 @@ getByRefreshTokenAndPopulateUser = function (refreshToken: string) { | |||
149 | }) | 148 | }) |
150 | } | 149 | } |
151 | 150 | ||
152 | removeByUserId = function (userId, callback) { | 151 | removeByUserId = function (userId: number) { |
153 | const query = { | 152 | const query = { |
154 | where: { | 153 | where: { |
155 | userId: userId | 154 | userId: userId |
156 | } | 155 | } |
157 | } | 156 | } |
158 | 157 | ||
159 | return OAuthToken.destroy(query).asCallback(callback) | 158 | return OAuthToken.destroy(query) |
160 | } | 159 | } |
diff --git a/server/models/pod/pod-interface.ts b/server/models/pod/pod-interface.ts index d88847c45..f6963d47e 100644 --- a/server/models/pod/pod-interface.ts +++ b/server/models/pod/pod-interface.ts | |||
@@ -1,4 +1,5 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
3 | // Don't use barrel, import just what we need | 4 | // Don't use barrel, import just what we need |
4 | import { Pod as FormatedPod } from '../../../shared/models/pod.model' | 5 | import { Pod as FormatedPod } from '../../../shared/models/pod.model' |
@@ -6,32 +7,23 @@ import { Pod as FormatedPod } from '../../../shared/models/pod.model' | |||
6 | export namespace PodMethods { | 7 | export namespace PodMethods { |
7 | export type ToFormatedJSON = (this: PodInstance) => FormatedPod | 8 | export type ToFormatedJSON = (this: PodInstance) => FormatedPod |
8 | 9 | ||
9 | export type CountAllCallback = (err: Error, total: number) => void | 10 | export type CountAll = () => Promise<number> |
10 | export type CountAll = (callback) => void | ||
11 | 11 | ||
12 | export type IncrementScoresCallback = (err: Error) => void | 12 | export type IncrementScores = (ids: number[], value: number) => Promise<[ number, PodInstance[] ]> |
13 | export type IncrementScores = (ids: number[], value: number, callback?: IncrementScoresCallback) => void | ||
14 | 13 | ||
15 | export type ListCallback = (err: Error, podInstances?: PodInstance[]) => void | 14 | export type List = () => Promise<PodInstance[]> |
16 | export type List = (callback: ListCallback) => void | ||
17 | 15 | ||
18 | export type ListAllIdsCallback = (err: Error, ids?: number[]) => void | 16 | export type ListAllIds = (transaction: Sequelize.Transaction) => Promise<number[]> |
19 | export type ListAllIds = (transaction: Sequelize.Transaction, callback: ListAllIdsCallback) => void | ||
20 | 17 | ||
21 | export type ListRandomPodIdsWithRequestCallback = (err: Error, podInstanceIds?: number[]) => void | 18 | export type ListRandomPodIdsWithRequest = (limit: number, tableWithPods: string, tableWithPodsJoins: string) => Promise<number[]> |
22 | export type ListRandomPodIdsWithRequest = (limit: number, tableWithPods: string, tableWithPodsJoins: string, callback: ListRandomPodIdsWithRequestCallback) => void | ||
23 | 19 | ||
24 | export type ListBadPodsCallback = (err: Error, podInstances?: PodInstance[]) => void | 20 | export type ListBadPods = () => Promise<PodInstance[]> |
25 | export type ListBadPods = (callback: ListBadPodsCallback) => void | ||
26 | 21 | ||
27 | export type LoadCallback = (err: Error, podInstance: PodInstance) => void | 22 | export type Load = (id: number) => Promise<PodInstance> |
28 | export type Load = (id: number, callback: LoadCallback) => void | ||
29 | 23 | ||
30 | export type LoadByHostCallback = (err: Error, podInstance: PodInstance) => void | 24 | export type LoadByHost = (host: string) => Promise<PodInstance> |
31 | export type LoadByHost = (host: string, callback: LoadByHostCallback) => void | ||
32 | 25 | ||
33 | export type RemoveAllCallback = (err: Error) => void | 26 | export type RemoveAll = () => Promise<number> |
34 | export type RemoveAll = (callback: RemoveAllCallback) => void | ||
35 | 27 | ||
36 | export type UpdatePodsScore = (goodPods: number[], badPods: number[]) => void | 28 | export type UpdatePodsScore = (goodPods: number[], badPods: number[]) => void |
37 | } | 29 | } |
diff --git a/server/models/pod/pod.ts b/server/models/pod/pod.ts index 4fe7fda1c..9209380fc 100644 --- a/server/models/pod/pod.ts +++ b/server/models/pod/pod.ts | |||
@@ -1,4 +1,3 @@ | |||
1 | import { each, waterfall } from 'async' | ||
2 | import { map } from 'lodash' | 1 | import { map } from 'lodash' |
3 | import * as Sequelize from 'sequelize' | 2 | import * as Sequelize from 'sequelize' |
4 | 3 | ||
@@ -7,7 +6,6 @@ import { logger, isHostValid } from '../../helpers' | |||
7 | 6 | ||
8 | import { addMethodsToModel } from '../utils' | 7 | import { addMethodsToModel } from '../utils' |
9 | import { | 8 | import { |
10 | PodClass, | ||
11 | PodInstance, | 9 | PodInstance, |
12 | PodAttributes, | 10 | PodAttributes, |
13 | 11 | ||
@@ -118,13 +116,11 @@ function associate (models) { | |||
118 | }) | 116 | }) |
119 | } | 117 | } |
120 | 118 | ||
121 | countAll = function (callback: PodMethods.CountAllCallback) { | 119 | countAll = function () { |
122 | return Pod.count().asCallback(callback) | 120 | return Pod.count() |
123 | } | 121 | } |
124 | 122 | ||
125 | incrementScores = function (ids: number[], value: number, callback?: PodMethods.IncrementScoresCallback) { | 123 | incrementScores = function (ids: number[], value: number) { |
126 | if (!callback) callback = function () { /* empty */ } | ||
127 | |||
128 | const update = { | 124 | const update = { |
129 | score: Sequelize.literal('score +' + value) | 125 | score: Sequelize.literal('score +' + value) |
130 | } | 126 | } |
@@ -139,33 +135,28 @@ incrementScores = function (ids: number[], value: number, callback?: PodMethods. | |||
139 | validate: false | 135 | validate: false |
140 | } | 136 | } |
141 | 137 | ||
142 | return Pod.update(update, options).asCallback(callback) | 138 | return Pod.update(update, options) |
143 | } | 139 | } |
144 | 140 | ||
145 | list = function (callback: PodMethods.ListCallback) { | 141 | list = function () { |
146 | return Pod.findAll().asCallback(callback) | 142 | return Pod.findAll() |
147 | } | 143 | } |
148 | 144 | ||
149 | listAllIds = function (transaction: Sequelize.Transaction, callback: PodMethods.ListAllIdsCallback) { | 145 | listAllIds = function (transaction: Sequelize.Transaction) { |
150 | const query: any = { | 146 | const query: Sequelize.FindOptions = { |
151 | attributes: [ 'id' ] | 147 | attributes: [ 'id' ], |
148 | transaction | ||
152 | } | 149 | } |
153 | 150 | ||
154 | if (transaction !== null) query.transaction = transaction | 151 | return Pod.findAll(query).then(pods => { |
155 | 152 | return map(pods, 'id') | |
156 | return Pod.findAll(query).asCallback(function (err: Error, pods) { | ||
157 | if (err) return callback(err) | ||
158 | |||
159 | return callback(null, map(pods, 'id')) | ||
160 | }) | 153 | }) |
161 | } | 154 | } |
162 | 155 | ||
163 | listRandomPodIdsWithRequest = function (limit: number, tableWithPods: string, tableWithPodsJoins: string, callback: PodMethods.ListRandomPodIdsWithRequestCallback) { | 156 | listRandomPodIdsWithRequest = function (limit: number, tableWithPods: string, tableWithPodsJoins: string) { |
164 | Pod.count().asCallback(function (err, count) { | 157 | return Pod.count().then(count => { |
165 | if (err) return callback(err) | ||
166 | |||
167 | // Optimization... | 158 | // Optimization... |
168 | if (count === 0) return callback(null, []) | 159 | if (count === 0) return [] |
169 | 160 | ||
170 | let start = Math.floor(Math.random() * count) - limit | 161 | let start = Math.floor(Math.random() * count) - limit |
171 | if (start < 0) start = 0 | 162 | if (start < 0) start = 0 |
@@ -186,56 +177,55 @@ listRandomPodIdsWithRequest = function (limit: number, tableWithPods: string, ta | |||
186 | } | 177 | } |
187 | } | 178 | } |
188 | 179 | ||
189 | return Pod.findAll(query).asCallback(function (err, pods) { | 180 | return Pod.findAll(query).then(pods => { |
190 | if (err) return callback(err) | 181 | return map(pods, 'id') |
191 | |||
192 | return callback(null, map(pods, 'id')) | ||
193 | }) | 182 | }) |
194 | }) | 183 | }) |
195 | } | 184 | } |
196 | 185 | ||
197 | listBadPods = function (callback: PodMethods.ListBadPodsCallback) { | 186 | listBadPods = function () { |
198 | const query = { | 187 | const query = { |
199 | where: { | 188 | where: { |
200 | score: { $lte: 0 } | 189 | score: { $lte: 0 } |
201 | } | 190 | } |
202 | } | 191 | } |
203 | 192 | ||
204 | return Pod.findAll(query).asCallback(callback) | 193 | return Pod.findAll(query) |
205 | } | 194 | } |
206 | 195 | ||
207 | load = function (id: number, callback: PodMethods.LoadCallback) { | 196 | load = function (id: number) { |
208 | return Pod.findById(id).asCallback(callback) | 197 | return Pod.findById(id) |
209 | } | 198 | } |
210 | 199 | ||
211 | loadByHost = function (host: string, callback: PodMethods.LoadByHostCallback) { | 200 | loadByHost = function (host: string) { |
212 | const query = { | 201 | const query = { |
213 | where: { | 202 | where: { |
214 | host: host | 203 | host: host |
215 | } | 204 | } |
216 | } | 205 | } |
217 | 206 | ||
218 | return Pod.findOne(query).asCallback(callback) | 207 | return Pod.findOne(query) |
219 | } | 208 | } |
220 | 209 | ||
221 | removeAll = function (callback: PodMethods.RemoveAllCallback) { | 210 | removeAll = function () { |
222 | return Pod.destroy().asCallback(callback) | 211 | return Pod.destroy() |
223 | } | 212 | } |
224 | 213 | ||
225 | updatePodsScore = function (goodPods: number[], badPods: number[]) { | 214 | updatePodsScore = function (goodPods: number[], badPods: number[]) { |
226 | logger.info('Updating %d good pods and %d bad pods scores.', goodPods.length, badPods.length) | 215 | logger.info('Updating %d good pods and %d bad pods scores.', goodPods.length, badPods.length) |
227 | 216 | ||
228 | if (goodPods.length !== 0) { | 217 | if (goodPods.length !== 0) { |
229 | incrementScores(goodPods, PODS_SCORE.BONUS, function (err) { | 218 | incrementScores(goodPods, PODS_SCORE.BONUS).catch(err => { |
230 | if (err) logger.error('Cannot increment scores of good pods.', { error: err }) | 219 | logger.error('Cannot increment scores of good pods.', { error: err }) |
231 | }) | 220 | }) |
232 | } | 221 | } |
233 | 222 | ||
234 | if (badPods.length !== 0) { | 223 | if (badPods.length !== 0) { |
235 | incrementScores(badPods, PODS_SCORE.MALUS, function (err) { | 224 | incrementScores(badPods, PODS_SCORE.MALUS) |
236 | if (err) logger.error('Cannot decrement scores of bad pods.', { error: err }) | 225 | .then(() => removeBadPods()) |
237 | removeBadPods() | 226 | .catch(err => { |
238 | }) | 227 | if (err) logger.error('Cannot decrement scores of bad pods.', { error: err }) |
228 | }) | ||
239 | } | 229 | } |
240 | } | 230 | } |
241 | 231 | ||
@@ -243,32 +233,19 @@ updatePodsScore = function (goodPods: number[], badPods: number[]) { | |||
243 | 233 | ||
244 | // Remove pods with a score of 0 (too many requests where they were unreachable) | 234 | // Remove pods with a score of 0 (too many requests where they were unreachable) |
245 | function removeBadPods () { | 235 | function removeBadPods () { |
246 | waterfall([ | 236 | return listBadPods() |
247 | function findBadPods (callback) { | 237 | .then(pods => { |
248 | listBadPods(function (err, pods) { | 238 | const podsRemovePromises = pods.map(pod => pod.destroy()) |
249 | if (err) { | 239 | return Promise.all(podsRemovePromises).then(() => pods.length) |
250 | logger.error('Cannot find bad pods.', { error: err }) | 240 | }) |
251 | return callback(err) | 241 | .then(numberOfPodsRemoved => { |
252 | } | 242 | if (numberOfPodsRemoved) { |
253 | 243 | logger.info('Removed %d pods.', numberOfPodsRemoved) | |
254 | return callback(null, pods) | 244 | } else { |
255 | }) | 245 | logger.info('No need to remove bad pods.') |
256 | }, | 246 | } |
257 | 247 | }) | |
258 | function removeTheseBadPods (pods, callback) { | 248 | .catch(err => { |
259 | each(pods, function (pod: any, callbackEach) { | ||
260 | pod.destroy().asCallback(callbackEach) | ||
261 | }, function (err) { | ||
262 | return callback(err, pods.length) | ||
263 | }) | ||
264 | } | ||
265 | ], function (err, numberOfPodsRemoved) { | ||
266 | if (err) { | ||
267 | logger.error('Cannot remove bad pods.', { error: err }) | 249 | logger.error('Cannot remove bad pods.', { error: err }) |
268 | } else if (numberOfPodsRemoved) { | 250 | }) |
269 | logger.info('Removed %d pods.', numberOfPodsRemoved) | ||
270 | } else { | ||
271 | logger.info('No need to remove bad pods.') | ||
272 | } | ||
273 | }) | ||
274 | } | 251 | } |
diff --git a/server/models/request/abstract-request-interface.ts b/server/models/request/abstract-request-interface.ts new file mode 100644 index 000000000..a384f4d27 --- /dev/null +++ b/server/models/request/abstract-request-interface.ts | |||
@@ -0,0 +1,12 @@ | |||
1 | import * as Promise from 'bluebird' | ||
2 | |||
3 | export interface AbstractRequestClass <T> { | ||
4 | countTotalRequests: () => Promise<number> | ||
5 | listWithLimitAndRandom: (limitPods: number, limitRequestsPerPod: number) => Promise<T> | ||
6 | removeWithEmptyTo: () => Promise<number> | ||
7 | removeAll: () => Promise<void> | ||
8 | } | ||
9 | |||
10 | export interface AbstractRequestToPodClass { | ||
11 | removeByRequestIdsAndPod: (ids: number[], podId: number) => Promise<number> | ||
12 | } | ||
diff --git a/server/models/request/index.ts b/server/models/request/index.ts index 824c140f5..3dd6aedc2 100644 --- a/server/models/request/index.ts +++ b/server/models/request/index.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | export * from './abstract-request-interface' | ||
1 | export * from './request-interface' | 2 | export * from './request-interface' |
2 | export * from './request-to-pod-interface' | 3 | export * from './request-to-pod-interface' |
3 | export * from './request-video-event-interface' | 4 | export * from './request-video-event-interface' |
diff --git a/server/models/request/request-interface.ts b/server/models/request/request-interface.ts index 483850633..7b0ee4df9 100644 --- a/server/models/request/request-interface.ts +++ b/server/models/request/request-interface.ts | |||
@@ -1,5 +1,7 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
4 | import { AbstractRequestClass } from './abstract-request-interface' | ||
3 | import { PodInstance, PodAttributes } from '../pod' | 5 | import { PodInstance, PodAttributes } from '../pod' |
4 | import { RequestEndpoint } from '../../../shared/models/request-scheduler.model' | 6 | import { RequestEndpoint } from '../../../shared/models/request-scheduler.model' |
5 | 7 | ||
@@ -11,20 +13,16 @@ export type RequestsGrouped = { | |||
11 | } | 13 | } |
12 | 14 | ||
13 | export namespace RequestMethods { | 15 | export namespace RequestMethods { |
14 | export type CountTotalRequestsCallback = (err: Error, total: number) => void | 16 | export type CountTotalRequests = () => Promise<number> |
15 | export type CountTotalRequests = (callback: CountTotalRequestsCallback) => void | ||
16 | 17 | ||
17 | export type ListWithLimitAndRandomCallback = (err: Error, requestsGrouped?: RequestsGrouped) => void | 18 | export type ListWithLimitAndRandom = (limitPods: number, limitRequestsPerPod: number) => Promise<RequestsGrouped> |
18 | export type ListWithLimitAndRandom = (limitPods, limitRequestsPerPod, callback: ListWithLimitAndRandomCallback) => void | ||
19 | 19 | ||
20 | export type RemoveWithEmptyToCallback = (err: Error) => void | 20 | export type RemoveWithEmptyTo = () => Promise<number> |
21 | export type RemoveWithEmptyTo = (callback: RemoveWithEmptyToCallback) => void | ||
22 | 21 | ||
23 | export type RemoveAllCallback = (err: Error) => void | 22 | export type RemoveAll = () => Promise<void> |
24 | export type RemoveAll = (callback: RemoveAllCallback) => void | ||
25 | } | 23 | } |
26 | 24 | ||
27 | export interface RequestClass { | 25 | export interface RequestClass extends AbstractRequestClass<RequestsGrouped> { |
28 | countTotalRequests: RequestMethods.CountTotalRequests | 26 | countTotalRequests: RequestMethods.CountTotalRequests |
29 | listWithLimitAndRandom: RequestMethods.ListWithLimitAndRandom | 27 | listWithLimitAndRandom: RequestMethods.ListWithLimitAndRandom |
30 | removeWithEmptyTo: RequestMethods.RemoveWithEmptyTo | 28 | removeWithEmptyTo: RequestMethods.RemoveWithEmptyTo |
diff --git a/server/models/request/request-to-pod-interface.ts b/server/models/request/request-to-pod-interface.ts index 6d75ca6e5..7ca99f4d4 100644 --- a/server/models/request/request-to-pod-interface.ts +++ b/server/models/request/request-to-pod-interface.ts | |||
@@ -1,11 +1,13 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
3 | |||
4 | import { AbstractRequestToPodClass } from './abstract-request-interface' | ||
2 | 5 | ||
3 | export namespace RequestToPodMethods { | 6 | export namespace RequestToPodMethods { |
4 | export type RemoveByRequestIdsAndPodCallback = (err: Error) => void | 7 | export type RemoveByRequestIdsAndPod = (requestsIds: number[], podId: number) => Promise<number> |
5 | export type RemoveByRequestIdsAndPod = (requestsIds: number[], podId: number, callback?: RemoveByRequestIdsAndPodCallback) => void | ||
6 | } | 8 | } |
7 | 9 | ||
8 | export interface RequestToPodClass { | 10 | export interface RequestToPodClass extends AbstractRequestToPodClass { |
9 | removeByRequestIdsAndPod: RequestToPodMethods.RemoveByRequestIdsAndPod | 11 | removeByRequestIdsAndPod: RequestToPodMethods.RemoveByRequestIdsAndPod |
10 | } | 12 | } |
11 | 13 | ||
diff --git a/server/models/request/request-to-pod.ts b/server/models/request/request-to-pod.ts index 67331be1d..6678ed290 100644 --- a/server/models/request/request-to-pod.ts +++ b/server/models/request/request-to-pod.ts | |||
@@ -2,7 +2,6 @@ import * as Sequelize from 'sequelize' | |||
2 | 2 | ||
3 | import { addMethodsToModel } from '../utils' | 3 | import { addMethodsToModel } from '../utils' |
4 | import { | 4 | import { |
5 | RequestToPodClass, | ||
6 | RequestToPodInstance, | 5 | RequestToPodInstance, |
7 | RequestToPodAttributes, | 6 | RequestToPodAttributes, |
8 | 7 | ||
@@ -38,9 +37,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
38 | 37 | ||
39 | // --------------------------------------------------------------------------- | 38 | // --------------------------------------------------------------------------- |
40 | 39 | ||
41 | removeByRequestIdsAndPod = function (requestsIds: number[], podId: number, callback?: RequestToPodMethods.RemoveByRequestIdsAndPodCallback) { | 40 | removeByRequestIdsAndPod = function (requestsIds: number[], podId: number) { |
42 | if (!callback) callback = function () { /* empty */ } | ||
43 | |||
44 | const query = { | 41 | const query = { |
45 | where: { | 42 | where: { |
46 | requestId: { | 43 | requestId: { |
@@ -50,5 +47,5 @@ removeByRequestIdsAndPod = function (requestsIds: number[], podId: number, callb | |||
50 | } | 47 | } |
51 | } | 48 | } |
52 | 49 | ||
53 | RequestToPod.destroy(query).asCallback(callback) | 50 | return RequestToPod.destroy(query) |
54 | } | 51 | } |
diff --git a/server/models/request/request-video-event-interface.ts b/server/models/request/request-video-event-interface.ts index 3ed03339a..a5032e1b1 100644 --- a/server/models/request/request-video-event-interface.ts +++ b/server/models/request/request-video-event-interface.ts | |||
@@ -1,5 +1,7 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
4 | import { AbstractRequestClass, AbstractRequestToPodClass } from './abstract-request-interface' | ||
3 | import { VideoInstance } from '../video' | 5 | import { VideoInstance } from '../video' |
4 | import { PodInstance } from '../pod' | 6 | import { PodInstance } from '../pod' |
5 | 7 | ||
@@ -16,20 +18,16 @@ export type RequestsVideoEventGrouped = { | |||
16 | } | 18 | } |
17 | 19 | ||
18 | export namespace RequestVideoEventMethods { | 20 | export namespace RequestVideoEventMethods { |
19 | export type CountTotalRequestsCallback = (err: Error, total: number) => void | 21 | export type CountTotalRequests = () => Promise<number> |
20 | export type CountTotalRequests = (callback: CountTotalRequestsCallback) => void | ||
21 | 22 | ||
22 | export type ListWithLimitAndRandomCallback = (err: Error, requestsGrouped?: RequestsVideoEventGrouped) => void | 23 | export type ListWithLimitAndRandom = (limitPods: number, limitRequestsPerPod: number) => Promise<RequestsVideoEventGrouped> |
23 | export type ListWithLimitAndRandom = (limitPods: number, limitRequestsPerPod: number, callback: ListWithLimitAndRandomCallback) => void | ||
24 | 24 | ||
25 | export type RemoveByRequestIdsAndPodCallback = () => void | 25 | export type RemoveByRequestIdsAndPod = (ids: number[], podId: number) => Promise<number> |
26 | export type RemoveByRequestIdsAndPod = (ids: number[], podId: number, callback: RemoveByRequestIdsAndPodCallback) => void | ||
27 | 26 | ||
28 | export type RemoveAllCallback = () => void | 27 | export type RemoveAll = () => Promise<void> |
29 | export type RemoveAll = (callback: RemoveAllCallback) => void | ||
30 | } | 28 | } |
31 | 29 | ||
32 | export interface RequestVideoEventClass { | 30 | export interface RequestVideoEventClass extends AbstractRequestClass<RequestsVideoEventGrouped>, AbstractRequestToPodClass { |
33 | countTotalRequests: RequestVideoEventMethods.CountTotalRequests | 31 | countTotalRequests: RequestVideoEventMethods.CountTotalRequests |
34 | listWithLimitAndRandom: RequestVideoEventMethods.ListWithLimitAndRandom | 32 | listWithLimitAndRandom: RequestVideoEventMethods.ListWithLimitAndRandom |
35 | removeByRequestIdsAndPod: RequestVideoEventMethods.RemoveByRequestIdsAndPod | 33 | removeByRequestIdsAndPod: RequestVideoEventMethods.RemoveByRequestIdsAndPod |
@@ -41,10 +39,12 @@ export interface RequestVideoEventAttributes { | |||
41 | count: number | 39 | count: number |
42 | } | 40 | } |
43 | 41 | ||
44 | export interface RequestVideoEventInstance extends RequestVideoEventClass, RequestVideoEventAttributes, Sequelize.Instance<RequestVideoEventAttributes> { | 42 | export interface RequestVideoEventInstance |
43 | extends RequestVideoEventClass, RequestVideoEventAttributes, Sequelize.Instance<RequestVideoEventAttributes> { | ||
45 | id: number | 44 | id: number |
46 | 45 | ||
47 | Video: VideoInstance | 46 | Video: VideoInstance |
48 | } | 47 | } |
49 | 48 | ||
50 | export interface RequestVideoEventModel extends RequestVideoEventClass, Sequelize.Model<RequestVideoEventInstance, RequestVideoEventAttributes> {} | 49 | export interface RequestVideoEventModel |
50 | extends RequestVideoEventClass, Sequelize.Model<RequestVideoEventInstance, RequestVideoEventAttributes> {} | ||
diff --git a/server/models/request/request-video-event.ts b/server/models/request/request-video-event.ts index f552ef50b..90ea15702 100644 --- a/server/models/request/request-video-event.ts +++ b/server/models/request/request-video-event.ts | |||
@@ -10,7 +10,6 @@ import { REQUEST_VIDEO_EVENT_TYPES } from '../../initializers' | |||
10 | import { isVideoEventCountValid } from '../../helpers' | 10 | import { isVideoEventCountValid } from '../../helpers' |
11 | import { addMethodsToModel } from '../utils' | 11 | import { addMethodsToModel } from '../utils' |
12 | import { | 12 | import { |
13 | RequestVideoEventClass, | ||
14 | RequestVideoEventInstance, | 13 | RequestVideoEventInstance, |
15 | RequestVideoEventAttributes, | 14 | RequestVideoEventAttributes, |
16 | 15 | ||
@@ -77,23 +76,21 @@ function associate (models) { | |||
77 | }) | 76 | }) |
78 | } | 77 | } |
79 | 78 | ||
80 | countTotalRequests = function (callback: RequestVideoEventMethods.CountTotalRequestsCallback) { | 79 | countTotalRequests = function () { |
81 | const query = {} | 80 | const query = {} |
82 | return RequestVideoEvent.count(query).asCallback(callback) | 81 | return RequestVideoEvent.count(query) |
83 | } | 82 | } |
84 | 83 | ||
85 | listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number, callback: RequestVideoEventMethods.ListWithLimitAndRandomCallback) { | 84 | listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number) { |
86 | const Pod = db.Pod | 85 | const Pod = db.Pod |
87 | 86 | ||
88 | // We make a join between videos and authors to find the podId of our video event requests | 87 | // We make a join between videos and authors to find the podId of our video event requests |
89 | const podJoins = 'INNER JOIN "Videos" ON "Videos"."authorId" = "Authors"."id" ' + | 88 | const podJoins = 'INNER JOIN "Videos" ON "Videos"."authorId" = "Authors"."id" ' + |
90 | 'INNER JOIN "RequestVideoEvents" ON "RequestVideoEvents"."videoId" = "Videos"."id"' | 89 | 'INNER JOIN "RequestVideoEvents" ON "RequestVideoEvents"."videoId" = "Videos"."id"' |
91 | 90 | ||
92 | Pod.listRandomPodIdsWithRequest(limitPods, 'Authors', podJoins, function (err, podIds) { | 91 | return Pod.listRandomPodIdsWithRequest(limitPods, 'Authors', podJoins).then(podIds => { |
93 | if (err) return callback(err) | ||
94 | |||
95 | // We don't have friends that have requests | 92 | // We don't have friends that have requests |
96 | if (podIds.length === 0) return callback(null, []) | 93 | if (podIds.length === 0) return [] |
97 | 94 | ||
98 | const query = { | 95 | const query = { |
99 | order: [ | 96 | order: [ |
@@ -121,16 +118,14 @@ listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: numbe | |||
121 | ] | 118 | ] |
122 | } | 119 | } |
123 | 120 | ||
124 | RequestVideoEvent.findAll(query).asCallback(function (err, requests) { | 121 | return RequestVideoEvent.findAll(query).then(requests => { |
125 | if (err) return callback(err) | ||
126 | |||
127 | const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod) | 122 | const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod) |
128 | return callback(err, requestsGrouped) | 123 | return requestsGrouped |
129 | }) | 124 | }) |
130 | }) | 125 | }) |
131 | } | 126 | } |
132 | 127 | ||
133 | removeByRequestIdsAndPod = function (ids: number[], podId: number, callback: RequestVideoEventMethods.RemoveByRequestIdsAndPodCallback) { | 128 | removeByRequestIdsAndPod = function (ids: number[], podId: number) { |
134 | const query = { | 129 | const query = { |
135 | where: { | 130 | where: { |
136 | id: { | 131 | id: { |
@@ -152,12 +147,12 @@ removeByRequestIdsAndPod = function (ids: number[], podId: number, callback: Req | |||
152 | ] | 147 | ] |
153 | } | 148 | } |
154 | 149 | ||
155 | RequestVideoEvent.destroy(query).asCallback(callback) | 150 | return RequestVideoEvent.destroy(query) |
156 | } | 151 | } |
157 | 152 | ||
158 | removeAll = function (callback: RequestVideoEventMethods.RemoveAllCallback) { | 153 | removeAll = function () { |
159 | // Delete all requests | 154 | // Delete all requests |
160 | RequestVideoEvent.truncate({ cascade: true }).asCallback(callback) | 155 | return RequestVideoEvent.truncate({ cascade: true }) |
161 | } | 156 | } |
162 | 157 | ||
163 | // --------------------------------------------------------------------------- | 158 | // --------------------------------------------------------------------------- |
diff --git a/server/models/request/request-video-qadu-interface.ts b/server/models/request/request-video-qadu-interface.ts index 805771cda..9a172a4d4 100644 --- a/server/models/request/request-video-qadu-interface.ts +++ b/server/models/request/request-video-qadu-interface.ts | |||
@@ -1,5 +1,7 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
4 | import { AbstractRequestClass, AbstractRequestToPodClass } from './abstract-request-interface' | ||
3 | import { VideoInstance } from '../video' | 5 | import { VideoInstance } from '../video' |
4 | import { PodInstance } from '../pod' | 6 | import { PodInstance } from '../pod' |
5 | 7 | ||
@@ -14,20 +16,16 @@ export type RequestsVideoQaduGrouped = { | |||
14 | } | 16 | } |
15 | 17 | ||
16 | export namespace RequestVideoQaduMethods { | 18 | export namespace RequestVideoQaduMethods { |
17 | export type CountTotalRequestsCallback = (err: Error, total: number) => void | 19 | export type CountTotalRequests = () => Promise<number> |
18 | export type CountTotalRequests = (callback: CountTotalRequestsCallback) => void | ||
19 | 20 | ||
20 | export type ListWithLimitAndRandomCallback = (err: Error, requestsGrouped?: RequestsVideoQaduGrouped) => void | 21 | export type ListWithLimitAndRandom = (limitPods: number, limitRequestsPerPod: number) => Promise<RequestsVideoQaduGrouped> |
21 | export type ListWithLimitAndRandom = (limitPods: number, limitRequestsPerPod: number, callback: ListWithLimitAndRandomCallback) => void | ||
22 | 22 | ||
23 | export type RemoveByRequestIdsAndPodCallback = () => void | 23 | export type RemoveByRequestIdsAndPod = (ids: number[], podId: number) => Promise<number> |
24 | export type RemoveByRequestIdsAndPod = (ids: number[], podId: number, callback: RemoveByRequestIdsAndPodCallback) => void | ||
25 | 24 | ||
26 | export type RemoveAllCallback = () => void | 25 | export type RemoveAll = () => Promise<void> |
27 | export type RemoveAll = (callback: RemoveAllCallback) => void | ||
28 | } | 26 | } |
29 | 27 | ||
30 | export interface RequestVideoQaduClass { | 28 | export interface RequestVideoQaduClass extends AbstractRequestClass<RequestsVideoQaduGrouped>, AbstractRequestToPodClass { |
31 | countTotalRequests: RequestVideoQaduMethods.CountTotalRequests | 29 | countTotalRequests: RequestVideoQaduMethods.CountTotalRequests |
32 | listWithLimitAndRandom: RequestVideoQaduMethods.ListWithLimitAndRandom | 30 | listWithLimitAndRandom: RequestVideoQaduMethods.ListWithLimitAndRandom |
33 | removeByRequestIdsAndPod: RequestVideoQaduMethods.RemoveByRequestIdsAndPod | 31 | removeByRequestIdsAndPod: RequestVideoQaduMethods.RemoveByRequestIdsAndPod |
@@ -38,11 +36,13 @@ export interface RequestVideoQaduAttributes { | |||
38 | type: RequestVideoQaduType | 36 | type: RequestVideoQaduType |
39 | } | 37 | } |
40 | 38 | ||
41 | export interface RequestVideoQaduInstance extends RequestVideoQaduClass, RequestVideoQaduAttributes, Sequelize.Instance<RequestVideoQaduAttributes> { | 39 | export interface RequestVideoQaduInstance |
40 | extends RequestVideoQaduClass, RequestVideoQaduAttributes, Sequelize.Instance<RequestVideoQaduAttributes> { | ||
42 | id: number | 41 | id: number |
43 | 42 | ||
44 | Pod: PodInstance | 43 | Pod: PodInstance |
45 | Video: VideoInstance | 44 | Video: VideoInstance |
46 | } | 45 | } |
47 | 46 | ||
48 | export interface RequestVideoQaduModel extends RequestVideoQaduClass, Sequelize.Model<RequestVideoQaduInstance, RequestVideoQaduAttributes> {} | 47 | export interface RequestVideoQaduModel |
48 | extends RequestVideoQaduClass, Sequelize.Model<RequestVideoQaduInstance, RequestVideoQaduAttributes> {} | ||
diff --git a/server/models/request/request-video-qadu.ts b/server/models/request/request-video-qadu.ts index da62239f5..74e28f129 100644 --- a/server/models/request/request-video-qadu.ts +++ b/server/models/request/request-video-qadu.ts | |||
@@ -16,7 +16,6 @@ import { database as db } from '../../initializers/database' | |||
16 | import { REQUEST_VIDEO_QADU_TYPES } from '../../initializers' | 16 | import { REQUEST_VIDEO_QADU_TYPES } from '../../initializers' |
17 | import { addMethodsToModel } from '../utils' | 17 | import { addMethodsToModel } from '../utils' |
18 | import { | 18 | import { |
19 | RequestVideoQaduClass, | ||
20 | RequestVideoQaduInstance, | 19 | RequestVideoQaduInstance, |
21 | RequestVideoQaduAttributes, | 20 | RequestVideoQaduAttributes, |
22 | 21 | ||
@@ -83,20 +82,18 @@ function associate (models) { | |||
83 | }) | 82 | }) |
84 | } | 83 | } |
85 | 84 | ||
86 | countTotalRequests = function (callback: RequestVideoQaduMethods.CountTotalRequestsCallback) { | 85 | countTotalRequests = function () { |
87 | const query = {} | 86 | const query = {} |
88 | return RequestVideoQadu.count(query).asCallback(callback) | 87 | return RequestVideoQadu.count(query) |
89 | } | 88 | } |
90 | 89 | ||
91 | listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number, callback: RequestVideoQaduMethods.ListWithLimitAndRandomCallback) { | 90 | listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number) { |
92 | const Pod = db.Pod | 91 | const Pod = db.Pod |
93 | const tableJoin = '' | 92 | const tableJoin = '' |
94 | 93 | ||
95 | Pod.listRandomPodIdsWithRequest(limitPods, 'RequestVideoQadus', tableJoin, function (err, podIds) { | 94 | return Pod.listRandomPodIdsWithRequest(limitPods, 'RequestVideoQadus', tableJoin).then(podIds => { |
96 | if (err) return callback(err) | ||
97 | |||
98 | // We don't have friends that have requests | 95 | // We don't have friends that have requests |
99 | if (podIds.length === 0) return callback(null, []) | 96 | if (podIds.length === 0) return [] |
100 | 97 | ||
101 | const query = { | 98 | const query = { |
102 | include: [ | 99 | include: [ |
@@ -114,16 +111,14 @@ listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: numbe | |||
114 | ] | 111 | ] |
115 | } | 112 | } |
116 | 113 | ||
117 | RequestVideoQadu.findAll(query).asCallback(function (err, requests) { | 114 | return RequestVideoQadu.findAll(query).then(requests => { |
118 | if (err) return callback(err) | ||
119 | |||
120 | const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod) | 115 | const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod) |
121 | return callback(err, requestsGrouped) | 116 | return requestsGrouped |
122 | }) | 117 | }) |
123 | }) | 118 | }) |
124 | } | 119 | } |
125 | 120 | ||
126 | removeByRequestIdsAndPod = function (ids: number[], podId: number, callback: RequestVideoQaduMethods.RemoveByRequestIdsAndPodCallback) { | 121 | removeByRequestIdsAndPod = function (ids: number[], podId: number) { |
127 | const query = { | 122 | const query = { |
128 | where: { | 123 | where: { |
129 | id: { | 124 | id: { |
@@ -133,12 +128,12 @@ removeByRequestIdsAndPod = function (ids: number[], podId: number, callback: Req | |||
133 | } | 128 | } |
134 | } | 129 | } |
135 | 130 | ||
136 | RequestVideoQadu.destroy(query).asCallback(callback) | 131 | return RequestVideoQadu.destroy(query) |
137 | } | 132 | } |
138 | 133 | ||
139 | removeAll = function (callback: RequestVideoQaduMethods.RemoveAllCallback) { | 134 | removeAll = function () { |
140 | // Delete all requests | 135 | // Delete all requests |
141 | RequestVideoQadu.truncate({ cascade: true }).asCallback(callback) | 136 | return RequestVideoQadu.truncate({ cascade: true }) |
142 | } | 137 | } |
143 | 138 | ||
144 | // --------------------------------------------------------------------------- | 139 | // --------------------------------------------------------------------------- |
diff --git a/server/models/request/request.ts b/server/models/request/request.ts index 66e7da845..c3ce2cd4e 100644 --- a/server/models/request/request.ts +++ b/server/models/request/request.ts | |||
@@ -5,7 +5,6 @@ import { database as db } from '../../initializers/database' | |||
5 | import { REQUEST_ENDPOINTS } from '../../initializers' | 5 | import { REQUEST_ENDPOINTS } from '../../initializers' |
6 | import { addMethodsToModel } from '../utils' | 6 | import { addMethodsToModel } from '../utils' |
7 | import { | 7 | import { |
8 | RequestClass, | ||
9 | RequestInstance, | 8 | RequestInstance, |
10 | RequestAttributes, | 9 | RequestAttributes, |
11 | 10 | ||
@@ -60,25 +59,23 @@ function associate (models) { | |||
60 | }) | 59 | }) |
61 | } | 60 | } |
62 | 61 | ||
63 | countTotalRequests = function (callback: RequestMethods.CountTotalRequestsCallback) { | 62 | countTotalRequests = function () { |
64 | // We need to include Pod because there are no cascade delete when a pod is removed | 63 | // We need to include Pod because there are no cascade delete when a pod is removed |
65 | // So we could count requests that do not have existing pod anymore | 64 | // So we could count requests that do not have existing pod anymore |
66 | const query = { | 65 | const query = { |
67 | include: [ Request['sequelize'].models.Pod ] | 66 | include: [ Request['sequelize'].models.Pod ] |
68 | } | 67 | } |
69 | 68 | ||
70 | return Request.count(query).asCallback(callback) | 69 | return Request.count(query) |
71 | } | 70 | } |
72 | 71 | ||
73 | listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number, callback: RequestMethods.ListWithLimitAndRandomCallback) { | 72 | listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number) { |
74 | const Pod = db.Pod | 73 | const Pod = db.Pod |
75 | const tableJoin = '' | 74 | const tableJoin = '' |
76 | 75 | ||
77 | Pod.listRandomPodIdsWithRequest(limitPods, 'RequestToPods', '', function (err, podIds) { | 76 | return Pod.listRandomPodIdsWithRequest(limitPods, 'RequestToPods', tableJoin).then(podIds => { |
78 | if (err) return callback(err) | ||
79 | |||
80 | // We don't have friends that have requests | 77 | // We don't have friends that have requests |
81 | if (podIds.length === 0) return callback(null, []) | 78 | if (podIds.length === 0) return [] |
82 | 79 | ||
83 | // The first x requests of these pods | 80 | // The first x requests of these pods |
84 | // It is very important to sort by id ASC to keep the requests order! | 81 | // It is very important to sort by id ASC to keep the requests order! |
@@ -98,23 +95,20 @@ listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: numbe | |||
98 | ] | 95 | ] |
99 | } | 96 | } |
100 | 97 | ||
101 | Request.findAll(query).asCallback(function (err, requests) { | 98 | return Request.findAll(query).then(requests => { |
102 | if (err) return callback(err) | ||
103 | 99 | ||
104 | const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod) | 100 | const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod) |
105 | return callback(err, requestsGrouped) | 101 | return requestsGrouped |
106 | }) | 102 | }) |
107 | }) | 103 | }) |
108 | } | 104 | } |
109 | 105 | ||
110 | removeAll = function (callback: RequestMethods.RemoveAllCallback) { | 106 | removeAll = function () { |
111 | // Delete all requests | 107 | // Delete all requests |
112 | Request.truncate({ cascade: true }).asCallback(callback) | 108 | return Request.truncate({ cascade: true }) |
113 | } | 109 | } |
114 | 110 | ||
115 | removeWithEmptyTo = function (callback?: RequestMethods.RemoveWithEmptyToCallback) { | 111 | removeWithEmptyTo = function () { |
116 | if (!callback) callback = function () { /* empty */ } | ||
117 | |||
118 | const query = { | 112 | const query = { |
119 | where: { | 113 | where: { |
120 | id: { | 114 | id: { |
@@ -125,7 +119,7 @@ removeWithEmptyTo = function (callback?: RequestMethods.RemoveWithEmptyToCallbac | |||
125 | } | 119 | } |
126 | } | 120 | } |
127 | 121 | ||
128 | Request.destroy(query).asCallback(callback) | 122 | return Request.destroy(query) |
129 | } | 123 | } |
130 | 124 | ||
131 | // --------------------------------------------------------------------------- | 125 | // --------------------------------------------------------------------------- |
diff --git a/server/models/user/user-interface.ts b/server/models/user/user-interface.ts index 48c67678b..f743945f8 100644 --- a/server/models/user/user-interface.ts +++ b/server/models/user/user-interface.ts | |||
@@ -1,35 +1,29 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Bluebird from 'bluebird' | 2 | import * as Promise from 'bluebird' |
3 | 3 | ||
4 | // Don't use barrel, import just what we need | 4 | // Don't use barrel, import just what we need |
5 | import { UserRole, User as FormatedUser } from '../../../shared/models/user.model' | 5 | import { UserRole, User as FormatedUser } from '../../../shared/models/user.model' |
6 | import { ResultList } from '../../../shared/models/result-list.model' | ||
6 | 7 | ||
7 | export namespace UserMethods { | 8 | export namespace UserMethods { |
8 | export type IsPasswordMatchCallback = (err: Error, same: boolean) => void | 9 | export type IsPasswordMatch = (this: UserInstance, password: string) => Promise<boolean> |
9 | export type IsPasswordMatch = (this: UserInstance, password: string, callback: IsPasswordMatchCallback) => void | ||
10 | 10 | ||
11 | export type ToFormatedJSON = (this: UserInstance) => FormatedUser | 11 | export type ToFormatedJSON = (this: UserInstance) => FormatedUser |
12 | export type IsAdmin = (this: UserInstance) => boolean | 12 | export type IsAdmin = (this: UserInstance) => boolean |
13 | 13 | ||
14 | export type CountTotalCallback = (err: Error, total: number) => void | 14 | export type CountTotal = () => Promise<number> |
15 | export type CountTotal = (callback: CountTotalCallback) => void | ||
16 | 15 | ||
17 | export type GetByUsername = (username: string) => Bluebird<UserInstance> | 16 | export type GetByUsername = (username: string) => Promise<UserInstance> |
18 | 17 | ||
19 | export type ListCallback = (err: Error, userInstances: UserInstance[]) => void | 18 | export type List = () => Promise<UserInstance[]> |
20 | export type List = (callback: ListCallback) => void | ||
21 | 19 | ||
22 | export type ListForApiCallback = (err: Error, userInstances?: UserInstance[], total?: number) => void | 20 | export type ListForApi = (start: number, count: number, sort: string) => Promise< ResultList<UserInstance> > |
23 | export type ListForApi = (start: number, count: number, sort: string, callback: ListForApiCallback) => void | ||
24 | 21 | ||
25 | export type LoadByIdCallback = (err: Error, userInstance: UserInstance) => void | 22 | export type LoadById = (id: number) => Promise<UserInstance> |
26 | export type LoadById = (id: number, callback: LoadByIdCallback) => void | ||
27 | 23 | ||
28 | export type LoadByUsernameCallback = (err: Error, userInstance: UserInstance) => void | 24 | export type LoadByUsername = (username: string) => Promise<UserInstance> |
29 | export type LoadByUsername = (username: string, callback: LoadByUsernameCallback) => void | ||
30 | 25 | ||
31 | export type LoadByUsernameOrEmailCallback = (err: Error, userInstance: UserInstance) => void | 26 | export type LoadByUsernameOrEmail = (username: string, email: string) => Promise<UserInstance> |
32 | export type LoadByUsernameOrEmail = (username: string, email: string, callback: LoadByUsernameOrEmailCallback) => void | ||
33 | } | 27 | } |
34 | 28 | ||
35 | export interface UserClass { | 29 | export interface UserClass { |
diff --git a/server/models/user/user-video-rate-interface.ts b/server/models/user/user-video-rate-interface.ts index a726639b1..e0b65a13d 100644 --- a/server/models/user/user-video-rate-interface.ts +++ b/server/models/user/user-video-rate-interface.ts | |||
@@ -1,10 +1,10 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
3 | import { VideoRateType } from '../../../shared/models/user-video-rate.model' | 4 | import { VideoRateType } from '../../../shared/models/user-video-rate.model' |
4 | 5 | ||
5 | export namespace UserVideoRateMethods { | 6 | export namespace UserVideoRateMethods { |
6 | export type LoadCallback = (err: Error, userVideoRateInstance: UserVideoRateInstance) => void | 7 | export type Load = (userId: number, videoId: string, transaction: Sequelize.Transaction) => Promise<UserVideoRateInstance> |
7 | export type Load = (userId: number, videoId: string, transaction: Sequelize.Transaction, callback: LoadCallback) => void | ||
8 | } | 8 | } |
9 | 9 | ||
10 | export interface UserVideoRateClass { | 10 | export interface UserVideoRateClass { |
diff --git a/server/models/user/user-video-rate.ts b/server/models/user/user-video-rate.ts index 4bdd35bc9..37d0222cf 100644 --- a/server/models/user/user-video-rate.ts +++ b/server/models/user/user-video-rate.ts | |||
@@ -8,7 +8,6 @@ import { VIDEO_RATE_TYPES } from '../../initializers' | |||
8 | 8 | ||
9 | import { addMethodsToModel } from '../utils' | 9 | import { addMethodsToModel } from '../utils' |
10 | import { | 10 | import { |
11 | UserVideoRateClass, | ||
12 | UserVideoRateInstance, | 11 | UserVideoRateInstance, |
13 | UserVideoRateAttributes, | 12 | UserVideoRateAttributes, |
14 | 13 | ||
@@ -66,7 +65,7 @@ function associate (models) { | |||
66 | }) | 65 | }) |
67 | } | 66 | } |
68 | 67 | ||
69 | load = function (userId: number, videoId: string, transaction: Sequelize.Transaction, callback: UserVideoRateMethods.LoadCallback) { | 68 | load = function (userId: number, videoId: string, transaction: Sequelize.Transaction) { |
70 | const options: Sequelize.FindOptions = { | 69 | const options: Sequelize.FindOptions = { |
71 | where: { | 70 | where: { |
72 | userId, | 71 | userId, |
@@ -75,5 +74,5 @@ load = function (userId: number, videoId: string, transaction: Sequelize.Transac | |||
75 | } | 74 | } |
76 | if (transaction) options.transaction = transaction | 75 | if (transaction) options.transaction = transaction |
77 | 76 | ||
78 | return UserVideoRate.findOne(options).asCallback(callback) | 77 | return UserVideoRate.findOne(options) |
79 | } | 78 | } |
diff --git a/server/models/user/user.ts b/server/models/user/user.ts index 6b2410259..5ff81e741 100644 --- a/server/models/user/user.ts +++ b/server/models/user/user.ts | |||
@@ -13,7 +13,6 @@ import { | |||
13 | 13 | ||
14 | import { addMethodsToModel } from '../utils' | 14 | import { addMethodsToModel } from '../utils' |
15 | import { | 15 | import { |
16 | UserClass, | ||
17 | UserInstance, | 16 | UserInstance, |
18 | UserAttributes, | 17 | UserAttributes, |
19 | 18 | ||
@@ -118,21 +117,16 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
118 | } | 117 | } |
119 | 118 | ||
120 | function beforeCreateOrUpdate (user: UserInstance) { | 119 | function beforeCreateOrUpdate (user: UserInstance) { |
121 | return new Promise(function (resolve, reject) { | 120 | return cryptPassword(user.password).then(hash => { |
122 | cryptPassword(user.password, function (err, hash) { | 121 | user.password = hash |
123 | if (err) return reject(err) | 122 | return undefined |
124 | |||
125 | user.password = hash | ||
126 | |||
127 | return resolve() | ||
128 | }) | ||
129 | }) | 123 | }) |
130 | } | 124 | } |
131 | 125 | ||
132 | // ------------------------------ METHODS ------------------------------ | 126 | // ------------------------------ METHODS ------------------------------ |
133 | 127 | ||
134 | isPasswordMatch = function (this: UserInstance, password: string, callback: UserMethods.IsPasswordMatchCallback) { | 128 | isPasswordMatch = function (this: UserInstance, password: string) { |
135 | return comparePassword(password, this.password, callback) | 129 | return comparePassword(password, this.password) |
136 | } | 130 | } |
137 | 131 | ||
138 | toFormatedJSON = function (this: UserInstance) { | 132 | toFormatedJSON = function (this: UserInstance) { |
@@ -164,8 +158,8 @@ function associate (models) { | |||
164 | }) | 158 | }) |
165 | } | 159 | } |
166 | 160 | ||
167 | countTotal = function (callback: UserMethods.CountTotalCallback) { | 161 | countTotal = function () { |
168 | return this.count().asCallback(callback) | 162 | return this.count() |
169 | } | 163 | } |
170 | 164 | ||
171 | getByUsername = function (username: string) { | 165 | getByUsername = function (username: string) { |
@@ -178,44 +172,45 @@ getByUsername = function (username: string) { | |||
178 | return User.findOne(query) | 172 | return User.findOne(query) |
179 | } | 173 | } |
180 | 174 | ||
181 | list = function (callback: UserMethods.ListCallback) { | 175 | list = function () { |
182 | return User.find().asCallback(callback) | 176 | return User.findAll() |
183 | } | 177 | } |
184 | 178 | ||
185 | listForApi = function (start: number, count: number, sort: string, callback: UserMethods.ListForApiCallback) { | 179 | listForApi = function (start: number, count: number, sort: string) { |
186 | const query = { | 180 | const query = { |
187 | offset: start, | 181 | offset: start, |
188 | limit: count, | 182 | limit: count, |
189 | order: [ getSort(sort) ] | 183 | order: [ getSort(sort) ] |
190 | } | 184 | } |
191 | 185 | ||
192 | return User.findAndCountAll(query).asCallback(function (err, result) { | 186 | return User.findAndCountAll(query).then(({ rows, count }) => { |
193 | if (err) return callback(err) | 187 | return { |
194 | 188 | data: rows, | |
195 | return callback(null, result.rows, result.count) | 189 | total: count |
190 | } | ||
196 | }) | 191 | }) |
197 | } | 192 | } |
198 | 193 | ||
199 | loadById = function (id: number, callback: UserMethods.LoadByIdCallback) { | 194 | loadById = function (id: number) { |
200 | return User.findById(id).asCallback(callback) | 195 | return User.findById(id) |
201 | } | 196 | } |
202 | 197 | ||
203 | loadByUsername = function (username: string, callback: UserMethods.LoadByUsernameCallback) { | 198 | loadByUsername = function (username: string) { |
204 | const query = { | 199 | const query = { |
205 | where: { | 200 | where: { |
206 | username: username | 201 | username: username |
207 | } | 202 | } |
208 | } | 203 | } |
209 | 204 | ||
210 | return User.findOne(query).asCallback(callback) | 205 | return User.findOne(query) |
211 | } | 206 | } |
212 | 207 | ||
213 | loadByUsernameOrEmail = function (username: string, email: string, callback: UserMethods.LoadByUsernameOrEmailCallback) { | 208 | loadByUsernameOrEmail = function (username: string, email: string) { |
214 | const query = { | 209 | const query = { |
215 | where: { | 210 | where: { |
216 | $or: [ { username }, { email } ] | 211 | $or: [ { username }, { email } ] |
217 | } | 212 | } |
218 | } | 213 | } |
219 | 214 | ||
220 | return User.findOne(query).asCallback(callback) | 215 | return User.findOne(query) |
221 | } | 216 | } |
diff --git a/server/models/video/author-interface.ts b/server/models/video/author-interface.ts index c1b30848c..dbcb85b17 100644 --- a/server/models/video/author-interface.ts +++ b/server/models/video/author-interface.ts | |||
@@ -1,10 +1,15 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
3 | import { PodInstance } from '../pod' | 4 | import { PodInstance } from '../pod' |
4 | 5 | ||
5 | export namespace AuthorMethods { | 6 | export namespace AuthorMethods { |
6 | export type FindOrCreateAuthorCallback = (err: Error, authorInstance?: AuthorInstance) => void | 7 | export type FindOrCreateAuthor = ( |
7 | export type FindOrCreateAuthor = (name: string, podId: number, userId: number, transaction: Sequelize.Transaction, callback: FindOrCreateAuthorCallback) => void | 8 | name: string, |
9 | podId: number, | ||
10 | userId: number, | ||
11 | transaction: Sequelize.Transaction | ||
12 | ) => Promise<AuthorInstance> | ||
8 | } | 13 | } |
9 | 14 | ||
10 | export interface AuthorClass { | 15 | export interface AuthorClass { |
diff --git a/server/models/video/author.ts b/server/models/video/author.ts index 4a115e328..3222c4834 100644 --- a/server/models/video/author.ts +++ b/server/models/video/author.ts | |||
@@ -4,7 +4,6 @@ import { isUserUsernameValid } from '../../helpers' | |||
4 | 4 | ||
5 | import { addMethodsToModel } from '../utils' | 5 | import { addMethodsToModel } from '../utils' |
6 | import { | 6 | import { |
7 | AuthorClass, | ||
8 | AuthorInstance, | 7 | AuthorInstance, |
9 | AuthorAttributes, | 8 | AuthorAttributes, |
10 | 9 | ||
@@ -74,30 +73,18 @@ function associate (models) { | |||
74 | }) | 73 | }) |
75 | } | 74 | } |
76 | 75 | ||
77 | findOrCreateAuthor = function ( | 76 | findOrCreateAuthor = function (name: string, podId: number, userId: number, transaction: Sequelize.Transaction) { |
78 | name: string, | ||
79 | podId: number, | ||
80 | userId: number, | ||
81 | transaction: Sequelize.Transaction, | ||
82 | callback: AuthorMethods.FindOrCreateAuthorCallback | ||
83 | ) { | ||
84 | const author = { | 77 | const author = { |
85 | name, | 78 | name, |
86 | podId, | 79 | podId, |
87 | userId | 80 | userId |
88 | } | 81 | } |
89 | 82 | ||
90 | const query: any = { | 83 | const query: Sequelize.FindOrInitializeOptions<AuthorAttributes> = { |
91 | where: author, | 84 | where: author, |
92 | defaults: author | 85 | defaults: author, |
86 | transaction | ||
93 | } | 87 | } |
94 | 88 | ||
95 | if (transaction !== null) query.transaction = transaction | 89 | return Author.findOrCreate(query).then(([ authorInstance ]) => authorInstance) |
96 | |||
97 | Author.findOrCreate(query).asCallback(function (err, result) { | ||
98 | if (err) return callback(err) | ||
99 | |||
100 | // [ instance, wasCreated ] | ||
101 | return callback(null, result[0]) | ||
102 | }) | ||
103 | } | 90 | } |
diff --git a/server/models/video/tag-interface.ts b/server/models/video/tag-interface.ts index e045e7ca5..08e5c3246 100644 --- a/server/models/video/tag-interface.ts +++ b/server/models/video/tag-interface.ts | |||
@@ -1,8 +1,8 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
3 | export namespace TagMethods { | 4 | export namespace TagMethods { |
4 | export type FindOrCreateTagsCallback = (err: Error, tagInstances: TagInstance[]) => void | 5 | export type FindOrCreateTags = (tags: string[], transaction: Sequelize.Transaction) => Promise<TagInstance[]> |
5 | export type FindOrCreateTags = (tags: string[], transaction: Sequelize.Transaction, callback: FindOrCreateTagsCallback) => void | ||
6 | } | 6 | } |
7 | 7 | ||
8 | export interface TagClass { | 8 | export interface TagClass { |
diff --git a/server/models/video/tag.ts b/server/models/video/tag.ts index 3c657d751..d0d8353d7 100644 --- a/server/models/video/tag.ts +++ b/server/models/video/tag.ts | |||
@@ -1,9 +1,8 @@ | |||
1 | import { each } from 'async' | ||
2 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
3 | 3 | ||
4 | import { addMethodsToModel } from '../utils' | 4 | import { addMethodsToModel } from '../utils' |
5 | import { | 5 | import { |
6 | TagClass, | ||
7 | TagInstance, | 6 | TagInstance, |
8 | TagAttributes, | 7 | TagAttributes, |
9 | 8 | ||
@@ -52,10 +51,9 @@ function associate (models) { | |||
52 | }) | 51 | }) |
53 | } | 52 | } |
54 | 53 | ||
55 | findOrCreateTags = function (tags: string[], transaction: Sequelize.Transaction, callback: TagMethods.FindOrCreateTagsCallback) { | 54 | findOrCreateTags = function (tags: string[], transaction: Sequelize.Transaction) { |
56 | const tagInstances = [] | 55 | const tasks: Promise<TagInstance>[] = [] |
57 | 56 | tags.forEach(tag => { | |
58 | each<string, Error>(tags, function (tag, callbackEach) { | ||
59 | const query: any = { | 57 | const query: any = { |
60 | where: { | 58 | where: { |
61 | name: tag | 59 | name: tag |
@@ -67,15 +65,9 @@ findOrCreateTags = function (tags: string[], transaction: Sequelize.Transaction, | |||
67 | 65 | ||
68 | if (transaction) query.transaction = transaction | 66 | if (transaction) query.transaction = transaction |
69 | 67 | ||
70 | Tag.findOrCreate(query).asCallback(function (err, res) { | 68 | const promise = Tag.findOrCreate(query).then(([ tagInstance ]) => tagInstance) |
71 | if (err) return callbackEach(err) | 69 | tasks.push(promise) |
72 | |||
73 | // res = [ tag, isCreated ] | ||
74 | const tag = res[0] | ||
75 | tagInstances.push(tag) | ||
76 | return callbackEach() | ||
77 | }) | ||
78 | }, function (err) { | ||
79 | return callback(err, tagInstances) | ||
80 | }) | 70 | }) |
71 | |||
72 | return Promise.all(tasks) | ||
81 | } | 73 | } |
diff --git a/server/models/video/video-abuse-interface.ts b/server/models/video/video-abuse-interface.ts index c85d09091..75647fe0e 100644 --- a/server/models/video/video-abuse-interface.ts +++ b/server/models/video/video-abuse-interface.ts | |||
@@ -1,6 +1,8 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
3 | import { PodInstance } from '../pod' | 4 | import { PodInstance } from '../pod' |
5 | import { ResultList } from '../../../shared' | ||
4 | 6 | ||
5 | // Don't use barrel, import just what we need | 7 | // Don't use barrel, import just what we need |
6 | import { VideoAbuse as FormatedVideoAbuse } from '../../../shared/models/video-abuse.model' | 8 | import { VideoAbuse as FormatedVideoAbuse } from '../../../shared/models/video-abuse.model' |
@@ -8,8 +10,7 @@ import { VideoAbuse as FormatedVideoAbuse } from '../../../shared/models/video-a | |||
8 | export namespace VideoAbuseMethods { | 10 | export namespace VideoAbuseMethods { |
9 | export type ToFormatedJSON = (this: VideoAbuseInstance) => FormatedVideoAbuse | 11 | export type ToFormatedJSON = (this: VideoAbuseInstance) => FormatedVideoAbuse |
10 | 12 | ||
11 | export type ListForApiCallback = (err: Error, videoAbuseInstances?: VideoAbuseInstance[], total?: number) => void | 13 | export type ListForApi = (start: number, count: number, sort: string) => Promise< ResultList<VideoAbuseInstance> > |
12 | export type ListForApi = (start: number, count: number, sort: string, callback: ListForApiCallback) => void | ||
13 | } | 14 | } |
14 | 15 | ||
15 | export interface VideoAbuseClass { | 16 | export interface VideoAbuseClass { |
diff --git a/server/models/video/video-abuse.ts b/server/models/video/video-abuse.ts index bc5f01e21..ab1a3ea7d 100644 --- a/server/models/video/video-abuse.ts +++ b/server/models/video/video-abuse.ts | |||
@@ -5,7 +5,6 @@ import { isVideoAbuseReporterUsernameValid, isVideoAbuseReasonValid } from '../. | |||
5 | 5 | ||
6 | import { addMethodsToModel, getSort } from '../utils' | 6 | import { addMethodsToModel, getSort } from '../utils' |
7 | import { | 7 | import { |
8 | VideoAbuseClass, | ||
9 | VideoAbuseInstance, | 8 | VideoAbuseInstance, |
10 | VideoAbuseAttributes, | 9 | VideoAbuseAttributes, |
11 | 10 | ||
@@ -109,7 +108,7 @@ function associate (models) { | |||
109 | }) | 108 | }) |
110 | } | 109 | } |
111 | 110 | ||
112 | listForApi = function (start: number, count: number, sort: string, callback: VideoAbuseMethods.ListForApiCallback) { | 111 | listForApi = function (start: number, count: number, sort: string) { |
113 | const query = { | 112 | const query = { |
114 | offset: start, | 113 | offset: start, |
115 | limit: count, | 114 | limit: count, |
@@ -122,11 +121,7 @@ listForApi = function (start: number, count: number, sort: string, callback: Vid | |||
122 | ] | 121 | ] |
123 | } | 122 | } |
124 | 123 | ||
125 | return VideoAbuse.findAndCountAll(query).asCallback(function (err, result) { | 124 | return VideoAbuse.findAndCountAll(query).then(({ rows, count }) => { |
126 | if (err) return callback(err) | 125 | return { total: count, data: rows } |
127 | |||
128 | return callback(null, result.rows, result.count) | ||
129 | }) | 126 | }) |
130 | } | 127 | } |
131 | |||
132 | |||
diff --git a/server/models/video/video-blacklist-interface.ts b/server/models/video/video-blacklist-interface.ts index d4d6528d1..5ca423801 100644 --- a/server/models/video/video-blacklist-interface.ts +++ b/server/models/video/video-blacklist-interface.ts | |||
@@ -1,4 +1,7 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
3 | |||
4 | import { ResultList } from '../../../shared' | ||
2 | 5 | ||
3 | // Don't use barrel, import just what we need | 6 | // Don't use barrel, import just what we need |
4 | import { BlacklistedVideo as FormatedBlacklistedVideo } from '../../../shared/models/video-blacklist.model' | 7 | import { BlacklistedVideo as FormatedBlacklistedVideo } from '../../../shared/models/video-blacklist.model' |
@@ -6,20 +9,15 @@ import { BlacklistedVideo as FormatedBlacklistedVideo } from '../../../shared/mo | |||
6 | export namespace BlacklistedVideoMethods { | 9 | export namespace BlacklistedVideoMethods { |
7 | export type ToFormatedJSON = (this: BlacklistedVideoInstance) => FormatedBlacklistedVideo | 10 | export type ToFormatedJSON = (this: BlacklistedVideoInstance) => FormatedBlacklistedVideo |
8 | 11 | ||
9 | export type CountTotalCallback = (err: Error, total: number) => void | 12 | export type CountTotal = () => Promise<number> |
10 | export type CountTotal = (callback: CountTotalCallback) => void | ||
11 | 13 | ||
12 | export type ListCallback = (err: Error, backlistedVideoInstances: BlacklistedVideoInstance[]) => void | 14 | export type List = () => Promise<BlacklistedVideoInstance[]> |
13 | export type List = (callback: ListCallback) => void | ||
14 | 15 | ||
15 | export type ListForApiCallback = (err: Error, blacklistedVIdeoInstances?: BlacklistedVideoInstance[], total?: number) => void | 16 | export type ListForApi = (start: number, count: number, sort: string) => Promise< ResultList<BlacklistedVideoInstance> > |
16 | export type ListForApi = (start: number, count: number, sort: string, callback: ListForApiCallback) => void | ||
17 | 17 | ||
18 | export type LoadByIdCallback = (err: Error, blacklistedVideoInstance: BlacklistedVideoInstance) => void | 18 | export type LoadById = (id: number) => Promise<BlacklistedVideoInstance> |
19 | export type LoadById = (id: number, callback: LoadByIdCallback) => void | ||
20 | 19 | ||
21 | export type LoadByVideoIdCallback = (err: Error, blacklistedVideoInstance: BlacklistedVideoInstance) => void | 20 | export type LoadByVideoId = (id: string) => Promise<BlacklistedVideoInstance> |
22 | export type LoadByVideoId = (id: string, callback: LoadByVideoIdCallback) => void | ||
23 | } | 21 | } |
24 | 22 | ||
25 | export interface BlacklistedVideoClass { | 23 | export interface BlacklistedVideoClass { |
@@ -35,7 +33,8 @@ export interface BlacklistedVideoAttributes { | |||
35 | videoId: string | 33 | videoId: string |
36 | } | 34 | } |
37 | 35 | ||
38 | export interface BlacklistedVideoInstance extends BlacklistedVideoClass, BlacklistedVideoAttributes, Sequelize.Instance<BlacklistedVideoAttributes> { | 36 | export interface BlacklistedVideoInstance |
37 | extends BlacklistedVideoClass, BlacklistedVideoAttributes, Sequelize.Instance<BlacklistedVideoAttributes> { | ||
39 | id: number | 38 | id: number |
40 | createdAt: Date | 39 | createdAt: Date |
41 | updatedAt: Date | 40 | updatedAt: Date |
@@ -43,4 +42,5 @@ export interface BlacklistedVideoInstance extends BlacklistedVideoClass, Blackli | |||
43 | toFormatedJSON: BlacklistedVideoMethods.ToFormatedJSON | 42 | toFormatedJSON: BlacklistedVideoMethods.ToFormatedJSON |
44 | } | 43 | } |
45 | 44 | ||
46 | export interface BlacklistedVideoModel extends BlacklistedVideoClass, Sequelize.Model<BlacklistedVideoInstance, BlacklistedVideoAttributes> {} | 45 | export interface BlacklistedVideoModel |
46 | extends BlacklistedVideoClass, Sequelize.Model<BlacklistedVideoInstance, BlacklistedVideoAttributes> {} | ||
diff --git a/server/models/video/video-blacklist.ts b/server/models/video/video-blacklist.ts index 3576c96f6..8c42dbc21 100644 --- a/server/models/video/video-blacklist.ts +++ b/server/models/video/video-blacklist.ts | |||
@@ -2,7 +2,6 @@ import * as Sequelize from 'sequelize' | |||
2 | 2 | ||
3 | import { addMethodsToModel, getSort } from '../utils' | 3 | import { addMethodsToModel, getSort } from '../utils' |
4 | import { | 4 | import { |
5 | BlacklistedVideoClass, | ||
6 | BlacklistedVideoInstance, | 5 | BlacklistedVideoInstance, |
7 | BlacklistedVideoAttributes, | 6 | BlacklistedVideoAttributes, |
8 | 7 | ||
@@ -66,38 +65,39 @@ function associate (models) { | |||
66 | }) | 65 | }) |
67 | } | 66 | } |
68 | 67 | ||
69 | countTotal = function (callback: BlacklistedVideoMethods.CountTotalCallback) { | 68 | countTotal = function () { |
70 | return BlacklistedVideo.count().asCallback(callback) | 69 | return BlacklistedVideo.count() |
71 | } | 70 | } |
72 | 71 | ||
73 | list = function (callback: BlacklistedVideoMethods.ListCallback) { | 72 | list = function () { |
74 | return BlacklistedVideo.findAll().asCallback(callback) | 73 | return BlacklistedVideo.findAll() |
75 | } | 74 | } |
76 | 75 | ||
77 | listForApi = function (start: number, count: number, sort: string, callback: BlacklistedVideoMethods.ListForApiCallback) { | 76 | listForApi = function (start: number, count: number, sort: string) { |
78 | const query = { | 77 | const query = { |
79 | offset: start, | 78 | offset: start, |
80 | limit: count, | 79 | limit: count, |
81 | order: [ getSort(sort) ] | 80 | order: [ getSort(sort) ] |
82 | } | 81 | } |
83 | 82 | ||
84 | return BlacklistedVideo.findAndCountAll(query).asCallback(function (err, result) { | 83 | return BlacklistedVideo.findAndCountAll(query).then(({ rows, count }) => { |
85 | if (err) return callback(err) | 84 | return { |
86 | 85 | data: rows, | |
87 | return callback(null, result.rows, result.count) | 86 | total: count |
87 | } | ||
88 | }) | 88 | }) |
89 | } | 89 | } |
90 | 90 | ||
91 | loadById = function (id: number, callback: BlacklistedVideoMethods.LoadByIdCallback) { | 91 | loadById = function (id: number) { |
92 | return BlacklistedVideo.findById(id).asCallback(callback) | 92 | return BlacklistedVideo.findById(id) |
93 | } | 93 | } |
94 | 94 | ||
95 | loadByVideoId = function (id: string, callback: BlacklistedVideoMethods.LoadByIdCallback) { | 95 | loadByVideoId = function (id: string) { |
96 | const query = { | 96 | const query = { |
97 | where: { | 97 | where: { |
98 | videoId: id | 98 | videoId: id |
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | return BlacklistedVideo.find(query).asCallback(callback) | 102 | return BlacklistedVideo.findOne(query) |
103 | } | 103 | } |
diff --git a/server/models/video/video-interface.ts b/server/models/video/video-interface.ts index 4b591b9e7..c3e3365d5 100644 --- a/server/models/video/video-interface.ts +++ b/server/models/video/video-interface.ts | |||
@@ -1,10 +1,12 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
3 | import { AuthorInstance } from './author-interface' | 4 | import { AuthorInstance } from './author-interface' |
4 | import { VideoTagInstance } from './video-tag-interface' | 5 | import { TagAttributes, TagInstance } from './tag-interface' |
5 | 6 | ||
6 | // Don't use barrel, import just what we need | 7 | // Don't use barrel, import just what we need |
7 | import { Video as FormatedVideo } from '../../../shared/models/video.model' | 8 | import { Video as FormatedVideo } from '../../../shared/models/video.model' |
9 | import { ResultList } from '../../../shared/models/result-list.model' | ||
8 | 10 | ||
9 | export type FormatedAddRemoteVideo = { | 11 | export type FormatedAddRemoteVideo = { |
10 | name: string | 12 | name: string |
@@ -56,46 +58,32 @@ export namespace VideoMethods { | |||
56 | export type IsOwned = (this: VideoInstance) => boolean | 58 | export type IsOwned = (this: VideoInstance) => boolean |
57 | export type ToFormatedJSON = (this: VideoInstance) => FormatedVideo | 59 | export type ToFormatedJSON = (this: VideoInstance) => FormatedVideo |
58 | 60 | ||
59 | export type ToAddRemoteJSONCallback = (err: Error, videoFormated?: FormatedAddRemoteVideo) => void | 61 | export type ToAddRemoteJSON = (this: VideoInstance) => Promise<FormatedAddRemoteVideo> |
60 | export type ToAddRemoteJSON = (this: VideoInstance, callback: ToAddRemoteJSONCallback) => void | ||
61 | |||
62 | export type ToUpdateRemoteJSON = (this: VideoInstance) => FormatedUpdateRemoteVideo | 62 | export type ToUpdateRemoteJSON = (this: VideoInstance) => FormatedUpdateRemoteVideo |
63 | 63 | ||
64 | export type TranscodeVideofileCallback = (err: Error) => void | 64 | export type TranscodeVideofile = (this: VideoInstance) => Promise<void> |
65 | export type TranscodeVideofile = (this: VideoInstance, callback: TranscodeVideofileCallback) => void | 65 | |
66 | 66 | // Return thumbnail name | |
67 | export type GenerateThumbnailFromDataCallback = (err: Error, thumbnailName?: string) => void | 67 | export type GenerateThumbnailFromData = (video: VideoInstance, thumbnailData: string) => Promise<string> |
68 | export type GenerateThumbnailFromData = (video: VideoInstance, thumbnailData: string, callback: GenerateThumbnailFromDataCallback) => void | 68 | export type GetDurationFromFile = (videoPath: string) => Promise<number> |
69 | 69 | ||
70 | export type GetDurationFromFileCallback = (err: Error, duration?: number) => void | 70 | export type List = () => Promise<VideoInstance[]> |
71 | export type GetDurationFromFile = (videoPath, callback) => void | 71 | export type ListOwnedAndPopulateAuthorAndTags = () => Promise<VideoInstance[]> |
72 | 72 | export type ListOwnedByAuthor = (author: string) => Promise<VideoInstance[]> | |
73 | export type ListCallback = (err: Error, videoInstances: VideoInstance[]) => void | 73 | |
74 | export type List = (callback: ListCallback) => void | 74 | export type ListForApi = (start: number, count: number, sort: string) => Promise< ResultList<VideoInstance> > |
75 | 75 | export type SearchAndPopulateAuthorAndPodAndTags = ( | |
76 | export type ListForApiCallback = (err: Error, videoInstances?: VideoInstance[], total?: number) => void | 76 | value: string, |
77 | export type ListForApi = (start: number, count: number, sort: string, callback: ListForApiCallback) => void | 77 | field: string, |
78 | 78 | start: number, | |
79 | export type LoadByHostAndRemoteIdCallback = (err: Error, videoInstance: VideoInstance) => void | 79 | count: number, |
80 | export type LoadByHostAndRemoteId = (fromHost: string, remoteId: string, callback: LoadByHostAndRemoteIdCallback) => void | 80 | sort: string |
81 | 81 | ) => Promise< ResultList<VideoInstance> > | |
82 | export type ListOwnedAndPopulateAuthorAndTagsCallback = (err: Error, videoInstances: VideoInstance[]) => void | 82 | |
83 | export type ListOwnedAndPopulateAuthorAndTags = (callback: ListOwnedAndPopulateAuthorAndTagsCallback) => void | 83 | export type Load = (id: string) => Promise<VideoInstance> |
84 | 84 | export type LoadByHostAndRemoteId = (fromHost: string, remoteId: string) => Promise<VideoInstance> | |
85 | export type ListOwnedByAuthorCallback = (err: Error, videoInstances: VideoInstance[]) => void | 85 | export type LoadAndPopulateAuthor = (id: string) => Promise<VideoInstance> |
86 | export type ListOwnedByAuthor = (author: string, callback: ListOwnedByAuthorCallback) => void | 86 | export type LoadAndPopulateAuthorAndPodAndTags = (id: string) => Promise<VideoInstance> |
87 | |||
88 | export type LoadCallback = (err: Error, videoInstance: VideoInstance) => void | ||
89 | export type Load = (id: string, callback: LoadCallback) => void | ||
90 | |||
91 | export type LoadAndPopulateAuthorCallback = (err: Error, videoInstance: VideoInstance) => void | ||
92 | export type LoadAndPopulateAuthor = (id: string, callback: LoadAndPopulateAuthorCallback) => void | ||
93 | |||
94 | export type LoadAndPopulateAuthorAndPodAndTagsCallback = (err: Error, videoInstance: VideoInstance) => void | ||
95 | export type LoadAndPopulateAuthorAndPodAndTags = (id: string, callback: LoadAndPopulateAuthorAndPodAndTagsCallback) => void | ||
96 | |||
97 | export type SearchAndPopulateAuthorAndPodAndTagsCallback = (err: Error, videoInstances?: VideoInstance[], total?: number) => void | ||
98 | export type SearchAndPopulateAuthorAndPodAndTags = (value: string, field: string, start: number, count: number, sort: string, callback: SearchAndPopulateAuthorAndPodAndTagsCallback) => void | ||
99 | } | 87 | } |
100 | 88 | ||
101 | export interface VideoClass { | 89 | export interface VideoClass { |
@@ -139,7 +127,7 @@ export interface VideoAttributes { | |||
139 | dislikes?: number | 127 | dislikes?: number |
140 | 128 | ||
141 | Author?: AuthorInstance | 129 | Author?: AuthorInstance |
142 | Tags?: VideoTagInstance[] | 130 | Tags?: TagInstance[] |
143 | } | 131 | } |
144 | 132 | ||
145 | export interface VideoInstance extends VideoClass, VideoAttributes, Sequelize.Instance<VideoAttributes> { | 133 | export interface VideoInstance extends VideoClass, VideoAttributes, Sequelize.Instance<VideoAttributes> { |
@@ -157,6 +145,8 @@ export interface VideoInstance extends VideoClass, VideoAttributes, Sequelize.In | |||
157 | toAddRemoteJSON: VideoMethods.ToAddRemoteJSON | 145 | toAddRemoteJSON: VideoMethods.ToAddRemoteJSON |
158 | toUpdateRemoteJSON: VideoMethods.ToUpdateRemoteJSON | 146 | toUpdateRemoteJSON: VideoMethods.ToUpdateRemoteJSON |
159 | transcodeVideofile: VideoMethods.TranscodeVideofile | 147 | transcodeVideofile: VideoMethods.TranscodeVideofile |
148 | |||
149 | setTags: Sequelize.HasManySetAssociationsMixin<TagAttributes, string> | ||
160 | } | 150 | } |
161 | 151 | ||
162 | export interface VideoModel extends VideoClass, Sequelize.Model<VideoInstance, VideoAttributes> {} | 152 | export interface VideoModel extends VideoClass, Sequelize.Model<VideoInstance, VideoAttributes> {} |
diff --git a/server/models/video/video-tag.ts b/server/models/video/video-tag.ts index 71ca85332..ac45374f8 100644 --- a/server/models/video/video-tag.ts +++ b/server/models/video/video-tag.ts | |||
@@ -1,12 +1,8 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | 2 | ||
3 | import { addMethodsToModel } from '../utils' | ||
4 | import { | 3 | import { |
5 | VideoTagClass, | ||
6 | VideoTagInstance, | 4 | VideoTagInstance, |
7 | VideoTagAttributes, | 5 | VideoTagAttributes |
8 | |||
9 | VideoTagMethods | ||
10 | } from './video-tag-interface' | 6 | } from './video-tag-interface' |
11 | 7 | ||
12 | let VideoTag: Sequelize.Model<VideoTagInstance, VideoTagAttributes> | 8 | let VideoTag: Sequelize.Model<VideoTagInstance, VideoTagAttributes> |
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index e66ebee2d..629051ae4 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -1,17 +1,15 @@ | |||
1 | import * as safeBuffer from 'safe-buffer' | 1 | import * as safeBuffer from 'safe-buffer' |
2 | const Buffer = safeBuffer.Buffer | 2 | const Buffer = safeBuffer.Buffer |
3 | import * as createTorrent from 'create-torrent' | ||
4 | import * as ffmpeg from 'fluent-ffmpeg' | 3 | import * as ffmpeg from 'fluent-ffmpeg' |
5 | import * as fs from 'fs' | ||
6 | import * as magnetUtil from 'magnet-uri' | 4 | import * as magnetUtil from 'magnet-uri' |
7 | import { map, values } from 'lodash' | 5 | import { map, values } from 'lodash' |
8 | import { parallel, series } from 'async' | ||
9 | import * as parseTorrent from 'parse-torrent' | 6 | import * as parseTorrent from 'parse-torrent' |
10 | import { join } from 'path' | 7 | import { join } from 'path' |
11 | import * as Sequelize from 'sequelize' | 8 | import * as Sequelize from 'sequelize' |
9 | import * as Promise from 'bluebird' | ||
12 | 10 | ||
13 | import { database as db } from '../../initializers/database' | 11 | import { database as db } from '../../initializers/database' |
14 | import { VideoTagInstance } from './video-tag-interface' | 12 | import { TagInstance } from './tag-interface' |
15 | import { | 13 | import { |
16 | logger, | 14 | logger, |
17 | isVideoNameValid, | 15 | isVideoNameValid, |
@@ -21,7 +19,12 @@ import { | |||
21 | isVideoNSFWValid, | 19 | isVideoNSFWValid, |
22 | isVideoDescriptionValid, | 20 | isVideoDescriptionValid, |
23 | isVideoInfoHashValid, | 21 | isVideoInfoHashValid, |
24 | isVideoDurationValid | 22 | isVideoDurationValid, |
23 | readFileBufferPromise, | ||
24 | unlinkPromise, | ||
25 | renamePromise, | ||
26 | writeFilePromise, | ||
27 | createTorrentPromise | ||
25 | } from '../../helpers' | 28 | } from '../../helpers' |
26 | import { | 29 | import { |
27 | CONSTRAINTS_FIELDS, | 30 | CONSTRAINTS_FIELDS, |
@@ -37,7 +40,6 @@ import { JobScheduler, removeVideoToFriends } from '../../lib' | |||
37 | 40 | ||
38 | import { addMethodsToModel, getSort } from '../utils' | 41 | import { addMethodsToModel, getSort } from '../utils' |
39 | import { | 42 | import { |
40 | VideoClass, | ||
41 | VideoInstance, | 43 | VideoInstance, |
42 | VideoAttributes, | 44 | VideoAttributes, |
43 | 45 | ||
@@ -260,7 +262,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
260 | toFormatedJSON, | 262 | toFormatedJSON, |
261 | toAddRemoteJSON, | 263 | toAddRemoteJSON, |
262 | toUpdateRemoteJSON, | 264 | toUpdateRemoteJSON, |
263 | transcodeVideofile, | 265 | transcodeVideofile |
264 | ] | 266 | ] |
265 | addMethodsToModel(Video, classMethods, instanceMethods) | 267 | addMethodsToModel(Video, classMethods, instanceMethods) |
266 | 268 | ||
@@ -276,91 +278,53 @@ function beforeValidate (video: VideoInstance) { | |||
276 | } | 278 | } |
277 | 279 | ||
278 | function beforeCreate (video: VideoInstance, options: { transaction: Sequelize.Transaction }) { | 280 | function beforeCreate (video: VideoInstance, options: { transaction: Sequelize.Transaction }) { |
279 | return new Promise(function (resolve, reject) { | 281 | if (video.isOwned()) { |
282 | const videoPath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename()) | ||
280 | const tasks = [] | 283 | const tasks = [] |
281 | 284 | ||
282 | if (video.isOwned()) { | 285 | tasks.push( |
283 | const videoPath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename()) | 286 | createTorrentFromVideo(video, videoPath), |
284 | 287 | createThumbnail(video, videoPath), | |
285 | tasks.push( | 288 | createPreview(video, videoPath) |
286 | function createVideoTorrent (callback) { | 289 | ) |
287 | createTorrentFromVideo(video, videoPath, callback) | ||
288 | }, | ||
289 | |||
290 | function createVideoThumbnail (callback) { | ||
291 | createThumbnail(video, videoPath, callback) | ||
292 | }, | ||
293 | |||
294 | function createVideoPreview (callback) { | ||
295 | createPreview(video, videoPath, callback) | ||
296 | } | ||
297 | ) | ||
298 | |||
299 | if (CONFIG.TRANSCODING.ENABLED === true) { | ||
300 | tasks.push( | ||
301 | function createVideoTranscoderJob (callback) { | ||
302 | const dataInput = { | ||
303 | id: video.id | ||
304 | } | ||
305 | 290 | ||
306 | JobScheduler.Instance.createJob(options.transaction, 'videoTranscoder', dataInput, callback) | 291 | if (CONFIG.TRANSCODING.ENABLED === true) { |
307 | } | 292 | const dataInput = { |
308 | ) | 293 | id: video.id |
309 | } | 294 | } |
310 | 295 | ||
311 | return parallel(tasks, function (err) { | 296 | tasks.push( |
312 | if (err) return reject(err) | 297 | JobScheduler.Instance.createJob(options.transaction, 'videoTranscoder', dataInput) |
313 | 298 | ) | |
314 | return resolve() | ||
315 | }) | ||
316 | } | 299 | } |
317 | 300 | ||
318 | return resolve() | 301 | return Promise.all(tasks) |
319 | }) | 302 | } |
303 | |||
304 | return Promise.resolve() | ||
320 | } | 305 | } |
321 | 306 | ||
322 | function afterDestroy (video: VideoInstance) { | 307 | function afterDestroy (video: VideoInstance) { |
323 | return new Promise(function (resolve, reject) { | 308 | const tasks = [] |
324 | const tasks = [] | ||
325 | |||
326 | tasks.push( | ||
327 | function (callback) { | ||
328 | removeThumbnail(video, callback) | ||
329 | } | ||
330 | ) | ||
331 | |||
332 | if (video.isOwned()) { | ||
333 | tasks.push( | ||
334 | function removeVideoFile (callback) { | ||
335 | removeFile(video, callback) | ||
336 | }, | ||
337 | 309 | ||
338 | function removeVideoTorrent (callback) { | 310 | tasks.push( |
339 | removeTorrent(video, callback) | 311 | removeThumbnail(video) |
340 | }, | 312 | ) |
341 | |||
342 | function removeVideoPreview (callback) { | ||
343 | removePreview(video, callback) | ||
344 | }, | ||
345 | |||
346 | function notifyFriends (callback) { | ||
347 | const params = { | ||
348 | remoteId: video.id | ||
349 | } | ||
350 | |||
351 | removeVideoToFriends(params) | ||
352 | 313 | ||
353 | return callback() | 314 | if (video.isOwned()) { |
354 | } | 315 | const removeVideoToFriendsParams = { |
355 | ) | 316 | remoteId: video.id |
356 | } | 317 | } |
357 | 318 | ||
358 | parallel(tasks, function (err) { | 319 | tasks.push( |
359 | if (err) return reject(err) | 320 | removeFile(video), |
321 | removeTorrent(video), | ||
322 | removePreview(video), | ||
323 | removeVideoToFriends(removeVideoToFriendsParams) | ||
324 | ) | ||
325 | } | ||
360 | 326 | ||
361 | return resolve() | 327 | return Promise.all(tasks) |
362 | }) | ||
363 | }) | ||
364 | } | 328 | } |
365 | 329 | ||
366 | // ------------------------------ METHODS ------------------------------ | 330 | // ------------------------------ METHODS ------------------------------ |
@@ -488,7 +452,7 @@ toFormatedJSON = function (this: VideoInstance) { | |||
488 | views: this.views, | 452 | views: this.views, |
489 | likes: this.likes, | 453 | likes: this.likes, |
490 | dislikes: this.dislikes, | 454 | dislikes: this.dislikes, |
491 | tags: map<VideoTagInstance, string>(this.Tags, 'name'), | 455 | tags: map<TagInstance, string>(this.Tags, 'name'), |
492 | thumbnailPath: join(STATIC_PATHS.THUMBNAILS, this.getThumbnailName()), | 456 | thumbnailPath: join(STATIC_PATHS.THUMBNAILS, this.getThumbnailName()), |
493 | createdAt: this.createdAt, | 457 | createdAt: this.createdAt, |
494 | updatedAt: this.updatedAt | 458 | updatedAt: this.updatedAt |
@@ -497,15 +461,11 @@ toFormatedJSON = function (this: VideoInstance) { | |||
497 | return json | 461 | return json |
498 | } | 462 | } |
499 | 463 | ||
500 | toAddRemoteJSON = function (this: VideoInstance, callback: VideoMethods.ToAddRemoteJSONCallback) { | 464 | toAddRemoteJSON = function (this: VideoInstance) { |
501 | // Get thumbnail data to send to the other pod | 465 | // Get thumbnail data to send to the other pod |
502 | const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, this.getThumbnailName()) | 466 | const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, this.getThumbnailName()) |
503 | fs.readFile(thumbnailPath, (err, thumbnailData) => { | ||
504 | if (err) { | ||
505 | logger.error('Cannot read the thumbnail of the video') | ||
506 | return callback(err) | ||
507 | } | ||
508 | 467 | ||
468 | return readFileBufferPromise(thumbnailPath).then(thumbnailData => { | ||
509 | const remoteVideo = { | 469 | const remoteVideo = { |
510 | name: this.name, | 470 | name: this.name, |
511 | category: this.category, | 471 | category: this.category, |
@@ -518,7 +478,7 @@ toAddRemoteJSON = function (this: VideoInstance, callback: VideoMethods.ToAddRem | |||
518 | author: this.Author.name, | 478 | author: this.Author.name, |
519 | duration: this.duration, | 479 | duration: this.duration, |
520 | thumbnailData: thumbnailData.toString('binary'), | 480 | thumbnailData: thumbnailData.toString('binary'), |
521 | tags: map<VideoTagInstance, string>(this.Tags, 'name'), | 481 | tags: map<TagInstance, string>(this.Tags, 'name'), |
522 | createdAt: this.createdAt, | 482 | createdAt: this.createdAt, |
523 | updatedAt: this.updatedAt, | 483 | updatedAt: this.updatedAt, |
524 | extname: this.extname, | 484 | extname: this.extname, |
@@ -527,7 +487,7 @@ toAddRemoteJSON = function (this: VideoInstance, callback: VideoMethods.ToAddRem | |||
527 | dislikes: this.dislikes | 487 | dislikes: this.dislikes |
528 | } | 488 | } |
529 | 489 | ||
530 | return callback(null, remoteVideo) | 490 | return remoteVideo |
531 | }) | 491 | }) |
532 | } | 492 | } |
533 | 493 | ||
@@ -543,7 +503,7 @@ toUpdateRemoteJSON = function (this: VideoInstance) { | |||
543 | remoteId: this.id, | 503 | remoteId: this.id, |
544 | author: this.Author.name, | 504 | author: this.Author.name, |
545 | duration: this.duration, | 505 | duration: this.duration, |
546 | tags: map<VideoTagInstance, string>(this.Tags, 'name'), | 506 | tags: map<TagInstance, string>(this.Tags, 'name'), |
547 | createdAt: this.createdAt, | 507 | createdAt: this.createdAt, |
548 | updatedAt: this.updatedAt, | 508 | updatedAt: this.updatedAt, |
549 | extname: this.extname, | 509 | extname: this.extname, |
@@ -555,7 +515,7 @@ toUpdateRemoteJSON = function (this: VideoInstance) { | |||
555 | return json | 515 | return json |
556 | } | 516 | } |
557 | 517 | ||
558 | transcodeVideofile = function (this: VideoInstance, finalCallback: VideoMethods.TranscodeVideofileCallback) { | 518 | transcodeVideofile = function (this: VideoInstance) { |
559 | const video = this | 519 | const video = this |
560 | 520 | ||
561 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR | 521 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR |
@@ -563,78 +523,73 @@ transcodeVideofile = function (this: VideoInstance, finalCallback: VideoMethods. | |||
563 | const videoInputPath = join(videosDirectory, video.getVideoFilename()) | 523 | const videoInputPath = join(videosDirectory, video.getVideoFilename()) |
564 | const videoOutputPath = join(videosDirectory, video.id + '-transcoded' + newExtname) | 524 | const videoOutputPath = join(videosDirectory, video.id + '-transcoded' + newExtname) |
565 | 525 | ||
566 | ffmpeg(videoInputPath) | 526 | return new Promise<void>((res, rej) => { |
567 | .output(videoOutputPath) | 527 | ffmpeg(videoInputPath) |
568 | .videoCodec('libx264') | 528 | .output(videoOutputPath) |
569 | .outputOption('-threads ' + CONFIG.TRANSCODING.THREADS) | 529 | .videoCodec('libx264') |
570 | .outputOption('-movflags faststart') | 530 | .outputOption('-threads ' + CONFIG.TRANSCODING.THREADS) |
571 | .on('error', finalCallback) | 531 | .outputOption('-movflags faststart') |
572 | .on('end', function () { | 532 | .on('error', rej) |
573 | series([ | 533 | .on('end', () => { |
574 | function removeOldFile (callback) { | 534 | |
575 | fs.unlink(videoInputPath, callback) | 535 | return unlinkPromise(videoInputPath) |
576 | }, | 536 | .then(() => { |
577 | 537 | // Important to do this before getVideoFilename() to take in account the new file extension | |
578 | function moveNewFile (callback) { | 538 | video.set('extname', newExtname) |
579 | // Important to do this before getVideoFilename() to take in account the new file extension | 539 | |
580 | video.set('extname', newExtname) | 540 | const newVideoPath = join(videosDirectory, video.getVideoFilename()) |
581 | 541 | return renamePromise(videoOutputPath, newVideoPath) | |
582 | const newVideoPath = join(videosDirectory, video.getVideoFilename()) | ||
583 | fs.rename(videoOutputPath, newVideoPath, callback) | ||
584 | }, | ||
585 | |||
586 | function torrent (callback) { | ||
587 | const newVideoPath = join(videosDirectory, video.getVideoFilename()) | ||
588 | createTorrentFromVideo(video, newVideoPath, callback) | ||
589 | }, | ||
590 | |||
591 | function videoExtension (callback) { | ||
592 | video.save().asCallback(callback) | ||
593 | } | ||
594 | |||
595 | ], function (err: Error) { | ||
596 | if (err) { | ||
597 | // Autodesctruction... | ||
598 | video.destroy().asCallback(function (err) { | ||
599 | if (err) logger.error('Cannot destruct video after transcoding failure.', { error: err }) | ||
600 | }) | 542 | }) |
543 | .then(() => { | ||
544 | const newVideoPath = join(videosDirectory, video.getVideoFilename()) | ||
545 | return createTorrentFromVideo(video, newVideoPath) | ||
546 | }) | ||
547 | .then(() => { | ||
548 | return video.save() | ||
549 | }) | ||
550 | .then(() => { | ||
551 | return res() | ||
552 | }) | ||
553 | .catch(err => { | ||
554 | // Autodesctruction... | ||
555 | video.destroy().asCallback(function (err) { | ||
556 | if (err) logger.error('Cannot destruct video after transcoding failure.', { error: err }) | ||
557 | }) | ||
601 | 558 | ||
602 | return finalCallback(err) | 559 | return rej(err) |
603 | } | 560 | }) |
604 | |||
605 | return finalCallback(null) | ||
606 | }) | 561 | }) |
607 | }) | 562 | .run() |
608 | .run() | 563 | }) |
609 | } | 564 | } |
610 | 565 | ||
611 | // ------------------------------ STATICS ------------------------------ | 566 | // ------------------------------ STATICS ------------------------------ |
612 | 567 | ||
613 | generateThumbnailFromData = function (video: VideoInstance, thumbnailData: string, callback: VideoMethods.GenerateThumbnailFromDataCallback) { | 568 | generateThumbnailFromData = function (video: VideoInstance, thumbnailData: string) { |
614 | // Creating the thumbnail for a remote video | 569 | // Creating the thumbnail for a remote video |
615 | 570 | ||
616 | const thumbnailName = video.getThumbnailName() | 571 | const thumbnailName = video.getThumbnailName() |
617 | const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName) | 572 | const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName) |
618 | fs.writeFile(thumbnailPath, Buffer.from(thumbnailData, 'binary'), function (err) { | 573 | return writeFilePromise(thumbnailPath, Buffer.from(thumbnailData, 'binary')).then(() => { |
619 | if (err) return callback(err) | 574 | return thumbnailName |
620 | |||
621 | return callback(null, thumbnailName) | ||
622 | }) | 575 | }) |
623 | } | 576 | } |
624 | 577 | ||
625 | getDurationFromFile = function (videoPath: string, callback: VideoMethods.GetDurationFromFileCallback) { | 578 | getDurationFromFile = function (videoPath: string) { |
626 | ffmpeg.ffprobe(videoPath, function (err, metadata) { | 579 | return new Promise<number>((res, rej) => { |
627 | if (err) return callback(err) | 580 | ffmpeg.ffprobe(videoPath, function (err, metadata) { |
581 | if (err) return rej(err) | ||
628 | 582 | ||
629 | return callback(null, Math.floor(metadata.format.duration)) | 583 | return res(Math.floor(metadata.format.duration)) |
584 | }) | ||
630 | }) | 585 | }) |
631 | } | 586 | } |
632 | 587 | ||
633 | list = function (callback: VideoMethods.ListCallback) { | 588 | list = function () { |
634 | return Video.findAll().asCallback(callback) | 589 | return Video.findAll() |
635 | } | 590 | } |
636 | 591 | ||
637 | listForApi = function (start: number, count: number, sort: string, callback: VideoMethods.ListForApiCallback) { | 592 | listForApi = function (start: number, count: number, sort: string) { |
638 | // Exclude Blakclisted videos from the list | 593 | // Exclude Blakclisted videos from the list |
639 | const query = { | 594 | const query = { |
640 | distinct: true, | 595 | distinct: true, |
@@ -652,14 +607,15 @@ listForApi = function (start: number, count: number, sort: string, callback: Vid | |||
652 | where: createBaseVideosWhere() | 607 | where: createBaseVideosWhere() |
653 | } | 608 | } |
654 | 609 | ||
655 | return Video.findAndCountAll(query).asCallback(function (err, result) { | 610 | return Video.findAndCountAll(query).then(({ rows, count }) => { |
656 | if (err) return callback(err) | 611 | return { |
657 | 612 | data: rows, | |
658 | return callback(null, result.rows, result.count) | 613 | total: count |
614 | } | ||
659 | }) | 615 | }) |
660 | } | 616 | } |
661 | 617 | ||
662 | loadByHostAndRemoteId = function (fromHost: string, remoteId: string, callback: VideoMethods.LoadByHostAndRemoteIdCallback) { | 618 | loadByHostAndRemoteId = function (fromHost: string, remoteId: string) { |
663 | const query = { | 619 | const query = { |
664 | where: { | 620 | where: { |
665 | remoteId: remoteId | 621 | remoteId: remoteId |
@@ -680,10 +636,10 @@ loadByHostAndRemoteId = function (fromHost: string, remoteId: string, callback: | |||
680 | ] | 636 | ] |
681 | } | 637 | } |
682 | 638 | ||
683 | return Video.findOne(query).asCallback(callback) | 639 | return Video.findOne(query) |
684 | } | 640 | } |
685 | 641 | ||
686 | listOwnedAndPopulateAuthorAndTags = function (callback: VideoMethods.ListOwnedAndPopulateAuthorAndTagsCallback) { | 642 | listOwnedAndPopulateAuthorAndTags = function () { |
687 | // If remoteId is null this is *our* video | 643 | // If remoteId is null this is *our* video |
688 | const query = { | 644 | const query = { |
689 | where: { | 645 | where: { |
@@ -692,10 +648,10 @@ listOwnedAndPopulateAuthorAndTags = function (callback: VideoMethods.ListOwnedAn | |||
692 | include: [ Video['sequelize'].models.Author, Video['sequelize'].models.Tag ] | 648 | include: [ Video['sequelize'].models.Author, Video['sequelize'].models.Tag ] |
693 | } | 649 | } |
694 | 650 | ||
695 | return Video.findAll(query).asCallback(callback) | 651 | return Video.findAll(query) |
696 | } | 652 | } |
697 | 653 | ||
698 | listOwnedByAuthor = function (author: string, callback: VideoMethods.ListOwnedByAuthorCallback) { | 654 | listOwnedByAuthor = function (author: string) { |
699 | const query = { | 655 | const query = { |
700 | where: { | 656 | where: { |
701 | remoteId: null | 657 | remoteId: null |
@@ -710,22 +666,22 @@ listOwnedByAuthor = function (author: string, callback: VideoMethods.ListOwnedBy | |||
710 | ] | 666 | ] |
711 | } | 667 | } |
712 | 668 | ||
713 | return Video.findAll(query).asCallback(callback) | 669 | return Video.findAll(query) |
714 | } | 670 | } |
715 | 671 | ||
716 | load = function (id: string, callback: VideoMethods.LoadCallback) { | 672 | load = function (id: string) { |
717 | return Video.findById(id).asCallback(callback) | 673 | return Video.findById(id) |
718 | } | 674 | } |
719 | 675 | ||
720 | loadAndPopulateAuthor = function (id: string, callback: VideoMethods.LoadAndPopulateAuthorCallback) { | 676 | loadAndPopulateAuthor = function (id: string) { |
721 | const options = { | 677 | const options = { |
722 | include: [ Video['sequelize'].models.Author ] | 678 | include: [ Video['sequelize'].models.Author ] |
723 | } | 679 | } |
724 | 680 | ||
725 | return Video.findById(id, options).asCallback(callback) | 681 | return Video.findById(id, options) |
726 | } | 682 | } |
727 | 683 | ||
728 | loadAndPopulateAuthorAndPodAndTags = function (id: string, callback: VideoMethods.LoadAndPopulateAuthorAndPodAndTagsCallback) { | 684 | loadAndPopulateAuthorAndPodAndTags = function (id: string) { |
729 | const options = { | 685 | const options = { |
730 | include: [ | 686 | include: [ |
731 | { | 687 | { |
@@ -736,17 +692,10 @@ loadAndPopulateAuthorAndPodAndTags = function (id: string, callback: VideoMethod | |||
736 | ] | 692 | ] |
737 | } | 693 | } |
738 | 694 | ||
739 | return Video.findById(id, options).asCallback(callback) | 695 | return Video.findById(id, options) |
740 | } | 696 | } |
741 | 697 | ||
742 | searchAndPopulateAuthorAndPodAndTags = function ( | 698 | searchAndPopulateAuthorAndPodAndTags = function (value: string, field: string, start: number, count: number, sort: string) { |
743 | value: string, | ||
744 | field: string, | ||
745 | start: number, | ||
746 | count: number, | ||
747 | sort: string, | ||
748 | callback: VideoMethods.SearchAndPopulateAuthorAndPodAndTagsCallback | ||
749 | ) { | ||
750 | const podInclude: any = { | 699 | const podInclude: any = { |
751 | model: Video['sequelize'].models.Pod, | 700 | model: Video['sequelize'].models.Pod, |
752 | required: false | 701 | required: false |
@@ -778,7 +727,11 @@ searchAndPopulateAuthorAndPodAndTags = function ( | |||
778 | } else if (field === 'tags') { | 727 | } else if (field === 'tags') { |
779 | const escapedValue = Video['sequelize'].escape('%' + value + '%') | 728 | const escapedValue = Video['sequelize'].escape('%' + value + '%') |
780 | query.where.id.$in = Video['sequelize'].literal( | 729 | query.where.id.$in = Video['sequelize'].literal( |
781 | '(SELECT "VideoTags"."videoId" FROM "Tags" INNER JOIN "VideoTags" ON "Tags"."id" = "VideoTags"."tagId" WHERE name LIKE ' + escapedValue + ')' | 730 | `(SELECT "VideoTags"."videoId" |
731 | FROM "Tags" | ||
732 | INNER JOIN "VideoTags" ON "Tags"."id" = "VideoTags"."tagId" | ||
733 | WHERE name LIKE ${escapedValue} | ||
734 | )` | ||
782 | ) | 735 | ) |
783 | } else if (field === 'host') { | 736 | } else if (field === 'host') { |
784 | // FIXME: Include our pod? (not stored in the database) | 737 | // FIXME: Include our pod? (not stored in the database) |
@@ -810,10 +763,11 @@ searchAndPopulateAuthorAndPodAndTags = function ( | |||
810 | // query.include.push([ Video['sequelize'].models.Tag ]) | 763 | // query.include.push([ Video['sequelize'].models.Tag ]) |
811 | } | 764 | } |
812 | 765 | ||
813 | return Video.findAndCountAll(query).asCallback(function (err, result) { | 766 | return Video.findAndCountAll(query).then(({ rows, count }) => { |
814 | if (err) return callback(err) | 767 | return { |
815 | 768 | data: rows, | |
816 | return callback(null, result.rows, result.count) | 769 | total: count |
770 | } | ||
817 | }) | 771 | }) |
818 | } | 772 | } |
819 | 773 | ||
@@ -829,27 +783,27 @@ function createBaseVideosWhere () { | |||
829 | } | 783 | } |
830 | } | 784 | } |
831 | 785 | ||
832 | function removeThumbnail (video: VideoInstance, callback: (err: Error) => void) { | 786 | function removeThumbnail (video: VideoInstance) { |
833 | const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, video.getThumbnailName()) | 787 | const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, video.getThumbnailName()) |
834 | fs.unlink(thumbnailPath, callback) | 788 | return unlinkPromise(thumbnailPath) |
835 | } | 789 | } |
836 | 790 | ||
837 | function removeFile (video: VideoInstance, callback: (err: Error) => void) { | 791 | function removeFile (video: VideoInstance) { |
838 | const filePath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename()) | 792 | const filePath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename()) |
839 | fs.unlink(filePath, callback) | 793 | return unlinkPromise(filePath) |
840 | } | 794 | } |
841 | 795 | ||
842 | function removeTorrent (video: VideoInstance, callback: (err: Error) => void) { | 796 | function removeTorrent (video: VideoInstance) { |
843 | const torrenPath = join(CONFIG.STORAGE.TORRENTS_DIR, video.getTorrentName()) | 797 | const torrenPath = join(CONFIG.STORAGE.TORRENTS_DIR, video.getTorrentName()) |
844 | fs.unlink(torrenPath, callback) | 798 | return unlinkPromise(torrenPath) |
845 | } | 799 | } |
846 | 800 | ||
847 | function removePreview (video: VideoInstance, callback: (err: Error) => void) { | 801 | function removePreview (video: VideoInstance) { |
848 | // Same name than video thumnail | 802 | // Same name than video thumnail |
849 | fs.unlink(CONFIG.STORAGE.PREVIEWS_DIR + video.getPreviewName(), callback) | 803 | return unlinkPromise(CONFIG.STORAGE.PREVIEWS_DIR + video.getPreviewName()) |
850 | } | 804 | } |
851 | 805 | ||
852 | function createTorrentFromVideo (video: VideoInstance, videoPath: string, callback: (err: Error) => void) { | 806 | function createTorrentFromVideo (video: VideoInstance, videoPath: string) { |
853 | const options = { | 807 | const options = { |
854 | announceList: [ | 808 | announceList: [ |
855 | [ CONFIG.WEBSERVER.WS + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT + '/tracker/socket' ] | 809 | [ CONFIG.WEBSERVER.WS + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT + '/tracker/socket' ] |
@@ -859,30 +813,27 @@ function createTorrentFromVideo (video: VideoInstance, videoPath: string, callba | |||
859 | ] | 813 | ] |
860 | } | 814 | } |
861 | 815 | ||
862 | createTorrent(videoPath, options, function (err, torrent) { | 816 | return createTorrentPromise(videoPath, options) |
863 | if (err) return callback(err) | 817 | .then(torrent => { |
864 | 818 | const filePath = join(CONFIG.STORAGE.TORRENTS_DIR, video.getTorrentName()) | |
865 | const filePath = join(CONFIG.STORAGE.TORRENTS_DIR, video.getTorrentName()) | 819 | return writeFilePromise(filePath, torrent).then(() => torrent) |
866 | fs.writeFile(filePath, torrent, function (err) { | 820 | }) |
867 | if (err) return callback(err) | 821 | .then(torrent => { |
868 | |||
869 | const parsedTorrent = parseTorrent(torrent) | 822 | const parsedTorrent = parseTorrent(torrent) |
870 | video.set('infoHash', parsedTorrent.infoHash) | 823 | video.set('infoHash', parsedTorrent.infoHash) |
871 | video.validate().asCallback(callback) | 824 | return video.validate() |
872 | }) | 825 | }) |
873 | }) | ||
874 | } | 826 | } |
875 | 827 | ||
876 | function createPreview (video: VideoInstance, videoPath: string, callback: (err: Error) => void) { | 828 | function createPreview (video: VideoInstance, videoPath: string) { |
877 | generateImage(video, videoPath, CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName(), null, callback) | 829 | return generateImage(video, videoPath, CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName(), null) |
878 | } | 830 | } |
879 | 831 | ||
880 | function createThumbnail (video: VideoInstance, videoPath: string, callback: (err: Error) => void) { | 832 | function createThumbnail (video: VideoInstance, videoPath: string) { |
881 | generateImage(video, videoPath, CONFIG.STORAGE.THUMBNAILS_DIR, video.getThumbnailName(), THUMBNAILS_SIZE, callback) | 833 | return generateImage(video, videoPath, CONFIG.STORAGE.THUMBNAILS_DIR, video.getThumbnailName(), THUMBNAILS_SIZE) |
882 | } | 834 | } |
883 | 835 | ||
884 | type GenerateImageCallback = (err: Error, imageName: string) => void | 836 | function generateImage (video: VideoInstance, videoPath: string, folder: string, imageName: string, size: string) { |
885 | function generateImage (video: VideoInstance, videoPath: string, folder: string, imageName: string, size: string, callback?: GenerateImageCallback) { | ||
886 | const options: any = { | 837 | const options: any = { |
887 | filename: imageName, | 838 | filename: imageName, |
888 | count: 1, | 839 | count: 1, |
@@ -893,29 +844,25 @@ function generateImage (video: VideoInstance, videoPath: string, folder: string, | |||
893 | options.size = size | 844 | options.size = size |
894 | } | 845 | } |
895 | 846 | ||
896 | ffmpeg(videoPath) | 847 | return new Promise<string>((res, rej) => { |
897 | .on('error', callback) | 848 | ffmpeg(videoPath) |
898 | .on('end', function () { | 849 | .on('error', rej) |
899 | callback(null, imageName) | 850 | .on('end', function () { |
900 | }) | 851 | return res(imageName) |
901 | .thumbnail(options) | 852 | }) |
853 | .thumbnail(options) | ||
854 | }) | ||
902 | } | 855 | } |
903 | 856 | ||
904 | function removeFromBlacklist (video: VideoInstance, callback: (err: Error) => void) { | 857 | function removeFromBlacklist (video: VideoInstance) { |
905 | // Find the blacklisted video | 858 | // Find the blacklisted video |
906 | db.BlacklistedVideo.loadByVideoId(video.id, function (err, video) { | 859 | return db.BlacklistedVideo.loadByVideoId(video.id).then(video => { |
907 | // If an error occured, stop here | 860 | // Not found the video, skip |
908 | if (err) { | 861 | if (!video) { |
909 | logger.error('Error when fetching video from blacklist.', { error: err }) | 862 | return null |
910 | return callback(err) | ||
911 | } | 863 | } |
912 | 864 | ||
913 | // If we found the video, remove it from the blacklist | 865 | // If we found the video, remove it from the blacklist |
914 | if (video) { | 866 | return video.destroy() |
915 | video.destroy().asCallback(callback) | ||
916 | } else { | ||
917 | // If haven't found it, simply ignore it and do nothing | ||
918 | return callback(null) | ||
919 | } | ||
920 | }) | 867 | }) |
921 | } | 868 | } |