Use global uuid instead of remoteId for videos
This commit is contained in:
parent
e6d4b0ff24
commit
0a6658fdcb
|
@ -22,7 +22,7 @@ export class VideoAbuseService {
|
||||||
return new RestDataSource(this.authHttp, VideoAbuseService.BASE_VIDEO_ABUSE_URL + 'abuse')
|
return new RestDataSource(this.authHttp, VideoAbuseService.BASE_VIDEO_ABUSE_URL + 'abuse')
|
||||||
}
|
}
|
||||||
|
|
||||||
reportVideo (id: string, reason: string) {
|
reportVideo (id: number, reason: string) {
|
||||||
const body = {
|
const body = {
|
||||||
reason
|
reason
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,8 @@ export class Video implements VideoServerModel {
|
||||||
description: string
|
description: string
|
||||||
duration: number
|
duration: number
|
||||||
durationLabel: string
|
durationLabel: string
|
||||||
id: string
|
id: number
|
||||||
|
uuid: string
|
||||||
isLocal: boolean
|
isLocal: boolean
|
||||||
magnetUri: string
|
magnetUri: string
|
||||||
name: string
|
name: string
|
||||||
|
@ -51,7 +52,8 @@ export class Video implements VideoServerModel {
|
||||||
language: number
|
language: number
|
||||||
description: string,
|
description: string,
|
||||||
duration: number
|
duration: number
|
||||||
id: string,
|
id: number,
|
||||||
|
uuid: string,
|
||||||
isLocal: boolean,
|
isLocal: boolean,
|
||||||
magnetUri: string,
|
magnetUri: string,
|
||||||
name: string,
|
name: string,
|
||||||
|
@ -75,6 +77,7 @@ export class Video implements VideoServerModel {
|
||||||
this.duration = hash.duration
|
this.duration = hash.duration
|
||||||
this.durationLabel = Video.createDurationString(hash.duration)
|
this.durationLabel = Video.createDurationString(hash.duration)
|
||||||
this.id = hash.id
|
this.id = hash.id
|
||||||
|
this.uuid = hash.uuid
|
||||||
this.isLocal = hash.isLocal
|
this.isLocal = hash.isLocal
|
||||||
this.magnetUri = hash.magnetUri
|
this.magnetUri = hash.magnetUri
|
||||||
this.name = hash.name
|
this.name = hash.name
|
||||||
|
|
|
@ -52,8 +52,8 @@ export class VideoService {
|
||||||
return this.loadVideoAttributeEnum('languages', this.videoLanguages)
|
return this.loadVideoAttributeEnum('languages', this.videoLanguages)
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideo (id: string): Observable<Video> {
|
getVideo (uuid: string): Observable<Video> {
|
||||||
return this.http.get(VideoService.BASE_VIDEO_URL + id)
|
return this.http.get(VideoService.BASE_VIDEO_URL + uuid)
|
||||||
.map(this.restExtractor.extractDataGet)
|
.map(this.restExtractor.extractDataGet)
|
||||||
.map(videoHash => new Video(videoHash))
|
.map(videoHash => new Video(videoHash))
|
||||||
.catch((res) => this.restExtractor.handleError(res))
|
.catch((res) => this.restExtractor.handleError(res))
|
||||||
|
@ -89,7 +89,7 @@ export class VideoService {
|
||||||
.catch((res) => this.restExtractor.handleError(res))
|
.catch((res) => this.restExtractor.handleError(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
removeVideo (id: string) {
|
removeVideo (id: number) {
|
||||||
return this.authHttp.delete(VideoService.BASE_VIDEO_URL + id)
|
return this.authHttp.delete(VideoService.BASE_VIDEO_URL + id)
|
||||||
.map(this.restExtractor.extractDataBool)
|
.map(this.restExtractor.extractDataBool)
|
||||||
.catch((res) => this.restExtractor.handleError(res))
|
.catch((res) => this.restExtractor.handleError(res))
|
||||||
|
@ -106,7 +106,7 @@ export class VideoService {
|
||||||
.catch((res) => this.restExtractor.handleError(res))
|
.catch((res) => this.restExtractor.handleError(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
reportVideo (id: string, reason: string) {
|
reportVideo (id: number, reason: string) {
|
||||||
const url = VideoService.BASE_VIDEO_URL + id + '/abuse'
|
const url = VideoService.BASE_VIDEO_URL + id + '/abuse'
|
||||||
const body: VideoAbuseCreate = {
|
const body: VideoAbuseCreate = {
|
||||||
reason
|
reason
|
||||||
|
@ -117,15 +117,15 @@ export class VideoService {
|
||||||
.catch((res) => this.restExtractor.handleError(res))
|
.catch((res) => this.restExtractor.handleError(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
setVideoLike (id: string) {
|
setVideoLike (id: number) {
|
||||||
return this.setVideoRate(id, 'like')
|
return this.setVideoRate(id, 'like')
|
||||||
}
|
}
|
||||||
|
|
||||||
setVideoDislike (id: string) {
|
setVideoDislike (id: number) {
|
||||||
return this.setVideoRate(id, 'dislike')
|
return this.setVideoRate(id, 'dislike')
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserVideoRating (id: string): Observable<UserVideoRate> {
|
getUserVideoRating (id: number): Observable<UserVideoRate> {
|
||||||
const url = UserService.BASE_USERS_URL + '/me/videos/' + id + '/rating'
|
const url = UserService.BASE_USERS_URL + '/me/videos/' + id + '/rating'
|
||||||
|
|
||||||
return this.authHttp.get(url)
|
return this.authHttp.get(url)
|
||||||
|
@ -133,13 +133,13 @@ export class VideoService {
|
||||||
.catch((res) => this.restExtractor.handleError(res))
|
.catch((res) => this.restExtractor.handleError(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
blacklistVideo (id: string) {
|
blacklistVideo (id: number) {
|
||||||
return this.authHttp.post(VideoService.BASE_VIDEO_URL + id + '/blacklist', {})
|
return this.authHttp.post(VideoService.BASE_VIDEO_URL + id + '/blacklist', {})
|
||||||
.map(this.restExtractor.extractDataBool)
|
.map(this.restExtractor.extractDataBool)
|
||||||
.catch((res) => this.restExtractor.handleError(res))
|
.catch((res) => this.restExtractor.handleError(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
private setVideoRate (id: string, rateType: VideoRateType) {
|
private setVideoRate (id: number, rateType: VideoRateType) {
|
||||||
const url = VideoService.BASE_VIDEO_URL + id + '/rate'
|
const url = VideoService.BASE_VIDEO_URL + id + '/rate'
|
||||||
const body: UserVideoRateUpdate = {
|
const body: UserVideoRateUpdate = {
|
||||||
rating: rateType
|
rating: rateType
|
||||||
|
|
|
@ -85,8 +85,8 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
||||||
this.videoLicences = this.videoService.videoLicences
|
this.videoLicences = this.videoService.videoLicences
|
||||||
this.videoLanguages = this.videoService.videoLanguages
|
this.videoLanguages = this.videoService.videoLanguages
|
||||||
|
|
||||||
const id = this.route.snapshot.params['id']
|
const uuid: string = this.route.snapshot.params['uuid']
|
||||||
this.videoService.getVideo(id)
|
this.videoService.getVideo(uuid)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
video => {
|
video => {
|
||||||
this.video = video
|
this.video = video
|
||||||
|
@ -118,7 +118,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
||||||
.subscribe(
|
.subscribe(
|
||||||
() => {
|
() => {
|
||||||
this.notificationsService.success('Success', 'Video updated.')
|
this.notificationsService.success('Success', 'Video updated.')
|
||||||
this.router.navigate([ '/videos/watch', this.video.id ])
|
this.router.navigate([ '/videos/watch', this.video.uuid ])
|
||||||
},
|
},
|
||||||
|
|
||||||
err => {
|
err => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="video-miniature">
|
<div class="video-miniature">
|
||||||
<a
|
<a
|
||||||
[routerLink]="['/videos/watch', video.id]" [attr.title]="video.description"
|
[routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.description"
|
||||||
class="video-miniature-thumbnail"
|
class="video-miniature-thumbnail"
|
||||||
>
|
>
|
||||||
<img *ngIf="isVideoNSFWForThisUser() === false" [attr.src]="video.thumbnailUrl" alt="video thumbnail" />
|
<img *ngIf="isVideoNSFWForThisUser() === false" [attr.src]="video.thumbnailUrl" alt="video thumbnail" />
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
<div class="video-miniature-informations">
|
<div class="video-miniature-informations">
|
||||||
<span class="video-miniature-name">
|
<span class="video-miniature-name">
|
||||||
<a [routerLink]="['/videos/watch', video.id]" [attr.title]="getVideoName()" class="video-miniature-name">{{ getVideoName() }}</a>
|
<a [routerLink]="['/videos/watch', video.uuid]" [attr.title]="getVideoName()" class="video-miniature-name">{{ getVideoName() }}</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="video-miniature-tags">
|
<div class="video-miniature-tags">
|
||||||
|
|
|
@ -27,7 +27,7 @@ export class VideoShareComponent {
|
||||||
|
|
||||||
getVideoIframeCode () {
|
getVideoIframeCode () {
|
||||||
return '<iframe width="560" height="315" ' +
|
return '<iframe width="560" height="315" ' +
|
||||||
'src="' + window.location.origin + '/videos/embed/' + this.video.id + '" ' +
|
'src="' + window.location.origin + '/videos/embed/' + this.video.uuid + '" ' +
|
||||||
'frameborder="0" allowfullscreen>' +
|
'frameborder="0" allowfullscreen>' +
|
||||||
'</iframe>'
|
'</iframe>'
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
|
|
||||||
<ul *dropdownMenu class="dropdown-menu" id="more-menu" role="menu" aria-labelledby="single-button">
|
<ul *dropdownMenu class="dropdown-menu" id="more-menu" role="menu" aria-labelledby="single-button">
|
||||||
<li *ngIf="canUserUpdateVideo()" role="menuitem">
|
<li *ngIf="canUserUpdateVideo()" role="menuitem">
|
||||||
<a class="dropdown-item" title="Update this video" href="#" [routerLink]="[ '/videos/edit', video.id ]">
|
<a class="dropdown-item" title="Update this video" href="#" [routerLink]="[ '/videos/edit', video.uuid ]">
|
||||||
<span class="glyphicon glyphicon-pencil"></span> Update
|
<span class="glyphicon glyphicon-pencil"></span> Update
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -58,8 +58,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
this.paramsSub = this.route.params.subscribe(routeParams => {
|
this.paramsSub = this.route.params.subscribe(routeParams => {
|
||||||
let id = routeParams['id']
|
let uuid = routeParams['uuid']
|
||||||
this.videoService.getVideo(id).subscribe(
|
this.videoService.getVideo(uuid).subscribe(
|
||||||
video => this.onVideoFetched(video),
|
video => this.onVideoFetched(video),
|
||||||
|
|
||||||
error => {
|
error => {
|
||||||
|
|
|
@ -33,7 +33,7 @@ const videosRoutes: Routes = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'edit/:id',
|
path: 'edit/:uuid',
|
||||||
component: VideoUpdateComponent,
|
component: VideoUpdateComponent,
|
||||||
data: {
|
data: {
|
||||||
meta: {
|
meta: {
|
||||||
|
@ -42,11 +42,11 @@ const videosRoutes: Routes = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':id',
|
path: ':uuid',
|
||||||
redirectTo: 'watch/:id'
|
redirectTo: 'watch/:uuid'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'watch/:id',
|
path: 'watch/:uuid',
|
||||||
component: VideoWatchComponent
|
component: VideoWatchComponent
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -133,7 +133,7 @@ function processVideosEventsRetryWrapper (eventData: RemoteVideoEventData, fromP
|
||||||
function processVideosEvents (eventData: RemoteVideoEventData, fromPod: PodInstance) {
|
function processVideosEvents (eventData: RemoteVideoEventData, fromPod: PodInstance) {
|
||||||
|
|
||||||
return db.sequelize.transaction(t => {
|
return db.sequelize.transaction(t => {
|
||||||
return fetchOwnedVideo(eventData.remoteId)
|
return fetchVideoByUUID(eventData.uuid)
|
||||||
.then(videoInstance => {
|
.then(videoInstance => {
|
||||||
const options = { transaction: t }
|
const options = { transaction: t }
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ function processVideosEvents (eventData: RemoteVideoEventData, fromPod: PodInsta
|
||||||
return quickAndDirtyUpdatesVideoToFriends(qadusParams, t)
|
return quickAndDirtyUpdatesVideoToFriends(qadusParams, t)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.then(() => logger.info('Remote video event processed for video %s.', eventData.remoteId))
|
.then(() => logger.info('Remote video event processed for video %s.', eventData.uuid))
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
logger.debug('Cannot process a video event.', err)
|
logger.debug('Cannot process a video event.', err)
|
||||||
throw err
|
throw err
|
||||||
|
@ -196,7 +196,7 @@ function quickAndDirtyUpdateVideo (videoData: RemoteQaduVideoData, fromPod: PodI
|
||||||
let videoName
|
let videoName
|
||||||
|
|
||||||
return db.sequelize.transaction(t => {
|
return db.sequelize.transaction(t => {
|
||||||
return fetchRemoteVideo(fromPod.host, videoData.remoteId)
|
return fetchVideoByHostAndUUID(fromPod.host, videoData.uuid)
|
||||||
.then(videoInstance => {
|
.then(videoInstance => {
|
||||||
const options = { transaction: t }
|
const options = { transaction: t }
|
||||||
|
|
||||||
|
@ -232,12 +232,12 @@ function addRemoteVideoRetryWrapper (videoToCreateData: RemoteVideoCreateData, f
|
||||||
}
|
}
|
||||||
|
|
||||||
function addRemoteVideo (videoToCreateData: RemoteVideoCreateData, fromPod: PodInstance) {
|
function addRemoteVideo (videoToCreateData: RemoteVideoCreateData, fromPod: PodInstance) {
|
||||||
logger.debug('Adding remote video "%s".', videoToCreateData.remoteId)
|
logger.debug('Adding remote video "%s".', videoToCreateData.uuid)
|
||||||
|
|
||||||
return db.sequelize.transaction(t => {
|
return db.sequelize.transaction(t => {
|
||||||
return db.Video.loadByHostAndRemoteId(fromPod.host, videoToCreateData.remoteId)
|
return db.Video.loadByUUID(videoToCreateData.uuid)
|
||||||
.then(video => {
|
.then(video => {
|
||||||
if (video) throw new Error('RemoteId and host pair is not unique.')
|
if (video) throw new Error('UUID already exists.')
|
||||||
|
|
||||||
return undefined
|
return undefined
|
||||||
})
|
})
|
||||||
|
@ -257,7 +257,7 @@ function addRemoteVideo (videoToCreateData: RemoteVideoCreateData, fromPod: PodI
|
||||||
.then(({ author, tagInstances }) => {
|
.then(({ author, tagInstances }) => {
|
||||||
const videoData = {
|
const videoData = {
|
||||||
name: videoToCreateData.name,
|
name: videoToCreateData.name,
|
||||||
remoteId: videoToCreateData.remoteId,
|
uuid: videoToCreateData.uuid,
|
||||||
extname: videoToCreateData.extname,
|
extname: videoToCreateData.extname,
|
||||||
infoHash: videoToCreateData.infoHash,
|
infoHash: videoToCreateData.infoHash,
|
||||||
category: videoToCreateData.category,
|
category: videoToCreateData.category,
|
||||||
|
@ -272,7 +272,8 @@ function addRemoteVideo (videoToCreateData: RemoteVideoCreateData, fromPod: PodI
|
||||||
updatedAt: videoToCreateData.updatedAt,
|
updatedAt: videoToCreateData.updatedAt,
|
||||||
views: videoToCreateData.views,
|
views: videoToCreateData.views,
|
||||||
likes: videoToCreateData.likes,
|
likes: videoToCreateData.likes,
|
||||||
dislikes: videoToCreateData.dislikes
|
dislikes: videoToCreateData.dislikes,
|
||||||
|
remote: true
|
||||||
}
|
}
|
||||||
|
|
||||||
const video = db.Video.build(videoData)
|
const video = db.Video.build(videoData)
|
||||||
|
@ -314,10 +315,10 @@ function updateRemoteVideoRetryWrapper (videoAttributesToUpdate: RemoteVideoUpda
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateRemoteVideo (videoAttributesToUpdate: RemoteVideoUpdateData, fromPod: PodInstance) {
|
function updateRemoteVideo (videoAttributesToUpdate: RemoteVideoUpdateData, fromPod: PodInstance) {
|
||||||
logger.debug('Updating remote video "%s".', videoAttributesToUpdate.remoteId)
|
logger.debug('Updating remote video "%s".', videoAttributesToUpdate.uuid)
|
||||||
|
|
||||||
return db.sequelize.transaction(t => {
|
return db.sequelize.transaction(t => {
|
||||||
return fetchRemoteVideo(fromPod.host, videoAttributesToUpdate.remoteId)
|
return fetchVideoByHostAndUUID(fromPod.host, videoAttributesToUpdate.uuid)
|
||||||
.then(videoInstance => {
|
.then(videoInstance => {
|
||||||
const tags = videoAttributesToUpdate.tags
|
const tags = videoAttributesToUpdate.tags
|
||||||
|
|
||||||
|
@ -359,18 +360,18 @@ function updateRemoteVideo (videoAttributesToUpdate: RemoteVideoUpdateData, from
|
||||||
|
|
||||||
function removeRemoteVideo (videoToRemoveData: RemoteVideoRemoveData, fromPod: PodInstance) {
|
function removeRemoteVideo (videoToRemoveData: RemoteVideoRemoveData, fromPod: PodInstance) {
|
||||||
// We need the instance because we have to remove some other stuffs (thumbnail etc)
|
// We need the instance because we have to remove some other stuffs (thumbnail etc)
|
||||||
return fetchRemoteVideo(fromPod.host, videoToRemoveData.remoteId)
|
return fetchVideoByHostAndUUID(fromPod.host, videoToRemoveData.uuid)
|
||||||
.then(video => {
|
.then(video => {
|
||||||
logger.debug('Removing remote video %s.', video.remoteId)
|
logger.debug('Removing remote video %s.', video.uuid)
|
||||||
return video.destroy()
|
return video.destroy()
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
logger.debug('Could not fetch remote video.', { host: fromPod.host, remoteId: videoToRemoveData.remoteId, error: err.stack })
|
logger.debug('Could not fetch remote video.', { host: fromPod.host, uuid: videoToRemoveData.uuid, error: err.stack })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function reportAbuseRemoteVideo (reportData: RemoteVideoReportAbuseData, fromPod: PodInstance) {
|
function reportAbuseRemoteVideo (reportData: RemoteVideoReportAbuseData, fromPod: PodInstance) {
|
||||||
return fetchOwnedVideo(reportData.videoRemoteId)
|
return fetchVideoByUUID(reportData.videoUUID)
|
||||||
.then(video => {
|
.then(video => {
|
||||||
logger.debug('Reporting remote abuse for video %s.', video.id)
|
logger.debug('Reporting remote abuse for video %s.', video.id)
|
||||||
|
|
||||||
|
@ -386,8 +387,8 @@ function reportAbuseRemoteVideo (reportData: RemoteVideoReportAbuseData, fromPod
|
||||||
.catch(err => logger.error('Cannot create remote abuse video.', err))
|
.catch(err => logger.error('Cannot create remote abuse video.', err))
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchOwnedVideo (id: string) {
|
function fetchVideoByUUID (id: string) {
|
||||||
return db.Video.load(id)
|
return db.Video.loadByUUID(id)
|
||||||
.then(video => {
|
.then(video => {
|
||||||
if (!video) throw new Error('Video not found')
|
if (!video) throw new Error('Video not found')
|
||||||
|
|
||||||
|
@ -399,15 +400,15 @@ function fetchOwnedVideo (id: string) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchRemoteVideo (podHost: string, remoteId: string) {
|
function fetchVideoByHostAndUUID (podHost: string, uuid: string) {
|
||||||
return db.Video.loadByHostAndRemoteId(podHost, remoteId)
|
return db.Video.loadByHostAndUUID(podHost, uuid)
|
||||||
.then(video => {
|
.then(video => {
|
||||||
if (!video) throw new Error('Video not found')
|
if (!video) throw new Error('Video not found')
|
||||||
|
|
||||||
return video
|
return video
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
logger.error('Cannot load video from host and remote id.', { error: err.stack, podHost, remoteId })
|
logger.error('Cannot load video from host and uuid.', { error: err.stack, podHost, uuid })
|
||||||
throw err
|
throw err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ function getUserInformation (req: express.Request, res: express.Response, next:
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUserVideoRating (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function getUserVideoRating (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const videoId = '' + req.params.videoId
|
const videoId = +req.params.videoId
|
||||||
const userId = +res.locals.oauth.token.User.id
|
const userId = +res.locals.oauth.token.User.id
|
||||||
|
|
||||||
db.UserVideoRate.load(userId, videoId, null)
|
db.UserVideoRate.load(userId, videoId, null)
|
||||||
|
|
|
@ -62,7 +62,7 @@ function reportVideoAbuseRetryWrapper (req: express.Request, res: express.Respon
|
||||||
}
|
}
|
||||||
|
|
||||||
function reportVideoAbuse (req: express.Request, res: express.Response) {
|
function reportVideoAbuse (req: express.Request, res: express.Response) {
|
||||||
const videoInstance = res.locals.video
|
const videoInstance = res.locals.video as VideoInstance
|
||||||
const reporterUsername = res.locals.oauth.token.User.username
|
const reporterUsername = res.locals.oauth.token.User.username
|
||||||
const body: VideoAbuseCreate = req.body
|
const body: VideoAbuseCreate = req.body
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ function reportVideoAbuse (req: express.Request, res: express.Response) {
|
||||||
const reportData = {
|
const reportData = {
|
||||||
reporterUsername,
|
reporterUsername,
|
||||||
reportReason: abuse.reason,
|
reportReason: abuse.reason,
|
||||||
videoRemoteId: videoInstance.remoteId
|
videoUUID: videoInstance.uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
return friends.reportAbuseVideoToFriend(reportData, videoInstance, t).then(() => videoInstance)
|
return friends.reportAbuseVideoToFriend(reportData, videoInstance, t).then(() => videoInstance)
|
||||||
|
|
|
@ -176,7 +176,7 @@ function addVideo (req: express.Request, res: express.Response, videoFile: Expre
|
||||||
.then(({ author, tagInstances }) => {
|
.then(({ author, tagInstances }) => {
|
||||||
const videoData = {
|
const videoData = {
|
||||||
name: videoInfos.name,
|
name: videoInfos.name,
|
||||||
remoteId: null,
|
remote: false,
|
||||||
extname: path.extname(videoFile.filename),
|
extname: path.extname(videoFile.filename),
|
||||||
category: videoInfos.category,
|
category: videoInfos.category,
|
||||||
licence: videoInfos.licence,
|
licence: videoInfos.licence,
|
||||||
|
|
|
@ -69,7 +69,7 @@ function rateVideo (req: express.Request, res: express.Response) {
|
||||||
|
|
||||||
// There was a previous rate, update it
|
// There was a previous rate, update it
|
||||||
if (previousRate) {
|
if (previousRate) {
|
||||||
// We will remove the previous rate, so we will need to remove it from the video attribute
|
// We will remove the previous rate, so we will need to update the video count attribute
|
||||||
if (previousRate.type === VIDEO_RATE_TYPES.LIKE) likesToIncrement--
|
if (previousRate.type === VIDEO_RATE_TYPES.LIKE) likesToIncrement--
|
||||||
else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
|
else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ function addOpenGraphTags (htmlStringPage: string, video: VideoInstance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let tagsString = ''
|
let tagsString = ''
|
||||||
Object.keys(metaTags).forEach(function (tagName) {
|
Object.keys(metaTags).forEach(tagName => {
|
||||||
const tagValue = metaTags[tagName]
|
const tagValue = metaTags[tagName]
|
||||||
|
|
||||||
tagsString += '<meta property="' + tagName + '" content="' + tagValue + '" />'
|
tagsString += '<meta property="' + tagName + '" content="' + tagValue + '" />'
|
||||||
|
@ -89,13 +89,20 @@ function addOpenGraphTags (htmlStringPage: string, video: VideoInstance) {
|
||||||
|
|
||||||
function generateWatchHtmlPage (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function generateWatchHtmlPage (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const videoId = '' + req.params.id
|
const videoId = '' + req.params.id
|
||||||
|
let videoPromise: Promise<VideoInstance>
|
||||||
|
|
||||||
// Let Angular application handle errors
|
// Let Angular application handle errors
|
||||||
if (!validator.isUUID(videoId, 4)) return res.sendFile(indexPath)
|
if (validator.isUUID(videoId, 4)) {
|
||||||
|
videoPromise = db.Video.loadByUUIDAndPopulateAuthorAndPodAndTags(videoId)
|
||||||
|
} else if (validator.isInt(videoId)) {
|
||||||
|
videoPromise = db.Video.loadAndPopulateAuthorAndPodAndTags(+videoId)
|
||||||
|
} else {
|
||||||
|
return res.sendFile(indexPath)
|
||||||
|
}
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
readFileBufferPromise(indexPath),
|
readFileBufferPromise(indexPath),
|
||||||
db.Video.loadAndPopulateAuthorAndPodAndTags(videoId)
|
videoPromise
|
||||||
])
|
])
|
||||||
.then(([ file, video ]) => {
|
.then(([ file, video ]) => {
|
||||||
file = file as Buffer
|
file = file as Buffer
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { isArray } from '../misc'
|
||||||
import {
|
import {
|
||||||
isVideoAuthorValid,
|
isVideoAuthorValid,
|
||||||
isVideoThumbnailDataValid,
|
isVideoThumbnailDataValid,
|
||||||
isVideoRemoteIdValid,
|
isVideoUUIDValid,
|
||||||
isVideoAbuseReasonValid,
|
isVideoAbuseReasonValid,
|
||||||
isVideoAbuseReporterUsernameValid,
|
isVideoAbuseReporterUsernameValid,
|
||||||
isVideoViewsValid,
|
isVideoViewsValid,
|
||||||
|
@ -50,11 +50,11 @@ function isEachRemoteRequestVideosValid (requests: any[]) {
|
||||||
) ||
|
) ||
|
||||||
(
|
(
|
||||||
isRequestTypeRemoveValid(request.type) &&
|
isRequestTypeRemoveValid(request.type) &&
|
||||||
isVideoRemoteIdValid(video.remoteId)
|
isVideoUUIDValid(video.uuid)
|
||||||
) ||
|
) ||
|
||||||
(
|
(
|
||||||
isRequestTypeReportAbuseValid(request.type) &&
|
isRequestTypeReportAbuseValid(request.type) &&
|
||||||
isVideoRemoteIdValid(request.data.videoRemoteId) &&
|
isVideoUUIDValid(request.data.videoUUID) &&
|
||||||
isVideoAbuseReasonValid(request.data.reportReason) &&
|
isVideoAbuseReasonValid(request.data.reportReason) &&
|
||||||
isVideoAbuseReporterUsernameValid(request.data.reporterUsername)
|
isVideoAbuseReporterUsernameValid(request.data.reporterUsername)
|
||||||
)
|
)
|
||||||
|
@ -69,7 +69,7 @@ function isEachRemoteRequestVideosQaduValid (requests: any[]) {
|
||||||
if (!video) return false
|
if (!video) return false
|
||||||
|
|
||||||
return (
|
return (
|
||||||
isVideoRemoteIdValid(video.remoteId) &&
|
isVideoUUIDValid(video.uuid) &&
|
||||||
(has(video, 'views') === false || isVideoViewsValid(video.views)) &&
|
(has(video, 'views') === false || isVideoViewsValid(video.views)) &&
|
||||||
(has(video, 'likes') === false || isVideoLikesValid(video.likes)) &&
|
(has(video, 'likes') === false || isVideoLikesValid(video.likes)) &&
|
||||||
(has(video, 'dislikes') === false || isVideoDislikesValid(video.dislikes))
|
(has(video, 'dislikes') === false || isVideoDislikesValid(video.dislikes))
|
||||||
|
@ -85,7 +85,7 @@ function isEachRemoteRequestVideosEventsValid (requests: any[]) {
|
||||||
if (!eventData) return false
|
if (!eventData) return false
|
||||||
|
|
||||||
return (
|
return (
|
||||||
isVideoRemoteIdValid(eventData.remoteId) &&
|
isVideoUUIDValid(eventData.uuid) &&
|
||||||
values(REQUEST_VIDEO_EVENT_TYPES).indexOf(eventData.eventType) !== -1 &&
|
values(REQUEST_VIDEO_EVENT_TYPES).indexOf(eventData.eventType) !== -1 &&
|
||||||
isVideoEventCountValid(eventData.count)
|
isVideoEventCountValid(eventData.count)
|
||||||
)
|
)
|
||||||
|
@ -124,7 +124,7 @@ function isCommonVideoAttributesValid (video: any) {
|
||||||
isVideoInfoHashValid(video.infoHash) &&
|
isVideoInfoHashValid(video.infoHash) &&
|
||||||
isVideoNameValid(video.name) &&
|
isVideoNameValid(video.name) &&
|
||||||
isVideoTagsValid(video.tags) &&
|
isVideoTagsValid(video.tags) &&
|
||||||
isVideoRemoteIdValid(video.remoteId) &&
|
isVideoUUIDValid(video.uuid) &&
|
||||||
isVideoExtnameValid(video.extname) &&
|
isVideoExtnameValid(video.extname) &&
|
||||||
isVideoViewsValid(video.views) &&
|
isVideoViewsValid(video.views) &&
|
||||||
isVideoLikesValid(video.likes) &&
|
isVideoLikesValid(video.likes) &&
|
||||||
|
|
|
@ -17,6 +17,10 @@ const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
|
||||||
const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
|
const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
|
||||||
const VIDEO_EVENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_EVENTS
|
const VIDEO_EVENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_EVENTS
|
||||||
|
|
||||||
|
function isVideoIdOrUUIDValid (value: string) {
|
||||||
|
return validator.isInt(value) || isVideoUUIDValid(value)
|
||||||
|
}
|
||||||
|
|
||||||
function isVideoAuthorValid (value: string) {
|
function isVideoAuthorValid (value: string) {
|
||||||
return isUserUsernameValid(value)
|
return isUserUsernameValid(value)
|
||||||
}
|
}
|
||||||
|
@ -77,8 +81,8 @@ function isVideoThumbnailDataValid (value: string) {
|
||||||
return exists(value) && validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA)
|
return exists(value) && validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL_DATA)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isVideoRemoteIdValid (value: string) {
|
function isVideoUUIDValid (value: string) {
|
||||||
return exists(value) && validator.isUUID(value, 4)
|
return exists(value) && validator.isUUID('' + value, 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isVideoAbuseReasonValid (value: string) {
|
function isVideoAbuseReasonValid (value: string) {
|
||||||
|
@ -127,6 +131,7 @@ function isVideoFile (value: string, files: { [ fieldname: string ]: Express.Mul
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
isVideoIdOrUUIDValid,
|
||||||
isVideoAuthorValid,
|
isVideoAuthorValid,
|
||||||
isVideoDateValid,
|
isVideoDateValid,
|
||||||
isVideoCategoryValid,
|
isVideoCategoryValid,
|
||||||
|
@ -141,7 +146,7 @@ export {
|
||||||
isVideoThumbnailValid,
|
isVideoThumbnailValid,
|
||||||
isVideoThumbnailDataValid,
|
isVideoThumbnailDataValid,
|
||||||
isVideoExtnameValid,
|
isVideoExtnameValid,
|
||||||
isVideoRemoteIdValid,
|
isVideoUUIDValid,
|
||||||
isVideoAbuseReasonValid,
|
isVideoAbuseReasonValid,
|
||||||
isVideoAbuseReporterUsernameValid,
|
isVideoAbuseReporterUsernameValid,
|
||||||
isVideoFile,
|
isVideoFile,
|
||||||
|
@ -155,6 +160,7 @@ export {
|
||||||
declare global {
|
declare global {
|
||||||
namespace ExpressValidator {
|
namespace ExpressValidator {
|
||||||
export interface Validator {
|
export interface Validator {
|
||||||
|
isVideoIdOrUUIDValid,
|
||||||
isVideoAuthorValid,
|
isVideoAuthorValid,
|
||||||
isVideoDateValid,
|
isVideoDateValid,
|
||||||
isVideoCategoryValid,
|
isVideoCategoryValid,
|
||||||
|
@ -169,7 +175,7 @@ declare global {
|
||||||
isVideoThumbnailValid,
|
isVideoThumbnailValid,
|
||||||
isVideoThumbnailDataValid,
|
isVideoThumbnailDataValid,
|
||||||
isVideoExtnameValid,
|
isVideoExtnameValid,
|
||||||
isVideoRemoteIdValid,
|
isVideoUUIDValid,
|
||||||
isVideoAbuseReasonValid,
|
isVideoAbuseReasonValid,
|
||||||
isVideoAbuseReporterUsernameValid,
|
isVideoAbuseReporterUsernameValid,
|
||||||
isVideoFile,
|
isVideoFile,
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const LAST_MIGRATION_VERSION = 50
|
const LAST_MIGRATION_VERSION = 55
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ function up (utils: {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function down (options, callback) {
|
function down (options) {
|
||||||
throw new Error('Not implemented.')
|
throw new Error('Not implemented.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ function up (utils: {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function down (options, callback) {
|
function down (options) {
|
||||||
throw new Error('Not implemented.')
|
throw new Error('Not implemented.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ function up (utils: {
|
||||||
return q.addColumn('Videos', 'views', data)
|
return q.addColumn('Videos', 'views', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
function down (options, callback) {
|
function down (options) {
|
||||||
throw new Error('Not implemented.')
|
throw new Error('Not implemented.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ function up (utils: {
|
||||||
return q.addColumn('Videos', 'likes', data)
|
return q.addColumn('Videos', 'likes', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
function down (options, callback) {
|
function down (options) {
|
||||||
throw new Error('Not implemented.')
|
throw new Error('Not implemented.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ function up (utils: {
|
||||||
return q.addColumn('Videos', 'dislikes', data)
|
return q.addColumn('Videos', 'dislikes', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
function down (options, callback) {
|
function down (options) {
|
||||||
throw new Error('Not implemented.')
|
throw new Error('Not implemented.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ function up (utils: {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function down (options, callback) {
|
function down (options) {
|
||||||
throw new Error('Not implemented.')
|
throw new Error('Not implemented.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ function up (utils: {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function down (options, callback) {
|
function down (options) {
|
||||||
throw new Error('Not implemented.')
|
throw new Error('Not implemented.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ function up (utils: {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function down (options, callback) {
|
function down (options) {
|
||||||
throw new Error('Not implemented.')
|
throw new Error('Not implemented.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ function up (utils: {
|
||||||
return q.addColumn('Users', 'displayNSFW', data)
|
return q.addColumn('Users', 'displayNSFW', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
function down (options, callback) {
|
function down (options) {
|
||||||
throw new Error('Not implemented.')
|
throw new Error('Not implemented.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ function up (utils: {
|
||||||
return q.addColumn('Videos', 'language', data)
|
return q.addColumn('Videos', 'language', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
function down (options, callback) {
|
function down (options) {
|
||||||
throw new Error('Not implemented.')
|
throw new Error('Not implemented.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
import * as Sequelize from 'sequelize'
|
||||||
|
import * as Promise from 'bluebird'
|
||||||
|
|
||||||
|
function up (utils: {
|
||||||
|
transaction: Sequelize.Transaction,
|
||||||
|
queryInterface: Sequelize.QueryInterface,
|
||||||
|
sequelize: Sequelize.Sequelize
|
||||||
|
}): Promise<void> {
|
||||||
|
const q = utils.queryInterface
|
||||||
|
|
||||||
|
const dataUUID = {
|
||||||
|
type: Sequelize.UUID,
|
||||||
|
defaultValue: Sequelize.UUIDV4,
|
||||||
|
allowNull: true
|
||||||
|
}
|
||||||
|
|
||||||
|
return q.addColumn('Videos', 'uuid', dataUUID)
|
||||||
|
.then(() => {
|
||||||
|
const query = 'UPDATE "Videos" SET "uuid" = "id" WHERE "remoteId" IS NULL'
|
||||||
|
return utils.sequelize.query(query)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const query = 'UPDATE "Videos" SET "uuid" = "remoteId" WHERE "remoteId" IS NOT NULL'
|
||||||
|
return utils.sequelize.query(query)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
dataUUID.defaultValue = null
|
||||||
|
|
||||||
|
return q.changeColumn('Videos', 'uuid', dataUUID)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return removeForeignKey(utils.sequelize, 'RequestVideoQadus')
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return removeForeignKey(utils.sequelize, 'RequestVideoEvents')
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return removeForeignKey(utils.sequelize, 'BlacklistedVideos')
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return removeForeignKey(utils.sequelize, 'UserVideoRates')
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return removeForeignKey(utils.sequelize, 'VideoAbuses')
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return removeForeignKey(utils.sequelize, 'VideoTags')
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const query = 'ALTER TABLE "Videos" DROP CONSTRAINT "Videos_pkey"'
|
||||||
|
return utils.sequelize.query(query)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const query = 'ALTER TABLE "Videos" ADD COLUMN "id2" SERIAL PRIMARY KEY'
|
||||||
|
return utils.sequelize.query(query)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return q.renameColumn('Videos', 'id', 'oldId')
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return q.renameColumn('Videos', 'id2', 'id')
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return changeForeignKey(q, utils.sequelize, 'RequestVideoQadus', false)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return changeForeignKey(q, utils.sequelize, 'RequestVideoEvents', false)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return changeForeignKey(q, utils.sequelize, 'BlacklistedVideos', false)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return changeForeignKey(q, utils.sequelize, 'UserVideoRates', false)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return changeForeignKey(q, utils.sequelize, 'VideoAbuses', false)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return changeForeignKey(q, utils.sequelize, 'VideoTags', true)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return q.removeColumn('Videos', 'oldId')
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const dataRemote = {
|
||||||
|
type: Sequelize.BOOLEAN,
|
||||||
|
defaultValue: false,
|
||||||
|
allowNull: false
|
||||||
|
}
|
||||||
|
return q.addColumn('Videos', 'remote', dataRemote)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const query = 'UPDATE "Videos" SET "remote" = false WHERE "remoteId" IS NULL'
|
||||||
|
return utils.sequelize.query(query)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const query = 'UPDATE "Videos" SET "remote" = true WHERE "remoteId" IS NOT NULL'
|
||||||
|
return utils.sequelize.query(query)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return q.removeColumn('Videos', 'remoteId')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function down (options) {
|
||||||
|
throw new Error('Not implemented.')
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeForeignKey (sequelize: Sequelize.Sequelize, tableName: string) {
|
||||||
|
const query = 'ALTER TABLE "' + tableName + '" DROP CONSTRAINT "' + tableName + '_videoId_fkey' + '"'
|
||||||
|
return sequelize.query(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeForeignKey (q: Sequelize.QueryInterface, sequelize: Sequelize.Sequelize, tableName: string, allowNull: boolean) {
|
||||||
|
const data = {
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
allowNull: true
|
||||||
|
}
|
||||||
|
|
||||||
|
return q.addColumn(tableName, 'videoId2', data)
|
||||||
|
.then(() => {
|
||||||
|
const query = 'UPDATE "' + tableName + '" SET "videoId2" = ' +
|
||||||
|
'(SELECT "id" FROM "Videos" WHERE "' + tableName + '"."videoId" = "Videos"."oldId")'
|
||||||
|
return sequelize.query(query)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
if (allowNull === false) {
|
||||||
|
data.allowNull = false
|
||||||
|
|
||||||
|
return q.changeColumn(tableName, 'videoId2', data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve()
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return q.removeColumn(tableName, 'videoId')
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return q.renameColumn(tableName, 'videoId2', 'videoId')
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return q.addIndex(tableName, [ 'videoId' ])
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const constraintName = tableName + '_videoId_fkey'
|
||||||
|
const query = 'ALTER TABLE "' + tableName + '" ' +
|
||||||
|
' ADD CONSTRAINT "' + constraintName + '"' +
|
||||||
|
' FOREIGN KEY ("videoId") REFERENCES "Videos" ON DELETE CASCADE'
|
||||||
|
|
||||||
|
return sequelize.query(query)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
up,
|
||||||
|
down
|
||||||
|
}
|
|
@ -96,10 +96,10 @@ function executeMigration (actualVersion: number, entity: { version: string, scr
|
||||||
sequelize: db.sequelize
|
sequelize: db.sequelize
|
||||||
}
|
}
|
||||||
|
|
||||||
migrationScript.up(options)
|
return migrationScript.up(options)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// Update the new migration version
|
// Update the new migration version
|
||||||
db.Application.updateMigrationVersion(versionScript, t)
|
return db.Application.updateMigrationVersion(versionScript, t)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,8 @@ import {
|
||||||
Pod as FormatedPod
|
Pod as FormatedPod
|
||||||
} from '../../shared'
|
} from '../../shared'
|
||||||
|
|
||||||
type QaduParam = { videoId: string, type: RequestVideoQaduType }
|
type QaduParam = { videoId: number, type: RequestVideoQaduType }
|
||||||
type EventParam = { videoId: string, type: RequestVideoEventType }
|
type EventParam = { videoId: number, type: RequestVideoEventType }
|
||||||
|
|
||||||
const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
|
const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ import { logger } from '../../../helpers'
|
||||||
import { addVideoToFriends } from '../../../lib'
|
import { addVideoToFriends } from '../../../lib'
|
||||||
import { VideoInstance } from '../../../models'
|
import { VideoInstance } from '../../../models'
|
||||||
|
|
||||||
function process (data: { id: string }) {
|
function process (data: { videoUUID: string }) {
|
||||||
return db.Video.loadAndPopulateAuthorAndPodAndTags(data.id).then(video => {
|
return db.Video.loadByUUIDAndPopulateAuthorAndPodAndTags(data.videoUUID).then(video => {
|
||||||
return video.transcodeVideofile().then(() => video)
|
return video.transcodeVideofile().then(() => video)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { RequestVideoEventType, RemoteVideoEventRequest, RemoteVideoEventType }
|
||||||
|
|
||||||
export type RequestVideoEventSchedulerOptions = {
|
export type RequestVideoEventSchedulerOptions = {
|
||||||
type: RequestVideoEventType
|
type: RequestVideoEventType
|
||||||
videoId: string
|
videoId: number
|
||||||
count?: number
|
count?: number
|
||||||
transaction?: Sequelize.Transaction
|
transaction?: Sequelize.Transaction
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ class RequestVideoEventScheduler extends AbstractRequestScheduler<RequestsVideoE
|
||||||
*/
|
*/
|
||||||
const eventsPerVideoPerPod: {
|
const eventsPerVideoPerPod: {
|
||||||
[ podId: string ]: {
|
[ podId: string ]: {
|
||||||
[ videoRemoteId: string ]: {
|
[ videoUUID: string ]: {
|
||||||
views?: number
|
views?: number
|
||||||
likes?: number
|
likes?: number
|
||||||
dislikes?: number
|
dislikes?: number
|
||||||
|
@ -74,10 +74,10 @@ class RequestVideoEventScheduler extends AbstractRequestScheduler<RequestsVideoE
|
||||||
requestsToMakeGrouped[toPodId].ids.push(eventToProcess.id)
|
requestsToMakeGrouped[toPodId].ids.push(eventToProcess.id)
|
||||||
|
|
||||||
const eventsPerVideo = eventsPerVideoPerPod[toPodId]
|
const eventsPerVideo = eventsPerVideoPerPod[toPodId]
|
||||||
const remoteId = eventToProcess.video.remoteId
|
const uuid = eventToProcess.video.uuid
|
||||||
if (!eventsPerVideo[remoteId]) eventsPerVideo[remoteId] = {}
|
if (!eventsPerVideo[uuid]) eventsPerVideo[uuid] = {}
|
||||||
|
|
||||||
const events = eventsPerVideo[remoteId]
|
const events = eventsPerVideo[uuid]
|
||||||
if (!events[eventToProcess.type]) events[eventToProcess.type] = 0
|
if (!events[eventToProcess.type]) events[eventToProcess.type] = 0
|
||||||
|
|
||||||
events[eventToProcess.type] += eventToProcess.count
|
events[eventToProcess.type] += eventToProcess.count
|
||||||
|
@ -88,13 +88,13 @@ class RequestVideoEventScheduler extends AbstractRequestScheduler<RequestsVideoE
|
||||||
Object.keys(eventsPerVideoPerPod).forEach(toPodId => {
|
Object.keys(eventsPerVideoPerPod).forEach(toPodId => {
|
||||||
const eventsForPod = eventsPerVideoPerPod[toPodId]
|
const eventsForPod = eventsPerVideoPerPod[toPodId]
|
||||||
|
|
||||||
Object.keys(eventsForPod).forEach(remoteId => {
|
Object.keys(eventsForPod).forEach(uuid => {
|
||||||
const eventsForVideo = eventsForPod[remoteId]
|
const eventsForVideo = eventsForPod[uuid]
|
||||||
|
|
||||||
Object.keys(eventsForVideo).forEach(eventType => {
|
Object.keys(eventsForVideo).forEach(eventType => {
|
||||||
requestsToMakeGrouped[toPodId].datas.push({
|
requestsToMakeGrouped[toPodId].datas.push({
|
||||||
data: {
|
data: {
|
||||||
remoteId,
|
uuid,
|
||||||
eventType: eventType as RemoteVideoEventType,
|
eventType: eventType as RemoteVideoEventType,
|
||||||
count: +eventsForVideo[eventType]
|
count: +eventsForVideo[eventType]
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@ interface RequestsObjectsCustom<U> extends RequestsObjects<U> {
|
||||||
datas: U[]
|
datas: U[]
|
||||||
|
|
||||||
videos: {
|
videos: {
|
||||||
[ id: string ]: {
|
[ uuid: string ]: {
|
||||||
remoteId: string
|
uuid: string
|
||||||
likes?: number
|
likes?: number
|
||||||
dislikes?: number
|
dislikes?: number
|
||||||
views?: number
|
views?: number
|
||||||
|
@ -33,7 +33,7 @@ interface RequestsObjectsCustom<U> extends RequestsObjects<U> {
|
||||||
|
|
||||||
export type RequestVideoQaduSchedulerOptions = {
|
export type RequestVideoQaduSchedulerOptions = {
|
||||||
type: RequestVideoQaduType
|
type: RequestVideoQaduType
|
||||||
videoId: string
|
videoId: number
|
||||||
transaction?: Sequelize.Transaction
|
transaction?: Sequelize.Transaction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class RequestVideoQaduScheduler extends AbstractRequestScheduler<RequestsVideoQa
|
||||||
|
|
||||||
// Maybe another attribute was filled for this video
|
// Maybe another attribute was filled for this video
|
||||||
let videoData = requestsToMakeGrouped[hashKey].videos[video.id]
|
let videoData = requestsToMakeGrouped[hashKey].videos[video.id]
|
||||||
if (!videoData) videoData = { remoteId: null }
|
if (!videoData) videoData = { uuid: null }
|
||||||
|
|
||||||
switch (request.type) {
|
switch (request.type) {
|
||||||
case REQUEST_VIDEO_QADU_TYPES.LIKES:
|
case REQUEST_VIDEO_QADU_TYPES.LIKES:
|
||||||
|
@ -98,8 +98,8 @@ class RequestVideoQaduScheduler extends AbstractRequestScheduler<RequestsVideoQa
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not forget the remoteId so the remote pod can identify the video
|
// Do not forget the uuid so the remote pod can identify the video
|
||||||
videoData.remoteId = video.id
|
videoData.uuid = video.uuid
|
||||||
requestsToMakeGrouped[hashKey].ids.push(request.id)
|
requestsToMakeGrouped[hashKey].ids.push(request.id)
|
||||||
|
|
||||||
// Maybe there are multiple quick and dirty update for the same video
|
// Maybe there are multiple quick and dirty update for the same video
|
||||||
|
@ -110,8 +110,8 @@ class RequestVideoQaduScheduler extends AbstractRequestScheduler<RequestsVideoQa
|
||||||
|
|
||||||
// Now we deduped similar quick and dirty updates, we can build our requests datas
|
// Now we deduped similar quick and dirty updates, we can build our requests datas
|
||||||
Object.keys(requestsToMakeGrouped).forEach(hashKey => {
|
Object.keys(requestsToMakeGrouped).forEach(hashKey => {
|
||||||
Object.keys(requestsToMakeGrouped[hashKey].videos).forEach(videoId => {
|
Object.keys(requestsToMakeGrouped[hashKey].videos).forEach(videoUUID => {
|
||||||
const videoData = requestsToMakeGrouped[hashKey].videos[videoId]
|
const videoData = requestsToMakeGrouped[hashKey].videos[videoUUID]
|
||||||
|
|
||||||
requestsToMakeGrouped[hashKey].datas.push({
|
requestsToMakeGrouped[hashKey].datas.push({
|
||||||
data: videoData
|
data: videoData
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import 'express-validator'
|
import 'express-validator'
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
|
import * as Promise from 'bluebird'
|
||||||
|
import * as validator from 'validator'
|
||||||
|
|
||||||
import { database as db } from '../../initializers/database'
|
import { database as db } from '../../initializers/database'
|
||||||
import { checkErrors } from './utils'
|
import { checkErrors } from './utils'
|
||||||
import { logger } from '../../helpers'
|
import { logger } from '../../helpers'
|
||||||
|
import { VideoInstance } from '../../models'
|
||||||
|
|
||||||
function usersAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function usersAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
req.checkBody('username', 'Should have a valid username').isUserUsernameValid()
|
req.checkBody('username', 'Should have a valid username').isUserUsernameValid()
|
||||||
|
@ -59,12 +62,20 @@ function usersUpdateValidator (req: express.Request, res: express.Response, next
|
||||||
}
|
}
|
||||||
|
|
||||||
function usersVideoRatingValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function usersVideoRatingValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
req.checkParams('videoId', 'Should have a valid video id').notEmpty().isUUID(4)
|
req.checkParams('videoId', 'Should have a valid video id').notEmpty().isVideoIdOrUUIDValid()
|
||||||
|
|
||||||
logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
|
logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
|
||||||
|
|
||||||
checkErrors(req, res, function () {
|
checkErrors(req, res, function () {
|
||||||
db.Video.load(req.params.videoId)
|
let videoPromise: Promise<VideoInstance>
|
||||||
|
|
||||||
|
if (validator.isUUID(req.params.videoId)) {
|
||||||
|
videoPromise = db.Video.loadByUUID(req.params.videoId)
|
||||||
|
} else {
|
||||||
|
videoPromise = db.Video.load(req.params.videoId)
|
||||||
|
}
|
||||||
|
|
||||||
|
videoPromise
|
||||||
.then(video => {
|
.then(video => {
|
||||||
if (!video) return res.status(404).send('Video not found')
|
if (!video) return res.status(404).send('Video not found')
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import 'express-validator'
|
import 'express-validator'
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
|
import * as Promise from 'bluebird'
|
||||||
|
import * as validator from 'validator'
|
||||||
|
|
||||||
import { database as db } from '../../initializers/database'
|
import { database as db } from '../../initializers/database'
|
||||||
import { checkErrors } from './utils'
|
import { checkErrors } from './utils'
|
||||||
import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers'
|
import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers'
|
||||||
import { logger, isVideoDurationValid } from '../../helpers'
|
import { logger, isVideoDurationValid } from '../../helpers'
|
||||||
|
import { VideoInstance } from '../../models'
|
||||||
|
|
||||||
function videosAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function videosAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
// FIXME: Don't write an error message, it seems there is a bug with express-validator
|
// FIXME: Don't write an error message, it seems there is a bug with express-validator
|
||||||
|
@ -40,7 +43,7 @@ function videosAddValidator (req: express.Request, res: express.Response, next:
|
||||||
}
|
}
|
||||||
|
|
||||||
function videosUpdateValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function videosUpdateValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid()
|
||||||
req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid()
|
req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid()
|
||||||
req.checkBody('category', 'Should have a valid category').optional().isVideoCategoryValid()
|
req.checkBody('category', 'Should have a valid category').optional().isVideoCategoryValid()
|
||||||
req.checkBody('licence', 'Should have a valid licence').optional().isVideoLicenceValid()
|
req.checkBody('licence', 'Should have a valid licence').optional().isVideoLicenceValid()
|
||||||
|
@ -68,7 +71,7 @@ function videosUpdateValidator (req: express.Request, res: express.Response, nex
|
||||||
}
|
}
|
||||||
|
|
||||||
function videosGetValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function videosGetValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid()
|
||||||
|
|
||||||
logger.debug('Checking videosGet parameters', { parameters: req.params })
|
logger.debug('Checking videosGet parameters', { parameters: req.params })
|
||||||
|
|
||||||
|
@ -78,7 +81,7 @@ function videosGetValidator (req: express.Request, res: express.Response, next:
|
||||||
}
|
}
|
||||||
|
|
||||||
function videosRemoveValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function videosRemoveValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid()
|
||||||
|
|
||||||
logger.debug('Checking videosRemove parameters', { parameters: req.params })
|
logger.debug('Checking videosRemove parameters', { parameters: req.params })
|
||||||
|
|
||||||
|
@ -105,7 +108,7 @@ function videosSearchValidator (req: express.Request, res: express.Response, nex
|
||||||
}
|
}
|
||||||
|
|
||||||
function videoAbuseReportValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function videoAbuseReportValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid()
|
||||||
req.checkBody('reason', 'Should have a valid reason').isVideoAbuseReasonValid()
|
req.checkBody('reason', 'Should have a valid reason').isVideoAbuseReasonValid()
|
||||||
|
|
||||||
logger.debug('Checking videoAbuseReport parameters', { parameters: req.body })
|
logger.debug('Checking videoAbuseReport parameters', { parameters: req.body })
|
||||||
|
@ -116,7 +119,7 @@ function videoAbuseReportValidator (req: express.Request, res: express.Response,
|
||||||
}
|
}
|
||||||
|
|
||||||
function videoRateValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function videoRateValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid()
|
||||||
req.checkBody('rating', 'Should have a valid rate type').isVideoRatingTypeValid()
|
req.checkBody('rating', 'Should have a valid rate type').isVideoRatingTypeValid()
|
||||||
|
|
||||||
logger.debug('Checking videoRate parameters', { parameters: req.body })
|
logger.debug('Checking videoRate parameters', { parameters: req.body })
|
||||||
|
@ -127,7 +130,7 @@ function videoRateValidator (req: express.Request, res: express.Response, next:
|
||||||
}
|
}
|
||||||
|
|
||||||
function videosBlacklistValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function videosBlacklistValidator (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
req.checkParams('id', 'Should have a valid id').notEmpty().isVideoIdOrUUIDValid()
|
||||||
|
|
||||||
logger.debug('Checking videosBlacklist parameters', { parameters: req.params })
|
logger.debug('Checking videosBlacklist parameters', { parameters: req.params })
|
||||||
|
|
||||||
|
@ -157,7 +160,14 @@ export {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function checkVideoExists (id: string, res: express.Response, callback: () => void) {
|
function checkVideoExists (id: string, res: express.Response, callback: () => void) {
|
||||||
db.Video.loadAndPopulateAuthorAndPodAndTags(id).then(video => {
|
let promise: Promise<VideoInstance>
|
||||||
|
if (validator.isInt(id)) {
|
||||||
|
promise = db.Video.loadAndPopulateAuthorAndPodAndTags(+id)
|
||||||
|
} else { // UUID
|
||||||
|
promise = db.Video.loadByUUIDAndPopulateAuthorAndPodAndTags(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
promise.then(video => {
|
||||||
if (!video) return res.status(404).send('Video not found')
|
if (!video) return res.status(404).send('Video not found')
|
||||||
|
|
||||||
res.locals.video = video
|
res.locals.video = video
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as Promise from 'bluebird'
|
||||||
import { VideoRateType } from '../../../shared/models/videos/video-rate.type'
|
import { VideoRateType } from '../../../shared/models/videos/video-rate.type'
|
||||||
|
|
||||||
export namespace UserVideoRateMethods {
|
export namespace UserVideoRateMethods {
|
||||||
export type Load = (userId: number, videoId: string, transaction: Sequelize.Transaction) => Promise<UserVideoRateInstance>
|
export type Load = (userId: number, videoId: number, transaction: Sequelize.Transaction) => Promise<UserVideoRateInstance>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserVideoRateClass {
|
export interface UserVideoRateClass {
|
||||||
|
|
|
@ -65,7 +65,7 @@ function associate (models) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
load = function (userId: number, videoId: string, transaction: Sequelize.Transaction) {
|
load = function (userId: number, videoId: number, transaction: Sequelize.Transaction) {
|
||||||
const options: Sequelize.FindOptions = {
|
const options: Sequelize.FindOptions = {
|
||||||
where: {
|
where: {
|
||||||
userId,
|
userId,
|
||||||
|
|
|
@ -47,7 +47,7 @@ function associate (models) {
|
||||||
Tag.belongsToMany(models.Video, {
|
Tag.belongsToMany(models.Video, {
|
||||||
foreignKey: 'tagId',
|
foreignKey: 'tagId',
|
||||||
through: models.VideoTag,
|
through: models.VideoTag,
|
||||||
onDelete: 'cascade'
|
onDelete: 'CASCADE'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ export interface VideoAbuseClass {
|
||||||
export interface VideoAbuseAttributes {
|
export interface VideoAbuseAttributes {
|
||||||
reporterUsername: string
|
reporterUsername: string
|
||||||
reason: string
|
reason: string
|
||||||
videoId: string
|
videoId: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VideoAbuseInstance extends VideoAbuseClass, VideoAbuseAttributes, Sequelize.Instance<VideoAbuseAttributes> {
|
export interface VideoAbuseInstance extends VideoAbuseClass, VideoAbuseAttributes, Sequelize.Instance<VideoAbuseAttributes> {
|
||||||
|
|
|
@ -96,7 +96,7 @@ function associate (models) {
|
||||||
name: 'reporterPodId',
|
name: 'reporterPodId',
|
||||||
allowNull: true
|
allowNull: true
|
||||||
},
|
},
|
||||||
onDelete: 'cascade'
|
onDelete: 'CASCADE'
|
||||||
})
|
})
|
||||||
|
|
||||||
VideoAbuse.belongsTo(models.Video, {
|
VideoAbuse.belongsTo(models.Video, {
|
||||||
|
@ -104,7 +104,7 @@ function associate (models) {
|
||||||
name: 'videoId',
|
name: 'videoId',
|
||||||
allowNull: false
|
allowNull: false
|
||||||
},
|
},
|
||||||
onDelete: 'cascade'
|
onDelete: 'CASCADE'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ export namespace BlacklistedVideoMethods {
|
||||||
|
|
||||||
export type LoadById = (id: number) => Promise<BlacklistedVideoInstance>
|
export type LoadById = (id: number) => Promise<BlacklistedVideoInstance>
|
||||||
|
|
||||||
export type LoadByVideoId = (id: string) => Promise<BlacklistedVideoInstance>
|
export type LoadByVideoId = (id: number) => Promise<BlacklistedVideoInstance>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BlacklistedVideoClass {
|
export interface BlacklistedVideoClass {
|
||||||
|
@ -30,7 +30,7 @@ export interface BlacklistedVideoClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BlacklistedVideoAttributes {
|
export interface BlacklistedVideoAttributes {
|
||||||
videoId: string
|
videoId: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BlacklistedVideoInstance
|
export interface BlacklistedVideoInstance
|
||||||
|
|
|
@ -60,8 +60,11 @@ toFormatedJSON = function (this: BlacklistedVideoInstance) {
|
||||||
|
|
||||||
function associate (models) {
|
function associate (models) {
|
||||||
BlacklistedVideo.belongsTo(models.Video, {
|
BlacklistedVideo.belongsTo(models.Video, {
|
||||||
foreignKey: 'videoId',
|
foreignKey: {
|
||||||
onDelete: 'cascade'
|
name: 'videoId',
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
onDelete: 'CASCADE'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +95,7 @@ loadById = function (id: number) {
|
||||||
return BlacklistedVideo.findById(id)
|
return BlacklistedVideo.findById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
loadByVideoId = function (id: string) {
|
loadByVideoId = function (id: number) {
|
||||||
const query = {
|
const query = {
|
||||||
where: {
|
where: {
|
||||||
videoId: id
|
videoId: id
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { Video as FormatedVideo } from '../../../shared/models/videos/video.mode
|
||||||
import { ResultList } from '../../../shared/models/result-list.model'
|
import { ResultList } from '../../../shared/models/result-list.model'
|
||||||
|
|
||||||
export type FormatedAddRemoteVideo = {
|
export type FormatedAddRemoteVideo = {
|
||||||
|
uuid: string
|
||||||
name: string
|
name: string
|
||||||
category: number
|
category: number
|
||||||
licence: number
|
licence: number
|
||||||
|
@ -16,7 +17,6 @@ export type FormatedAddRemoteVideo = {
|
||||||
nsfw: boolean
|
nsfw: boolean
|
||||||
description: string
|
description: string
|
||||||
infoHash: string
|
infoHash: string
|
||||||
remoteId: string
|
|
||||||
author: string
|
author: string
|
||||||
duration: number
|
duration: number
|
||||||
thumbnailData: string
|
thumbnailData: string
|
||||||
|
@ -30,6 +30,7 @@ export type FormatedAddRemoteVideo = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FormatedUpdateRemoteVideo = {
|
export type FormatedUpdateRemoteVideo = {
|
||||||
|
uuid: string
|
||||||
name: string
|
name: string
|
||||||
category: number
|
category: number
|
||||||
licence: number
|
licence: number
|
||||||
|
@ -37,7 +38,6 @@ export type FormatedUpdateRemoteVideo = {
|
||||||
nsfw: boolean
|
nsfw: boolean
|
||||||
description: string
|
description: string
|
||||||
infoHash: string
|
infoHash: string
|
||||||
remoteId: string
|
|
||||||
author: string
|
author: string
|
||||||
duration: number
|
duration: number
|
||||||
tags: string[]
|
tags: string[]
|
||||||
|
@ -80,10 +80,12 @@ export namespace VideoMethods {
|
||||||
sort: string
|
sort: string
|
||||||
) => Promise< ResultList<VideoInstance> >
|
) => Promise< ResultList<VideoInstance> >
|
||||||
|
|
||||||
export type Load = (id: string) => Promise<VideoInstance>
|
export type Load = (id: number) => Promise<VideoInstance>
|
||||||
export type LoadByHostAndRemoteId = (fromHost: string, remoteId: string) => Promise<VideoInstance>
|
export type LoadByUUID = (uuid: string) => Promise<VideoInstance>
|
||||||
export type LoadAndPopulateAuthor = (id: string) => Promise<VideoInstance>
|
export type LoadByHostAndUUID = (fromHost: string, uuid: string) => Promise<VideoInstance>
|
||||||
export type LoadAndPopulateAuthorAndPodAndTags = (id: string) => Promise<VideoInstance>
|
export type LoadAndPopulateAuthor = (id: number) => Promise<VideoInstance>
|
||||||
|
export type LoadAndPopulateAuthorAndPodAndTags = (id: number) => Promise<VideoInstance>
|
||||||
|
export type LoadByUUIDAndPopulateAuthorAndPodAndTags = (uuid: string) => Promise<VideoInstance>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VideoClass {
|
export interface VideoClass {
|
||||||
|
@ -102,19 +104,21 @@ export interface VideoClass {
|
||||||
getDurationFromFile: VideoMethods.GetDurationFromFile
|
getDurationFromFile: VideoMethods.GetDurationFromFile
|
||||||
list: VideoMethods.List
|
list: VideoMethods.List
|
||||||
listForApi: VideoMethods.ListForApi
|
listForApi: VideoMethods.ListForApi
|
||||||
loadByHostAndRemoteId: VideoMethods.LoadByHostAndRemoteId
|
loadByHostAndUUID: VideoMethods.LoadByHostAndUUID
|
||||||
listOwnedAndPopulateAuthorAndTags: VideoMethods.ListOwnedAndPopulateAuthorAndTags
|
listOwnedAndPopulateAuthorAndTags: VideoMethods.ListOwnedAndPopulateAuthorAndTags
|
||||||
listOwnedByAuthor: VideoMethods.ListOwnedByAuthor
|
listOwnedByAuthor: VideoMethods.ListOwnedByAuthor
|
||||||
load: VideoMethods.Load
|
load: VideoMethods.Load
|
||||||
|
loadByUUID: VideoMethods.LoadByUUID
|
||||||
loadAndPopulateAuthor: VideoMethods.LoadAndPopulateAuthor
|
loadAndPopulateAuthor: VideoMethods.LoadAndPopulateAuthor
|
||||||
loadAndPopulateAuthorAndPodAndTags: VideoMethods.LoadAndPopulateAuthorAndPodAndTags
|
loadAndPopulateAuthorAndPodAndTags: VideoMethods.LoadAndPopulateAuthorAndPodAndTags
|
||||||
|
loadByUUIDAndPopulateAuthorAndPodAndTags: VideoMethods.LoadByUUIDAndPopulateAuthorAndPodAndTags
|
||||||
searchAndPopulateAuthorAndPodAndTags: VideoMethods.SearchAndPopulateAuthorAndPodAndTags
|
searchAndPopulateAuthorAndPodAndTags: VideoMethods.SearchAndPopulateAuthorAndPodAndTags
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VideoAttributes {
|
export interface VideoAttributes {
|
||||||
|
uuid?: string
|
||||||
name: string
|
name: string
|
||||||
extname: string
|
extname: string
|
||||||
remoteId: string
|
|
||||||
category: number
|
category: number
|
||||||
licence: number
|
licence: number
|
||||||
language: number
|
language: number
|
||||||
|
@ -125,13 +129,14 @@ export interface VideoAttributes {
|
||||||
views?: number
|
views?: number
|
||||||
likes?: number
|
likes?: number
|
||||||
dislikes?: number
|
dislikes?: number
|
||||||
|
remote: boolean
|
||||||
|
|
||||||
Author?: AuthorInstance
|
Author?: AuthorInstance
|
||||||
Tags?: TagInstance[]
|
Tags?: TagInstance[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VideoInstance extends VideoClass, VideoAttributes, Sequelize.Instance<VideoAttributes> {
|
export interface VideoInstance extends VideoClass, VideoAttributes, Sequelize.Instance<VideoAttributes> {
|
||||||
id: string
|
id: number
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
updatedAt: Date
|
updatedAt: Date
|
||||||
|
|
||||||
|
|
|
@ -62,21 +62,23 @@ let generateThumbnailFromData: VideoMethods.GenerateThumbnailFromData
|
||||||
let getDurationFromFile: VideoMethods.GetDurationFromFile
|
let getDurationFromFile: VideoMethods.GetDurationFromFile
|
||||||
let list: VideoMethods.List
|
let list: VideoMethods.List
|
||||||
let listForApi: VideoMethods.ListForApi
|
let listForApi: VideoMethods.ListForApi
|
||||||
let loadByHostAndRemoteId: VideoMethods.LoadByHostAndRemoteId
|
let loadByHostAndUUID: VideoMethods.LoadByHostAndUUID
|
||||||
let listOwnedAndPopulateAuthorAndTags: VideoMethods.ListOwnedAndPopulateAuthorAndTags
|
let listOwnedAndPopulateAuthorAndTags: VideoMethods.ListOwnedAndPopulateAuthorAndTags
|
||||||
let listOwnedByAuthor: VideoMethods.ListOwnedByAuthor
|
let listOwnedByAuthor: VideoMethods.ListOwnedByAuthor
|
||||||
let load: VideoMethods.Load
|
let load: VideoMethods.Load
|
||||||
|
let loadByUUID: VideoMethods.LoadByUUID
|
||||||
let loadAndPopulateAuthor: VideoMethods.LoadAndPopulateAuthor
|
let loadAndPopulateAuthor: VideoMethods.LoadAndPopulateAuthor
|
||||||
let loadAndPopulateAuthorAndPodAndTags: VideoMethods.LoadAndPopulateAuthorAndPodAndTags
|
let loadAndPopulateAuthorAndPodAndTags: VideoMethods.LoadAndPopulateAuthorAndPodAndTags
|
||||||
|
let loadByUUIDAndPopulateAuthorAndPodAndTags: VideoMethods.LoadByUUIDAndPopulateAuthorAndPodAndTags
|
||||||
let searchAndPopulateAuthorAndPodAndTags: VideoMethods.SearchAndPopulateAuthorAndPodAndTags
|
let searchAndPopulateAuthorAndPodAndTags: VideoMethods.SearchAndPopulateAuthorAndPodAndTags
|
||||||
|
|
||||||
export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
|
export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
|
||||||
Video = sequelize.define<VideoInstance, VideoAttributes>('Video',
|
Video = sequelize.define<VideoInstance, VideoAttributes>('Video',
|
||||||
{
|
{
|
||||||
id: {
|
uuid: {
|
||||||
type: DataTypes.UUID,
|
type: DataTypes.UUID,
|
||||||
defaultValue: DataTypes.UUIDV4,
|
defaultValue: DataTypes.UUIDV4,
|
||||||
primaryKey: true,
|
allowNull: false,
|
||||||
validate: {
|
validate: {
|
||||||
isUUID: 4
|
isUUID: 4
|
||||||
}
|
}
|
||||||
|
@ -95,13 +97,6 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
||||||
type: DataTypes.ENUM(values(CONSTRAINTS_FIELDS.VIDEOS.EXTNAME)),
|
type: DataTypes.ENUM(values(CONSTRAINTS_FIELDS.VIDEOS.EXTNAME)),
|
||||||
allowNull: false
|
allowNull: false
|
||||||
},
|
},
|
||||||
remoteId: {
|
|
||||||
type: DataTypes.UUID,
|
|
||||||
allowNull: true,
|
|
||||||
validate: {
|
|
||||||
isUUID: 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
category: {
|
category: {
|
||||||
type: DataTypes.INTEGER,
|
type: DataTypes.INTEGER,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
|
@ -199,6 +194,11 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
||||||
min: 0,
|
min: 0,
|
||||||
isInt: true
|
isInt: true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
remote: {
|
||||||
|
type: DataTypes.BOOLEAN,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -206,9 +206,6 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
||||||
{
|
{
|
||||||
fields: [ 'authorId' ]
|
fields: [ 'authorId' ]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
fields: [ 'remoteId' ]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
fields: [ 'name' ]
|
fields: [ 'name' ]
|
||||||
},
|
},
|
||||||
|
@ -226,6 +223,9 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fields: [ 'likes' ]
|
fields: [ 'likes' ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: [ 'uuid' ]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
hooks: {
|
hooks: {
|
||||||
|
@ -246,9 +246,11 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
||||||
listOwnedAndPopulateAuthorAndTags,
|
listOwnedAndPopulateAuthorAndTags,
|
||||||
listOwnedByAuthor,
|
listOwnedByAuthor,
|
||||||
load,
|
load,
|
||||||
loadByHostAndRemoteId,
|
loadByUUID,
|
||||||
|
loadByHostAndUUID,
|
||||||
loadAndPopulateAuthor,
|
loadAndPopulateAuthor,
|
||||||
loadAndPopulateAuthorAndPodAndTags,
|
loadAndPopulateAuthorAndPodAndTags,
|
||||||
|
loadByUUIDAndPopulateAuthorAndPodAndTags,
|
||||||
searchAndPopulateAuthorAndPodAndTags,
|
searchAndPopulateAuthorAndPodAndTags,
|
||||||
removeFromBlacklist
|
removeFromBlacklist
|
||||||
]
|
]
|
||||||
|
@ -289,8 +291,9 @@ function beforeCreate (video: VideoInstance, options: { transaction: Sequelize.T
|
||||||
)
|
)
|
||||||
|
|
||||||
if (CONFIG.TRANSCODING.ENABLED === true) {
|
if (CONFIG.TRANSCODING.ENABLED === true) {
|
||||||
|
// Put uuid because we don't have id auto incremented for now
|
||||||
const dataInput = {
|
const dataInput = {
|
||||||
id: video.id
|
videoUUID: video.uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.push(
|
tasks.push(
|
||||||
|
@ -313,7 +316,7 @@ function afterDestroy (video: VideoInstance) {
|
||||||
|
|
||||||
if (video.isOwned()) {
|
if (video.isOwned()) {
|
||||||
const removeVideoToFriendsParams = {
|
const removeVideoToFriendsParams = {
|
||||||
remoteId: video.id
|
uuid: video.uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.push(
|
tasks.push(
|
||||||
|
@ -381,34 +384,27 @@ generateMagnetUri = function (this: VideoInstance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideoFilename = function (this: VideoInstance) {
|
getVideoFilename = function (this: VideoInstance) {
|
||||||
if (this.isOwned()) return this.id + this.extname
|
return this.uuid + this.extname
|
||||||
|
|
||||||
return this.remoteId + this.extname
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getThumbnailName = function (this: VideoInstance) {
|
getThumbnailName = function (this: VideoInstance) {
|
||||||
// We always have a copy of the thumbnail
|
// We always have a copy of the thumbnail
|
||||||
return this.id + '.jpg'
|
const extension = '.jpg'
|
||||||
|
return this.uuid + extension
|
||||||
}
|
}
|
||||||
|
|
||||||
getPreviewName = function (this: VideoInstance) {
|
getPreviewName = function (this: VideoInstance) {
|
||||||
const extension = '.jpg'
|
const extension = '.jpg'
|
||||||
|
return this.uuid + extension
|
||||||
if (this.isOwned()) return this.id + extension
|
|
||||||
|
|
||||||
return this.remoteId + extension
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getTorrentName = function (this: VideoInstance) {
|
getTorrentName = function (this: VideoInstance) {
|
||||||
const extension = '.torrent'
|
const extension = '.torrent'
|
||||||
|
return this.uuid + extension
|
||||||
if (this.isOwned()) return this.id + extension
|
|
||||||
|
|
||||||
return this.remoteId + extension
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isOwned = function (this: VideoInstance) {
|
isOwned = function (this: VideoInstance) {
|
||||||
return this.remoteId === null
|
return this.remote === false
|
||||||
}
|
}
|
||||||
|
|
||||||
toFormatedJSON = function (this: VideoInstance) {
|
toFormatedJSON = function (this: VideoInstance) {
|
||||||
|
@ -435,6 +431,7 @@ toFormatedJSON = function (this: VideoInstance) {
|
||||||
|
|
||||||
const json = {
|
const json = {
|
||||||
id: this.id,
|
id: this.id,
|
||||||
|
uuid: this.uuid,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
category: this.category,
|
category: this.category,
|
||||||
categoryLabel,
|
categoryLabel,
|
||||||
|
@ -467,6 +464,7 @@ toAddRemoteJSON = function (this: VideoInstance) {
|
||||||
|
|
||||||
return readFileBufferPromise(thumbnailPath).then(thumbnailData => {
|
return readFileBufferPromise(thumbnailPath).then(thumbnailData => {
|
||||||
const remoteVideo = {
|
const remoteVideo = {
|
||||||
|
uuid: this.uuid,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
category: this.category,
|
category: this.category,
|
||||||
licence: this.licence,
|
licence: this.licence,
|
||||||
|
@ -474,7 +472,6 @@ toAddRemoteJSON = function (this: VideoInstance) {
|
||||||
nsfw: this.nsfw,
|
nsfw: this.nsfw,
|
||||||
description: this.description,
|
description: this.description,
|
||||||
infoHash: this.infoHash,
|
infoHash: this.infoHash,
|
||||||
remoteId: this.id,
|
|
||||||
author: this.Author.name,
|
author: this.Author.name,
|
||||||
duration: this.duration,
|
duration: this.duration,
|
||||||
thumbnailData: thumbnailData.toString('binary'),
|
thumbnailData: thumbnailData.toString('binary'),
|
||||||
|
@ -493,6 +490,7 @@ toAddRemoteJSON = function (this: VideoInstance) {
|
||||||
|
|
||||||
toUpdateRemoteJSON = function (this: VideoInstance) {
|
toUpdateRemoteJSON = function (this: VideoInstance) {
|
||||||
const json = {
|
const json = {
|
||||||
|
uuid: this.uuid,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
category: this.category,
|
category: this.category,
|
||||||
licence: this.licence,
|
licence: this.licence,
|
||||||
|
@ -500,7 +498,6 @@ toUpdateRemoteJSON = function (this: VideoInstance) {
|
||||||
nsfw: this.nsfw,
|
nsfw: this.nsfw,
|
||||||
description: this.description,
|
description: this.description,
|
||||||
infoHash: this.infoHash,
|
infoHash: this.infoHash,
|
||||||
remoteId: this.id,
|
|
||||||
author: this.Author.name,
|
author: this.Author.name,
|
||||||
duration: this.duration,
|
duration: this.duration,
|
||||||
tags: map<TagInstance, string>(this.Tags, 'name'),
|
tags: map<TagInstance, string>(this.Tags, 'name'),
|
||||||
|
@ -615,10 +612,10 @@ listForApi = function (start: number, count: number, sort: string) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
loadByHostAndRemoteId = function (fromHost: string, remoteId: string) {
|
loadByHostAndUUID = function (fromHost: string, uuid: string) {
|
||||||
const query = {
|
const query = {
|
||||||
where: {
|
where: {
|
||||||
remoteId: remoteId
|
uuid
|
||||||
},
|
},
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
|
@ -640,10 +637,9 @@ loadByHostAndRemoteId = function (fromHost: string, remoteId: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
listOwnedAndPopulateAuthorAndTags = function () {
|
listOwnedAndPopulateAuthorAndTags = function () {
|
||||||
// If remoteId is null this is *our* video
|
|
||||||
const query = {
|
const query = {
|
||||||
where: {
|
where: {
|
||||||
remoteId: null
|
remote: false
|
||||||
},
|
},
|
||||||
include: [ Video['sequelize'].models.Author, Video['sequelize'].models.Tag ]
|
include: [ Video['sequelize'].models.Author, Video['sequelize'].models.Tag ]
|
||||||
}
|
}
|
||||||
|
@ -654,7 +650,7 @@ listOwnedAndPopulateAuthorAndTags = function () {
|
||||||
listOwnedByAuthor = function (author: string) {
|
listOwnedByAuthor = function (author: string) {
|
||||||
const query = {
|
const query = {
|
||||||
where: {
|
where: {
|
||||||
remoteId: null
|
remote: false
|
||||||
},
|
},
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
|
@ -669,11 +665,20 @@ listOwnedByAuthor = function (author: string) {
|
||||||
return Video.findAll(query)
|
return Video.findAll(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
load = function (id: string) {
|
load = function (id: number) {
|
||||||
return Video.findById(id)
|
return Video.findById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
loadAndPopulateAuthor = function (id: string) {
|
loadByUUID = function (uuid: string) {
|
||||||
|
const query = {
|
||||||
|
where: {
|
||||||
|
uuid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Video.findOne(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
loadAndPopulateAuthor = function (id: number) {
|
||||||
const options = {
|
const options = {
|
||||||
include: [ Video['sequelize'].models.Author ]
|
include: [ Video['sequelize'].models.Author ]
|
||||||
}
|
}
|
||||||
|
@ -681,7 +686,7 @@ loadAndPopulateAuthor = function (id: string) {
|
||||||
return Video.findById(id, options)
|
return Video.findById(id, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
loadAndPopulateAuthorAndPodAndTags = function (id: string) {
|
loadAndPopulateAuthorAndPodAndTags = function (id: number) {
|
||||||
const options = {
|
const options = {
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
|
@ -695,6 +700,23 @@ loadAndPopulateAuthorAndPodAndTags = function (id: string) {
|
||||||
return Video.findById(id, options)
|
return Video.findById(id, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadByUUIDAndPopulateAuthorAndPodAndTags = function (uuid: string) {
|
||||||
|
const options = {
|
||||||
|
where: {
|
||||||
|
uuid
|
||||||
|
},
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Video['sequelize'].models.Author,
|
||||||
|
include: [ { model: Video['sequelize'].models.Pod, required: false } ]
|
||||||
|
},
|
||||||
|
Video['sequelize'].models.Tag
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
return Video.findOne(options)
|
||||||
|
}
|
||||||
|
|
||||||
searchAndPopulateAuthorAndPodAndTags = function (value: string, field: string, start: number, count: number, sort: string) {
|
searchAndPopulateAuthorAndPodAndTags = function (value: string, field: string, start: number, count: number, sort: string) {
|
||||||
const podInclude: Sequelize.IncludeOptions = {
|
const podInclude: Sequelize.IncludeOptions = {
|
||||||
model: Video['sequelize'].models.Pod,
|
model: Video['sequelize'].models.Pod,
|
||||||
|
|
|
@ -44,7 +44,7 @@ describe('Test remote videos API validators', function () {
|
||||||
describe('When adding a video', function () {
|
describe('When adding a video', function () {
|
||||||
it('Should check when adding a video')
|
it('Should check when adding a video')
|
||||||
|
|
||||||
it('Should not add an existing remoteId and host pair')
|
it('Should not add an existing uuid')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('When removing a video', function () {
|
describe('When removing a video', function () {
|
||||||
|
|
|
@ -20,6 +20,7 @@ const videosUtils = require('../utils/videos')
|
||||||
describe('Test multiple pods', function () {
|
describe('Test multiple pods', function () {
|
||||||
let servers = []
|
let servers = []
|
||||||
const toRemove = []
|
const toRemove = []
|
||||||
|
let videoUUID = ''
|
||||||
|
|
||||||
before(function (done) {
|
before(function (done) {
|
||||||
this.timeout(120000)
|
this.timeout(120000)
|
||||||
|
@ -746,6 +747,36 @@ describe('Test multiple pods', function () {
|
||||||
expect(videos[0].name).not.to.equal(toRemove[1].name)
|
expect(videos[0].name).not.to.equal(toRemove[1].name)
|
||||||
expect(videos[1].name).not.to.equal(toRemove[1].name)
|
expect(videos[1].name).not.to.equal(toRemove[1].name)
|
||||||
|
|
||||||
|
videoUUID = videos[0].uuid
|
||||||
|
|
||||||
|
callback()
|
||||||
|
})
|
||||||
|
}, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should get the same video by UUID on each pod', function (done) {
|
||||||
|
let baseVideo = null
|
||||||
|
each(servers, function (server, callback) {
|
||||||
|
videosUtils.getVideo(server.url, videoUUID, function (err, res) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
const video = res.body
|
||||||
|
|
||||||
|
if (baseVideo === null) {
|
||||||
|
baseVideo = video
|
||||||
|
return callback()
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(baseVideo.name).to.equal(video.name)
|
||||||
|
expect(baseVideo.uuid).to.equal(video.uuid)
|
||||||
|
expect(baseVideo.category).to.equal(video.category)
|
||||||
|
expect(baseVideo.language).to.equal(video.language)
|
||||||
|
expect(baseVideo.licence).to.equal(video.licence)
|
||||||
|
expect(baseVideo.category).to.equal(video.category)
|
||||||
|
expect(baseVideo.nsfw).to.equal(video.nsfw)
|
||||||
|
expect(baseVideo.author).to.equal(video.author)
|
||||||
|
expect(baseVideo.tags).to.deep.equal(video.tags)
|
||||||
|
|
||||||
callback()
|
callback()
|
||||||
})
|
})
|
||||||
}, done)
|
}, done)
|
||||||
|
|
|
@ -19,6 +19,7 @@ const videosUtils = require('../utils/videos')
|
||||||
describe('Test a single pod', function () {
|
describe('Test a single pod', function () {
|
||||||
let server = null
|
let server = null
|
||||||
let videoId = -1
|
let videoId = -1
|
||||||
|
let videoUUID = ''
|
||||||
let videosListBase = null
|
let videosListBase = null
|
||||||
|
|
||||||
before(function (done) {
|
before(function (done) {
|
||||||
|
@ -140,6 +141,7 @@ describe('Test a single pod', function () {
|
||||||
expect(test).to.equal(true)
|
expect(test).to.equal(true)
|
||||||
|
|
||||||
videoId = video.id
|
videoId = video.id
|
||||||
|
videoUUID = video.uuid
|
||||||
|
|
||||||
webtorrent.add(video.magnetUri, function (torrent) {
|
webtorrent.add(video.magnetUri, function (torrent) {
|
||||||
expect(torrent.files).to.exist
|
expect(torrent.files).to.exist
|
||||||
|
@ -181,18 +183,33 @@ describe('Test a single pod', function () {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
expect(test).to.equal(true)
|
expect(test).to.equal(true)
|
||||||
|
|
||||||
// Wait the async views increment
|
// Wait the async views increment
|
||||||
setTimeout(done, 500)
|
setTimeout(done, 500)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should get the video by UUID', function (done) {
|
||||||
|
// Yes, this could be long
|
||||||
|
this.timeout(60000)
|
||||||
|
|
||||||
|
videosUtils.getVideo(server.url, videoUUID, function (err, res) {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
const video = res.body
|
||||||
|
expect(video.name).to.equal('my super name')
|
||||||
|
|
||||||
|
// Wait the async views increment
|
||||||
|
setTimeout(done, 500)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('Should have the views updated', function (done) {
|
it('Should have the views updated', function (done) {
|
||||||
videosUtils.getVideo(server.url, videoId, function (err, res) {
|
videosUtils.getVideo(server.url, videoId, function (err, res) {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
|
||||||
const video = res.body
|
const video = res.body
|
||||||
expect(video.views).to.equal(1)
|
expect(video.views).to.equal(2)
|
||||||
|
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export interface RemoteQaduVideoData {
|
export interface RemoteQaduVideoData {
|
||||||
remoteId: string
|
uuid: string
|
||||||
views?: number
|
views?: number
|
||||||
likes?: number
|
likes?: number
|
||||||
dislikes?: number
|
dislikes?: number
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { RemoteVideoRequest } from './remote-video-request.model'
|
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||||
|
|
||||||
export interface RemoteVideoCreateData {
|
export interface RemoteVideoCreateData {
|
||||||
remoteId: string
|
uuid: string
|
||||||
author: string
|
author: string
|
||||||
tags: string[]
|
tags: string[]
|
||||||
name: string
|
name: string
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
export type RemoteVideoEventType = 'views' | 'likes' | 'dislikes'
|
export type RemoteVideoEventType = 'views' | 'likes' | 'dislikes'
|
||||||
|
|
||||||
export interface RemoteVideoEventData {
|
export interface RemoteVideoEventData {
|
||||||
remoteId: string
|
uuid: string
|
||||||
eventType: RemoteVideoEventType
|
eventType: RemoteVideoEventType
|
||||||
count: number
|
count: number
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { RemoteVideoRequest } from './remote-video-request.model'
|
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||||
|
|
||||||
export interface RemoteVideoRemoveData {
|
export interface RemoteVideoRemoveData {
|
||||||
remoteId: string
|
uuid: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RemoteVideoRemoveRequest extends RemoteVideoRequest {
|
export interface RemoteVideoRemoveRequest extends RemoteVideoRequest {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { RemoteVideoRequest } from './remote-video-request.model'
|
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||||
|
|
||||||
export interface RemoteVideoReportAbuseData {
|
export interface RemoteVideoReportAbuseData {
|
||||||
videoRemoteId: string
|
videoUUID: string
|
||||||
reporterUsername: string
|
reporterUsername: string
|
||||||
reportReason: string
|
reportReason: string
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export interface RemoteVideoUpdateData {
|
export interface RemoteVideoUpdateData {
|
||||||
remoteId: string
|
uuid: string
|
||||||
tags: string[]
|
tags: string[]
|
||||||
name: string
|
name: string
|
||||||
extname: string
|
extname: string
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { UserVideoRateType } from './user-video-rate.type'
|
import { UserVideoRateType } from './user-video-rate.type'
|
||||||
|
|
||||||
export interface UserVideoRate {
|
export interface UserVideoRate {
|
||||||
videoId: string
|
videoId: number
|
||||||
rating: UserVideoRateType
|
rating: UserVideoRateType
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,6 @@ export interface VideoAbuse {
|
||||||
reporterPodHost: string
|
reporterPodHost: string
|
||||||
reason: string
|
reason: string
|
||||||
reporterUsername: string
|
reporterUsername: string
|
||||||
videoId: string
|
videoId: number
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export interface BlacklistedVideo {
|
export interface BlacklistedVideo {
|
||||||
id: number
|
id: number
|
||||||
videoId: string
|
videoId: number
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
export interface Video {
|
export interface Video {
|
||||||
id: string
|
id: number
|
||||||
|
uuid: string
|
||||||
author: string
|
author: string
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
categoryLabel: string
|
categoryLabel: string
|
||||||
|
|
Loading…
Reference in New Issue