"@types/config": "^0.0.32",
"@types/express": "^4.0.35",
"@types/lodash": "^4.14.64",
+ "@types/magnet-uri": "^5.1.1",
"@types/mkdirp": "^0.3.29",
"@types/morgan": "^1.7.32",
+ "@types/multer": "^0.0.34",
"@types/node": "^7.0.18",
"@types/request": "^0.0.43",
"@types/sequelize": "^4.0.55",
import * as express from 'express'
-import { CONFIG } from '../../initializers';
+import { CONFIG } from '../../initializers'
import { logger } from '../../helpers'
import { database as db } from '../../initializers/database'
clientsRouter.get('/local', getLocalClient)
// Get the client credentials for the PeerTube front end
-function getLocalClient (req, res, next) {
+function getLocalClient (req: express.Request, res: express.Response, next: express.NextFunction) {
const serverHostname = CONFIG.WEBSERVER.HOSTNAME
const serverPort = CONFIG.WEBSERVER.PORT
let headerHostShouldBe = serverHostname
configRouter.get('/', getConfig)
// Get the client credentials for the PeerTube front end
-function getConfig (req, res, next) {
+function getConfig (req: express.Request, res: express.Response, next: express.NextFunction) {
res.json({
signup: {
enabled: CONFIG.SIGNUP.ENABLED
// ---------------------------------------------------------------------------
-function pong (req, res, next) {
+function pong (req: express.Request, res: express.Response, next: express.NextFunction) {
return res.send('pong').status(200).end()
}
setBodyHostPort,
setBodyHostsPort
} from '../../middlewares'
+import {
+ PodInstance
+} from '../../models'
const podsRouter = express.Router()
// ---------------------------------------------------------------------------
-function addPods (req, res, next) {
+function addPods (req: express.Request, res: express.Response, next: express.NextFunction) {
const informations = req.body
- waterfall([
+ waterfall<string, Error>([
function addPod (callback) {
const pod = db.Pod.build(informations)
pod.save().asCallback(function (err, podCreated) {
})
},
- function sendMyVideos (podCreated, callback) {
+ function sendMyVideos (podCreated: PodInstance, callback) {
sendOwnedVideosToPod(podCreated.id)
callback(null)
})
}
-function listPods (req, res, next) {
+function listPods (req: express.Request, res: express.Response, next: express.NextFunction) {
db.Pod.list(function (err, podsList) {
if (err) return next(err)
})
}
-function makeFriendsController (req, res, next) {
- const hosts = req.body.hosts
+function makeFriendsController (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const hosts = req.body.hosts as string[]
makeFriends(hosts, function (err) {
if (err) {
res.type('json').status(204).end()
}
-function quitFriendsController (req, res, next) {
+function quitFriendsController (req: express.Request, res: express.Response, next: express.NextFunction) {
quitFriends(function (err) {
if (err) return next(err)
// ---------------------------------------------------------------------------
-function removePods (req, res, next) {
+function removePods (req: express.Request, res: express.Response, next: express.NextFunction) {
const host = req.body.signature.host
waterfall([
import * as express from 'express'
+import * as Sequelize from 'sequelize'
import { eachSeries, waterfall } from 'async'
import { database as db } from '../../../initializers/database'
startSerializableTransaction
} from '../../../helpers'
import { quickAndDirtyUpdatesVideoToFriends } from '../../../lib'
+import { PodInstance, VideoInstance } from '../../../models'
const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
// ---------------------------------------------------------------------------
-function remoteVideos (req, res, next) {
+function remoteVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
const requests = req.body.data
const fromPod = res.locals.secure.pod
return res.type('json').status(204).end()
}
-function remoteVideosQadu (req, res, next) {
+function remoteVideosQadu (req: express.Request, res: express.Response, next: express.NextFunction) {
const requests = req.body.data
const fromPod = res.locals.secure.pod
return res.type('json').status(204).end()
}
-function remoteVideosEvents (req, res, next) {
+function remoteVideosEvents (req: express.Request, res: express.Response, next: express.NextFunction) {
const requests = req.body.data
const fromPod = res.locals.secure.pod
return res.type('json').status(204).end()
}
-function processVideosEventsRetryWrapper (eventData, fromPod, finalCallback) {
+function processVideosEventsRetryWrapper (eventData: any, fromPod: PodInstance, finalCallback: (err: Error) => void) {
const options = {
arguments: [ eventData, fromPod ],
errorMessage: 'Cannot process videos events with many retries.'
retryTransactionWrapper(processVideosEvents, options, finalCallback)
}
-function processVideosEvents (eventData, fromPod, finalCallback) {
+function processVideosEvents (eventData: any, fromPod: PodInstance, finalCallback: (err: Error) => void) {
waterfall([
startSerializableTransaction,
commitTransaction
- ], function (err, t) {
+ ], function (err: Error, t: Sequelize.Transaction) {
if (err) {
logger.debug('Cannot process a video event.', { error: err })
return rollbackTransaction(err, t, finalCallback)
})
}
-function quickAndDirtyUpdateVideoRetryWrapper (videoData, fromPod, finalCallback) {
+function quickAndDirtyUpdateVideoRetryWrapper (videoData: any, fromPod: PodInstance, finalCallback: (err: Error) => void) {
const options = {
arguments: [ videoData, fromPod ],
errorMessage: 'Cannot update quick and dirty the remote video with many retries.'
retryTransactionWrapper(quickAndDirtyUpdateVideo, options, finalCallback)
}
-function quickAndDirtyUpdateVideo (videoData, fromPod, finalCallback) {
+function quickAndDirtyUpdateVideo (videoData: any, fromPod: PodInstance, finalCallback: (err: Error) => void) {
let videoName
waterfall([
commitTransaction
- ], function (err, t) {
+ ], function (err: Error, t: Sequelize.Transaction) {
if (err) {
logger.debug('Cannot quick and dirty update the remote video.', { error: err })
return rollbackTransaction(err, t, finalCallback)
}
// Handle retries on fail
-function addRemoteVideoRetryWrapper (videoToCreateData, fromPod, finalCallback) {
+function addRemoteVideoRetryWrapper (videoToCreateData: any, fromPod: PodInstance, finalCallback: (err: Error) => void) {
const options = {
arguments: [ videoToCreateData, fromPod ],
errorMessage: 'Cannot insert the remote video with many retries.'
retryTransactionWrapper(addRemoteVideo, options, finalCallback)
}
-function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
+function addRemoteVideo (videoToCreateData: any, fromPod: PodInstance, finalCallback: (err: Error) => void) {
logger.debug('Adding remote video "%s".', videoToCreateData.remoteId)
waterfall([
commitTransaction
- ], function (err, t) {
+ ], function (err: Error, t: Sequelize.Transaction) {
if (err) {
// This is just a debug because we will retry the insert
logger.debug('Cannot insert the remote video.', { error: err })
}
// Handle retries on fail
-function updateRemoteVideoRetryWrapper (videoAttributesToUpdate, fromPod, finalCallback) {
+function updateRemoteVideoRetryWrapper (videoAttributesToUpdate: any, fromPod: PodInstance, finalCallback: (err: Error) => void) {
const options = {
arguments: [ videoAttributesToUpdate, fromPod ],
errorMessage: 'Cannot update the remote video with many retries'
retryTransactionWrapper(updateRemoteVideo, options, finalCallback)
}
-function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) {
+function updateRemoteVideo (videoAttributesToUpdate: any, fromPod: PodInstance, finalCallback: (err: Error) => void) {
logger.debug('Updating remote video "%s".', videoAttributesToUpdate.remoteId)
waterfall([
commitTransaction
- ], function (err, t) {
+ ], function (err: Error, t: Sequelize.Transaction) {
if (err) {
// This is just a debug because we will retry the insert
logger.debug('Cannot update the remote video.', { error: err })
})
}
-function removeRemoteVideo (videoToRemoveData, fromPod, callback) {
+function removeRemoteVideo (videoToRemoveData: any, fromPod: PodInstance, callback: (err: Error) => void) {
// We need the instance because we have to remove some other stuffs (thumbnail etc)
fetchRemoteVideo(fromPod.host, videoToRemoveData.remoteId, function (err, video) {
// Do not return the error, continue the process
})
}
-function reportAbuseRemoteVideo (reportData, fromPod, callback) {
+function reportAbuseRemoteVideo (reportData: any, fromPod: PodInstance, callback: (err: Error) => void) {
fetchOwnedVideo(reportData.videoRemoteId, function (err, video) {
if (err || !video) {
if (!err) err = new Error('video not found')
})
}
-function fetchOwnedVideo (id, callback) {
+function fetchOwnedVideo (id: string, callback: (err: Error, video?: VideoInstance) => void) {
db.Video.load(id, function (err, video) {
if (err || !video) {
if (!err) err = new Error('video not found')
})
}
-function fetchRemoteVideo (podHost, remoteId, callback) {
+function fetchRemoteVideo (podHost: string, remoteId: string, callback: (err: Error, video?: VideoInstance) => void) {
db.Video.loadByHostAndRemoteId(podHost, remoteId, function (err, video) {
if (err || !video) {
if (!err) err = new Error('video not found')
import { parallel } from 'async'
import {
+ BaseRequestScheduler,
getRequestScheduler,
getRequestVideoQaduScheduler,
getRequestVideoEventScheduler
// ---------------------------------------------------------------------------
-function getStatsRequests (req, res, next) {
+function getStatsRequests (req: express.Request, res: express.Response, next: express.NextFunction) {
parallel({
requestScheduler: buildRequestSchedulerFunction(getRequestScheduler()),
requestVideoQaduScheduler: buildRequestSchedulerFunction(getRequestVideoQaduScheduler()),
// ---------------------------------------------------------------------------
-function buildRequestSchedulerFunction (requestScheduler) {
+function buildRequestSchedulerFunction (requestScheduler: BaseRequestScheduler) {
return function (callback) {
requestScheduler.remainingRequestsCount(function (err, count) {
if (err) return callback(err)
// ---------------------------------------------------------------------------
-function ensureRegistrationEnabled (req, res, next) {
+function ensureRegistrationEnabled (req: express.Request, res: express.Response, next: express.NextFunction) {
const registrationEnabled = CONFIG.SIGNUP.ENABLED
if (registrationEnabled === true) {
return res.status(400).send('User registration is not enabled.')
}
-function createUser (req, res, next) {
+function createUser (req: express.Request, res: express.Response, next: express.NextFunction) {
const user = db.User.build({
username: req.body.username,
password: req.body.password,
role: USER_ROLES.USER
})
- user.save().asCallback(function (err, createdUser) {
+ user.save().asCallback(function (err) {
if (err) return next(err)
return res.type('json').status(204).end()
})
}
-function getUserInformation (req, res, next) {
+function getUserInformation (req: express.Request, res: express.Response, next: express.NextFunction) {
db.User.loadByUsername(res.locals.oauth.token.user.username, function (err, user) {
if (err) return next(err)
})
}
-function getUserVideoRating (req, res, next) {
- const videoId = req.params.videoId
- const userId = res.locals.oauth.token.User.id
+function getUserVideoRating (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const videoId = '' + req.params.videoId
+ const userId = +res.locals.oauth.token.User.id
db.UserVideoRate.load(userId, videoId, null, function (err, ratingObj) {
if (err) return next(err)
})
}
-function listUsers (req, res, next) {
+function listUsers (req: express.Request, res: express.Response, next: express.NextFunction) {
db.User.listForApi(req.query.start, req.query.count, req.query.sort, function (err, usersList, usersTotal) {
if (err) return next(err)
})
}
-function removeUser (req, res, next) {
+function removeUser (req: express.Request, res: express.Response, next: express.NextFunction) {
waterfall([
function loadUser (callback) {
db.User.loadById(req.params.id, callback)
})
}
-function updateUser (req, res, next) {
+function updateUser (req: express.Request, res: express.Response, next: express.NextFunction) {
db.User.loadByUsername(res.locals.oauth.token.user.username, function (err, user) {
if (err) return next(err)
})
}
-function success (req, res, next) {
+function success (req: express.Request, res: express.Response, next: express.NextFunction) {
res.end()
}
import * as express from 'express'
+import * as Sequelize from 'sequelize'
import { waterfall } from 'async'
import { database as db } from '../../../initializers/database'
// ---------------------------------------------------------------------------
-function listVideoAbuses (req, res, next) {
+function listVideoAbuses (req: express.Request, res: express.Response, next: express.NextFunction) {
db.VideoAbuse.listForApi(req.query.start, req.query.count, req.query.sort, function (err, abusesList, abusesTotal) {
if (err) return next(err)
})
}
-function reportVideoAbuseRetryWrapper (req, res, next) {
+function reportVideoAbuseRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res ],
errorMessage: 'Cannot report abuse to the video with many retries.'
})
}
-function reportVideoAbuse (req, res, finalCallback) {
+function reportVideoAbuse (req: express.Request, res: express.Response, finalCallback: (err: Error) => void) {
const videoInstance = res.locals.video
const reporterUsername = res.locals.oauth.token.User.username
commitTransaction
- ], function andFinally (err, t) {
+ ], function andFinally (err: Error, t: Sequelize.Transaction) {
if (err) {
logger.debug('Cannot update the video.', { error: err })
return rollbackTransaction(err, t, finalCallback)
// ---------------------------------------------------------------------------
-function addVideoToBlacklist (req, res, next) {
+function addVideoToBlacklist (req: express.Request, res: express.Response, next: express.NextFunction) {
const videoInstance = res.locals.video
const toCreate = {
import * as express from 'express'
+import * as Sequelize from 'sequelize'
import * as fs from 'fs'
import * as multer from 'multer'
import * as path from 'path'
// ---------------------------------------------------------------------------
-function listVideoCategories (req, res, next) {
+function listVideoCategories (req: express.Request, res: express.Response, next: express.NextFunction) {
res.json(VIDEO_CATEGORIES)
}
-function listVideoLicences (req, res, next) {
+function listVideoLicences (req: express.Request, res: express.Response, next: express.NextFunction) {
res.json(VIDEO_LICENCES)
}
-function listVideoLanguages (req, res, next) {
+function listVideoLanguages (req: express.Request, res: express.Response, next: express.NextFunction) {
res.json(VIDEO_LANGUAGES)
}
// Wrapper to video add that retry the function if there is a database error
// We need this because we run the transaction in SERIALIZABLE isolation that can fail
-function addVideoRetryWrapper (req, res, next) {
+function addVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res, req.files.videofile[0] ],
errorMessage: 'Cannot insert the video with many retries.'
})
}
-function addVideo (req, res, videoFile, finalCallback) {
+function addVideo (req: express.Request, res: express.Response, videoFile: Express.Multer.File, finalCallback: (err: Error) => void) {
const videoInfos = req.body
waterfall([
language: videoInfos.language,
nsfw: videoInfos.nsfw,
description: videoInfos.description,
- duration: videoFile.duration,
+ duration: videoFile['duration'], // duration was added by a previous middleware
authorId: author.id
}
commitTransaction
- ], function andFinally (err, t) {
+ ], function andFinally (err: Error, t: Sequelize.Transaction) {
if (err) {
// This is just a debug because we will retry the insert
logger.debug('Cannot insert the video.', { error: err })
})
}
-function updateVideoRetryWrapper (req, res, next) {
+function updateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res ],
errorMessage: 'Cannot update the video with many retries.'
})
}
-function updateVideo (req, res, finalCallback) {
+function updateVideo (req: express.Request, res: express.Response, finalCallback: (err: Error) => void) {
const videoInstance = res.locals.video
const videoFieldsSave = videoInstance.toJSON()
const videoInfosToUpdate = req.body
commitTransaction
- ], function andFinally (err, t) {
+ ], function andFinally (err: Error, t: Sequelize.Transaction) {
if (err) {
logger.debug('Cannot update the video.', { error: err })
})
}
-function getVideo (req, res, next) {
+function getVideo (req: express.Request, res: express.Response, next: express.NextFunction) {
const videoInstance = res.locals.video
if (videoInstance.isOwned()) {
res.json(videoInstance.toFormatedJSON())
}
-function listVideos (req, res, next) {
+function listVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
db.Video.listForApi(req.query.start, req.query.count, req.query.sort, function (err, videosList, videosTotal) {
if (err) return next(err)
})
}
-function removeVideo (req, res, next) {
+function removeVideo (req: express.Request, res: express.Response, next: express.NextFunction) {
const videoInstance = res.locals.video
videoInstance.destroy().asCallback(function (err) {
})
}
-function searchVideos (req, res, next) {
+function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
db.Video.searchAndPopulateAuthorAndPodAndTags(
req.params.value, req.query.field, req.query.start, req.query.count, req.query.sort,
function (err, videosList, videosTotal) {
import * as express from 'express'
+import * as Sequelize from 'sequelize'
import { waterfall } from 'async'
import { database as db } from '../../../initializers/database'
// ---------------------------------------------------------------------------
-function rateVideoRetryWrapper (req, res, next) {
+function rateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
const options = {
arguments: [ req, res ],
errorMessage: 'Cannot update the user video rate.'
})
}
-function rateVideo (req, res, finalCallback) {
+function rateVideo (req: express.Request, res: express.Response, finalCallback: (err: Error) => void) {
const rateType = req.body.rating
const videoInstance = res.locals.video
const userInstance = res.locals.oauth.token.User
commitTransaction
- ], function (err, t) {
+ ], function (err: Error, t: Sequelize.Transaction) {
if (err) {
// This is just a debug because we will retry the insert
logger.debug('Cannot add the user video rate.', { error: err })
STATIC_MAX_AGE
} from '../initializers'
import { root } from '../helpers'
+import { VideoInstance } from '../models'
const clientsRouter = express.Router()
// Do not use a template engine for a so little thing
clientsRouter.use('/videos/watch/:id', generateWatchHtmlPage)
-clientsRouter.use('/videos/embed', function (req, res, next) {
+clientsRouter.use('/videos/embed', function (req: express.Request, res: express.Response, next: express.NextFunction) {
res.sendFile(embedPath)
})
clientsRouter.use('/client', express.static(distPath, { maxAge: STATIC_MAX_AGE }))
// 404 for static files not found
-clientsRouter.use('/client/*', function (req, res, next) {
+clientsRouter.use('/client/*', function (req: express.Request, res: express.Response, next: express.NextFunction) {
res.sendStatus(404)
})
// ---------------------------------------------------------------------------
-function addOpenGraphTags (htmlStringPage, video) {
+function addOpenGraphTags (htmlStringPage: string, video: VideoInstance) {
let basePreviewUrlHttp
if (video.isOwned()) {
return htmlStringPage.replace(opengraphComment, tagsString)
}
-function generateWatchHtmlPage (req, res, next) {
- const videoId = req.params.id
+function generateWatchHtmlPage (req: express.Request, res: express.Response, next: express.NextFunction) {
+ const videoId = '' + req.params.id
// Let Angular application handle errors
if (!validator.isUUID(videoId, 4)) return res.sendFile(indexPath)
video: function (callback) {
db.Video.loadAndPopulateAuthorAndPodAndTags(videoId, callback)
}
- }, function (err, result: any) {
+ }, function (err: Error, result: { file: Buffer, video: VideoInstance }) {
if (err) return next(err)
const html = result.file.toString()
-function exists (value) {
+function exists (value: any) {
return value !== undefined && value !== null
}
-function isArray (value) {
+function isArray (value: any) {
return Array.isArray(value)
}
exists,
isArray
}
+
+declare global {
+ namespace ExpressValidator {
+ export interface Validator {
+ exists,
+ isArray
+ }
+ }
+}
import * as validator from 'validator'
-import { isArray } from './misc'
+import { isArray, exists } from './misc'
-function isHostValid (host) {
- return validator.isURL(host) && host.split('://').length === 1
+function isHostValid (host: string) {
+ return exists(host) && validator.isURL(host) && host.split('://').length === 1
}
-function isEachUniqueHostValid (hosts) {
+function isEachUniqueHostValid (hosts: string[]) {
return isArray(hosts) &&
hosts.length !== 0 &&
hosts.every(function (host) {
isEachUniqueHostValid,
isHostValid
}
+
+declare global {
+ namespace ExpressValidator {
+ export interface Validator {
+ isEachUniqueHostValid
+ isHostValid
+ }
+ }
+}
-export * from './videos';
+export * from './videos'
const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
-function isEachRemoteRequestVideosValid (requests) {
+function isEachRemoteRequestVideosValid (requests: any[]) {
return isArray(requests) &&
requests.every(function (request) {
const video = request.data
})
}
-function isEachRemoteRequestVideosQaduValid (requests) {
+function isEachRemoteRequestVideosQaduValid (requests: any[]) {
return isArray(requests) &&
requests.every(function (request) {
const video = request.data
return (
isVideoRemoteIdValid(video.remoteId) &&
- (has(video, 'views') === false || isVideoViewsValid) &&
- (has(video, 'likes') === false || isVideoLikesValid) &&
- (has(video, 'dislikes') === false || isVideoDislikesValid)
+ (has(video, 'views') === false || isVideoViewsValid(video.views)) &&
+ (has(video, 'likes') === false || isVideoLikesValid(video.likes)) &&
+ (has(video, 'dislikes') === false || isVideoDislikesValid(video.dislikes))
)
})
}
-function isEachRemoteRequestVideosEventsValid (requests) {
+function isEachRemoteRequestVideosEventsValid (requests: any[]) {
return isArray(requests) &&
requests.every(function (request) {
const eventData = request.data
isEachRemoteRequestVideosEventsValid
}
+declare global {
+ namespace ExpressValidator {
+ export interface Validator {
+ isEachRemoteRequestVideosValid,
+ isEachRemoteRequestVideosQaduValid,
+ isEachRemoteRequestVideosEventsValid
+ }
+ }
+}
+
// ---------------------------------------------------------------------------
-function isCommonVideoAttributesValid (video) {
+function isCommonVideoAttributesValid (video: any) {
return isVideoDateValid(video.createdAt) &&
isVideoDateValid(video.updatedAt) &&
isVideoCategoryValid(video.category) &&
isVideoDislikesValid(video.dislikes)
}
-function isRequestTypeAddValid (value) {
+function isRequestTypeAddValid (value: string) {
return value === ENDPOINT_ACTIONS.ADD
}
-function isRequestTypeUpdateValid (value) {
+function isRequestTypeUpdateValid (value: string) {
return value === ENDPOINT_ACTIONS.UPDATE
}
-function isRequestTypeRemoveValid (value) {
+function isRequestTypeRemoveValid (value: string) {
return value === ENDPOINT_ACTIONS.REMOVE
}
-function isRequestTypeReportAbuseValid (value) {
+function isRequestTypeReportAbuseValid (value: string) {
return value === ENDPOINT_ACTIONS.REPORT_ABUSE
}
import { values } from 'lodash'
import * as validator from 'validator'
+import { exists } from './misc'
import { CONSTRAINTS_FIELDS, USER_ROLES } from '../../initializers'
const USERS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.USERS
-function isUserPasswordValid (value) {
+function isUserPasswordValid (value: string) {
return validator.isLength(value, USERS_CONSTRAINTS_FIELDS.PASSWORD)
}
-function isUserRoleValid (value) {
+function isUserRoleValid (value: string) {
return values(USER_ROLES).indexOf(value) !== -1
}
-function isUserUsernameValid (value) {
+function isUserUsernameValid (value: string) {
const max = USERS_CONSTRAINTS_FIELDS.USERNAME.max
const min = USERS_CONSTRAINTS_FIELDS.USERNAME.min
- return validator.matches(value, new RegExp(`^[a-zA-Z0-9._]{${min},${max}}$`))
+ return exists(value) && validator.matches(value, new RegExp(`^[a-zA-Z0-9._]{${min},${max}}$`))
}
-function isUserDisplayNSFWValid (value) {
- return validator.isBoolean(value)
+function isUserDisplayNSFWValid (value: any) {
+ return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
}
// ---------------------------------------------------------------------------
isUserUsernameValid,
isUserDisplayNSFWValid
}
+
+declare global {
+ namespace ExpressValidator {
+ export interface Validator {
+ isUserPasswordValid,
+ isUserRoleValid,
+ isUserUsernameValid,
+ isUserDisplayNSFWValid
+ }
+ }
+}
VIDEO_RATE_TYPES
} from '../../initializers'
import { isUserUsernameValid } from './users'
-import { isArray } from './misc'
+import { isArray, exists } from './misc'
const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
const VIDEO_EVENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_EVENTS
-function isVideoAuthorValid (value) {
+function isVideoAuthorValid (value: string) {
return isUserUsernameValid(value)
}
-function isVideoDateValid (value) {
- return validator.isDate(value)
+function isVideoDateValid (value: string) {
+ return exists(value) && validator.isISO8601(value)
}
-function isVideoCategoryValid (value) {
+function isVideoCategoryValid (value: number) {
return VIDEO_CATEGORIES[value] !== undefined
}
-function isVideoLicenceValid (value) {
+function isVideoLicenceValid (value: number) {
return VIDEO_LICENCES[value] !== undefined
}
-function isVideoLanguageValid (value) {
+function isVideoLanguageValid (value: number) {
return value === null || VIDEO_LANGUAGES[value] !== undefined
}
-function isVideoNSFWValid (value) {
- return validator.isBoolean(value)
+function isVideoNSFWValid (value: any) {
+ return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value))
}
-function isVideoDescriptionValid (value) {
- return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
+function isVideoDescriptionValid (value: string) {
+ return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION)
}
-function isVideoDurationValid (value) {
- return validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
+function isVideoDurationValid (value: string) {
+ return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION)
}
-function isVideoExtnameValid (value) {
+function isVideoExtnameValid (value: string) {
return VIDEOS_CONSTRAINTS_FIELDS.EXTNAME.indexOf(value) !== -1
}
-function isVideoInfoHashValid (value) {
- return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
+function isVideoInfoHashValid (value: string) {
+ return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.INFO_HASH)
}
-function isVideoNameValid (value) {
- return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
+function isVideoNameValid (value: string) {
+ return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
}
-function isVideoTagsValid (tags) {
+function isVideoTagsValid (tags: string[]) {
return isArray(tags) &&
- validator.isInt(tags.length, VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
+ validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
tags.every(function (tag) {
- return validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
+ return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
})
}
-function isVideoThumbnailValid (value) {
- return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL)
+function isVideoThumbnailValid (value: string) {
+ return exists(value) && validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL)
}
-function isVideoThumbnailDataValid (value) {
- return validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA)
+function isVideoThumbnailDataValid (value: string) {
+ return exists(value) && validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA)
}
-function isVideoRemoteIdValid (value) {
- return validator.isUUID(value, 4)
+function isVideoRemoteIdValid (value: string) {
+ return exists(value) && validator.isUUID(value, 4)
}
-function isVideoAbuseReasonValid (value) {
- return validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
+function isVideoAbuseReasonValid (value: string) {
+ return exists(value) && validator.isLength(value, VIDEO_ABUSES_CONSTRAINTS_FIELDS.REASON)
}
-function isVideoAbuseReporterUsernameValid (value) {
+function isVideoAbuseReporterUsernameValid (value: string) {
return isUserUsernameValid(value)
}
-function isVideoViewsValid (value) {
- return validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
+function isVideoViewsValid (value: string) {
+ return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.VIEWS)
}
-function isVideoLikesValid (value) {
- return validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.LIKES)
+function isVideoLikesValid (value: string) {
+ return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.LIKES)
}
-function isVideoDislikesValid (value) {
- return validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DISLIKES)
+function isVideoDislikesValid (value: string) {
+ return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DISLIKES)
}
-function isVideoEventCountValid (value) {
- return validator.isInt(value + '', VIDEO_EVENTS_CONSTRAINTS_FIELDS.COUNT)
+function isVideoEventCountValid (value: string) {
+ return exists(value) && validator.isInt(value + '', VIDEO_EVENTS_CONSTRAINTS_FIELDS.COUNT)
}
-function isVideoRatingTypeValid (value) {
+function isVideoRatingTypeValid (value: string) {
return values(VIDEO_RATE_TYPES).indexOf(value) !== -1
}
-function isVideoFile (value, files) {
+function isVideoFile (value: string, files: { [ fieldname: string ]: Express.Multer.File[] }) {
// Should have files
if (!files) return false
isVideoDislikesValid,
isVideoEventCountValid
}
+
+declare global {
+ namespace ExpressValidator {
+ export interface Validator {
+ isVideoAuthorValid,
+ isVideoDateValid,
+ isVideoCategoryValid,
+ isVideoLicenceValid,
+ isVideoLanguageValid,
+ isVideoNSFWValid,
+ isVideoDescriptionValid,
+ isVideoDurationValid,
+ isVideoInfoHashValid,
+ isVideoNameValid,
+ isVideoTagsValid,
+ isVideoThumbnailValid,
+ isVideoThumbnailDataValid,
+ isVideoExtnameValid,
+ isVideoRemoteIdValid,
+ isVideoAbuseReasonValid,
+ isVideoAbuseReporterUsernameValid,
+ isVideoFile,
+ isVideoViewsValid,
+ isVideoLikesValid,
+ isVideoRatingTypeValid,
+ isVideoDislikesValid,
+ isVideoEventCountValid
+ }
+ }
+}
+import * as Sequelize from 'sequelize'
// TODO: import from ES6 when retry typing file will include errorFilter function
import * as retry from 'async/retry'
import { database as db } from '../initializers/database'
import { logger } from './logger'
-function commitTransaction (t, callback) {
+function commitTransaction (t: Sequelize.Transaction, callback: (err: Error) => void) {
return t.commit().asCallback(callback)
}
-function rollbackTransaction (err, t, callback) {
+function rollbackTransaction (err: Error, t: Sequelize.Transaction, callback: (err: Error) => void) {
// Try to rollback transaction
if (t) {
// Do not catch err, report the original one
}
}
-// { arguments, errorMessage }
-function retryTransactionWrapper (functionToRetry, options, finalCallback) {
+type RetryTransactionWrapperOptions = { errorMessage: string, arguments?: any[] }
+function retryTransactionWrapper (functionToRetry: Function, options: RetryTransactionWrapperOptions, finalCallback: Function) {
const args = options.arguments ? options.arguments : []
transactionRetryer(
)
}
-function transactionRetryer (func, callback) {
+function transactionRetryer (func: Function, callback: (err: Error) => void) {
retry({
times: 5,
}, func, callback)
}
-function startSerializableTransaction (callback) {
+function startSerializableTransaction (callback: (err: Error, t: Sequelize.Transaction) => void) {
db.sequelize.transaction(/* { isolationLevel: 'SERIALIZABLE' } */).asCallback(function (err, t) {
// We force to return only two parameters
return callback(err, t)
} from '../initializers'
import { logger } from './logger'
-function checkSignature (publicKey, data, hexSignature) {
+function checkSignature (publicKey: string, data: string, hexSignature: string) {
const verify = crypto.createVerify(SIGNATURE_ALGORITHM)
let dataString
return isValid
}
-function sign (data) {
+function sign (data: string|Object) {
const sign = crypto.createSign(SIGNATURE_ALGORITHM)
- let dataString
+ let dataString: string
if (typeof data === 'string') {
dataString = data
} else {
return signature
}
-function comparePassword (plainPassword, hashPassword, callback) {
+function comparePassword (plainPassword: string, hashPassword: string, callback: (err: Error, match?: boolean) => void) {
bcrypt.compare(plainPassword, hashPassword, function (err, isPasswordMatch) {
if (err) return callback(err)
})
}
-function createCertsIfNotExist (callback) {
+function createCertsIfNotExist (callback: (err: Error) => void) {
certsExist(function (err, exist) {
if (err) return callback(err)
})
}
-function cryptPassword (password, callback) {
+function cryptPassword (password: string, callback: (err: Error, hash?: string) => void) {
bcrypt.genSalt(BCRYPT_SALT_SIZE, function (err, salt) {
if (err) return callback(err)
})
}
-function getMyPrivateCert (callback) {
+function getMyPrivateCert (callback: (err: Error, privateCert: string) => void) {
const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
fs.readFile(certPath, 'utf8', callback)
}
-function getMyPublicCert (callback) {
+function getMyPublicCert (callback: (err: Error, publicCert: string) => void) {
const certPath = join(CONFIG.STORAGE.CERT_DIR, PUBLIC_CERT_NAME)
fs.readFile(certPath, 'utf8', callback)
}
// ---------------------------------------------------------------------------
-function certsExist (callback) {
+function certsExist (callback: (err: Error, certsExist: boolean) => void) {
const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
fs.access(certPath, function (err) {
// If there is an error the certificates do not exist
})
}
-function createCerts (callback) {
+function createCerts (callback: (err: Error) => void) {
certsExist(function (err, exist) {
if (err) return callback(err)
if (exist === true) {
- const string = 'Certs already exist.'
- logger.warning(string)
- return callback(new Error(string))
+ const errorMessage = 'Certs already exist.'
+ logger.warning(errorMessage)
+ return callback(new Error(errorMessage))
}
logger.info('Generating a RSA key...')
REMOTE_SCHEME,
CONFIG
} from '../initializers'
+import { PodInstance } from '../models'
import { sign } from './peertube-crypto'
-function makeRetryRequest (params, callback) {
+type MakeRetryRequestParams = {
+ url: string,
+ method: 'GET'|'POST',
+ json: Object
+}
+function makeRetryRequest (params: MakeRetryRequestParams, callback: request.RequestCallback) {
replay(
request(params, callback),
{
)
}
-function makeSecureRequest (params, callback) {
+type MakeSecureRequestParams = {
+ method: 'GET'|'POST'
+ toPod: PodInstance
+ path: string
+ sign: boolean
+ data?: Object
+}
+function makeSecureRequest (params: MakeSecureRequestParams, callback: request.RequestCallback) {
const requestParams = {
url: REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path,
json: {}
}
if (params.method !== 'POST') {
- return callback(new Error('Cannot make a secure request with a non POST method.'))
+ return callback(new Error('Cannot make a secure request with a non POST method.'), null, null)
}
// Add signature if it is specified in the params
+import * as express from 'express'
+
import { pseudoRandomBytes } from 'crypto'
import { join } from 'path'
import { logger } from './logger'
-function badRequest (req, res, next) {
+function badRequest (req: express.Request, res: express.Response, next: express.NextFunction) {
res.type('json').status(400).end()
}
-function generateRandomString (size, callback) {
+function generateRandomString (size: number, callback: (err: Error, randomString?: string) => void) {
pseudoRandomBytes(size, function (err, raw) {
if (err) return callback(err)
})
}
-function cleanForExit (webtorrentProcess) {
- logger.info('Gracefully exiting.')
- process.kill(-webtorrentProcess.pid)
-}
-
function createEmptyCallback () {
return function (err) {
if (err) logger.error('Error in empty callback.', { error: err })
}
function isTestInstance () {
- return (process.env.NODE_ENV === 'test')
+ return process.env.NODE_ENV === 'test'
}
-function getFormatedObjects (objects, objectsTotal) {
+function getFormatedObjects (objects: any[], objectsTotal: number) {
const formatedObjects = []
objects.forEach(function (object) {
export {
badRequest,
createEmptyCallback,
- cleanForExit,
generateRandomString,
isTestInstance,
getFormatedObjects,
'storage.certs', 'storage.videos', 'storage.logs', 'storage.thumbnails', 'storage.previews',
'admin.email', 'signup.enabled', 'transcoding.enabled', 'transcoding.threads'
]
- const miss = []
+ const miss: string[] = []
for (const key of required) {
if (!config.has(key)) {
}
// Check the available codecs
-function checkFFmpeg (callback) {
+function checkFFmpeg (callback: (err: Error) => void) {
const Ffmpeg = require('fluent-ffmpeg')
Ffmpeg.getAvailableCodecs(function (err, codecs) {
})
}
-function clientsExist (callback) {
+function clientsExist (callback: (err: Error, clientsExist?: boolean) => void) {
db.OAuthClient.countTotal(function (err, totalClients) {
if (err) return callback(err)
})
}
-function usersExist (callback) {
+function usersExist (callback: (err: Error, usersExist?: boolean) => void) {
db.User.countTotal(function (err, totalUsers) {
if (err) return callback(err)
VIDEOS: 'videos'
}
-const REQUEST_ENDPOINT_ACTIONS = {}
+const REQUEST_ENDPOINT_ACTIONS: { [ id: string ]: any } = {}
REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS] = {
ADD: 'add',
UPDATE: 'update',
port: CONFIG.DATABASE.PORT,
benchmark: isTestInstance(),
- logging: function (message, benchmark) {
+ logging: function (message: string, benchmark: number) {
let newMessage = message
if (benchmark !== undefined) {
newMessage += ' | ' + benchmark + 'ms'
database.sequelize = sequelize
-database.init = function (silent, callback) {
+database.init = function (silent: boolean, callback: (err: Error) => void) {
const modelDirectory = join(__dirname, '..', 'models')
fs.readdir(modelDirectory, function (err, files) {
import { clientsExist, usersExist } from './checker'
import { logger, createCertsIfNotExist, root } from '../helpers'
-function installApplication (callback) {
+function installApplication (callback: (err: Error) => void) {
series([
function createDatabase (callbackAsync) {
db.sequelize.sync().asCallback(callbackAsync)
// ---------------------------------------------------------------------------
-function createDirectoriesIfNotExist (callback) {
+function createDirectoriesIfNotExist (callback: (err: Error) => void) {
const storages = config.get('storage')
each(Object.keys(storages), function (key, callbackEach) {
}, callback)
}
-function createOAuthClientIfNotExist (callback) {
+function createOAuthClientIfNotExist (callback: (err: Error) => void) {
clientsExist(function (err, exist) {
if (err) return callback(err)
})
}
-function createOAuthAdminIfNotExist (callback) {
+function createOAuthAdminIfNotExist (callback: (err: Error) => void) {
usersExist(function (err, exist) {
if (err) return callback(err)
import { logger } from '../helpers'
import { ApplicationInstance } from '../models'
-function migrate (finalCallback) {
+function migrate (finalCallback: (err: Error) => void) {
waterfall([
function checkApplicationTableExists (callback) {
},
function doMigrations (actualVersion, migrationScripts, callback) {
- eachSeries(migrationScripts, function (entity, callbackEach) {
+ eachSeries(migrationScripts, function (entity: any, callbackEach) {
executeMigration(actualVersion, entity, callbackEach)
}, function (err) {
if (err) return callback(err)
// ---------------------------------------------------------------------------
-function getMigrationScripts (callback) {
+type GetMigrationScriptsCallback = (err: Error, filesToMigrate?: { version: string, script: string }[]) => void
+function getMigrationScripts (callback: GetMigrationScriptsCallback) {
fs.readdir(path.join(__dirname, 'migrations'), function (err, files) {
if (err) return callback(err)
})
}
-function executeMigration (actualVersion, entity, callback) {
+function executeMigration (actualVersion: number, entity: { version: string, script: string }, callback: (err: Error) => void) {
const versionScript = parseInt(entity.version, 10)
// Do not execute old migration scripts
import { each, eachLimit, eachSeries, series, waterfall } from 'async'
import * as request from 'request'
+import * as Sequelize from 'sequelize'
import { database as db } from '../initializers/database'
import {
} from '../helpers'
import {
RequestScheduler,
+ RequestSchedulerOptions,
+
RequestVideoQaduScheduler,
- RequestVideoEventScheduler
+ RequestVideoQaduSchedulerOptions,
+
+ RequestVideoEventScheduler,
+ RequestVideoEventSchedulerOptions
} from './request'
+import { PodInstance, VideoInstance } from '../models'
+
+type QaduParam = { videoId: string, type: string }
+type EventParam = { videoId: string, type: string }
const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
requestVideoEventScheduler.activate()
}
-function addVideoToFriends (videoData, transaction, callback) {
+function addVideoToFriends (videoData: Object, transaction: Sequelize.Transaction, callback: (err: Error) => void) {
const options = {
type: ENDPOINT_ACTIONS.ADD,
endpoint: REQUEST_ENDPOINTS.VIDEOS,
createRequest(options, callback)
}
-function updateVideoToFriends (videoData, transaction, callback) {
+function updateVideoToFriends (videoData: Object, transaction: Sequelize.Transaction, callback: (err: Error) => void) {
const options = {
type: ENDPOINT_ACTIONS.UPDATE,
endpoint: REQUEST_ENDPOINTS.VIDEOS,
createRequest(options, callback)
}
-function removeVideoToFriends (videoParams) {
+function removeVideoToFriends (videoParams: Object) {
const options = {
type: ENDPOINT_ACTIONS.REMOVE,
endpoint: REQUEST_ENDPOINTS.VIDEOS,
- data: videoParams
+ data: videoParams,
+ transaction: null
}
createRequest(options)
}
-function reportAbuseVideoToFriend (reportData, video) {
+function reportAbuseVideoToFriend (reportData: Object, video: VideoInstance) {
const options = {
type: ENDPOINT_ACTIONS.REPORT_ABUSE,
endpoint: REQUEST_ENDPOINTS.VIDEOS,
data: reportData,
- toIds: [ video.Author.podId ]
+ toIds: [ video.Author.podId ],
+ transaction: null
}
createRequest(options)
}
-function quickAndDirtyUpdateVideoToFriends (qaduParams, transaction?, callback?) {
+function quickAndDirtyUpdateVideoToFriends (qaduParam: QaduParam, transaction?: Sequelize.Transaction, callback?: (err: Error) => void) {
const options = {
- videoId: qaduParams.videoId,
- type: qaduParams.type,
+ videoId: qaduParam.videoId,
+ type: qaduParam.type,
transaction
}
return createVideoQaduRequest(options, callback)
}
-function quickAndDirtyUpdatesVideoToFriends (qadusParams, transaction, finalCallback) {
+function quickAndDirtyUpdatesVideoToFriends (qadusParams: QaduParam[], transaction: Sequelize.Transaction, finalCallback: (err: Error) => void) {
const tasks = []
qadusParams.forEach(function (qaduParams) {
series(tasks, finalCallback)
}
-function addEventToRemoteVideo (eventParams, transaction?, callback?) {
+function addEventToRemoteVideo (eventParam: EventParam, transaction?: Sequelize.Transaction, callback?: (err: Error) => void) {
const options = {
- videoId: eventParams.videoId,
- type: eventParams.type,
+ videoId: eventParam.videoId,
+ type: eventParam.type,
transaction
}
createVideoEventRequest(options, callback)
}
-function addEventsToRemoteVideo (eventsParams, transaction, finalCallback) {
+function addEventsToRemoteVideo (eventsParams: EventParam[], transaction: Sequelize.Transaction, finalCallback: (err: Error) => void) {
const tasks = []
eventsParams.forEach(function (eventParams) {
series(tasks, finalCallback)
}
-function hasFriends (callback) {
+function hasFriends (callback: (err: Error, hasFriends?: boolean) => void) {
db.Pod.countAll(function (err, count) {
if (err) return callback(err)
})
}
-function makeFriends (hosts, callback) {
+function makeFriends (hosts: string[], callback: (err: Error) => void) {
const podsScore = {}
logger.info('Make friends!')
eachSeries(hosts, function (host, callbackEach) {
computeForeignPodsList(host, podsScore, callbackEach)
- }, function (err) {
+ }, function (err: Error) {
if (err) return callback(err)
logger.debug('Pods scores computed.', { podsScore: podsScore })
})
}
-function quitFriends (callback) {
+function quitFriends (callback: (err: Error) => void) {
// Stop pool requests
requestScheduler.deactivate()
function announceIQuitMyFriends (pods, callbackAsync) {
const requestParams = {
- method: 'POST',
+ method: 'POST' as 'POST',
path: '/api/' + API_VERSION + '/remote/pods/remove',
sign: true,
toPod: null
pod.destroy().asCallback(callbackEach)
}, callbackAsync)
}
- ], function (err) {
+ ], function (err: Error) {
// Don't forget to re activate the scheduler, even if there was an error
requestScheduler.activate()
})
}
-function sendOwnedVideosToPod (podId) {
+function sendOwnedVideosToPod (podId: number) {
db.Video.listOwnedAndPopulateAuthorAndTags(function (err, videosList) {
if (err) {
logger.error('Cannot get the list of videos we own.')
type: 'add',
endpoint: REQUEST_ENDPOINTS.VIDEOS,
data: remoteVideo,
- toIds: [ podId ]
+ toIds: [ podId ],
+ transaction: null
}
createRequest(options)
})
// ---------------------------------------------------------------------------
-function computeForeignPodsList (host, podsScore, callback) {
+function computeForeignPodsList (host: string, podsScore: { [ host: string ]: number }, callback: (err: Error) => void) {
getForeignPodsList(host, function (err, res) {
if (err) return callback(err)
else podsScore[foreignPodHost] = 1
})
- return callback()
+ return callback(null)
})
}
-function computeWinningPods (hosts, podsScore) {
+function computeWinningPods (hosts: string[], podsScore: { [ host: string ]: number }) {
// Build the list of pods to add
// Only add a pod if it exists in more than a half base pods
const podsList = []
return podsList
}
-function getForeignPodsList (host, callback) {
+function getForeignPodsList (host: string, callback: (err: Error, foreignPodsList?: any) => void) {
const path = '/api/' + API_VERSION + '/pods'
request.get(REMOTE_SCHEME.HTTP + '://' + host + path, function (err, response, body) {
})
}
-function makeRequestsToWinningPods (cert, podsList, callback) {
+function makeRequestsToWinningPods (cert: string, podsList: PodInstance[], callback: (err: Error) => void) {
// Stop pool requests
requestScheduler.deactivate()
// Flush pool requests
requestScheduler.forceSend()
- eachLimit(podsList, REQUESTS_IN_PARALLEL, function (pod: { host: string }, callbackEach) {
+ eachLimit(podsList, REQUESTS_IN_PARALLEL, function (pod: PodInstance, callbackEach) {
const params = {
url: REMOTE_SCHEME.HTTP + '://' + pod.host + '/api/' + API_VERSION + '/pods/',
- method: 'POST',
+ method: 'POST' as 'POST',
json: {
host: CONFIG.WEBSERVER.HOST,
email: CONFIG.ADMIN.EMAIL,
requestScheduler.activate()
logger.debug('makeRequestsToWinningPods finished.')
- return callback()
+ return callback(null)
})
}
// Wrapper that populate "toIds" argument with all our friends if it is not specified
-// { type, endpoint, data, toIds, transaction }
-function createRequest (options, callback?) {
+type CreateRequestOptions = {
+ type: string
+ endpoint: string
+ data: Object
+ toIds?: number[]
+ transaction: Sequelize.Transaction
+}
+function createRequest (options: CreateRequestOptions, callback?: (err: Error) => void) {
if (!callback) callback = function () { /* empty */ }
- if (options.toIds) return requestScheduler.createRequest(options, callback)
+
+ if (options.toIds !== undefined) return requestScheduler.createRequest(options as RequestSchedulerOptions, callback)
// If the "toIds" pods is not specified, we send the request to all our friends
db.Pod.listAllIds(options.transaction, function (err, podIds) {
})
}
-function createVideoQaduRequest (options, callback) {
+function createVideoQaduRequest (options: RequestVideoQaduSchedulerOptions, callback: (err: Error) => void) {
if (!callback) callback = createEmptyCallback()
requestVideoQaduScheduler.createRequest(options, callback)
}
-function createVideoEventRequest (options, callback) {
+function createVideoEventRequest (options: RequestVideoEventSchedulerOptions, callback: (err: Error) => void) {
if (!callback) callback = createEmptyCallback()
requestVideoEventScheduler.createRequest(options, callback)
}
-function isMe (host) {
+function isMe (host: string) {
return host === CONFIG.WEBSERVER.HOST
}
import * as videoTranscoder from './video-transcoder'
-const jobHandlers = {
+import { VideoInstance } from '../../../models'
+
+export interface JobHandler<T> {
+ process (data: object, callback: (err: Error, videoInstance?: T) => void)
+ onError (err: Error, jobId: number, video: T, callback: (err: Error) => void)
+ onSuccess (data: any, jobId: number, video: T, callback: (err: Error) => void)
+}
+
+const jobHandlers: { [ handlerName: string ]: JobHandler<any> } = {
videoTranscoder
}
import { database as db } from '../../../initializers/database'
import { logger } from '../../../helpers'
import { addVideoToFriends } from '../../../lib'
+import { VideoInstance } from '../../../models'
-function process (data, callback) {
+function process (data: { id: string }, callback: (err: Error, videoInstance?: VideoInstance) => void) {
db.Video.loadAndPopulateAuthorAndPodAndTags(data.id, function (err, video) {
if (err) return callback(err)
})
}
-function onError (err, jobId, video, callback) {
+function onError (err: Error, jobId: number, video: VideoInstance, callback: () => void) {
logger.error('Error when transcoding video file in job %d.', jobId, { error: err })
return callback()
}
-function onSuccess (data, jobId, video, callback) {
+function onSuccess (data: any, jobId: number, video: VideoInstance, callback: (err: Error) => void) {
logger.info('Job %d is a success.', jobId)
video.toAddRemoteJSON(function (err, remoteVideo) {
import { forever, queue } from 'async'
+import * as Sequelize from 'sequelize'
import { database as db } from '../../initializers/database'
import {
JOB_STATES
} from '../../initializers'
import { logger } from '../../helpers'
-import { jobHandlers } from './handlers'
+import { JobInstance } from '../../models'
+import { JobHandler, jobHandlers } from './handlers'
+
+type JobQueueCallback = (err: Error) => void
class JobScheduler {
logger.info('Jobs scheduler activated.')
- const jobsQueue = queue(this.processJob.bind(this))
+ const jobsQueue = queue<JobInstance, JobQueueCallback>(this.processJob.bind(this))
// Finish processing jobs from a previous start
const state = JOB_STATES.PROCESSING
})
}
- createJob (transaction, handlerName: string, handlerInputData: object, callback) {
+ createJob (transaction: Sequelize.Transaction, handlerName: string, handlerInputData: object, callback: (err: Error) => void) {
const createQuery = {
state: JOB_STATES.PENDING,
handlerName,
db.Job.create(createQuery, options).asCallback(callback)
}
- private enqueueJobs (err, jobsQueue, jobs) {
+ private enqueueJobs (err: Error, jobsQueue: AsyncQueue<JobInstance>, jobs: JobInstance[]) {
if (err) {
logger.error('Cannot list pending jobs.', { error: err })
} else {
}
}
- private processJob (job, callback) {
+ private processJob (job: JobInstance, callback: (err: Error) => void) {
const jobHandler = jobHandlers[job.handlerName]
logger.info('Processing job %d with handler %s.', job.id, job.handlerName)
if (err) return this.cannotSaveJobError(err, callback)
if (jobHandler === undefined) {
- logger.error('Unknown job handler for job %s.', jobHandler.handlerName)
- return callback()
+ logger.error('Unknown job handler for job %s.', job.handlerName)
+ return callback(null)
}
return jobHandler.process(job.handlerInputData, (err, result) => {
})
}
- private onJobError (jobHandler, job, jobResult, callback) {
+ private onJobError (jobHandler: JobHandler<any>, job: JobInstance, jobResult: any, callback: (err: Error) => void) {
job.state = JOB_STATES.ERROR
job.save().asCallback(err => {
})
}
- private onJobSuccess (jobHandler, job, jobResult, callback) {
+ private onJobSuccess (jobHandler: JobHandler<any>, job: JobInstance, jobResult: any, callback: (err: Error) => void) {
job.state = JOB_STATES.SUCCESS
job.save().asCallback(err => {
})
}
- private cannotSaveJobError (err, callback) {
+ private cannotSaveJobError (err: Error, callback: (err: Error) => void) {
logger.error('Cannot save new job state.', { error: err })
return callback(err)
}
+import { OAuthClientInstance, UserInstance } from '../models'
import { database as db } from '../initializers/database'
import { logger } from '../helpers'
+type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date }
+
// ---------------------------------------------------------------------------
-function getAccessToken (bearerToken) {
+function getAccessToken (bearerToken: string) {
logger.debug('Getting access token (bearerToken: ' + bearerToken + ').')
return db.OAuthToken.getByTokenAndPopulateUser(bearerToken)
}
-function getClient (clientId, clientSecret) {
+function getClient (clientId: string, clientSecret: string) {
logger.debug('Getting Client (clientId: ' + clientId + ', clientSecret: ' + clientSecret + ').')
return db.OAuthClient.getByIdAndSecret(clientId, clientSecret)
}
-function getRefreshToken (refreshToken) {
+function getRefreshToken (refreshToken: string) {
logger.debug('Getting RefreshToken (refreshToken: ' + refreshToken + ').')
return db.OAuthToken.getByRefreshTokenAndPopulateClient(refreshToken)
}
-function getUser (username, password) {
+function getUser (username: string, password: string) {
logger.debug('Getting User (username: ' + username + ', password: ' + password + ').')
return db.User.getByUsername(username).then(function (user) {
})
}
-function revokeToken (token) {
+function revokeToken (token: TokenInfo) {
return db.OAuthToken.getByRefreshTokenAndPopulateUser(token.refreshToken).then(function (tokenDB) {
if (tokenDB) tokenDB.destroy()
})
}
-function saveToken (token, client, user) {
+function saveToken (token: TokenInfo, client: OAuthClientInstance, user: UserInstance) {
logger.debug('Saving token ' + token.accessToken + ' for client ' + client.id + ' and user ' + user.id + '.')
const tokenToCreate = {
import { database as db } from '../../initializers/database'
import { logger, makeSecureRequest } from '../../helpers'
+import { PodInstance } from '../../models'
import {
API_VERSION,
REQUESTS_IN_PARALLEL,
} from '../../initializers'
abstract class BaseRequestScheduler {
+ requestInterval: number
+ limitPods: number
+ limitPerPod: number
+
protected lastRequestTimestamp: number
protected timer: NodeJS.Timer
- protected requestInterval: number
- protected limitPods: number
- protected limitPerPod: number
protected description: string
constructor () {
return REQUESTS_INTERVAL - (Date.now() - this.lastRequestTimestamp)
}
- remainingRequestsCount (callback) {
+ remainingRequestsCount (callback: (err: Error, total: number) => void) {
return this.getRequestModel().countTotalRequests(callback)
}
- flush (callback) {
+ flush (callback: (err: Error) => void) {
this.getRequestModel().removeAll(callback)
}
// ---------------------------------------------------------------------------
// Make a requests to friends of a certain type
- protected makeRequest (toPod, requestEndpoint, requestsToMake, callback) {
+ protected makeRequest (toPod: PodInstance, requestEndpoint: string, requestsToMake: Object, callback) {
if (!callback) callback = function () { /* empty */ }
const params = {
toPod: toPod,
sign: true, // Prove our identity
- method: 'POST',
+ method: 'POST' as 'POST',
path: '/api/' + API_VERSION + '/remote/' + requestEndpoint,
data: requestsToMake // Requests we need to make
}
+export * from './base-request-scheduler'
export * from './request-scheduler'
export * from './request-video-event-scheduler'
export * from './request-video-qadu-scheduler'
+import * as Sequelize from 'sequelize'
+
import { database as db } from '../../initializers/database'
import { BaseRequestScheduler } from './base-request-scheduler'
import { logger } from '../../helpers'
REQUESTS_LIMIT_PER_POD
} from '../../initializers'
+export type RequestSchedulerOptions = {
+ type: string
+ endpoint: string
+ data: Object
+ toIds: number[]
+ transaction: Sequelize.Transaction
+}
+
class RequestScheduler extends BaseRequestScheduler {
constructor () {
super()
return db.RequestToPod
}
- buildRequestObjects (requests) {
+ buildRequestObjects (requests: { [ toPodId: number ]: any }) {
const requestsToMakeGrouped = {}
Object.keys(requests).forEach(toPodId => {
return requestsToMakeGrouped
}
- // { type, endpoint, data, toIds, transaction }
- createRequest (options, callback) {
- const type = options.type
- const endpoint = options.endpoint
- const data = options.data
- const toIds = options.toIds
- const transaction = options.transaction
-
+ createRequest ({ type, endpoint, data, toIds, transaction }: RequestSchedulerOptions, callback: (err: Error) => void) {
// TODO: check the setPods works
const podIds = []
}
}
- const dbRequestOptions = {
+ const dbRequestOptions: Sequelize.CreateOptions = {
transaction
}
+import * as Sequelize from 'sequelize'
+
import { database as db } from '../../initializers/database'
import { BaseRequestScheduler } from './base-request-scheduler'
import {
REQUEST_VIDEO_EVENT_ENDPOINT
} from '../../initializers'
+export type RequestVideoEventSchedulerOptions = {
+ type: string
+ videoId: string
+ count?: number
+ transaction?: Sequelize.Transaction
+}
+
class RequestVideoEventScheduler extends BaseRequestScheduler {
constructor () {
super()
return db.RequestVideoEvent
}
- buildRequestObjects (eventsToProcess) {
+ buildRequestObjects (eventsToProcess: { [ toPodId: number ]: any }[]) {
const requestsToMakeGrouped = {}
/* Example:
return requestsToMakeGrouped
}
- // { type, videoId, count?, transaction? }
- createRequest (options, callback) {
- const type = options.type
- const videoId = options.videoId
- const transaction = options.transaction
- let count = options.count
-
+ createRequest ({ type, videoId, count, transaction }: RequestVideoEventSchedulerOptions, callback: (err: Error) => void) {
if (count === undefined) count = 1
- const dbRequestOptions: { transaction?: any } = {}
+ const dbRequestOptions: Sequelize.CreateOptions = {}
if (transaction) dbRequestOptions.transaction = transaction
const createQuery = {
+import * as Sequelize from 'sequelize'
+
import { database as db } from '../../initializers/database'
import { BaseRequestScheduler } from './base-request-scheduler'
import { logger } from '../../helpers'
REQUEST_VIDEO_QADU_TYPES
} from '../../initializers'
+export type RequestVideoQaduSchedulerOptions = {
+ type: string
+ videoId: string
+ transaction?: Sequelize.Transaction
+}
+
class RequestVideoQaduScheduler extends BaseRequestScheduler {
constructor () {
super()
return db.RequestVideoQadu
}
- buildRequestObjects (requests) {
+ buildRequestObjects (requests: { [ toPodId: number ]: any }[]) {
const requestsToMakeGrouped = {}
Object.keys(requests).forEach(toPodId => {
return requestsToMakeGrouped
}
- // { type, videoId, transaction? }
- createRequest (options, callback) {
- const type = options.type
- const videoId = options.videoId
- const transaction = options.transaction
-
- const dbRequestOptions: { transaction?: any } = {}
+ createRequest ({ type, videoId, transaction }: RequestVideoQaduSchedulerOptions, callback: (err: Error) => void) {
+ const dbRequestOptions: Sequelize.BulkCreateOptions = {}
if (transaction) dbRequestOptions.transaction = transaction
// Send the update to all our friends
- db.Pod.listAllIds(options.transaction, function (err, podIds) {
+ db.Pod.listAllIds(transaction, function (err, podIds) {
if (err) return callback(err)
const queries = []
+import 'express-validator'
+import * as express from 'express'
+
import { logger } from '../helpers'
-function ensureIsAdmin (req, res, next) {
+function ensureIsAdmin (req: express.Request, res: express.Response, next: express.NextFunction) {
const user = res.locals.oauth.token.user
if (user.isAdmin() === false) {
logger.info('A non admin user is trying to access to an admin content.')
-export * from './validators';
-export * from './admin';
-export * from './oauth';
-export * from './pagination';
-export * from './pods';
-export * from './search';
-export * from './secure';
-export * from './sort';
+export * from './validators'
+export * from './admin'
+export * from './oauth'
+export * from './pagination'
+export * from './pods'
+export * from './search'
+export * from './secure'
+export * from './sort'
+import 'express-validator'
+import * as express from 'express'
import * as OAuthServer from 'express-oauth-server'
import { OAUTH_LIFETIME } from '../initializers'
model: require('../lib/oauth-model')
})
-function authenticate (req, res, next) {
+function authenticate (req: express.Request, res: express.Response, next: express.NextFunction) {
oAuthServer.authenticate()(req, res, function (err) {
if (err) {
logger.error('Cannot authenticate.', { error: err })
})
}
-function token (req, res, next) {
+function token (req: express.Request, res: express.Response, next: express.NextFunction) {
return oAuthServer.token()(req, res, next)
}
+import 'express-validator'
+import * as express from 'express'
+
import { PAGINATION_COUNT_DEFAULT } from '../initializers'
-function setPagination (req, res, next) {
+function setPagination (req: express.Request, res: express.Response, next: express.NextFunction) {
if (!req.query.start) req.query.start = 0
else req.query.start = parseInt(req.query.start, 10)
+import 'express-validator'
+import * as express from 'express'
+
import { REMOTE_SCHEME } from '../initializers'
-function setBodyHostsPort (req, res, next) {
+function setBodyHostsPort (req: express.Request, res: express.Response, next: express.NextFunction) {
if (!req.body.hosts) return next()
for (let i = 0; i < req.body.hosts.length; i++) {
return next()
}
-function setBodyHostPort (req, res, next) {
+function setBodyHostPort (req: express.Request, res: express.Response, next: express.NextFunction) {
if (!req.body.host) return next()
const hostWithPort = getHostWithPort(req.body.host)
// ---------------------------------------------------------------------------
-function getHostWithPort (host) {
+function getHostWithPort (host: string) {
const splitted = host.split(':')
// The port was not specified
-function setVideosSearch (req, res, next) {
+import 'express-validator'
+import * as express from 'express'
+
+function setVideosSearch (req: express.Request, res: express.Response, next: express.NextFunction) {
if (!req.query.field) req.query.field = 'name'
return next()
+import 'express-validator'
+import * as express from 'express'
+
import { database as db } from '../initializers'
import {
logger,
checkSignature as peertubeCryptoCheckSignature
} from '../helpers'
-function checkSignature (req, res, next) {
+function checkSignature (req: express.Request, res: express.Response, next: express.NextFunction) {
const host = req.body.signature.host
db.Pod.loadByHost(host, function (err, pod) {
if (err) {
-function setUsersSort (req, res, next) {
+import 'express-validator'
+import * as express from 'express'
+
+function setUsersSort (req: express.Request, res: express.Response, next: express.NextFunction) {
if (!req.query.sort) req.query.sort = '-createdAt'
return next()
}
-function setVideoAbusesSort (req, res, next) {
+function setVideoAbusesSort (req: express.Request, res: express.Response, next: express.NextFunction) {
if (!req.query.sort) req.query.sort = '-createdAt'
return next()
}
-function setVideosSort (req, res, next) {
+function setVideosSort (req: express.Request, res: express.Response, next: express.NextFunction) {
if (!req.query.sort) req.query.sort = '-createdAt'
return next()
+import 'express-validator'
+import * as express from 'express'
+
import { checkErrors } from './utils'
import { logger } from '../../helpers'
-function paginationValidator (req, res, next) {
+function paginationValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkQuery('start', 'Should have a number start').optional().isInt()
req.checkQuery('count', 'Should have a number count').optional().isInt()
+import 'express-validator'
+import * as express from 'express'
+
import { database as db } from '../../initializers/database'
import { checkErrors } from './utils'
import { logger } from '../../helpers'
import { hasFriends } from '../../lib'
import { isTestInstance } from '../../helpers'
-function makeFriendsValidator (req, res, next) {
+function makeFriendsValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
// Force https if the administrator wants to make friends
if (isTestInstance() === false && CONFIG.WEBSERVER.SCHEME === 'http') {
return res.status(400).send('Cannot make friends with a non HTTPS webserver.')
})
}
-function podsAddValidator (req, res, next) {
+function podsAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkBody('host', 'Should have a host').isHostValid()
req.checkBody('email', 'Should have an email').isEmail()
req.checkBody('publicKey', 'Should have a public key').notEmpty()
+import 'express-validator'
+import * as express from 'express'
+
import { logger } from '../../../helpers'
import { checkErrors } from '../utils'
-function signatureValidator (req, res, next) {
+function signatureValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkBody('signature.host', 'Should have a signature host').isURL()
req.checkBody('signature.signature', 'Should have a signature').notEmpty()
+import 'express-validator'
+import * as express from 'express'
+
import { logger } from '../../../helpers'
import { checkErrors } from '../utils'
-function remoteVideosValidator (req, res, next) {
+function remoteVideosValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkBody('data').isEachRemoteRequestVideosValid()
logger.debug('Checking remoteVideos parameters', { parameters: req.body })
checkErrors(req, res, next)
}
-function remoteQaduVideosValidator (req, res, next) {
+function remoteQaduVideosValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkBody('data').isEachRemoteRequestVideosQaduValid()
logger.debug('Checking remoteQaduVideos parameters', { parameters: req.body })
checkErrors(req, res, next)
}
-function remoteEventsVideosValidator (req, res, next) {
+function remoteEventsVideosValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkBody('data').isEachRemoteRequestVideosEventsValid()
logger.debug('Checking remoteEventsVideos parameters', { parameters: req.body })
+import 'express-validator'
+import * as express from 'express'
+
import { checkErrors } from './utils'
import { logger } from '../../helpers'
import { SORTABLE_COLUMNS } from '../../initializers'
const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEO_ABUSES)
const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEOS)
-function usersSortValidator (req, res, next) {
+function usersSortValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
checkSort(req, res, next, SORTABLE_USERS_COLUMNS)
}
-function videoAbusesSortValidator (req, res, next) {
+function videoAbusesSortValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
checkSort(req, res, next, SORTABLE_VIDEO_ABUSES_COLUMNS)
}
-function videosSortValidator (req, res, next) {
+function videosSortValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
checkSort(req, res, next, SORTABLE_VIDEOS_COLUMNS)
}
// ---------------------------------------------------------------------------
-function checkSort (req, res, next, sortableColumns) {
+function checkSort (req: express.Request, res: express.Response, next: express.NextFunction, sortableColumns: string[]) {
req.checkQuery('sort', 'Should have correct sortable column').optional().isIn(sortableColumns)
logger.debug('Checking sort parameters', { parameters: req.query })
checkErrors(req, res, next)
}
-function createSortableColumns (sortableColumns) {
+function createSortableColumns (sortableColumns: string[]) {
const sortableColumnDesc = sortableColumns.map(sortableColumn => '-' + sortableColumn)
return sortableColumns.concat(sortableColumnDesc)
+import 'express-validator'
+import * as express from 'express'
+
import { database as db } from '../../initializers/database'
import { checkErrors } from './utils'
import { logger } from '../../helpers'
-function usersAddValidator (req, res, next) {
+function usersAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkBody('username', 'Should have a valid username').isUserUsernameValid()
req.checkBody('password', 'Should have a valid password').isUserPasswordValid()
req.checkBody('email', 'Should have a valid email').isEmail()
})
}
-function usersRemoveValidator (req, res, next) {
+function usersRemoveValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkParams('id', 'Should have a valid id').notEmpty().isInt()
logger.debug('Checking usersRemove parameters', { parameters: req.params })
})
}
-function usersUpdateValidator (req, res, next) {
+function usersUpdateValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkParams('id', 'Should have a valid id').notEmpty().isInt()
// Add old password verification
req.checkBody('password', 'Should have a valid password').optional().isUserPasswordValid()
checkErrors(req, res, next)
}
-function usersVideoRatingValidator (req, res, next) {
+function usersVideoRatingValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkParams('videoId', 'Should have a valid video id').notEmpty().isUUID(4)
logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
+import 'express-validator'
+import * as express from 'express'
import { inspect } from 'util'
import { logger } from '../../helpers'
-function checkErrors (req, res, next, statusCode?) {
- if (statusCode === undefined) statusCode = 400
+function checkErrors (req: express.Request, res: express.Response, next: express.NextFunction, statusCode = 400) {
const errors = req.validationErrors()
if (errors) {
+import 'express-validator'
+import * as multer from 'multer'
+import * as express from 'express'
+
import { database as db } from '../../initializers/database'
import { checkErrors } from './utils'
import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers'
import { logger, isVideoDurationValid } from '../../helpers'
-function videosAddValidator (req, res, next) {
+function videosAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkBody('videofile', 'Should have a valid file').isVideoFile(req.files)
req.checkBody('name', 'Should have a valid name').isVideoNameValid()
req.checkBody('category', 'Should have a valid category').isVideoCategoryValid()
return res.status(400).send('Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).')
}
- videoFile.duration = duration
+ videoFile['duration'] = duration
next()
})
})
}
-function videosUpdateValidator (req, res, next) {
+function videosUpdateValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid()
req.checkBody('category', 'Should have a valid category').optional().isVideoCategoryValid()
})
}
-function videosGetValidator (req, res, next) {
+function videosGetValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
logger.debug('Checking videosGet parameters', { parameters: req.params })
})
}
-function videosRemoveValidator (req, res, next) {
+function videosRemoveValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
logger.debug('Checking videosRemove parameters', { parameters: req.params })
})
}
-function videosSearchValidator (req, res, next) {
+function videosSearchValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
const searchableColumns = SEARCHABLE_COLUMNS.VIDEOS
req.checkParams('value', 'Should have a valid search').notEmpty()
req.checkQuery('field', 'Should have correct searchable column').optional().isIn(searchableColumns)
checkErrors(req, res, next)
}
-function videoAbuseReportValidator (req, res, next) {
+function videoAbuseReportValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
req.checkBody('reason', 'Should have a valid reason').isVideoAbuseReasonValid()
})
}
-function videoRateValidator (req, res, next) {
+function videoRateValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
req.checkBody('rating', 'Should have a valid rate type').isVideoRatingTypeValid()
})
}
-function videosBlacklistValidator (req, res, next) {
+function videosBlacklistValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
logger.debug('Checking videosBlacklist parameters', { parameters: req.params })
// ---------------------------------------------------------------------------
-function checkVideoExists (id, res, callback) {
+function checkVideoExists (id: string, res: express.Response, callback: () => void) {
db.Video.loadAndPopulateAuthorAndPodAndTags(id, function (err, video) {
if (err) {
logger.error('Error in video request validator.', { error: err })
})
}
-function checkUserCanDeleteVideo (userId, res, callback) {
+function checkUserCanDeleteVideo (userId: number, res: express.Response, callback: () => void) {
// Retrieve the user who did the request
db.User.loadById(userId, function (err, user) {
if (err) {
})
}
-function checkVideoIsBlacklistable (req, res, callback) {
+function checkVideoIsBlacklistable (req: express.Request, res: express.Response, callback: () => void) {
if (res.locals.video.isOwned() === true) {
return res.status(403).send('Cannot blacklist a local video')
}
import * as Sequelize from 'sequelize'
export namespace ApplicationMethods {
- export type LoadMigrationVersion = (callback: (err: Error, version: number) => void) => void
- export type UpdateMigrationVersion = (newVersion: number, transaction: any, callback: any) => void
+ export type LoadMigrationVersionCallback = (err: Error, version: number) => void
+ export type LoadMigrationVersion = (callback: LoadMigrationVersionCallback) => void
+
+ export type UpdateMigrationVersionCallback = (err: Error, applicationInstance: ApplicationAttributes) => void
+ export type UpdateMigrationVersion = (newVersion: number, transaction: Sequelize.Transaction, callback: UpdateMigrationVersionCallback) => void
}
export interface ApplicationClass {
// ---------------------------------------------------------------------------
-loadMigrationVersion = function (callback: (err: Error, version: number) => void) {
+loadMigrationVersion = function (callback: ApplicationMethods.LoadMigrationVersionCallback) {
const query = {
attributes: [ 'migrationVersion' ]
}
})
}
-updateMigrationVersion = function (newVersion: number, transaction: any, callback: any) {
+updateMigrationVersion = function (newVersion: number, transaction: Sequelize.Transaction, callback: ApplicationMethods.UpdateMigrationVersionCallback) {
const options: Sequelize.UpdateOptions = {
- where: {}
- }
-
- if (!callback) {
- transaction = callback
- } else {
- options.transaction = transaction
+ where: {},
+ transaction: transaction
}
return Application.update({ migrationVersion: newVersion }, options).asCallback(callback)
import * as Sequelize from 'sequelize'
+import { PodInstance } from './pod-interface'
+
export namespace AuthorMethods {
- export type FindOrCreateAuthor = (name, podId, userId, transaction, callback) => void
+ export type FindOrCreateAuthorCallback = (err: Error, authorInstance?: AuthorInstance) => void
+ export type FindOrCreateAuthor = (name: string, podId: number, userId: number, transaction: Sequelize.Transaction, callback: FindOrCreateAuthorCallback) => void
}
export interface AuthorClass {
id: number
createdAt: Date
updatedAt: Date
+
+ podId: number
+ Pod: PodInstance
}
export interface AuthorModel extends AuthorClass, Sequelize.Model<AuthorInstance, AuthorAttributes> {}
})
}
-findOrCreateAuthor = function (name, podId, userId, transaction, callback) {
- if (!callback) {
- callback = transaction
- transaction = null
- }
-
+findOrCreateAuthor = function (
+ name: string,
+ podId: number,
+ userId: number,
+ transaction: Sequelize.Transaction,
+ callback: AuthorMethods.FindOrCreateAuthorCallback
+) {
const author = {
name,
podId,
defaults: author
}
- if (transaction) query.transaction = transaction
+ if (transaction !== null) query.transaction = transaction
Author.findOrCreate(query).asCallback(function (err, result) {
if (err) return callback(err)
import * as Sequelize from 'sequelize'
export namespace JobMethods {
- export type ListWithLimit = (limit, state, callback) => void
+ export type ListWithLimitCallback = (err: Error, jobInstances: JobInstance[]) => void
+ export type ListWithLimit = (limit: number, state: string, callback: ListWithLimitCallback) => void
}
export interface JobClass {
// ---------------------------------------------------------------------------
-listWithLimit = function (limit, state, callback) {
+listWithLimit = function (limit: number, state: string, callback: JobMethods.ListWithLimitCallback) {
const query = {
order: [
[ 'id', 'ASC' ]
import * as Sequelize from 'sequelize'
export namespace OAuthClientMethods {
- export type CountTotal = (callback) => void
- export type LoadFirstClient = (callback) => void
+ export type CountTotalCallback = (err: Error, total: number) => void
+ export type CountTotal = (callback: CountTotalCallback) => void
+
+ export type LoadFirstClientCallback = (err: Error, client: OAuthClientInstance) => void
+ export type LoadFirstClient = (callback: LoadFirstClientCallback) => void
+
export type GetByIdAndSecret = (clientId, clientSecret) => void
}
})
}
-countTotal = function (callback) {
+countTotal = function (callback: OAuthClientMethods.CountTotalCallback) {
return OAuthClient.count().asCallback(callback)
}
-loadFirstClient = function (callback) {
+loadFirstClient = function (callback: OAuthClientMethods.LoadFirstClientCallback) {
return OAuthClient.findOne().asCallback(callback)
}
-getByIdAndSecret = function (clientId, clientSecret) {
+getByIdAndSecret = function (clientId: string, clientSecret: string) {
const query = {
where: {
clientId: clientId,
import * as Sequelize from 'sequelize'
+import * as Bluebird from 'bluebird'
import { UserModel } from './user-interface'
+export type OAuthTokenInfo = {
+ refreshToken: string
+ refreshTokenExpiresAt: Date,
+ client: {
+ id: number
+ },
+ user: {
+ id: number
+ }
+}
+
export namespace OAuthTokenMethods {
- export type GetByRefreshTokenAndPopulateClient = (refreshToken) => void
- export type GetByTokenAndPopulateUser = (bearerToken) => void
- export type GetByRefreshTokenAndPopulateUser = (refreshToken) => any
+ export type GetByRefreshTokenAndPopulateClient = (refreshToken: string) => Bluebird<OAuthTokenInfo>
+ export type GetByTokenAndPopulateUser = (bearerToken: string) => Bluebird<OAuthTokenInstance>
+ export type GetByRefreshTokenAndPopulateUser = (refreshToken: string) => Bluebird<OAuthTokenInstance>
+
+ export type RemoveByUserIdCallback = (err: Error) => void
export type RemoveByUserId = (userId, callback) => void
}
OAuthTokenInstance,
OAuthTokenAttributes,
- OAuthTokenMethods
+ OAuthTokenMethods,
+ OAuthTokenInfo
} from './oauth-token-interface'
let OAuthToken: Sequelize.Model<OAuthTokenInstance, OAuthTokenAttributes>
})
}
-getByRefreshTokenAndPopulateClient = function (refreshToken) {
+getByRefreshTokenAndPopulateClient = function (refreshToken: string) {
const query = {
where: {
refreshToken: refreshToken
}
return OAuthToken.findOne(query).then(function (token) {
- if (!token) return token
+ if (!token) return null
- const tokenInfos = {
+ const tokenInfos: OAuthTokenInfo = {
refreshToken: token.refreshToken,
refreshTokenExpiresAt: token.refreshTokenExpiresAt,
client: {
})
}
-getByTokenAndPopulateUser = function (bearerToken) {
+getByTokenAndPopulateUser = function (bearerToken: string) {
const query = {
where: {
accessToken: bearerToken
})
}
-getByRefreshTokenAndPopulateUser = function (refreshToken) {
+getByRefreshTokenAndPopulateUser = function (refreshToken: string) {
const query = {
where: {
refreshToken: refreshToken
import * as Sequelize from 'sequelize'
+// Don't use barrel, import just what we need
+import { Pod as FormatedPod } from '../../shared/models/pod.model'
+
export namespace PodMethods {
- export type ToFormatedJSON = () => void
+ export type ToFormatedJSON = () => FormatedPod
+ export type CountAllCallback = (err: Error, total: number) => void
export type CountAll = (callback) => void
- export type IncrementScores = (ids, value, callback) => void
- export type List = (callback) => void
- export type ListAllIds = (transaction, callback) => void
- export type ListRandomPodIdsWithRequest = (limit, tableWithPods, tableWithPodsJoins, callback) => void
- export type ListBadPods = (callback) => void
- export type Load = (id, callback) => void
- export type LoadByHost = (host, callback) => void
- export type RemoveAll = (callback) => void
- export type UpdatePodsScore = (goodPods, badPods) => void
+
+ export type IncrementScoresCallback = (err: Error) => void
+ export type IncrementScores = (ids: number[], value: number, callback?: IncrementScoresCallback) => void
+
+ export type ListCallback = (err: Error, podInstances?: PodInstance[]) => void
+ export type List = (callback: ListCallback) => void
+
+ export type ListAllIdsCallback = (err: Error, ids?: number[]) => void
+ export type ListAllIds = (transaction: Sequelize.Transaction, callback: ListAllIdsCallback) => void
+
+ export type ListRandomPodIdsWithRequestCallback = (err: Error, podInstanceIds?: number[]) => void
+ export type ListRandomPodIdsWithRequest = (limit: number, tableWithPods: string, tableWithPodsJoins: string, callback: ListRandomPodIdsWithRequestCallback) => void
+
+ export type ListBadPodsCallback = (err: Error, podInstances?: PodInstance[]) => void
+ export type ListBadPods = (callback: ListBadPodsCallback) => void
+
+ export type LoadCallback = (err: Error, podInstance: PodInstance) => void
+ export type Load = (id: number, callback: LoadCallback) => void
+
+ export type LoadByHostCallback = (err: Error, podInstance: PodInstance) => void
+ export type LoadByHost = (host: string, callback: LoadByHostCallback) => void
+
+ export type RemoveAllCallback = (err: Error) => void
+ export type RemoveAll = (callback: RemoveAllCallback) => void
+
+ export type UpdatePodsScore = (goodPods: number[], badPods: number[]) => void
}
export interface PodClass {
})
}
-countAll = function (callback) {
+countAll = function (callback: PodMethods.CountAllCallback) {
return Pod.count().asCallback(callback)
}
-incrementScores = function (ids, value, callback) {
+incrementScores = function (ids: number[], value: number, callback?: PodMethods.IncrementScoresCallback) {
if (!callback) callback = function () { /* empty */ }
const update = {
return Pod.update(update, options).asCallback(callback)
}
-list = function (callback) {
+list = function (callback: PodMethods.ListCallback) {
return Pod.findAll().asCallback(callback)
}
-listAllIds = function (transaction, callback) {
- if (!callback) {
- callback = transaction
- transaction = null
- }
-
+listAllIds = function (transaction: Sequelize.Transaction, callback: PodMethods.ListAllIdsCallback) {
const query: any = {
attributes: [ 'id' ]
}
- if (transaction) query.transaction = transaction
+ if (transaction !== null) query.transaction = transaction
- return Pod.findAll(query).asCallback(function (err, pods) {
+ return Pod.findAll(query).asCallback(function (err: Error, pods) {
if (err) return callback(err)
return callback(null, map(pods, 'id'))
})
}
-listRandomPodIdsWithRequest = function (limit, tableWithPods, tableWithPodsJoins, callback) {
- if (!callback) {
- callback = tableWithPodsJoins
- tableWithPodsJoins = ''
- }
-
+listRandomPodIdsWithRequest = function (limit: number, tableWithPods: string, tableWithPodsJoins: string, callback: PodMethods.ListRandomPodIdsWithRequestCallback) {
Pod.count().asCallback(function (err, count) {
if (err) return callback(err)
})
}
-listBadPods = function (callback) {
+listBadPods = function (callback: PodMethods.ListBadPodsCallback) {
const query = {
where: {
score: { $lte: 0 }
return Pod.findAll(query).asCallback(callback)
}
-load = function (id, callback) {
+load = function (id: number, callback: PodMethods.LoadCallback) {
return Pod.findById(id).asCallback(callback)
}
-loadByHost = function (host, callback) {
+loadByHost = function (host: string, callback: PodMethods.LoadByHostCallback) {
const query = {
where: {
host: host
return Pod.findOne(query).asCallback(callback)
}
-removeAll = function (callback) {
+removeAll = function (callback: PodMethods.RemoveAllCallback) {
return Pod.destroy().asCallback(callback)
}
-updatePodsScore = function (goodPods, badPods) {
+updatePodsScore = function (goodPods: number[], badPods: number[]) {
logger.info('Updating %d good pods and %d bad pods scores.', goodPods.length, badPods.length)
if (goodPods.length !== 0) {
import * as Sequelize from 'sequelize'
-import { PodAttributes } from './pod-interface'
+import { PodInstance, PodAttributes } from './pod-interface'
+
+export type RequestsGrouped = {
+ [ podId: number ]: {
+ request: RequestInstance,
+ pod: PodInstance
+ }[]
+}
export namespace RequestMethods {
- export type CountTotalRequests = (callback) => void
- export type ListWithLimitAndRandom = (limitPods, limitRequestsPerPod, callback) => void
- export type RemoveWithEmptyTo = (callback) => void
- export type RemoveAll = (callback) => void
+ export type CountTotalRequestsCallback = (err: Error, total: number) => void
+ export type CountTotalRequests = (callback: CountTotalRequestsCallback) => void
+
+ export type ListWithLimitAndRandomCallback = (err: Error, requestsGrouped?: RequestsGrouped) => void
+ export type ListWithLimitAndRandom = (limitPods, limitRequestsPerPod, callback: ListWithLimitAndRandomCallback) => void
+
+ export type RemoveWithEmptyToCallback = (err: Error) => void
+ export type RemoveWithEmptyTo = (callback: RemoveWithEmptyToCallback) => void
+
+ export type RemoveAllCallback = (err: Error) => void
+ export type RemoveAll = (callback: RemoveAllCallback) => void
}
export interface RequestClass {
endpoint: string
}
-export interface RequestInstance extends Sequelize.Instance<RequestAttributes> {
+export interface RequestInstance extends RequestClass, RequestAttributes, Sequelize.Instance<RequestAttributes> {
id: number
createdAt: Date
updatedAt: Date
setPods: Sequelize.HasManySetAssociationsMixin<PodAttributes, number>
+ Pods: PodInstance[]
}
export interface RequestModel extends RequestClass, Sequelize.Model<RequestInstance, RequestAttributes> {}
import * as Sequelize from 'sequelize'
export namespace RequestToPodMethods {
- export type RemoveByRequestIdsAndPod = (requestsIds, podId, callback) => void
+ export type RemoveByRequestIdsAndPodCallback = (err: Error) => void
+ export type RemoveByRequestIdsAndPod = (requestsIds: number[], podId: number, callback?: RemoveByRequestIdsAndPodCallback) => void
}
export interface RequestToPodClass {
export interface RequestToPodAttributes {
}
-export interface RequestToPodInstance extends Sequelize.Instance<RequestToPodAttributes> {
+export interface RequestToPodInstance extends RequestToPodClass, RequestToPodAttributes, Sequelize.Instance<RequestToPodAttributes> {
id: number
createdAt: Date
updatedAt: Date
// ---------------------------------------------------------------------------
-removeByRequestIdsAndPod = function (requestsIds, podId, callback) {
+removeByRequestIdsAndPod = function (requestsIds: number[], podId: number, callback?: RequestToPodMethods.RemoveByRequestIdsAndPodCallback) {
if (!callback) callback = function () { /* empty */ }
const query = {
import * as Sequelize from 'sequelize'
+import { VideoInstance } from './video-interface'
+import { PodInstance } from './pod-interface'
+
+export type RequestsVideoEventGrouped = {
+ [ podId: number ]: {
+ id: number
+ type: string
+ count: number
+ video: VideoInstance
+ pod: PodInstance
+ }[]
+}
+
export namespace RequestVideoEventMethods {
- export type CountTotalRequests = (callback) => void
- export type ListWithLimitAndRandom = (limitPods, limitRequestsPerPod, callback) => void
- export type RemoveByRequestIdsAndPod = (ids, podId, callback) => void
- export type RemoveAll = (callback) => void
+ export type CountTotalRequestsCallback = (err: Error, total: number) => void
+ export type CountTotalRequests = (callback: CountTotalRequestsCallback) => void
+
+ export type ListWithLimitAndRandomCallback = (err: Error, requestsGrouped?: RequestsVideoEventGrouped) => void
+ export type ListWithLimitAndRandom = (limitPods: number, limitRequestsPerPod: number, callback: ListWithLimitAndRandomCallback) => void
+
+ export type RemoveByRequestIdsAndPodCallback = () => void
+ export type RemoveByRequestIdsAndPod = (ids: number[], podId: number, callback: RemoveByRequestIdsAndPodCallback) => void
+
+ export type RemoveAllCallback = () => void
+ export type RemoveAll = (callback: RemoveAllCallback) => void
}
export interface RequestVideoEventClass {
count: number
}
-export interface RequestVideoEventInstance extends Sequelize.Instance<RequestVideoEventAttributes> {
+export interface RequestVideoEventInstance extends RequestVideoEventClass, RequestVideoEventAttributes, Sequelize.Instance<RequestVideoEventAttributes> {
id: number
+
+ Video: VideoInstance
}
export interface RequestVideoEventModel extends RequestVideoEventClass, Sequelize.Model<RequestVideoEventInstance, RequestVideoEventAttributes> {}
import { values } from 'lodash'
import * as Sequelize from 'sequelize'
+import { database as db } from '../initializers/database'
import { REQUEST_VIDEO_EVENT_TYPES } from '../initializers'
import { isVideoEventCountValid } from '../helpers'
-
import { addMethodsToModel } from './utils'
import {
RequestVideoEventClass,
RequestVideoEventInstance,
RequestVideoEventAttributes,
- RequestVideoEventMethods
+ RequestVideoEventMethods,
+ RequestsVideoEventGrouped
} from './request-video-event-interface'
let RequestVideoEvent: Sequelize.Model<RequestVideoEventInstance, RequestVideoEventAttributes>
})
}
-countTotalRequests = function (callback) {
+countTotalRequests = function (callback: RequestVideoEventMethods.CountTotalRequestsCallback) {
const query = {}
return RequestVideoEvent.count(query).asCallback(callback)
}
-listWithLimitAndRandom = function (limitPods, limitRequestsPerPod, callback) {
- const Pod = RequestVideoEvent['sequelize'].models.Pod
+listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number, callback: RequestVideoEventMethods.ListWithLimitAndRandomCallback) {
+ const Pod = db.Pod
// We make a join between videos and authors to find the podId of our video event requests
const podJoins = 'INNER JOIN "Videos" ON "Videos"."authorId" = "Authors"."id" ' +
})
}
-removeByRequestIdsAndPod = function (ids, podId, callback) {
+removeByRequestIdsAndPod = function (ids: number[], podId: number, callback: RequestVideoEventMethods.RemoveByRequestIdsAndPodCallback) {
const query = {
where: {
id: {
RequestVideoEvent.destroy(query).asCallback(callback)
}
-removeAll = function (callback) {
+removeAll = function (callback: RequestVideoEventMethods.RemoveAllCallback) {
// Delete all requests
RequestVideoEvent.truncate({ cascade: true }).asCallback(callback)
}
// ---------------------------------------------------------------------------
-function groupAndTruncateRequests (events, limitRequestsPerPod) {
- const eventsGrouped = {}
+function groupAndTruncateRequests (events: RequestVideoEventInstance[], limitRequestsPerPod: number) {
+ const eventsGrouped: RequestsVideoEventGrouped = {}
events.forEach(function (event) {
const pod = event.Video.Author.Pod
import * as Sequelize from 'sequelize'
+import { VideoInstance } from './video-interface'
+import { PodInstance } from './pod-interface'
+
+export type RequestsVideoQaduGrouped = {
+ [ podId: number ]: {
+ request: RequestVideoQaduInstance
+ video: VideoInstance
+ pod: PodInstance
+ }
+}
+
export namespace RequestVideoQaduMethods {
- export type CountTotalRequests = (callback) => void
- export type ListWithLimitAndRandom = (limitPods, limitRequestsPerPod, callback) => void
- export type RemoveByRequestIdsAndPod = (ids, podId, callback) => void
- export type RemoveAll = (callback) => void
+ export type CountTotalRequestsCallback = (err: Error, total: number) => void
+ export type CountTotalRequests = (callback: CountTotalRequestsCallback) => void
+
+ export type ListWithLimitAndRandomCallback = (err: Error, requestsGrouped?: RequestsVideoQaduGrouped) => void
+ export type ListWithLimitAndRandom = (limitPods: number, limitRequestsPerPod: number, callback: ListWithLimitAndRandomCallback) => void
+
+ export type RemoveByRequestIdsAndPodCallback = () => void
+ export type RemoveByRequestIdsAndPod = (ids: number[], podId: number, callback: RemoveByRequestIdsAndPodCallback) => void
+
+ export type RemoveAllCallback = () => void
+ export type RemoveAll = (callback: RemoveAllCallback) => void
}
export interface RequestVideoQaduClass {
type: string
}
-export interface RequestVideoQaduInstance extends Sequelize.Instance<RequestVideoQaduAttributes> {
+export interface RequestVideoQaduInstance extends RequestVideoQaduClass, RequestVideoQaduAttributes, Sequelize.Instance<RequestVideoQaduAttributes> {
id: number
+
+ Pod: PodInstance
+ Video: VideoInstance
}
export interface RequestVideoQaduModel extends RequestVideoQaduClass, Sequelize.Model<RequestVideoQaduInstance, RequestVideoQaduAttributes> {}
import { values } from 'lodash'
import * as Sequelize from 'sequelize'
+import { database as db } from '../initializers/database'
import { REQUEST_VIDEO_QADU_TYPES } from '../initializers'
-
import { addMethodsToModel } from './utils'
import {
RequestVideoQaduClass,
})
}
-countTotalRequests = function (callback) {
+countTotalRequests = function (callback: RequestVideoQaduMethods.CountTotalRequestsCallback) {
const query = {}
return RequestVideoQadu.count(query).asCallback(callback)
}
-listWithLimitAndRandom = function (limitPods, limitRequestsPerPod, callback) {
- const Pod = RequestVideoQadu['sequelize'].models.Pod
+listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number, callback: RequestVideoQaduMethods.ListWithLimitAndRandomCallback) {
+ const Pod = db.Pod
+ const tableJoin = ''
- Pod.listRandomPodIdsWithRequest(limitPods, 'RequestVideoQadus', function (err, podIds) {
+ Pod.listRandomPodIdsWithRequest(limitPods, 'RequestVideoQadus', tableJoin, function (err, podIds) {
if (err) return callback(err)
// We don't have friends that have requests
})
}
-removeByRequestIdsAndPod = function (ids, podId, callback) {
+removeByRequestIdsAndPod = function (ids: number[], podId: number, callback: RequestVideoQaduMethods.RemoveByRequestIdsAndPodCallback) {
const query = {
where: {
id: {
RequestVideoQadu.destroy(query).asCallback(callback)
}
-removeAll = function (callback) {
+removeAll = function (callback: RequestVideoQaduMethods.RemoveAllCallback) {
// Delete all requests
RequestVideoQadu.truncate({ cascade: true }).asCallback(callback)
}
// ---------------------------------------------------------------------------
-function groupAndTruncateRequests (requests, limitRequestsPerPod) {
+function groupAndTruncateRequests (requests: RequestVideoQaduInstance[], limitRequestsPerPod: number) {
const requestsGrouped = {}
requests.forEach(function (request) {
import { values } from 'lodash'
import * as Sequelize from 'sequelize'
+import { database as db } from '../initializers/database'
import { REQUEST_ENDPOINTS } from '../initializers'
-
import { addMethodsToModel } from './utils'
import {
RequestClass,
RequestInstance,
RequestAttributes,
- RequestMethods
+ RequestMethods,
+ RequestsGrouped
} from './request-interface'
let Request: Sequelize.Model<RequestInstance, RequestAttributes>
})
}
-countTotalRequests = function (callback) {
+countTotalRequests = function (callback: RequestMethods.CountTotalRequestsCallback) {
// We need to include Pod because there are no cascade delete when a pod is removed
// So we could count requests that do not have existing pod anymore
const query = {
return Request.count(query).asCallback(callback)
}
-listWithLimitAndRandom = function (limitPods, limitRequestsPerPod, callback) {
- const Pod = Request['sequelize'].models.Pod
+listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number, callback: RequestMethods.ListWithLimitAndRandomCallback) {
+ const Pod = db.Pod
+ const tableJoin = ''
- Pod.listRandomPodIdsWithRequest(limitPods, 'RequestToPods', function (err, podIds) {
+ Pod.listRandomPodIdsWithRequest(limitPods, 'RequestToPods', '', function (err, podIds) {
if (err) return callback(err)
// We don't have friends that have requests
})
}
-removeAll = function (callback) {
+removeAll = function (callback: RequestMethods.RemoveAllCallback) {
// Delete all requests
Request.truncate({ cascade: true }).asCallback(callback)
}
-removeWithEmptyTo = function (callback) {
+removeWithEmptyTo = function (callback?: RequestMethods.RemoveWithEmptyToCallback) {
if (!callback) callback = function () { /* empty */ }
const query = {
// ---------------------------------------------------------------------------
-function groupAndTruncateRequests (requests, limitRequestsPerPod) {
- const requestsGrouped = {}
+function groupAndTruncateRequests (requests: RequestInstance[], limitRequestsPerPod: number) {
+ const requestsGrouped: RequestsGrouped = {}
requests.forEach(function (request) {
request.Pods.forEach(function (pod) {
import * as Sequelize from 'sequelize'
export namespace TagMethods {
- export type FindOrCreateTags = (tags, transaction, callback) => void
+ export type FindOrCreateTagsCallback = (err: Error, tagInstances: TagInstance[]) => void
+ export type FindOrCreateTags = (tags: string[], transaction: Sequelize.Transaction, callback: FindOrCreateTagsCallback) => void
}
export interface TagClass {
})
}
-findOrCreateTags = function (tags, transaction, callback) {
- if (!callback) {
- callback = transaction
- transaction = null
- }
-
+findOrCreateTags = function (tags: string[], transaction: Sequelize.Transaction, callback: TagMethods.FindOrCreateTagsCallback) {
const tagInstances = []
- each(tags, function (tag, callbackEach) {
+ each<string, Error>(tags, function (tag, callbackEach) {
const query: any = {
where: {
name: tag
import * as Sequelize from 'sequelize'
+import * as Bluebird from 'bluebird'
+
+// Don't use barrel, import just what we need
+import { User as FormatedUser } from '../../shared/models/user.model'
export namespace UserMethods {
- export type IsPasswordMatch = (password, callback) => void
- export type ToFormatedJSON = () => void
+ export type IsPasswordMatchCallback = (err: Error, same: boolean) => void
+ export type IsPasswordMatch = (password: string, callback: IsPasswordMatchCallback) => void
+
+ export type ToFormatedJSON = () => FormatedUser
export type IsAdmin = () => boolean
- export type CountTotal = (callback) => void
- export type GetByUsername = (username) => any
- export type List = (callback) => void
- export type ListForApi = (start, count, sort, callback) => void
- export type LoadById = (id, callback) => void
- export type LoadByUsername = (username, callback) => void
- export type LoadByUsernameOrEmail = (username, email, callback) => void
+ export type CountTotalCallback = (err: Error, total: number) => void
+ export type CountTotal = (callback: CountTotalCallback) => void
+
+ export type GetByUsername = (username: string) => Bluebird<UserInstance>
+
+ export type ListCallback = (err: Error, userInstances: UserInstance[]) => void
+ export type List = (callback: ListCallback) => void
+
+ export type ListForApiCallback = (err: Error, userInstances?: UserInstance[], total?: number) => void
+ export type ListForApi = (start: number, count: number, sort: string, callback: ListForApiCallback) => void
+
+ export type LoadByIdCallback = (err: Error, userInstance: UserInstance) => void
+ export type LoadById = (id: number, callback: LoadByIdCallback) => void
+
+ export type LoadByUsernameCallback = (err: Error, userInstance: UserInstance) => void
+ export type LoadByUsername = (username: string, callback: LoadByUsernameCallback) => void
+
+ export type LoadByUsernameOrEmailCallback = (err: Error, userInstance: UserInstance) => void
+ export type LoadByUsernameOrEmail = (username: string, email: string, callback: LoadByUsernameOrEmailCallback) => void
}
export interface UserClass {
import * as Sequelize from 'sequelize'
export namespace UserVideoRateMethods {
+ export type LoadCallback = (err: Error, userVideoRateInstance: UserVideoRateInstance) => void
export type Load = (userId, videoId, transaction, callback) => void
}
type: string
}
-export interface UserVideoRateInstance extends Sequelize.Instance<UserVideoRateAttributes> {
+export interface UserVideoRateInstance extends UserVideoRateClass, UserVideoRateAttributes, Sequelize.Instance<UserVideoRateAttributes> {
id: number
createdAt: Date
updatedAt: Date
})
}
-load = function (userId, videoId, transaction, callback) {
+load = function (userId: number, videoId: number, transaction: Sequelize.Transaction, callback: UserVideoRateMethods.LoadCallback) {
const options: Sequelize.FindOptions = {
where: {
userId,
return User
}
-function beforeCreateOrUpdate (user, options) {
+function beforeCreateOrUpdate (user: UserInstance) {
return new Promise(function (resolve, reject) {
cryptPassword(user.password, function (err, hash) {
if (err) return reject(err)
// ------------------------------ METHODS ------------------------------
-isPasswordMatch = function (password, callback) {
+isPasswordMatch = function (password: string, callback: UserMethods.IsPasswordMatchCallback) {
return comparePassword(password, this.password, callback)
}
})
}
-countTotal = function (callback) {
+countTotal = function (callback: UserMethods.CountTotalCallback) {
return this.count().asCallback(callback)
}
-getByUsername = function (username) {
+getByUsername = function (username: string) {
const query = {
where: {
username: username
return User.findOne(query)
}
-list = function (callback) {
+list = function (callback: UserMethods.ListCallback) {
return User.find().asCallback(callback)
}
-listForApi = function (start, count, sort, callback) {
+listForApi = function (start: number, count: number, sort: string, callback: UserMethods.ListForApiCallback) {
const query = {
offset: start,
limit: count,
})
}
-loadById = function (id, callback) {
+loadById = function (id: number, callback: UserMethods.LoadByIdCallback) {
return User.findById(id).asCallback(callback)
}
-loadByUsername = function (username, callback) {
+loadByUsername = function (username: string, callback: UserMethods.LoadByUsernameCallback) {
const query = {
where: {
username: username
return User.findOne(query).asCallback(callback)
}
-loadByUsernameOrEmail = function (username, email, callback) {
+loadByUsernameOrEmail = function (username: string, email: string, callback: UserMethods.LoadByUsernameOrEmailCallback) {
const query = {
where: {
$or: [ { username }, { email } ]
// Translate for example "-name" to [ 'name', 'DESC' ]
-function getSort (value) {
- let field
- let direction
+function getSort (value: string) {
+ let field: string
+ let direction: 'ASC' | 'DESC'
if (value.substring(0, 1) === '-') {
direction = 'DESC'
import * as Sequelize from 'sequelize'
+// Don't use barrel, import just what we need
+import { VideoAbuse as FormatedVideoAbuse } from '../../shared/models/video-abuse.model'
+
export namespace VideoAbuseMethods {
- export type toFormatedJSON = () => void
+ export type toFormatedJSON = () => FormatedVideoAbuse
- export type ListForApi = (start, count, sort, callback) => void
+ export type ListForApiCallback = (err: Error, videoAbuseInstances?: VideoAbuseInstance[], total?: number) => void
+ export type ListForApi = (start: number, count: number, sort: string, callback: ListForApiCallback) => void
}
export interface VideoAbuseClass {
reason: string
}
-export interface VideoAbuseInstance extends Sequelize.Instance<VideoAbuseAttributes> {
+export interface VideoAbuseInstance extends VideoAbuseClass, VideoAbuseAttributes, Sequelize.Instance<VideoAbuseAttributes> {
id: number
createdAt: Date
updatedAt: Date
import * as Sequelize from 'sequelize'
+// Don't use barrel, import just what we need
+import { BlacklistedVideo as FormatedBlacklistedVideo } from '../../shared/models/video-blacklist.model'
+
export namespace BlacklistedVideoMethods {
- export type ToFormatedJSON = () => void
+ export type ToFormatedJSON = () => FormatedBlacklistedVideo
+
+ export type CountTotalCallback = (err: Error, total: number) => void
+ export type CountTotal = (callback: CountTotalCallback) => void
+
+ export type ListCallback = (err: Error, backlistedVideoInstances: BlacklistedVideoInstance[]) => void
+ export type List = (callback: ListCallback) => void
+
+ export type ListForApiCallback = (err: Error, blacklistedVIdeoInstances?: BlacklistedVideoInstance[], total?: number) => void
+ export type ListForApi = (start: number, count: number, sort: string, callback: ListForApiCallback) => void
+
+ export type LoadByIdCallback = (err: Error, blacklistedVideoInstance: BlacklistedVideoInstance) => void
+ export type LoadById = (id: number, callback: LoadByIdCallback) => void
- export type CountTotal = (callback) => void
- export type List = (callback) => void
- export type ListForApi = (start, count, sort, callback) => void
- export type LoadById = (id, callback) => void
- export type LoadByVideoId = (id, callback) => void
+ export type LoadByVideoIdCallback = (err: Error, blacklistedVideoInstance: BlacklistedVideoInstance) => void
+ export type LoadByVideoId = (id: string, callback: LoadByVideoIdCallback) => void
}
export interface BlacklistedVideoClass {
})
}
-countTotal = function (callback) {
+countTotal = function (callback: BlacklistedVideoMethods.CountTotalCallback) {
return BlacklistedVideo.count().asCallback(callback)
}
-list = function (callback) {
+list = function (callback: BlacklistedVideoMethods.ListCallback) {
return BlacklistedVideo.findAll().asCallback(callback)
}
-listForApi = function (start, count, sort, callback) {
+listForApi = function (start: number, count: number, sort: string, callback: BlacklistedVideoMethods.ListForApiCallback) {
const query = {
offset: start,
limit: count,
})
}
-loadById = function (id, callback) {
+loadById = function (id: number, callback: BlacklistedVideoMethods.LoadByIdCallback) {
return BlacklistedVideo.findById(id).asCallback(callback)
}
-loadByVideoId = function (id, callback) {
+loadByVideoId = function (id: string, callback: BlacklistedVideoMethods.LoadByIdCallback) {
const query = {
where: {
videoId: id
import * as Sequelize from 'sequelize'
+import { AuthorInstance } from './author-interface'
+import { VideoTagInstance } from './video-tag-interface'
+
+// Don't use barrel, import just what we need
+import { Video as FormatedVideo } from '../../shared/models/video.model'
+
+export type FormatedAddRemoteVideo = {
+ name: string
+ category: number
+ licence: number
+ language: number
+ nsfw: boolean
+ description: string
+ infoHash: string
+ remoteId: string
+ author: string
+ duration: number
+ thumbnailData: string
+ tags: string[]
+ createdAt: Date
+ updatedAt: Date
+ extname: string
+ views: number
+ likes: number
+ dislikes: number
+}
+
+export type FormatedUpdateRemoteVideo = {
+ name: string
+ category: number
+ licence: number
+ language: number
+ nsfw: boolean
+ description: string
+ infoHash: string
+ remoteId: string
+ author: string
+ duration: number
+ tags: string[]
+ createdAt: Date
+ updatedAt: Date
+ extname: string
+ views: number
+ likes: number
+ dislikes: number
+}
+
export namespace VideoMethods {
- export type GenerateMagnetUri = () => void
- export type GetVideoFilename = () => void
- export type GetThumbnailName = () => void
- export type GetPreviewName = () => void
- export type GetTorrentName = () => void
- export type IsOwned = () => void
- export type ToFormatedJSON = () => void
- export type ToAddRemoteJSON = (callback) => void
- export type ToUpdateRemoteJSON = (callback) => void
- export type TranscodeVideofile = (callback) => void
-
- export type GenerateThumbnailFromData = (video, thumbnailData, callback) => void
+ export type GenerateMagnetUri = () => string
+ export type GetVideoFilename = () => string
+ export type GetThumbnailName = () => string
+ export type GetPreviewName = () => string
+ export type GetTorrentName = () => string
+ export type IsOwned = () => boolean
+ export type ToFormatedJSON = () => FormatedVideo
+
+ export type ToAddRemoteJSONCallback = (err: Error, videoFormated?: FormatedAddRemoteVideo) => void
+ export type ToAddRemoteJSON = (callback: ToAddRemoteJSONCallback) => void
+
+ export type ToUpdateRemoteJSON = () => FormatedUpdateRemoteVideo
+
+ export type TranscodeVideofileCallback = (err: Error) => void
+ export type TranscodeVideofile = (callback: TranscodeVideofileCallback) => void
+
+ export type GenerateThumbnailFromDataCallback = (err: Error, thumbnailName?: string) => void
+ export type GenerateThumbnailFromData = (video: VideoInstance, thumbnailData: string, callback: GenerateThumbnailFromDataCallback) => void
+
+ export type GetDurationFromFileCallback = (err: Error, duration?: number) => void
export type GetDurationFromFile = (videoPath, callback) => void
- export type List = (callback) => void
- export type ListForApi = (start, count, sort, callback) => void
- export type LoadByHostAndRemoteId = (fromHost, remoteId, callback) => void
- export type ListOwnedAndPopulateAuthorAndTags = (callback) => void
- export type ListOwnedByAuthor = (author, callback) => void
- export type Load = (id, callback) => void
- export type LoadAndPopulateAuthor = (id, callback) => void
- export type LoadAndPopulateAuthorAndPodAndTags = (id, callback) => void
- export type SearchAndPopulateAuthorAndPodAndTags = (value, field, start, count, sort, callback) => void
+
+ export type ListCallback = () => void
+ export type List = (callback: ListCallback) => void
+
+ export type ListForApiCallback = (err: Error, videoInstances?: VideoInstance[], total?: number) => void
+ export type ListForApi = (start: number, count: number, sort: string, callback: ListForApiCallback) => void
+
+ export type LoadByHostAndRemoteIdCallback = (err: Error, videoInstance: VideoInstance) => void
+ export type LoadByHostAndRemoteId = (fromHost: string, remoteId: string, callback: LoadByHostAndRemoteIdCallback) => void
+
+ export type ListOwnedAndPopulateAuthorAndTagsCallback = (err: Error, videoInstances: VideoInstance[]) => void
+ export type ListOwnedAndPopulateAuthorAndTags = (callback: ListOwnedAndPopulateAuthorAndTagsCallback) => void
+
+ export type ListOwnedByAuthorCallback = (err: Error, videoInstances: VideoInstance[]) => void
+ export type ListOwnedByAuthor = (author: string, callback: ListOwnedByAuthorCallback) => void
+
+ export type LoadCallback = (err: Error, videoInstance: VideoInstance) => void
+ export type Load = (id: string, callback: LoadCallback) => void
+
+ export type LoadAndPopulateAuthorCallback = (err: Error, videoInstance: VideoInstance) => void
+ export type LoadAndPopulateAuthor = (id: string, callback: LoadAndPopulateAuthorCallback) => void
+
+ export type LoadAndPopulateAuthorAndPodAndTagsCallback = (err: Error, videoInstance: VideoInstance) => void
+ export type LoadAndPopulateAuthorAndPodAndTags = (id: string, callback: LoadAndPopulateAuthorAndPodAndTagsCallback) => void
+
+ export type SearchAndPopulateAuthorAndPodAndTagsCallback = (err: Error, videoInstances?: VideoInstance[], total?: number) => void
+ export type SearchAndPopulateAuthorAndPodAndTags = (value: string, field: string, start: number, count: number, sort: string, callback: SearchAndPopulateAuthorAndPodAndTagsCallback) => void
}
export interface VideoClass {
views?: number
likes?: number
dislikes?: number
+
+ Author?: AuthorInstance
+ Tags?: VideoTagInstance[]
}
export interface VideoInstance extends VideoClass, VideoAttributes, Sequelize.Instance<VideoAttributes> {
export interface VideoTagAttributes {
}
-export interface VideoTagInstance extends Sequelize.Instance<VideoTagAttributes> {
+export interface VideoTagInstance extends VideoTagClass, VideoTagAttributes, Sequelize.Instance<VideoTagAttributes> {
id: number
createdAt: Date
updatedAt: Date
import * as Sequelize from 'sequelize'
import { database as db } from '../initializers/database'
+import { VideoTagInstance } from './video-tag-interface'
import {
logger,
isVideoNameValid,
return Video
}
-function beforeValidate (video, options) {
+function beforeValidate (video: VideoInstance) {
// Put a fake infoHash if it does not exists yet
if (video.isOwned() && !video.infoHash) {
// 40 hexa length
}
}
-function beforeCreate (video, options) {
+function beforeCreate (video: VideoInstance, options: { transaction: Sequelize.Transaction }) {
return new Promise(function (resolve, reject) {
const tasks = []
})
}
-function afterDestroy (video, options) {
+function afterDestroy (video: VideoInstance) {
return new Promise(function (resolve, reject) {
const tasks = []
}
const xs = baseUrlHttp + STATIC_PATHS.TORRENTS + this.getTorrentName()
- const announce = baseUrlWs + '/tracker/socket'
+ const announce = [ baseUrlWs + '/tracker/socket' ]
const urlList = [ baseUrlHttp + STATIC_PATHS.WEBSEED + this.getVideoFilename() ]
const magnetHash = {
return json
}
-toAddRemoteJSON = function (callback) {
+toAddRemoteJSON = function (callback: VideoMethods.ToAddRemoteJSONCallback) {
// Get thumbnail data to send to the other pod
const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, this.getThumbnailName())
fs.readFile(thumbnailPath, (err, thumbnailData) => {
author: this.Author.name,
duration: this.duration,
thumbnailData: thumbnailData.toString('binary'),
- tags: map(this.Tags, 'name'),
+ tags: map<VideoTagInstance, string>(this.Tags, 'name'),
createdAt: this.createdAt,
updatedAt: this.updatedAt,
extname: this.extname,
})
}
-toUpdateRemoteJSON = function (callback) {
+toUpdateRemoteJSON = function () {
const json = {
name: this.name,
category: this.category,
remoteId: this.id,
author: this.Author.name,
duration: this.duration,
- tags: map(this.Tags, 'name'),
+ tags: map<VideoTagInstance, string>(this.Tags, 'name'),
createdAt: this.createdAt,
updatedAt: this.updatedAt,
extname: this.extname,
return json
}
-transcodeVideofile = function (finalCallback) {
+transcodeVideofile = function (finalCallback: VideoMethods.TranscodeVideofileCallback) {
const video = this
const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR
video.save().asCallback(callback)
}
- ], function (err) {
+ ], function (err: Error) {
if (err) {
- // Autodescruction...
+ // Autodesctruction...
video.destroy().asCallback(function (err) {
if (err) logger.error('Cannot destruct video after transcoding failure.', { error: err })
})
// ------------------------------ STATICS ------------------------------
-generateThumbnailFromData = function (video, thumbnailData, callback) {
+generateThumbnailFromData = function (video: VideoInstance, thumbnailData: string, callback: VideoMethods.GenerateThumbnailFromDataCallback) {
// Creating the thumbnail for a remote video
const thumbnailName = video.getThumbnailName()
})
}
-getDurationFromFile = function (videoPath, callback) {
+getDurationFromFile = function (videoPath: string, callback: VideoMethods.GetDurationFromFileCallback) {
ffmpeg.ffprobe(videoPath, function (err, metadata) {
if (err) return callback(err)
})
}
-list = function (callback) {
+list = function (callback: VideoMethods.ListCallback) {
return Video.findAll().asCallback(callback)
}
-listForApi = function (start, count, sort, callback) {
+listForApi = function (start: number, count: number, sort: string, callback: VideoMethods.ListForApiCallback) {
// Exclude Blakclisted videos from the list
const query = {
distinct: true,
})
}
-loadByHostAndRemoteId = function (fromHost, remoteId, callback) {
+loadByHostAndRemoteId = function (fromHost: string, remoteId: string, callback: VideoMethods.LoadByHostAndRemoteIdCallback) {
const query = {
where: {
remoteId: remoteId
return Video.findOne(query).asCallback(callback)
}
-listOwnedAndPopulateAuthorAndTags = function (callback) {
+listOwnedAndPopulateAuthorAndTags = function (callback: VideoMethods.ListOwnedAndPopulateAuthorAndTagsCallback) {
// If remoteId is null this is *our* video
const query = {
where: {
return Video.findAll(query).asCallback(callback)
}
-listOwnedByAuthor = function (author, callback) {
+listOwnedByAuthor = function (author: string, callback: VideoMethods.ListOwnedByAuthorCallback) {
const query = {
where: {
remoteId: null
return Video.findAll(query).asCallback(callback)
}
-load = function (id, callback) {
+load = function (id: string, callback: VideoMethods.LoadCallback) {
return Video.findById(id).asCallback(callback)
}
-loadAndPopulateAuthor = function (id, callback) {
+loadAndPopulateAuthor = function (id: string, callback: VideoMethods.LoadAndPopulateAuthorCallback) {
const options = {
include: [ Video['sequelize'].models.Author ]
}
return Video.findById(id, options).asCallback(callback)
}
-loadAndPopulateAuthorAndPodAndTags = function (id, callback) {
+loadAndPopulateAuthorAndPodAndTags = function (id: string, callback: VideoMethods.LoadAndPopulateAuthorAndPodAndTagsCallback) {
const options = {
include: [
{
return Video.findById(id, options).asCallback(callback)
}
-searchAndPopulateAuthorAndPodAndTags = function (value, field, start, count, sort, callback) {
+searchAndPopulateAuthorAndPodAndTags = function (
+ value: string,
+ field: string,
+ start: number,
+ count: number,
+ sort: string,
+ callback: VideoMethods.SearchAndPopulateAuthorAndPodAndTagsCallback
+) {
const podInclude: any = {
model: Video['sequelize'].models.Pod,
required: false
}
}
-function removeThumbnail (video, callback) {
+function removeThumbnail (video: VideoInstance, callback: (err: Error) => void) {
const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, video.getThumbnailName())
fs.unlink(thumbnailPath, callback)
}
-function removeFile (video, callback) {
+function removeFile (video: VideoInstance, callback: (err: Error) => void) {
const filePath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename())
fs.unlink(filePath, callback)
}
-function removeTorrent (video, callback) {
+function removeTorrent (video: VideoInstance, callback: (err: Error) => void) {
const torrenPath = join(CONFIG.STORAGE.TORRENTS_DIR, video.getTorrentName())
fs.unlink(torrenPath, callback)
}
-function removePreview (video, callback) {
+function removePreview (video: VideoInstance, callback: (err: Error) => void) {
// Same name than video thumnail
fs.unlink(CONFIG.STORAGE.PREVIEWS_DIR + video.getPreviewName(), callback)
}
-function createTorrentFromVideo (video, videoPath, callback) {
+function createTorrentFromVideo (video: VideoInstance, videoPath: string, callback: (err: Error) => void) {
const options = {
announceList: [
[ CONFIG.WEBSERVER.WS + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT + '/tracker/socket' ]
})
}
-function createPreview (video, videoPath, callback) {
- generateImage(video, videoPath, CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName(), callback)
+function createPreview (video: VideoInstance, videoPath: string, callback: (err: Error) => void) {
+ generateImage(video, videoPath, CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName(), null, callback)
}
-function createThumbnail (video, videoPath, callback) {
+function createThumbnail (video: VideoInstance, videoPath: string, callback: (err: Error) => void) {
generateImage(video, videoPath, CONFIG.STORAGE.THUMBNAILS_DIR, video.getThumbnailName(), THUMBNAILS_SIZE, callback)
}
-function generateImage (video, videoPath, folder, imageName, size, callback?) {
+type GenerateImageCallback = (err: Error, imageName: string) => void
+function generateImage (video: VideoInstance, videoPath: string, folder: string, imageName: string, size: string, callback?: GenerateImageCallback) {
const options: any = {
filename: imageName,
count: 1,
folder
}
- if (!callback) {
- callback = size
- } else {
+ if (size) {
options.size = size
}
.thumbnail(options)
}
-function removeFromBlacklist (video, callback) {
+function removeFromBlacklist (video: VideoInstance, callback: (err: Error) => void) {
// Find the blacklisted video
db.BlacklistedVideo.loadByVideoId(video.id, function (err, video) {
// If an error occured, stop here
video.destroy().asCallback(callback)
} else {
// If haven't found it, simply ignore it and do nothing
- return callback()
+ return callback(null)
}
})
}
--- /dev/null
+export * from './models'
--- /dev/null
+export * from './pod.model'
+export * from './user.model'
+export * from './video-abuse.model'
+export * from './video-blacklist.model'
+export * from './video.model'
--- /dev/null
+export interface Pod {
+ id: number,
+ host: string,
+ email: string,
+ score: number,
+ createdAt: Date
+}
--- /dev/null
+export interface User {
+ id: number
+ username: string
+ email: string
+ displayNSFW: boolean
+ role: string[]
+ createdAt: Date
+}
--- /dev/null
+export interface VideoAbuse {
+ id: number
+ reporterPodHost: string
+ reason: string
+ reporterUsername: string
+ videoId: number
+ createdAt: Date
+}
--- /dev/null
+export interface BlacklistedVideo {
+ id: number
+ videoId: number
+ createdAt: Date
+}
--- /dev/null
+export interface Video {
+
+}
version "4.14.64"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.64.tgz#979cf3a3d4a368670840bf9b3e448dc33ffe84ee"
+"@types/magnet-uri@^5.1.1":
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/@types/magnet-uri/-/magnet-uri-5.1.1.tgz#861aaf64c92a3137dd848fefc55cd352a8ea851a"
+ dependencies:
+ "@types/node" "*"
+
"@types/mime@*":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-0.0.29.tgz#fbcfd330573b912ef59eeee14602bface630754b"
dependencies:
"@types/express" "*"
+"@types/multer@^0.0.34":
+ version "0.0.34"
+ resolved "https://registry.yarnpkg.com/@types/multer/-/multer-0.0.34.tgz#4b542b380dcf59bced8b66294654dc67a7fab383"
+ dependencies:
+ "@types/express" "*"
+
"@types/node@*", "@types/node@^7.0.18":
version "7.0.22"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.22.tgz#4593f4d828bdd612929478ea40c67b4f403ca255"