Better typescript typing for a better world
This commit is contained in:
parent
7a214f746b
commit
4771e0008d
|
@ -15,7 +15,7 @@ import { FriendService } from '../shared'
|
||||||
})
|
})
|
||||||
export class FriendAddComponent implements OnInit {
|
export class FriendAddComponent implements OnInit {
|
||||||
form: FormGroup
|
form: FormGroup
|
||||||
hosts = [ ]
|
hosts: string[] = [ ]
|
||||||
error: string = null
|
error: string = null
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'rxjs/add/operator/catch'
|
||||||
import 'rxjs/add/operator/map'
|
import 'rxjs/add/operator/map'
|
||||||
|
|
||||||
import { AuthHttp, RestExtractor, RestDataSource, User } from '../../../shared'
|
import { AuthHttp, RestExtractor, RestDataSource, User } from '../../../shared'
|
||||||
|
import { UserCreate } from '../../../../../../shared'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
|
@ -13,14 +14,8 @@ export class UserService {
|
||||||
private restExtractor: RestExtractor
|
private restExtractor: RestExtractor
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
addUser (username: string, password: string, email: string) {
|
addUser (userCreate: UserCreate) {
|
||||||
const body = {
|
return this.authHttp.post(UserService.BASE_USERS_URL, userCreate)
|
||||||
username,
|
|
||||||
email,
|
|
||||||
password
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.authHttp.post(UserService.BASE_USERS_URL, body)
|
|
||||||
.map(this.restExtractor.extractDataBool)
|
.map(this.restExtractor.extractDataBool)
|
||||||
.catch(this.restExtractor.handleError)
|
.catch(this.restExtractor.handleError)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
USER_EMAIL,
|
USER_EMAIL,
|
||||||
USER_PASSWORD
|
USER_PASSWORD
|
||||||
} from '../../../shared'
|
} from '../../../shared'
|
||||||
|
import { UserCreate } from '../../../../../../shared'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-user-add',
|
selector: 'my-user-add',
|
||||||
|
@ -57,11 +58,11 @@ export class UserAddComponent extends FormReactive implements OnInit {
|
||||||
addUser () {
|
addUser () {
|
||||||
this.error = null
|
this.error = null
|
||||||
|
|
||||||
const { username, password, email } = this.form.value
|
const userCreate: UserCreate = this.form.value
|
||||||
|
|
||||||
this.userService.addUser(username, password, email).subscribe(
|
this.userService.addUser(userCreate).subscribe(
|
||||||
() => {
|
() => {
|
||||||
this.notificationsService.success('Success', `User ${username} created.`)
|
this.notificationsService.success('Success', `User ${userCreate.username} created.`)
|
||||||
this.router.navigate([ '/admin/users/list' ])
|
this.router.navigate([ '/admin/users/list' ])
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
UserService,
|
UserService,
|
||||||
USER_PASSWORD
|
USER_PASSWORD
|
||||||
} from '../../shared'
|
} from '../../shared'
|
||||||
|
import { UserUpdate } from '../../../../../shared'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-account-details',
|
selector: 'my-account-details',
|
||||||
|
@ -50,7 +51,7 @@ export class AccountDetailsComponent extends FormReactive implements OnInit {
|
||||||
|
|
||||||
updateDetails () {
|
updateDetails () {
|
||||||
const displayNSFW = this.form.value['displayNSFW']
|
const displayNSFW = this.form.value['displayNSFW']
|
||||||
const details = {
|
const details: UserUpdate = {
|
||||||
displayNSFW
|
displayNSFW
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Do not use the barrel (dependency loop)
|
// Do not use the barrel (dependency loop)
|
||||||
import { UserRole } from '../../../../../shared/models/user.model'
|
import { UserRole } from '../../../../../shared/models/users/user-role.type'
|
||||||
import { User } from '../../shared/users/user.model'
|
import { User } from '../../shared/users/user.model'
|
||||||
|
|
||||||
export type TokenOptions = {
|
export type TokenOptions = {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'rxjs/add/operator/map'
|
||||||
import { AuthService } from '../../core'
|
import { AuthService } from '../../core'
|
||||||
import { AuthHttp } from '../auth'
|
import { AuthHttp } from '../auth'
|
||||||
import { RestExtractor } from '../rest'
|
import { RestExtractor } from '../rest'
|
||||||
|
import { UserCreate, UserUpdate } from '../../../../../shared'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
|
@ -27,7 +28,7 @@ export class UserService {
|
||||||
|
|
||||||
changePassword (newPassword: string) {
|
changePassword (newPassword: string) {
|
||||||
const url = UserService.BASE_USERS_URL + this.authService.getUser().id
|
const url = UserService.BASE_USERS_URL + this.authService.getUser().id
|
||||||
const body = {
|
const body: UserUpdate = {
|
||||||
password: newPassword
|
password: newPassword
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ export class UserService {
|
||||||
.catch((res) => this.restExtractor.handleError(res))
|
.catch((res) => this.restExtractor.handleError(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDetails (details: { displayNSFW: boolean }) {
|
updateDetails (details: UserUpdate) {
|
||||||
const url = UserService.BASE_USERS_URL + this.authService.getUser().id
|
const url = UserService.BASE_USERS_URL + this.authService.getUser().id
|
||||||
|
|
||||||
return this.authHttp.put(url, details)
|
return this.authHttp.put(url, details)
|
||||||
|
@ -44,14 +45,8 @@ export class UserService {
|
||||||
.catch((res) => this.restExtractor.handleError(res))
|
.catch((res) => this.restExtractor.handleError(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
signup (username: string, password: string, email: string) {
|
signup (userCreate: UserCreate) {
|
||||||
const body = {
|
return this.http.post(UserService.BASE_USERS_URL + 'register', userCreate)
|
||||||
username,
|
|
||||||
email,
|
|
||||||
password
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.http.post(UserService.BASE_USERS_URL + 'register', body)
|
|
||||||
.map(this.restExtractor.extractDataBool)
|
.map(this.restExtractor.extractDataBool)
|
||||||
.catch(this.restExtractor.handleError)
|
.catch(this.restExtractor.handleError)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {
|
||||||
USER_EMAIL,
|
USER_EMAIL,
|
||||||
USER_PASSWORD
|
USER_PASSWORD
|
||||||
} from '../shared'
|
} from '../shared'
|
||||||
|
import { UserCreate } from '../../../../shared'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-signup',
|
selector: 'my-signup',
|
||||||
|
@ -58,11 +59,11 @@ export class SignupComponent extends FormReactive implements OnInit {
|
||||||
signup () {
|
signup () {
|
||||||
this.error = null
|
this.error = null
|
||||||
|
|
||||||
const { username, password, email } = this.form.value
|
const userCreate: UserCreate = this.form.value
|
||||||
|
|
||||||
this.userService.signup(username, password, email).subscribe(
|
this.userService.signup(userCreate).subscribe(
|
||||||
() => {
|
() => {
|
||||||
this.notificationsService.success('Success', `Registration for ${username} complete.`)
|
this.notificationsService.success('Success', `Registration for ${userCreate.username} complete.`)
|
||||||
this.router.navigate([ '/videos/list' ])
|
this.router.navigate([ '/videos/list' ])
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,13 @@ import {
|
||||||
UserService
|
UserService
|
||||||
} from '../../shared'
|
} from '../../shared'
|
||||||
import { Video } from './video.model'
|
import { Video } from './video.model'
|
||||||
import { UserVideoRate, VideoRateType } from '../../../../../shared'
|
import {
|
||||||
|
UserVideoRate,
|
||||||
|
VideoRateType,
|
||||||
|
VideoUpdate,
|
||||||
|
VideoAbuseCreate,
|
||||||
|
UserVideoRateUpdate
|
||||||
|
} from '../../../../../shared'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class VideoService {
|
export class VideoService {
|
||||||
|
@ -35,42 +41,15 @@ export class VideoService {
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
loadVideoCategories () {
|
loadVideoCategories () {
|
||||||
return this.http.get(VideoService.BASE_VIDEO_URL + 'categories')
|
return this.loadVideoAttributeEnum('categories', this.videoCategories)
|
||||||
.map(this.restExtractor.extractDataGet)
|
|
||||||
.subscribe(data => {
|
|
||||||
Object.keys(data).forEach(categoryKey => {
|
|
||||||
this.videoCategories.push({
|
|
||||||
id: parseInt(categoryKey, 10),
|
|
||||||
label: data[categoryKey]
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadVideoLicences () {
|
loadVideoLicences () {
|
||||||
return this.http.get(VideoService.BASE_VIDEO_URL + 'licences')
|
return this.loadVideoAttributeEnum('licences', this.videoLicences)
|
||||||
.map(this.restExtractor.extractDataGet)
|
|
||||||
.subscribe(data => {
|
|
||||||
Object.keys(data).forEach(licenceKey => {
|
|
||||||
this.videoLicences.push({
|
|
||||||
id: parseInt(licenceKey, 10),
|
|
||||||
label: data[licenceKey]
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadVideoLanguages () {
|
loadVideoLanguages () {
|
||||||
return this.http.get(VideoService.BASE_VIDEO_URL + 'languages')
|
return this.loadVideoAttributeEnum('languages', this.videoLanguages)
|
||||||
.map(this.restExtractor.extractDataGet)
|
|
||||||
.subscribe(data => {
|
|
||||||
Object.keys(data).forEach(languageKey => {
|
|
||||||
this.videoLanguages.push({
|
|
||||||
id: parseInt(languageKey, 10),
|
|
||||||
label: data[languageKey]
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideo (id: string): Observable<Video> {
|
getVideo (id: string): Observable<Video> {
|
||||||
|
@ -83,13 +62,14 @@ export class VideoService {
|
||||||
updateVideo (video: Video) {
|
updateVideo (video: Video) {
|
||||||
const language = video.language ? video.language : null
|
const language = video.language ? video.language : null
|
||||||
|
|
||||||
const body = {
|
const body: VideoUpdate = {
|
||||||
name: video.name,
|
name: video.name,
|
||||||
category: video.category,
|
category: video.category,
|
||||||
licence: video.licence,
|
licence: video.licence,
|
||||||
language,
|
language,
|
||||||
description: video.description,
|
description: video.description,
|
||||||
tags: video.tags
|
tags: video.tags,
|
||||||
|
nsfw: video.nsfw
|
||||||
}
|
}
|
||||||
|
|
||||||
const headers = new Headers({ 'Content-Type': 'application/json' })
|
const headers = new Headers({ 'Content-Type': 'application/json' })
|
||||||
|
@ -128,7 +108,7 @@ export class VideoService {
|
||||||
|
|
||||||
reportVideo (id: string, reason: string) {
|
reportVideo (id: string, reason: string) {
|
||||||
const url = VideoService.BASE_VIDEO_URL + id + '/abuse'
|
const url = VideoService.BASE_VIDEO_URL + id + '/abuse'
|
||||||
const body = {
|
const body: VideoAbuseCreate = {
|
||||||
reason
|
reason
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +141,7 @@ export class VideoService {
|
||||||
|
|
||||||
private setVideoRate (id: string, rateType: VideoRateType) {
|
private setVideoRate (id: string, rateType: VideoRateType) {
|
||||||
const url = VideoService.BASE_VIDEO_URL + id + '/rate'
|
const url = VideoService.BASE_VIDEO_URL + id + '/rate'
|
||||||
const body = {
|
const body: UserVideoRateUpdate = {
|
||||||
rating: rateType
|
rating: rateType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,4 +160,17 @@ export class VideoService {
|
||||||
|
|
||||||
return { videos, totalVideos }
|
return { videos, totalVideos }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private loadVideoAttributeEnum (attributeName: 'categories' | 'licences' | 'languages', hashToPopulate: { id: number, label: string }[]) {
|
||||||
|
return this.http.get(VideoService.BASE_VIDEO_URL + attributeName)
|
||||||
|
.map(this.restExtractor.extractDataGet)
|
||||||
|
.subscribe(data => {
|
||||||
|
Object.keys(data).forEach(dataKey => {
|
||||||
|
hashToPopulate.push({
|
||||||
|
id: parseInt(dataKey, 10),
|
||||||
|
label: data[dataKey]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {
|
||||||
VIDEO_TAGS
|
VIDEO_TAGS
|
||||||
} from '../../shared'
|
} from '../../shared'
|
||||||
import { VideoService } from '../shared'
|
import { VideoService } from '../shared'
|
||||||
|
import { VideoCreate } from '../../../../../shared'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-videos-add',
|
selector: 'my-videos-add',
|
||||||
|
@ -98,23 +99,25 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||||
removeAfterUpload: true
|
removeAfterUpload: true
|
||||||
})
|
})
|
||||||
|
|
||||||
this.uploader.onBuildItemForm = (item, form) => {
|
this.uploader.onBuildItemForm = (item, form: FormData) => {
|
||||||
const name = this.form.value['name']
|
const formValue: VideoCreate = this.form.value
|
||||||
const nsfw = this.form.value['nsfw']
|
|
||||||
const category = this.form.value['category']
|
const name = formValue.name
|
||||||
const licence = this.form.value['licence']
|
const nsfw = formValue.nsfw
|
||||||
const language = this.form.value['language']
|
const category = formValue.category
|
||||||
const description = this.form.value['description']
|
const licence = formValue.licence
|
||||||
const tags = this.form.value['tags']
|
const language = formValue.language
|
||||||
|
const description = formValue.description
|
||||||
|
const tags = formValue.tags
|
||||||
|
|
||||||
form.append('name', name)
|
form.append('name', name)
|
||||||
form.append('category', category)
|
form.append('category', '' + category)
|
||||||
form.append('nsfw', nsfw)
|
form.append('nsfw', '' + nsfw)
|
||||||
form.append('licence', licence)
|
form.append('licence', '' + licence)
|
||||||
|
|
||||||
// Language is optional
|
// Language is optional
|
||||||
if (language) {
|
if (language) {
|
||||||
form.append('language', language)
|
form.append('language', '' + language)
|
||||||
}
|
}
|
||||||
|
|
||||||
form.append('description', description)
|
form.append('description', description)
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
cd client || exit -1
|
cd client || exit -1
|
||||||
|
|
||||||
npm run webpack-dev-server -- --config config/webpack.dev.js --progress --profile --colors --watch --content-base src/ --inline --hot
|
npm run webpack-dev-server -- --config config/webpack.dev.js --progress --profile --colors --watch --content-base src/ --inline --hot --open
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
NODE_ENV=test concurrently \
|
NODE_ENV=test concurrently -k \
|
||||||
"npm run tsc -- --sourceMap && npm run nodemon -- --delay 2 --watch ./dist dist/server" \
|
"npm run tsc -- --sourceMap && npm run nodemon -- --delay 2 --watch ./dist dist/server" \
|
||||||
"npm run tsc -- --sourceMap -w"
|
"npm run tsc -- --sourceMap -w"
|
||||||
|
|
|
@ -2,6 +2,7 @@ import * as express from 'express'
|
||||||
|
|
||||||
import { database as db } from '../../../initializers/database'
|
import { database as db } from '../../../initializers/database'
|
||||||
import { checkSignature, signatureValidator } from '../../../middlewares'
|
import { checkSignature, signatureValidator } from '../../../middlewares'
|
||||||
|
import { PodSignature } from '../../../../shared'
|
||||||
|
|
||||||
const remotePodsRouter = express.Router()
|
const remotePodsRouter = express.Router()
|
||||||
|
|
||||||
|
@ -21,12 +22,11 @@ export {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function removePods (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function removePods (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const host = req.body.signature.host
|
const signature: PodSignature = req.body.signature
|
||||||
|
const host = signature.host
|
||||||
|
|
||||||
db.Pod.loadByHost(host)
|
db.Pod.loadByHost(host)
|
||||||
.then(pod => {
|
.then(pod => pod.destroy())
|
||||||
return pod.destroy()
|
|
||||||
})
|
|
||||||
.then(() => res.type('json').status(204).end())
|
.then(() => res.type('json').status(204).end())
|
||||||
.catch(err => next(err))
|
.catch(err => next(err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,17 @@ import {
|
||||||
import { logger, retryTransactionWrapper } from '../../../helpers'
|
import { logger, retryTransactionWrapper } from '../../../helpers'
|
||||||
import { quickAndDirtyUpdatesVideoToFriends } from '../../../lib'
|
import { quickAndDirtyUpdatesVideoToFriends } from '../../../lib'
|
||||||
import { PodInstance, VideoInstance } from '../../../models'
|
import { PodInstance, VideoInstance } from '../../../models'
|
||||||
|
import {
|
||||||
|
RemoteVideoRequest,
|
||||||
|
RemoteVideoCreateData,
|
||||||
|
RemoteVideoUpdateData,
|
||||||
|
RemoteVideoRemoveData,
|
||||||
|
RemoteVideoReportAbuseData,
|
||||||
|
RemoteQaduVideoRequest,
|
||||||
|
RemoteQaduVideoData,
|
||||||
|
RemoteVideoEventRequest,
|
||||||
|
RemoteVideoEventData
|
||||||
|
} from '../../../../shared'
|
||||||
|
|
||||||
const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
|
const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
|
||||||
|
|
||||||
|
@ -60,11 +71,11 @@ export {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function remoteVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function remoteVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const requests = req.body.data
|
const requests: RemoteVideoRequest[] = req.body.data
|
||||||
const fromPod = res.locals.secure.pod
|
const fromPod = res.locals.secure.pod
|
||||||
|
|
||||||
// We need to process in the same order to keep consistency
|
// We need to process in the same order to keep consistency
|
||||||
Promise.each(requests, (request: any) => {
|
Promise.each(requests, request => {
|
||||||
const data = request.data
|
const data = request.data
|
||||||
|
|
||||||
// Get the function we need to call in order to process the request
|
// Get the function we need to call in order to process the request
|
||||||
|
@ -83,10 +94,10 @@ function remoteVideos (req: express.Request, res: express.Response, next: expres
|
||||||
}
|
}
|
||||||
|
|
||||||
function remoteVideosQadu (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function remoteVideosQadu (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const requests = req.body.data
|
const requests: RemoteQaduVideoRequest[] = req.body.data
|
||||||
const fromPod = res.locals.secure.pod
|
const fromPod = res.locals.secure.pod
|
||||||
|
|
||||||
Promise.each(requests, (request: any) => {
|
Promise.each(requests, request => {
|
||||||
const videoData = request.data
|
const videoData = request.data
|
||||||
|
|
||||||
return quickAndDirtyUpdateVideoRetryWrapper(videoData, fromPod)
|
return quickAndDirtyUpdateVideoRetryWrapper(videoData, fromPod)
|
||||||
|
@ -97,10 +108,10 @@ function remoteVideosQadu (req: express.Request, res: express.Response, next: ex
|
||||||
}
|
}
|
||||||
|
|
||||||
function remoteVideosEvents (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function remoteVideosEvents (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const requests = req.body.data
|
const requests: RemoteVideoEventRequest[] = req.body.data
|
||||||
const fromPod = res.locals.secure.pod
|
const fromPod = res.locals.secure.pod
|
||||||
|
|
||||||
Promise.each(requests, (request: any) => {
|
Promise.each(requests, request => {
|
||||||
const eventData = request.data
|
const eventData = request.data
|
||||||
|
|
||||||
return processVideosEventsRetryWrapper(eventData, fromPod)
|
return processVideosEventsRetryWrapper(eventData, fromPod)
|
||||||
|
@ -110,7 +121,7 @@ function remoteVideosEvents (req: express.Request, res: express.Response, next:
|
||||||
return res.type('json').status(204).end()
|
return res.type('json').status(204).end()
|
||||||
}
|
}
|
||||||
|
|
||||||
function processVideosEventsRetryWrapper (eventData: any, fromPod: PodInstance) {
|
function processVideosEventsRetryWrapper (eventData: RemoteVideoEventData, fromPod: PodInstance) {
|
||||||
const options = {
|
const options = {
|
||||||
arguments: [ eventData, fromPod ],
|
arguments: [ eventData, fromPod ],
|
||||||
errorMessage: 'Cannot process videos events with many retries.'
|
errorMessage: 'Cannot process videos events with many retries.'
|
||||||
|
@ -119,7 +130,7 @@ function processVideosEventsRetryWrapper (eventData: any, fromPod: PodInstance)
|
||||||
return retryTransactionWrapper(processVideosEvents, options)
|
return retryTransactionWrapper(processVideosEvents, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
function processVideosEvents (eventData: any, fromPod: PodInstance) {
|
function processVideosEvents (eventData: RemoteVideoEventData, fromPod: PodInstance) {
|
||||||
|
|
||||||
return db.sequelize.transaction(t => {
|
return db.sequelize.transaction(t => {
|
||||||
return fetchOwnedVideo(eventData.remoteId)
|
return fetchOwnedVideo(eventData.remoteId)
|
||||||
|
@ -172,7 +183,7 @@ function processVideosEvents (eventData: any, fromPod: PodInstance) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function quickAndDirtyUpdateVideoRetryWrapper (videoData: any, fromPod: PodInstance) {
|
function quickAndDirtyUpdateVideoRetryWrapper (videoData: RemoteQaduVideoData, fromPod: PodInstance) {
|
||||||
const options = {
|
const options = {
|
||||||
arguments: [ videoData, fromPod ],
|
arguments: [ videoData, fromPod ],
|
||||||
errorMessage: 'Cannot update quick and dirty the remote video with many retries.'
|
errorMessage: 'Cannot update quick and dirty the remote video with many retries.'
|
||||||
|
@ -181,7 +192,7 @@ function quickAndDirtyUpdateVideoRetryWrapper (videoData: any, fromPod: PodInsta
|
||||||
return retryTransactionWrapper(quickAndDirtyUpdateVideo, options)
|
return retryTransactionWrapper(quickAndDirtyUpdateVideo, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
function quickAndDirtyUpdateVideo (videoData: any, fromPod: PodInstance) {
|
function quickAndDirtyUpdateVideo (videoData: RemoteQaduVideoData, fromPod: PodInstance) {
|
||||||
let videoName
|
let videoName
|
||||||
|
|
||||||
return db.sequelize.transaction(t => {
|
return db.sequelize.transaction(t => {
|
||||||
|
@ -211,7 +222,7 @@ function quickAndDirtyUpdateVideo (videoData: any, fromPod: PodInstance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle retries on fail
|
// Handle retries on fail
|
||||||
function addRemoteVideoRetryWrapper (videoToCreateData: any, fromPod: PodInstance) {
|
function addRemoteVideoRetryWrapper (videoToCreateData: RemoteVideoCreateData, fromPod: PodInstance) {
|
||||||
const options = {
|
const options = {
|
||||||
arguments: [ videoToCreateData, fromPod ],
|
arguments: [ videoToCreateData, fromPod ],
|
||||||
errorMessage: 'Cannot insert the remote video with many retries.'
|
errorMessage: 'Cannot insert the remote video with many retries.'
|
||||||
|
@ -220,7 +231,7 @@ function addRemoteVideoRetryWrapper (videoToCreateData: any, fromPod: PodInstanc
|
||||||
return retryTransactionWrapper(addRemoteVideo, options)
|
return retryTransactionWrapper(addRemoteVideo, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
function addRemoteVideo (videoToCreateData: any, fromPod: PodInstance) {
|
function addRemoteVideo (videoToCreateData: RemoteVideoCreateData, fromPod: PodInstance) {
|
||||||
logger.debug('Adding remote video "%s".', videoToCreateData.remoteId)
|
logger.debug('Adding remote video "%s".', videoToCreateData.remoteId)
|
||||||
|
|
||||||
return db.sequelize.transaction(t => {
|
return db.sequelize.transaction(t => {
|
||||||
|
@ -293,7 +304,7 @@ function addRemoteVideo (videoToCreateData: any, fromPod: PodInstance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle retries on fail
|
// Handle retries on fail
|
||||||
function updateRemoteVideoRetryWrapper (videoAttributesToUpdate: any, fromPod: PodInstance) {
|
function updateRemoteVideoRetryWrapper (videoAttributesToUpdate: RemoteVideoUpdateData, fromPod: PodInstance) {
|
||||||
const options = {
|
const options = {
|
||||||
arguments: [ videoAttributesToUpdate, fromPod ],
|
arguments: [ videoAttributesToUpdate, fromPod ],
|
||||||
errorMessage: 'Cannot update the remote video with many retries'
|
errorMessage: 'Cannot update the remote video with many retries'
|
||||||
|
@ -302,7 +313,7 @@ function updateRemoteVideoRetryWrapper (videoAttributesToUpdate: any, fromPod: P
|
||||||
return retryTransactionWrapper(updateRemoteVideo, options)
|
return retryTransactionWrapper(updateRemoteVideo, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateRemoteVideo (videoAttributesToUpdate: any, fromPod: PodInstance) {
|
function updateRemoteVideo (videoAttributesToUpdate: RemoteVideoUpdateData, fromPod: PodInstance) {
|
||||||
logger.debug('Updating remote video "%s".', videoAttributesToUpdate.remoteId)
|
logger.debug('Updating remote video "%s".', videoAttributesToUpdate.remoteId)
|
||||||
|
|
||||||
return db.sequelize.transaction(t => {
|
return db.sequelize.transaction(t => {
|
||||||
|
@ -346,7 +357,7 @@ function updateRemoteVideo (videoAttributesToUpdate: any, fromPod: PodInstance)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeRemoteVideo (videoToRemoveData: any, 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 fetchRemoteVideo(fromPod.host, videoToRemoveData.remoteId)
|
||||||
.then(video => {
|
.then(video => {
|
||||||
|
@ -358,7 +369,7 @@ function removeRemoteVideo (videoToRemoveData: any, fromPod: PodInstance) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function reportAbuseRemoteVideo (reportData: any, fromPod: PodInstance) {
|
function reportAbuseRemoteVideo (reportData: RemoteVideoReportAbuseData, fromPod: PodInstance) {
|
||||||
return fetchOwnedVideo(reportData.videoRemoteId)
|
return fetchOwnedVideo(reportData.videoRemoteId)
|
||||||
.then(video => {
|
.then(video => {
|
||||||
logger.debug('Reporting remote abuse for video %s.', video.id)
|
logger.debug('Reporting remote abuse for video %s.', video.id)
|
||||||
|
|
|
@ -17,7 +17,7 @@ import {
|
||||||
setUsersSort,
|
setUsersSort,
|
||||||
token
|
token
|
||||||
} from '../../middlewares'
|
} from '../../middlewares'
|
||||||
import { UserVideoRate as FormatedUserVideoRate } from '../../../shared'
|
import { UserVideoRate as FormatedUserVideoRate, UserCreate, UserUpdate } from '../../../shared'
|
||||||
|
|
||||||
const usersRouter = express.Router()
|
const usersRouter = express.Router()
|
||||||
|
|
||||||
|
@ -78,10 +78,12 @@ export {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function createUser (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function createUser (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
|
const body: UserCreate = req.body
|
||||||
|
|
||||||
const user = db.User.build({
|
const user = db.User.build({
|
||||||
username: req.body.username,
|
username: body.username,
|
||||||
password: req.body.password,
|
password: body.password,
|
||||||
email: req.body.email,
|
email: body.email,
|
||||||
displayNSFW: false,
|
displayNSFW: false,
|
||||||
role: USER_ROLES.USER
|
role: USER_ROLES.USER
|
||||||
})
|
})
|
||||||
|
@ -132,10 +134,12 @@ function removeUser (req: express.Request, res: express.Response, next: express.
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateUser (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function updateUser (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
|
const body: UserUpdate = req.body
|
||||||
|
|
||||||
db.User.loadByUsername(res.locals.oauth.token.user.username)
|
db.User.loadByUsername(res.locals.oauth.token.user.username)
|
||||||
.then(user => {
|
.then(user => {
|
||||||
if (req.body.password) user.password = req.body.password
|
if (body.password) user.password = body.password
|
||||||
if (req.body.displayNSFW !== undefined) user.displayNSFW = req.body.displayNSFW
|
if (body.displayNSFW !== undefined) user.displayNSFW = body.displayNSFW
|
||||||
|
|
||||||
return user.save()
|
return user.save()
|
||||||
})
|
})
|
||||||
|
|
|
@ -17,6 +17,7 @@ import {
|
||||||
setPagination
|
setPagination
|
||||||
} from '../../../middlewares'
|
} from '../../../middlewares'
|
||||||
import { VideoInstance } from '../../../models'
|
import { VideoInstance } from '../../../models'
|
||||||
|
import { VideoAbuseCreate } from '../../../../shared'
|
||||||
|
|
||||||
const abuseVideoRouter = express.Router()
|
const abuseVideoRouter = express.Router()
|
||||||
|
|
||||||
|
@ -63,10 +64,11 @@ 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
|
||||||
const reporterUsername = res.locals.oauth.token.User.username
|
const reporterUsername = res.locals.oauth.token.User.username
|
||||||
|
const body: VideoAbuseCreate = req.body
|
||||||
|
|
||||||
const abuse = {
|
const abuse = {
|
||||||
reporterUsername,
|
reporterUsername,
|
||||||
reason: req.body.reason,
|
reason: body.reason,
|
||||||
videoId: videoInstance.id,
|
videoId: videoInstance.id,
|
||||||
reporterPodId: null // This is our pod that reported this abuse
|
reporterPodId: null // This is our pod that reported this abuse
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import {
|
||||||
renamePromise
|
renamePromise
|
||||||
} from '../../../helpers'
|
} from '../../../helpers'
|
||||||
import { TagInstance } from '../../../models'
|
import { TagInstance } from '../../../models'
|
||||||
|
import { VideoCreate, VideoUpdate } from '../../../../shared'
|
||||||
|
|
||||||
import { abuseVideoRouter } from './abuse'
|
import { abuseVideoRouter } from './abuse'
|
||||||
import { blacklistRouter } from './blacklist'
|
import { blacklistRouter } from './blacklist'
|
||||||
|
@ -155,7 +156,7 @@ function addVideoRetryWrapper (req: express.Request, res: express.Response, next
|
||||||
}
|
}
|
||||||
|
|
||||||
function addVideo (req: express.Request, res: express.Response, videoFile: Express.Multer.File) {
|
function addVideo (req: express.Request, res: express.Response, videoFile: Express.Multer.File) {
|
||||||
const videoInfos = req.body
|
const videoInfos: VideoCreate = req.body
|
||||||
|
|
||||||
return db.sequelize.transaction(t => {
|
return db.sequelize.transaction(t => {
|
||||||
const user = res.locals.oauth.token.User
|
const user = res.locals.oauth.token.User
|
||||||
|
@ -257,7 +258,7 @@ function updateVideoRetryWrapper (req: express.Request, res: express.Response, n
|
||||||
function updateVideo (req: express.Request, res: express.Response) {
|
function updateVideo (req: express.Request, res: express.Response) {
|
||||||
const videoInstance = res.locals.video
|
const videoInstance = res.locals.video
|
||||||
const videoFieldsSave = videoInstance.toJSON()
|
const videoFieldsSave = videoInstance.toJSON()
|
||||||
const videoInfosToUpdate = req.body
|
const videoInfosToUpdate: VideoUpdate = req.body
|
||||||
|
|
||||||
return db.sequelize.transaction(t => {
|
return db.sequelize.transaction(t => {
|
||||||
let tagsPromise: Promise<TagInstance[]>
|
let tagsPromise: Promise<TagInstance[]>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
|
import * as Promise from 'bluebird'
|
||||||
|
|
||||||
import { database as db } from '../../../initializers/database'
|
import { database as db } from '../../../initializers/database'
|
||||||
import {
|
import {
|
||||||
|
@ -18,6 +19,7 @@ import {
|
||||||
authenticate,
|
authenticate,
|
||||||
videoRateValidator
|
videoRateValidator
|
||||||
} from '../../../middlewares'
|
} from '../../../middlewares'
|
||||||
|
import { UserVideoRateUpdate, VideoRateType } from '../../../../shared'
|
||||||
|
|
||||||
const rateVideoRouter = express.Router()
|
const rateVideoRouter = express.Router()
|
||||||
|
|
||||||
|
@ -47,7 +49,8 @@ function rateVideoRetryWrapper (req: express.Request, res: express.Response, nex
|
||||||
}
|
}
|
||||||
|
|
||||||
function rateVideo (req: express.Request, res: express.Response) {
|
function rateVideo (req: express.Request, res: express.Response) {
|
||||||
const rateType = req.body.rating
|
const body: UserVideoRateUpdate = req.body
|
||||||
|
const rateType = body.rating
|
||||||
const videoInstance = res.locals.video
|
const videoInstance = res.locals.video
|
||||||
const userInstance = res.locals.oauth.token.User
|
const userInstance = res.locals.oauth.token.User
|
||||||
|
|
||||||
|
@ -62,24 +65,34 @@ function rateVideo (req: express.Request, res: express.Response) {
|
||||||
if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++
|
if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++
|
||||||
else if (rateType === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
|
else if (rateType === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
|
||||||
|
|
||||||
|
let promise: Promise<any>
|
||||||
|
|
||||||
// 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 remove it from the video 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--
|
||||||
|
|
||||||
previousRate.type = rateType
|
if (rateType === 'none') { // Destroy previous rate
|
||||||
|
promise = previousRate.destroy()
|
||||||
|
} else { // Update previous rate
|
||||||
|
previousRate.type = rateType as VideoRateType
|
||||||
|
|
||||||
return previousRate.save(options).then(() => ({ t, likesToIncrement, dislikesToIncrement }))
|
promise = previousRate.save()
|
||||||
} else { // There was not a previous rate, insert a new one
|
}
|
||||||
|
} else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate
|
||||||
const query = {
|
const query = {
|
||||||
userId: userInstance.id,
|
userId: userInstance.id,
|
||||||
videoId: videoInstance.id,
|
videoId: videoInstance.id,
|
||||||
type: rateType
|
type: rateType
|
||||||
}
|
}
|
||||||
|
|
||||||
return db.UserVideoRate.create(query, options).then(() => ({ likesToIncrement, dislikesToIncrement }))
|
promise = db.UserVideoRate.create(query, options)
|
||||||
|
} else {
|
||||||
|
promise = Promise.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return promise.then(() => ({ likesToIncrement, dislikesToIncrement }))
|
||||||
})
|
})
|
||||||
.then(({ likesToIncrement, dislikesToIncrement }) => {
|
.then(({ likesToIncrement, dislikesToIncrement }) => {
|
||||||
const options = { transaction: t }
|
const options = { transaction: t }
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
CONFIG
|
CONFIG
|
||||||
} from '../initializers'
|
} from '../initializers'
|
||||||
import { PodInstance } from '../models'
|
import { PodInstance } from '../models'
|
||||||
|
import { PodSignature } from '../../shared'
|
||||||
import { sign } from './peertube-crypto'
|
import { sign } from './peertube-crypto'
|
||||||
|
|
||||||
type MakeRetryRequestParams = {
|
type MakeRetryRequestParams = {
|
||||||
|
@ -37,9 +38,18 @@ type MakeSecureRequestParams = {
|
||||||
}
|
}
|
||||||
function makeSecureRequest (params: MakeSecureRequestParams) {
|
function makeSecureRequest (params: MakeSecureRequestParams) {
|
||||||
return new Promise<{ response: request.RequestResponse, body: any }>((res, rej) => {
|
return new Promise<{ response: request.RequestResponse, body: any }>((res, rej) => {
|
||||||
const requestParams = {
|
const requestParams: {
|
||||||
|
url: string,
|
||||||
|
json: {
|
||||||
|
signature: PodSignature,
|
||||||
|
data: any
|
||||||
|
}
|
||||||
|
} = {
|
||||||
url: REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path,
|
url: REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path,
|
||||||
json: {}
|
json: {
|
||||||
|
signature: null,
|
||||||
|
data: null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.method !== 'POST') {
|
if (params.method !== 'POST') {
|
||||||
|
@ -58,14 +68,14 @@ function makeSecureRequest (params: MakeSecureRequestParams) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sign(dataToSign).then(signature => {
|
sign(dataToSign).then(signature => {
|
||||||
requestParams.json['signature'] = {
|
requestParams.json.signature = {
|
||||||
host, // Which host we pretend to be
|
host, // Which host we pretend to be
|
||||||
signature
|
signature
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are data informations
|
// If there are data informations
|
||||||
if (params.data) {
|
if (params.data) {
|
||||||
requestParams.json['data'] = params.data
|
requestParams.json.data = params.data
|
||||||
}
|
}
|
||||||
|
|
||||||
request.post(requestParams, (err, response, body) => err ? rej(err) : res({ response, body }))
|
request.post(requestParams, (err, response, body) => err ? rej(err) : res({ response, body }))
|
||||||
|
|
|
@ -34,7 +34,11 @@ import {
|
||||||
import {
|
import {
|
||||||
RequestEndpoint,
|
RequestEndpoint,
|
||||||
RequestVideoEventType,
|
RequestVideoEventType,
|
||||||
RequestVideoQaduType
|
RequestVideoQaduType,
|
||||||
|
RemoteVideoCreateData,
|
||||||
|
RemoteVideoUpdateData,
|
||||||
|
RemoteVideoRemoveData,
|
||||||
|
RemoteVideoReportAbuseData
|
||||||
} from '../../shared'
|
} from '../../shared'
|
||||||
|
|
||||||
type QaduParam = { videoId: string, type: RequestVideoQaduType }
|
type QaduParam = { videoId: string, type: RequestVideoQaduType }
|
||||||
|
@ -52,7 +56,7 @@ function activateSchedulers () {
|
||||||
requestVideoEventScheduler.activate()
|
requestVideoEventScheduler.activate()
|
||||||
}
|
}
|
||||||
|
|
||||||
function addVideoToFriends (videoData: Object, transaction: Sequelize.Transaction) {
|
function addVideoToFriends (videoData: RemoteVideoCreateData, transaction: Sequelize.Transaction) {
|
||||||
const options = {
|
const options = {
|
||||||
type: ENDPOINT_ACTIONS.ADD,
|
type: ENDPOINT_ACTIONS.ADD,
|
||||||
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
||||||
|
@ -62,7 +66,7 @@ function addVideoToFriends (videoData: Object, transaction: Sequelize.Transactio
|
||||||
return createRequest(options)
|
return createRequest(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateVideoToFriends (videoData: Object, transaction: Sequelize.Transaction) {
|
function updateVideoToFriends (videoData: RemoteVideoUpdateData, transaction: Sequelize.Transaction) {
|
||||||
const options = {
|
const options = {
|
||||||
type: ENDPOINT_ACTIONS.UPDATE,
|
type: ENDPOINT_ACTIONS.UPDATE,
|
||||||
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
||||||
|
@ -72,7 +76,7 @@ function updateVideoToFriends (videoData: Object, transaction: Sequelize.Transac
|
||||||
return createRequest(options)
|
return createRequest(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeVideoToFriends (videoParams: Object) {
|
function removeVideoToFriends (videoParams: RemoteVideoRemoveData) {
|
||||||
const options = {
|
const options = {
|
||||||
type: ENDPOINT_ACTIONS.REMOVE,
|
type: ENDPOINT_ACTIONS.REMOVE,
|
||||||
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
||||||
|
@ -82,7 +86,7 @@ function removeVideoToFriends (videoParams: Object) {
|
||||||
return createRequest(options)
|
return createRequest(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
function reportAbuseVideoToFriend (reportData: Object, video: VideoInstance, transaction: Sequelize.Transaction) {
|
function reportAbuseVideoToFriend (reportData: RemoteVideoReportAbuseData, video: VideoInstance, transaction: Sequelize.Transaction) {
|
||||||
const options = {
|
const options = {
|
||||||
type: ENDPOINT_ACTIONS.REPORT_ABUSE,
|
type: ENDPOINT_ACTIONS.REPORT_ABUSE,
|
||||||
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
||||||
|
|
|
@ -10,6 +10,15 @@ import {
|
||||||
REQUESTS_INTERVAL
|
REQUESTS_INTERVAL
|
||||||
} from '../../initializers'
|
} from '../../initializers'
|
||||||
|
|
||||||
|
interface RequestsObjects<U> {
|
||||||
|
[ id: string ]: {
|
||||||
|
toPod: PodInstance
|
||||||
|
endpoint: string
|
||||||
|
ids: number[] // ids
|
||||||
|
datas: U[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract class AbstractRequestScheduler <T> {
|
abstract class AbstractRequestScheduler <T> {
|
||||||
requestInterval: number
|
requestInterval: number
|
||||||
limitPods: number
|
limitPods: number
|
||||||
|
@ -27,7 +36,7 @@ abstract class AbstractRequestScheduler <T> {
|
||||||
|
|
||||||
abstract getRequestModel (): AbstractRequestClass<T>
|
abstract getRequestModel (): AbstractRequestClass<T>
|
||||||
abstract getRequestToPodModel (): AbstractRequestToPodClass
|
abstract getRequestToPodModel (): AbstractRequestToPodClass
|
||||||
abstract buildRequestObjects (requestsGrouped: T): {}
|
abstract buildRequestsObjects (requestsGrouped: T): RequestsObjects<any>
|
||||||
|
|
||||||
activate () {
|
activate () {
|
||||||
logger.info('Requests scheduler activated.')
|
logger.info('Requests scheduler activated.')
|
||||||
|
@ -67,7 +76,7 @@ abstract class AbstractRequestScheduler <T> {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Make a requests to friends of a certain type
|
// Make a requests to friends of a certain type
|
||||||
protected makeRequest (toPod: PodInstance, requestEndpoint: string, requestsToMake: Object) {
|
protected makeRequest (toPod: PodInstance, requestEndpoint: string, requestsToMake: any) {
|
||||||
const params = {
|
const params = {
|
||||||
toPod: toPod,
|
toPod: toPod,
|
||||||
method: 'POST' as 'POST',
|
method: 'POST' as 'POST',
|
||||||
|
@ -95,7 +104,7 @@ abstract class AbstractRequestScheduler <T> {
|
||||||
return this.getRequestModel().listWithLimitAndRandom(this.limitPods, this.limitPerPod)
|
return this.getRequestModel().listWithLimitAndRandom(this.limitPods, this.limitPerPod)
|
||||||
.then((requestsGrouped: T) => {
|
.then((requestsGrouped: T) => {
|
||||||
// We want to group requests by destinations pod and endpoint
|
// We want to group requests by destinations pod and endpoint
|
||||||
const requestsToMake = this.buildRequestObjects(requestsGrouped)
|
const requestsToMake = this.buildRequestsObjects(requestsGrouped)
|
||||||
|
|
||||||
// If there are no requests, abort
|
// If there are no requests, abort
|
||||||
if (isEmpty(requestsToMake) === true) {
|
if (isEmpty(requestsToMake) === true) {
|
||||||
|
@ -105,8 +114,8 @@ abstract class AbstractRequestScheduler <T> {
|
||||||
|
|
||||||
logger.info('Making "%s" to friends.', this.description)
|
logger.info('Making "%s" to friends.', this.description)
|
||||||
|
|
||||||
const goodPods = []
|
const goodPods: number[] = []
|
||||||
const badPods = []
|
const badPods: number[] = []
|
||||||
|
|
||||||
return Promise.map(Object.keys(requestsToMake), hashKey => {
|
return Promise.map(Object.keys(requestsToMake), hashKey => {
|
||||||
const requestToMake = requestsToMake[hashKey]
|
const requestToMake = requestsToMake[hashKey]
|
||||||
|
@ -149,5 +158,6 @@ abstract class AbstractRequestScheduler <T> {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
AbstractRequestScheduler
|
AbstractRequestScheduler,
|
||||||
|
RequestsObjects
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
|
|
||||||
import { database as db } from '../../initializers/database'
|
import { database as db } from '../../initializers/database'
|
||||||
import { AbstractRequestScheduler } from './abstract-request-scheduler'
|
import { AbstractRequestScheduler, RequestsObjects } from './abstract-request-scheduler'
|
||||||
import { logger } from '../../helpers'
|
import { logger } from '../../helpers'
|
||||||
import { REQUESTS_LIMIT_PODS, REQUESTS_LIMIT_PER_POD } from '../../initializers'
|
import { REQUESTS_LIMIT_PODS, REQUESTS_LIMIT_PER_POD } from '../../initializers'
|
||||||
import { RequestsGrouped } from '../../models'
|
import { RequestsGrouped } from '../../models'
|
||||||
import { RequestEndpoint } from '../../../shared'
|
import { RequestEndpoint, RemoteVideoRequest } from '../../../shared'
|
||||||
|
|
||||||
export type RequestSchedulerOptions = {
|
export type RequestSchedulerOptions = {
|
||||||
type: string
|
type: string
|
||||||
|
@ -34,8 +34,8 @@ class RequestScheduler extends AbstractRequestScheduler<RequestsGrouped> {
|
||||||
return db.RequestToPod
|
return db.RequestToPod
|
||||||
}
|
}
|
||||||
|
|
||||||
buildRequestObjects (requestsGrouped: RequestsGrouped) {
|
buildRequestsObjects (requestsGrouped: RequestsGrouped) {
|
||||||
const requestsToMakeGrouped = {}
|
const requestsToMakeGrouped: RequestsObjects<RemoteVideoRequest> = {}
|
||||||
|
|
||||||
Object.keys(requestsGrouped).forEach(toPodId => {
|
Object.keys(requestsGrouped).forEach(toPodId => {
|
||||||
requestsGrouped[toPodId].forEach(data => {
|
requestsGrouped[toPodId].forEach(data => {
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
|
|
||||||
import { database as db } from '../../initializers/database'
|
import { database as db } from '../../initializers/database'
|
||||||
import { AbstractRequestScheduler } from './abstract-request-scheduler'
|
import { AbstractRequestScheduler, RequestsObjects } from './abstract-request-scheduler'
|
||||||
import {
|
import {
|
||||||
REQUESTS_VIDEO_EVENT_LIMIT_PODS,
|
REQUESTS_VIDEO_EVENT_LIMIT_PODS,
|
||||||
REQUESTS_VIDEO_EVENT_LIMIT_PER_POD,
|
REQUESTS_VIDEO_EVENT_LIMIT_PER_POD,
|
||||||
REQUEST_VIDEO_EVENT_ENDPOINT
|
REQUEST_VIDEO_EVENT_ENDPOINT
|
||||||
} from '../../initializers'
|
} from '../../initializers'
|
||||||
import { RequestsVideoEventGrouped } from '../../models'
|
import { RequestsVideoEventGrouped } from '../../models'
|
||||||
import { RequestVideoEventType } from '../../../shared'
|
import { RequestVideoEventType, RemoteVideoEventRequest, RemoteVideoEventType } from '../../../shared'
|
||||||
|
|
||||||
export type RequestVideoEventSchedulerOptions = {
|
export type RequestVideoEventSchedulerOptions = {
|
||||||
type: RequestVideoEventType
|
type: RequestVideoEventType
|
||||||
|
@ -36,8 +36,8 @@ class RequestVideoEventScheduler extends AbstractRequestScheduler<RequestsVideoE
|
||||||
return db.RequestVideoEvent
|
return db.RequestVideoEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
buildRequestObjects (eventRequests: RequestsVideoEventGrouped) {
|
buildRequestsObjects (eventRequests: RequestsVideoEventGrouped) {
|
||||||
const requestsToMakeGrouped = {}
|
const requestsToMakeGrouped: RequestsObjects<RemoteVideoEventRequest> = {}
|
||||||
|
|
||||||
/* Example:
|
/* Example:
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,15 @@ class RequestVideoEventScheduler extends AbstractRequestScheduler<RequestsVideoE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
const eventsPerVideoPerPod = {}
|
const eventsPerVideoPerPod: {
|
||||||
|
[ podId: string ]: {
|
||||||
|
[ videoRemoteId: string ]: {
|
||||||
|
views?: number
|
||||||
|
likes?: number
|
||||||
|
dislikes?: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} = {}
|
||||||
|
|
||||||
// We group video events per video and per pod
|
// We group video events per video and per pod
|
||||||
// We add the counts of the same event types
|
// We add the counts of the same event types
|
||||||
|
@ -87,8 +95,8 @@ class RequestVideoEventScheduler extends AbstractRequestScheduler<RequestsVideoE
|
||||||
requestsToMakeGrouped[toPodId].datas.push({
|
requestsToMakeGrouped[toPodId].datas.push({
|
||||||
data: {
|
data: {
|
||||||
remoteId,
|
remoteId,
|
||||||
eventType,
|
eventType: eventType as RemoteVideoEventType,
|
||||||
count: eventsForVideo[eventType]
|
count: +eventsForVideo[eventType]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
|
|
||||||
import { database as db } from '../../initializers/database'
|
import { database as db } from '../../initializers/database'
|
||||||
import { AbstractRequestScheduler } from './abstract-request-scheduler'
|
import { AbstractRequestScheduler, RequestsObjects } from './abstract-request-scheduler'
|
||||||
import { logger } from '../../helpers'
|
import { logger } from '../../helpers'
|
||||||
import {
|
import {
|
||||||
REQUESTS_VIDEO_QADU_LIMIT_PODS,
|
REQUESTS_VIDEO_QADU_LIMIT_PODS,
|
||||||
|
@ -9,8 +9,27 @@ import {
|
||||||
REQUEST_VIDEO_QADU_ENDPOINT,
|
REQUEST_VIDEO_QADU_ENDPOINT,
|
||||||
REQUEST_VIDEO_QADU_TYPES
|
REQUEST_VIDEO_QADU_TYPES
|
||||||
} from '../../initializers'
|
} from '../../initializers'
|
||||||
import { RequestsVideoQaduGrouped } from '../../models'
|
import { RequestsVideoQaduGrouped, PodInstance } from '../../models'
|
||||||
import { RequestVideoQaduType } from '../../../shared'
|
import { RemoteQaduVideoRequest, RequestVideoQaduType } from '../../../shared'
|
||||||
|
|
||||||
|
// We create a custom interface because we need "videos" attribute for our computations
|
||||||
|
interface RequestsObjectsCustom<U> extends RequestsObjects<U> {
|
||||||
|
[ id: string ]: {
|
||||||
|
toPod: PodInstance
|
||||||
|
endpoint: string
|
||||||
|
ids: number[] // ids
|
||||||
|
datas: U[]
|
||||||
|
|
||||||
|
videos: {
|
||||||
|
[ id: string ]: {
|
||||||
|
remoteId: string
|
||||||
|
likes?: number
|
||||||
|
dislikes?: number
|
||||||
|
views?: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type RequestVideoQaduSchedulerOptions = {
|
export type RequestVideoQaduSchedulerOptions = {
|
||||||
type: RequestVideoQaduType
|
type: RequestVideoQaduType
|
||||||
|
@ -37,8 +56,8 @@ class RequestVideoQaduScheduler extends AbstractRequestScheduler<RequestsVideoQa
|
||||||
return db.RequestVideoQadu
|
return db.RequestVideoQadu
|
||||||
}
|
}
|
||||||
|
|
||||||
buildRequestObjects (requests: RequestsVideoQaduGrouped) {
|
buildRequestsObjects (requests: RequestsVideoQaduGrouped) {
|
||||||
const requestsToMakeGrouped = {}
|
const requestsToMakeGrouped: RequestsObjectsCustom<RemoteQaduVideoRequest> = {}
|
||||||
|
|
||||||
Object.keys(requests).forEach(toPodId => {
|
Object.keys(requests).forEach(toPodId => {
|
||||||
requests[toPodId].forEach(data => {
|
requests[toPodId].forEach(data => {
|
||||||
|
@ -59,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 = {}
|
if (!videoData) videoData = { remoteId: null }
|
||||||
|
|
||||||
switch (request.type) {
|
switch (request.type) {
|
||||||
case REQUEST_VIDEO_QADU_TYPES.LIKES:
|
case REQUEST_VIDEO_QADU_TYPES.LIKES:
|
||||||
|
|
|
@ -6,9 +6,12 @@ import {
|
||||||
logger,
|
logger,
|
||||||
checkSignature as peertubeCryptoCheckSignature
|
checkSignature as peertubeCryptoCheckSignature
|
||||||
} from '../helpers'
|
} from '../helpers'
|
||||||
|
import { PodSignature } from '../../shared'
|
||||||
|
|
||||||
function checkSignature (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function checkSignature (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const host = req.body.signature.host
|
const signatureObject: PodSignature = req.body.signature
|
||||||
|
const host = signatureObject.host
|
||||||
|
|
||||||
db.Pod.loadByHost(host)
|
db.Pod.loadByHost(host)
|
||||||
.then(pod => {
|
.then(pod => {
|
||||||
if (pod === null) {
|
if (pod === null) {
|
||||||
|
@ -27,7 +30,7 @@ function checkSignature (req: express.Request, res: express.Response, next: expr
|
||||||
signatureShouldBe = host
|
signatureShouldBe = host
|
||||||
}
|
}
|
||||||
|
|
||||||
const signatureOk = peertubeCryptoCheckSignature(pod.publicKey, signatureShouldBe, req.body.signature.signature)
|
const signatureOk = peertubeCryptoCheckSignature(pod.publicKey, signatureShouldBe, signatureObject.signature)
|
||||||
|
|
||||||
if (signatureOk === true) {
|
if (signatureOk === true) {
|
||||||
res.locals.secure = {
|
res.locals.secure = {
|
||||||
|
@ -37,11 +40,11 @@ function checkSignature (req: express.Request, res: express.Response, next: expr
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.error('Signature is not okay in body for %s.', req.body.signature.host)
|
logger.error('Signature is not okay in body for %s.', signatureObject.host)
|
||||||
return res.sendStatus(403)
|
return res.sendStatus(403)
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
logger.error('Cannot get signed host in body.', { error: err.stack, signature: req.body.signature.signature })
|
logger.error('Cannot get signed host in body.', { error: err.stack, signature: signatureObject.signature })
|
||||||
return res.sendStatus(500)
|
return res.sendStatus(500)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as Sequelize from 'sequelize'
|
||||||
import * as Promise from 'bluebird'
|
import * as Promise from 'bluebird'
|
||||||
|
|
||||||
// Don't use barrel, import just what we need
|
// Don't use barrel, import just what we need
|
||||||
import { Pod as FormatedPod } from '../../../shared/models/pod.model'
|
import { Pod as FormatedPod } from '../../../shared/models/pods/pod.model'
|
||||||
|
|
||||||
export namespace PodMethods {
|
export namespace PodMethods {
|
||||||
export type ToFormatedJSON = (this: PodInstance) => FormatedPod
|
export type ToFormatedJSON = (this: PodInstance) => FormatedPod
|
||||||
|
|
|
@ -2,7 +2,8 @@ import * as Sequelize from 'sequelize'
|
||||||
import * as Promise from 'bluebird'
|
import * as Promise from 'bluebird'
|
||||||
|
|
||||||
// Don't use barrel, import just what we need
|
// Don't use barrel, import just what we need
|
||||||
import { UserRole, User as FormatedUser } from '../../../shared/models/user.model'
|
import { User as FormatedUser } from '../../../shared/models/users/user.model'
|
||||||
|
import { UserRole } from '../../../shared/models/users/user-role.type'
|
||||||
import { ResultList } from '../../../shared/models/result-list.model'
|
import { ResultList } from '../../../shared/models/result-list.model'
|
||||||
|
|
||||||
export namespace UserMethods {
|
export namespace UserMethods {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
import * as Promise from 'bluebird'
|
import * as Promise from 'bluebird'
|
||||||
|
|
||||||
import { VideoRateType } from '../../../shared/models/user-video-rate.model'
|
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: string, transaction: Sequelize.Transaction) => Promise<UserVideoRateInstance>
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { PodInstance } from '../pod'
|
||||||
import { ResultList } from '../../../shared'
|
import { ResultList } from '../../../shared'
|
||||||
|
|
||||||
// Don't use barrel, import just what we need
|
// Don't use barrel, import just what we need
|
||||||
import { VideoAbuse as FormatedVideoAbuse } from '../../../shared/models/video-abuse.model'
|
import { VideoAbuse as FormatedVideoAbuse } from '../../../shared/models/videos/video-abuse.model'
|
||||||
|
|
||||||
export namespace VideoAbuseMethods {
|
export namespace VideoAbuseMethods {
|
||||||
export type ToFormatedJSON = (this: VideoAbuseInstance) => FormatedVideoAbuse
|
export type ToFormatedJSON = (this: VideoAbuseInstance) => FormatedVideoAbuse
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as Promise from 'bluebird'
|
||||||
import { ResultList } from '../../../shared'
|
import { ResultList } from '../../../shared'
|
||||||
|
|
||||||
// Don't use barrel, import just what we need
|
// Don't use barrel, import just what we need
|
||||||
import { BlacklistedVideo as FormatedBlacklistedVideo } from '../../../shared/models/video-blacklist.model'
|
import { BlacklistedVideo as FormatedBlacklistedVideo } from '../../../shared/models/videos/video-blacklist.model'
|
||||||
|
|
||||||
export namespace BlacklistedVideoMethods {
|
export namespace BlacklistedVideoMethods {
|
||||||
export type ToFormatedJSON = (this: BlacklistedVideoInstance) => FormatedBlacklistedVideo
|
export type ToFormatedJSON = (this: BlacklistedVideoInstance) => FormatedBlacklistedVideo
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { AuthorInstance } from './author-interface'
|
||||||
import { TagAttributes, TagInstance } from './tag-interface'
|
import { TagAttributes, TagInstance } from './tag-interface'
|
||||||
|
|
||||||
// Don't use barrel, import just what we need
|
// Don't use barrel, import just what we need
|
||||||
import { Video as FormatedVideo } from '../../../shared/models/video.model'
|
import { Video as FormatedVideo } from '../../../shared/models/videos/video.model'
|
||||||
import { ResultList } from '../../../shared/models/result-list.model'
|
import { ResultList } from '../../../shared/models/result-list.model'
|
||||||
|
|
||||||
export type FormatedAddRemoteVideo = {
|
export type FormatedAddRemoteVideo = {
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
|
export * from './pods'
|
||||||
|
export * from './users'
|
||||||
|
export * from './videos'
|
||||||
export * from './job.model'
|
export * from './job.model'
|
||||||
export * from './oauth-client-local.model'
|
export * from './oauth-client-local.model'
|
||||||
export * from './pod.model'
|
|
||||||
export * from './result-list.model'
|
export * from './result-list.model'
|
||||||
export * from './request-scheduler.model'
|
export * from './request-scheduler.model'
|
||||||
export * from './user-video-rate.model'
|
|
||||||
export * from './user.model'
|
|
||||||
export * from './video-abuse.model'
|
|
||||||
export * from './video-blacklist.model'
|
|
||||||
export * from './video.model'
|
|
||||||
export * from './server-config.model'
|
export * from './server-config.model'
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
export * from './pod-signature.model'
|
||||||
|
export * from './pod.model'
|
||||||
|
export * from './remote-video'
|
|
@ -0,0 +1,4 @@
|
||||||
|
export interface PodSignature {
|
||||||
|
host: string
|
||||||
|
signature: string
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
export * from './remote-qadu-video-request.model'
|
||||||
|
export * from './remote-video-event-request.model'
|
||||||
|
export * from './remote-video-request.model'
|
||||||
|
export * from './remote-video-create-request.model'
|
||||||
|
export * from './remote-video-update-request.model'
|
||||||
|
export * from './remote-video-remove-request.model'
|
||||||
|
export * from './remote-video-report-abuse-request.model'
|
|
@ -0,0 +1,10 @@
|
||||||
|
export interface RemoteQaduVideoData {
|
||||||
|
remoteId: string
|
||||||
|
views?: number
|
||||||
|
likes?: number
|
||||||
|
dislikes?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RemoteQaduVideoRequest {
|
||||||
|
data: RemoteQaduVideoData
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||||
|
|
||||||
|
export interface RemoteVideoCreateData {
|
||||||
|
remoteId: string
|
||||||
|
author: string
|
||||||
|
tags: string[]
|
||||||
|
name: string
|
||||||
|
extname: string
|
||||||
|
infoHash: string
|
||||||
|
category: number
|
||||||
|
licence: number
|
||||||
|
language: number
|
||||||
|
nsfw: boolean
|
||||||
|
description: string
|
||||||
|
duration: number
|
||||||
|
createdAt: Date
|
||||||
|
updatedAt: Date
|
||||||
|
views: number
|
||||||
|
likes: number
|
||||||
|
dislikes: number
|
||||||
|
thumbnailData: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RemoteVideoCreateRequest extends RemoteVideoRequest {
|
||||||
|
type: 'add'
|
||||||
|
data: RemoteVideoCreateData
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
export type RemoteVideoEventType = 'views' | 'likes' | 'dislikes'
|
||||||
|
|
||||||
|
export interface RemoteVideoEventData {
|
||||||
|
remoteId: string
|
||||||
|
eventType: RemoteVideoEventType
|
||||||
|
count: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RemoteVideoEventRequest {
|
||||||
|
data: RemoteVideoEventData
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||||
|
|
||||||
|
export interface RemoteVideoRemoveData {
|
||||||
|
remoteId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RemoteVideoRemoveRequest extends RemoteVideoRequest {
|
||||||
|
type: 'remove'
|
||||||
|
data: RemoteVideoRemoveData
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||||
|
|
||||||
|
export interface RemoteVideoReportAbuseData {
|
||||||
|
videoRemoteId: string
|
||||||
|
reporterUsername: string
|
||||||
|
reportReason: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RemoteVideoReportAbuseRequest extends RemoteVideoRequest {
|
||||||
|
type: 'report-abuse'
|
||||||
|
data: RemoteVideoReportAbuseData
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
export interface RemoteVideoRequest {
|
||||||
|
type: 'add' | 'update' | 'remove' | 'report-abuse'
|
||||||
|
data: any
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
export interface RemoteVideoUpdateData {
|
||||||
|
remoteId: string
|
||||||
|
tags: string[]
|
||||||
|
name: string
|
||||||
|
extname: string
|
||||||
|
infoHash: string
|
||||||
|
category: number
|
||||||
|
licence: number
|
||||||
|
language: number
|
||||||
|
nsfw: boolean
|
||||||
|
description: string
|
||||||
|
duration: number
|
||||||
|
createdAt: Date
|
||||||
|
updatedAt: Date
|
||||||
|
views: number
|
||||||
|
likes: number
|
||||||
|
dislikes: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RemoteVideoUpdateRequest {
|
||||||
|
type: 'update'
|
||||||
|
data: RemoteVideoUpdateData
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
export type VideoRateType = 'like' | 'dislike'
|
|
||||||
export type UserVideoRateType = 'like' | 'dislike' | 'none'
|
|
||||||
|
|
||||||
export interface UserVideoRate {
|
|
||||||
videoId: string
|
|
||||||
rating: UserVideoRateType
|
|
||||||
}
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
export * from './user.model'
|
||||||
|
export * from './user-create.model'
|
||||||
|
export * from './user-update.model'
|
||||||
|
export * from './user-role.type'
|
|
@ -0,0 +1,5 @@
|
||||||
|
export interface UserCreate {
|
||||||
|
username: string
|
||||||
|
password: string
|
||||||
|
email: string
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export type UserRole = 'admin' | 'user'
|
|
@ -0,0 +1,4 @@
|
||||||
|
export interface UserUpdate {
|
||||||
|
displayNSFW?: boolean
|
||||||
|
password?: string
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
export type UserRole = 'admin' | 'user'
|
import { UserRole } from './user-role.type'
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
id: number
|
id: number
|
|
@ -0,0 +1,10 @@
|
||||||
|
export * from './user-video-rate-update.model'
|
||||||
|
export * from './user-video-rate.model'
|
||||||
|
export * from './user-video-rate.type'
|
||||||
|
export * from './video-abuse-create.model'
|
||||||
|
export * from './video-abuse.model'
|
||||||
|
export * from './video-blacklist.model'
|
||||||
|
export * from './video-create.model'
|
||||||
|
export * from './video-rate.type'
|
||||||
|
export * from './video-update.model'
|
||||||
|
export * from './video.model'
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { UserVideoRateType } from './user-video-rate.type'
|
||||||
|
|
||||||
|
export interface UserVideoRateUpdate {
|
||||||
|
rating: UserVideoRateType
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { UserVideoRateType } from './user-video-rate.type'
|
||||||
|
|
||||||
|
export interface UserVideoRate {
|
||||||
|
videoId: string
|
||||||
|
rating: UserVideoRateType
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export type UserVideoRateType = 'like' | 'dislike' | 'none'
|
|
@ -0,0 +1,3 @@
|
||||||
|
export interface VideoAbuseCreate {
|
||||||
|
reason: string
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
export interface VideoCreate {
|
||||||
|
category: number
|
||||||
|
licence: number
|
||||||
|
language: number
|
||||||
|
description: string
|
||||||
|
nsfw: boolean
|
||||||
|
name: string
|
||||||
|
tags: string[]
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export type VideoRateType = 'like' | 'dislike'
|
|
@ -0,0 +1,9 @@
|
||||||
|
export interface VideoUpdate {
|
||||||
|
name?: string
|
||||||
|
category?: number
|
||||||
|
licence?: number
|
||||||
|
language?: number
|
||||||
|
description?: string
|
||||||
|
tags?: string[]
|
||||||
|
nsfw?: boolean
|
||||||
|
}
|
Loading…
Reference in New Issue