Rename Pod -> Server
This commit is contained in:
parent
51548b3181
commit
6086242524
77 changed files with 456 additions and 1047 deletions
|
@ -1,11 +1,9 @@
|
|||
import { Component, OnInit } from '@angular/core'
|
||||
import { Component } from '@angular/core'
|
||||
|
||||
import { NotificationsService } from 'angular2-notifications'
|
||||
import { SortMeta } from 'primeng/primeng'
|
||||
|
||||
import { ConfirmService } from '../../../core'
|
||||
import { RestTable, RestPagination } from '../../../shared'
|
||||
import { Pod } from '../../../../../../shared'
|
||||
import { AccountFollow } from '../../../../../../shared/models/accounts/follow.model'
|
||||
import { RestPagination, RestTable } from '../../../shared'
|
||||
import { FollowService } from '../shared'
|
||||
|
||||
@Component({
|
||||
|
@ -14,7 +12,7 @@ import { FollowService } from '../shared'
|
|||
styleUrls: [ './followers-list.component.scss' ]
|
||||
})
|
||||
export class FollowersListComponent extends RestTable {
|
||||
followers: Pod[] = []
|
||||
followers: AccountFollow[] = []
|
||||
totalRecords = 0
|
||||
rowsPerPage = 10
|
||||
sort: SortMeta = { field: 'createdAt', order: 1 }
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
</div>
|
||||
|
||||
<div *ngIf="canMakeFriends() === false" class="alert alert-warning">
|
||||
It seems that you are not on a HTTPS pod. Your webserver need to have TLS activated in order to follow servers.
|
||||
It seems that you are not on a HTTPS server. Your webserver need to have TLS activated in order to follow servers.
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Add following" class="btn btn-default" [disabled]="!isFormValid()">
|
||||
|
|
|
@ -94,8 +94,6 @@ export class FollowingAddComponent implements OnInit {
|
|||
this.followService.follow(notEmptyHosts).subscribe(
|
||||
status => {
|
||||
this.notificationsService.success('Success', 'Follow request(s) sent!')
|
||||
// Wait requests between pods
|
||||
setTimeout(() => this.router.navigate([ '/admin/friends/list' ]), 1000)
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
import { Component, OnInit } from '@angular/core'
|
||||
|
||||
import { Component } from '@angular/core'
|
||||
import { NotificationsService } from 'angular2-notifications'
|
||||
import { SortMeta } from 'primeng/primeng'
|
||||
|
||||
import { ConfirmService } from '../../../core'
|
||||
import { RestTable, RestPagination } from '../../../shared'
|
||||
import { Pod } from '../../../../../../shared'
|
||||
import { AccountFollow } from '../../../../../../shared/models/accounts/follow.model'
|
||||
import { RestPagination, RestTable } from '../../../shared'
|
||||
import { FollowService } from '../shared'
|
||||
|
||||
@Component({
|
||||
|
@ -13,7 +10,7 @@ import { FollowService } from '../shared'
|
|||
templateUrl: './following-list.component.html'
|
||||
})
|
||||
export class FollowingListComponent extends RestTable {
|
||||
following: Pod[] = []
|
||||
following: AccountFollow[] = []
|
||||
totalRecords = 0
|
||||
rowsPerPage = 10
|
||||
sort: SortMeta = { field: 'createdAt', order: 1 }
|
||||
|
|
|
@ -7,7 +7,7 @@ import 'rxjs/add/operator/map'
|
|||
import { SortMeta } from 'primeng/primeng'
|
||||
|
||||
import { RestExtractor, RestPagination, RestService } from '../../../shared'
|
||||
import { Pod, ResultList } from '../../../../../../shared'
|
||||
import { AccountFollow, ResultList } from '../../../../../../shared'
|
||||
|
||||
@Injectable()
|
||||
export class FollowService {
|
||||
|
@ -19,7 +19,7 @@ export class FollowService {
|
|||
private restExtractor: RestExtractor
|
||||
) {}
|
||||
|
||||
getFollowing (pagination: RestPagination, sort: SortMeta): Observable<ResultList<Pod>> {
|
||||
getFollowing (pagination: RestPagination, sort: SortMeta): Observable<ResultList<AccountFollow>> {
|
||||
let params = new HttpParams()
|
||||
params = this.restService.addRestGetParams(params, pagination, sort)
|
||||
|
||||
|
@ -28,7 +28,7 @@ export class FollowService {
|
|||
.catch(res => this.restExtractor.handleError(res))
|
||||
}
|
||||
|
||||
getFollowers (pagination: RestPagination, sort: SortMeta): Observable<ResultList<Pod>> {
|
||||
getFollowers (pagination: RestPagination, sort: SortMeta): Observable<ResultList<AccountFollow>> {
|
||||
let params = new HttpParams()
|
||||
params = this.restService.addRestGetParams(params, pagination, sort)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
>
|
||||
<p-column field="id" header="ID" [sortable]="true"></p-column>
|
||||
<p-column field="reason" header="Reason"></p-column>
|
||||
<p-column field="reporterPodHost" header="Reporter pod host"></p-column>
|
||||
<p-column field="reporterServerHost" header="Reporter server host"></p-column>
|
||||
<p-column field="reporterUsername" header="Reporter username"></p-column>
|
||||
<p-column header="Video" styleClass="action-cell">
|
||||
<ng-template pTemplate="body" let-videoAbuse="rowData">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="alert alert-danger">
|
||||
The video load seems to be abnormally long.
|
||||
<ul>
|
||||
<li>Maybe the server {{ video.podHost }} is down :(</li>
|
||||
<li>Maybe the server {{ video.serverHost }} is down :(</li>
|
||||
<li>
|
||||
If not, you can report an issue on
|
||||
<a href="https://github.com/Chocobozzz/PeerTube/issues" title="Report an issue">
|
||||
|
|
|
@ -27,7 +27,7 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
|
|||
uuid: string
|
||||
isLocal: boolean
|
||||
name: string
|
||||
podHost: string
|
||||
serverHost: string
|
||||
tags: string[]
|
||||
thumbnailPath: string
|
||||
thumbnailUrl: string
|
||||
|
|
|
@ -19,7 +19,7 @@ export class Video implements VideoServerModel {
|
|||
uuid: string
|
||||
isLocal: boolean
|
||||
name: string
|
||||
podHost: string
|
||||
serverHost: string
|
||||
tags: string[]
|
||||
thumbnailPath: string
|
||||
thumbnailUrl: string
|
||||
|
@ -32,8 +32,8 @@ export class Video implements VideoServerModel {
|
|||
dislikes: number
|
||||
nsfw: boolean
|
||||
|
||||
private static createByString (account: string, podHost: string) {
|
||||
return account + '@' + podHost
|
||||
private static createByString (account: string, serverHost: string) {
|
||||
return account + '@' + serverHost
|
||||
}
|
||||
|
||||
private static createDurationString (duration: number) {
|
||||
|
@ -67,7 +67,7 @@ export class Video implements VideoServerModel {
|
|||
this.uuid = hash.uuid
|
||||
this.isLocal = hash.isLocal
|
||||
this.name = hash.name
|
||||
this.podHost = hash.podHost
|
||||
this.serverHost = hash.serverHost
|
||||
this.tags = hash.tags
|
||||
this.thumbnailPath = hash.thumbnailPath
|
||||
this.thumbnailUrl = absoluteAPIUrl + hash.thumbnailPath
|
||||
|
@ -80,7 +80,7 @@ export class Video implements VideoServerModel {
|
|||
this.dislikes = hash.dislikes
|
||||
this.nsfw = hash.nsfw
|
||||
|
||||
this.by = Video.createByString(hash.account, hash.podHost)
|
||||
this.by = Video.createByString(hash.account, hash.serverHost)
|
||||
}
|
||||
|
||||
isVideoNSFWForUser (user: User) {
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
// import * as express from 'express'
|
||||
//
|
||||
// import { database as db } from '../../../initializers/database'
|
||||
// import {
|
||||
// checkSignature,
|
||||
// signatureValidator,
|
||||
// setBodyHostPort,
|
||||
// remotePodsAddValidator,
|
||||
// asyncMiddleware
|
||||
// } from '../../../middlewares'
|
||||
// import { sendOwnedDataToPod } from '../../../lib'
|
||||
// import { getMyPublicCert, getFormattedObjects } from '../../../helpers'
|
||||
// import { CONFIG } from '../../../initializers'
|
||||
// import { PodInstance } from '../../../models'
|
||||
// import { PodSignature, Pod as FormattedPod } from '../../../../shared'
|
||||
//
|
||||
// const remotePodsRouter = express.Router()
|
||||
//
|
||||
// remotePodsRouter.post('/remove',
|
||||
// signatureValidator,
|
||||
// checkSignature,
|
||||
// asyncMiddleware(removePods)
|
||||
// )
|
||||
//
|
||||
// remotePodsRouter.post('/list',
|
||||
// asyncMiddleware(remotePodsList)
|
||||
// )
|
||||
//
|
||||
// remotePodsRouter.post('/add',
|
||||
// setBodyHostPort, // We need to modify the host before running the validator!
|
||||
// remotePodsAddValidator,
|
||||
// asyncMiddleware(addPods)
|
||||
// )
|
||||
//
|
||||
// // ---------------------------------------------------------------------------
|
||||
//
|
||||
// export {
|
||||
// remotePodsRouter
|
||||
// }
|
||||
//
|
||||
// // ---------------------------------------------------------------------------
|
||||
//
|
||||
// async function addPods (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
// const information = req.body
|
||||
//
|
||||
// const pod = db.Pod.build(information)
|
||||
// const podCreated = await pod.save()
|
||||
//
|
||||
// await sendOwnedDataToPod(podCreated.id)
|
||||
//
|
||||
// const cert = await getMyPublicCert()
|
||||
// return res.json({ cert, email: CONFIG.ADMIN.EMAIL })
|
||||
// }
|
||||
//
|
||||
// async function remotePodsList (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
// const pods = await db.Pod.list()
|
||||
//
|
||||
// return res.json(getFormattedObjects<FormattedPod, PodInstance>(pods, pods.length))
|
||||
// }
|
||||
//
|
||||
// async function removePods (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
// const signature: PodSignature = req.body.signature
|
||||
// const host = signature.host
|
||||
//
|
||||
// const pod = await db.Pod.loadByHost(host)
|
||||
// await pod.destroy()
|
||||
//
|
||||
// return res.type('json').status(204).end()
|
||||
// }
|
|
@ -1,278 +0,0 @@
|
|||
// import * as express from 'express'
|
||||
// import * as Bluebird from 'bluebird'
|
||||
// import * as Sequelize from 'sequelize'
|
||||
//
|
||||
// import { database as db } from '../../../initializers/database'
|
||||
// import {
|
||||
// REQUEST_ENDPOINT_ACTIONS,
|
||||
// REQUEST_ENDPOINTS,
|
||||
// REQUEST_VIDEO_EVENT_TYPES,
|
||||
// REQUEST_VIDEO_QADU_TYPES
|
||||
// } from '../../../initializers'
|
||||
// import {
|
||||
// checkSignature,
|
||||
// signatureValidator,
|
||||
// remoteVideosValidator,
|
||||
// remoteQaduVideosValidator,
|
||||
// remoteEventsVideosValidator
|
||||
// } from '../../../middlewares'
|
||||
// import { logger, retryTransactionWrapper, resetSequelizeInstance } from '../../../helpers'
|
||||
// import { quickAndDirtyUpdatesVideoToFriends, fetchVideoChannelByHostAndUUID } from '../../../lib'
|
||||
// import { PodInstance, VideoFileInstance } from '../../../models'
|
||||
// import {
|
||||
// RemoteVideoRequest,
|
||||
// RemoteVideoCreateData,
|
||||
// RemoteVideoUpdateData,
|
||||
// RemoteVideoRemoveData,
|
||||
// RemoteVideoReportAbuseData,
|
||||
// RemoteQaduVideoRequest,
|
||||
// RemoteQaduVideoData,
|
||||
// RemoteVideoEventRequest,
|
||||
// RemoteVideoEventData,
|
||||
// RemoteVideoChannelCreateData,
|
||||
// RemoteVideoChannelUpdateData,
|
||||
// RemoteVideoChannelRemoveData,
|
||||
// RemoteVideoAccountRemoveData,
|
||||
// RemoteVideoAccountCreateData
|
||||
// } from '../../../../shared'
|
||||
// import { VideoInstance } from '../../../models/video/video-interface'
|
||||
//
|
||||
// const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
|
||||
//
|
||||
// // Functions to call when processing a remote request
|
||||
// // FIXME: use RemoteVideoRequestType as id type
|
||||
// const functionsHash: { [ id: string ]: (...args) => Promise<any> } = {}
|
||||
// functionsHash[ENDPOINT_ACTIONS.ADD_VIDEO] = addRemoteVideoRetryWrapper
|
||||
// functionsHash[ENDPOINT_ACTIONS.UPDATE_VIDEO] = updateRemoteVideoRetryWrapper
|
||||
// functionsHash[ENDPOINT_ACTIONS.REMOVE_VIDEO] = removeRemoteVideoRetryWrapper
|
||||
// functionsHash[ENDPOINT_ACTIONS.ADD_CHANNEL] = addRemoteVideoChannelRetryWrapper
|
||||
// functionsHash[ENDPOINT_ACTIONS.UPDATE_CHANNEL] = updateRemoteVideoChannelRetryWrapper
|
||||
// functionsHash[ENDPOINT_ACTIONS.REMOVE_CHANNEL] = removeRemoteVideoChannelRetryWrapper
|
||||
// functionsHash[ENDPOINT_ACTIONS.REPORT_ABUSE] = reportAbuseRemoteVideoRetryWrapper
|
||||
// functionsHash[ENDPOINT_ACTIONS.ADD_ACCOUNT] = addRemoteVideoAccountRetryWrapper
|
||||
// functionsHash[ENDPOINT_ACTIONS.REMOVE_ACCOUNT] = removeRemoteVideoAccountRetryWrapper
|
||||
//
|
||||
// const remoteVideosRouter = express.Router()
|
||||
//
|
||||
// remoteVideosRouter.post('/',
|
||||
// signatureValidator,
|
||||
// checkSignature,
|
||||
// remoteVideosValidator,
|
||||
// remoteVideos
|
||||
// )
|
||||
//
|
||||
// remoteVideosRouter.post('/qadu',
|
||||
// signatureValidator,
|
||||
// checkSignature,
|
||||
// remoteQaduVideosValidator,
|
||||
// remoteVideosQadu
|
||||
// )
|
||||
//
|
||||
// remoteVideosRouter.post('/events',
|
||||
// signatureValidator,
|
||||
// checkSignature,
|
||||
// remoteEventsVideosValidator,
|
||||
// remoteVideosEvents
|
||||
// )
|
||||
//
|
||||
// // ---------------------------------------------------------------------------
|
||||
//
|
||||
// export {
|
||||
// remoteVideosRouter
|
||||
// }
|
||||
//
|
||||
// // ---------------------------------------------------------------------------
|
||||
//
|
||||
// function remoteVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
// const requests: RemoteVideoRequest[] = req.body.data
|
||||
// const fromPod = res.locals.secure.pod
|
||||
//
|
||||
// // We need to process in the same order to keep consistency
|
||||
// Bluebird.each(requests, request => {
|
||||
// const data = request.data
|
||||
//
|
||||
// // Get the function we need to call in order to process the request
|
||||
// const fun = functionsHash[request.type]
|
||||
// if (fun === undefined) {
|
||||
// logger.error('Unknown remote request type %s.', request.type)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// return fun.call(this, data, fromPod)
|
||||
// })
|
||||
// .catch(err => logger.error('Error managing remote videos.', err))
|
||||
//
|
||||
// // Don't block the other pod
|
||||
// return res.type('json').status(204).end()
|
||||
// }
|
||||
//
|
||||
// function remoteVideosQadu (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
// const requests: RemoteQaduVideoRequest[] = req.body.data
|
||||
// const fromPod = res.locals.secure.pod
|
||||
//
|
||||
// Bluebird.each(requests, request => {
|
||||
// const videoData = request.data
|
||||
//
|
||||
// return quickAndDirtyUpdateVideoRetryWrapper(videoData, fromPod)
|
||||
// })
|
||||
// .catch(err => logger.error('Error managing remote videos.', err))
|
||||
//
|
||||
// return res.type('json').status(204).end()
|
||||
// }
|
||||
//
|
||||
// function remoteVideosEvents (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
// const requests: RemoteVideoEventRequest[] = req.body.data
|
||||
// const fromPod = res.locals.secure.pod
|
||||
//
|
||||
// Bluebird.each(requests, request => {
|
||||
// const eventData = request.data
|
||||
//
|
||||
// return processVideosEventsRetryWrapper(eventData, fromPod)
|
||||
// })
|
||||
// .catch(err => logger.error('Error managing remote videos.', err))
|
||||
//
|
||||
// return res.type('json').status(204).end()
|
||||
// }
|
||||
//
|
||||
// async function processVideosEventsRetryWrapper (eventData: RemoteVideoEventData, fromPod: PodInstance) {
|
||||
// const options = {
|
||||
// arguments: [ eventData, fromPod ],
|
||||
// errorMessage: 'Cannot process videos events with many retries.'
|
||||
// }
|
||||
//
|
||||
// await retryTransactionWrapper(processVideosEvents, options)
|
||||
// }
|
||||
//
|
||||
// async function processVideosEvents (eventData: RemoteVideoEventData, fromPod: PodInstance) {
|
||||
// await db.sequelize.transaction(async t => {
|
||||
// const sequelizeOptions = { transaction: t }
|
||||
// const videoInstance = await fetchLocalVideoByUUID(eventData.uuid, t)
|
||||
//
|
||||
// let columnToUpdate
|
||||
// let qaduType
|
||||
//
|
||||
// switch (eventData.eventType) {
|
||||
// case REQUEST_VIDEO_EVENT_TYPES.VIEWS:
|
||||
// columnToUpdate = 'views'
|
||||
// qaduType = REQUEST_VIDEO_QADU_TYPES.VIEWS
|
||||
// break
|
||||
//
|
||||
// case REQUEST_VIDEO_EVENT_TYPES.LIKES:
|
||||
// columnToUpdate = 'likes'
|
||||
// qaduType = REQUEST_VIDEO_QADU_TYPES.LIKES
|
||||
// break
|
||||
//
|
||||
// case REQUEST_VIDEO_EVENT_TYPES.DISLIKES:
|
||||
// columnToUpdate = 'dislikes'
|
||||
// qaduType = REQUEST_VIDEO_QADU_TYPES.DISLIKES
|
||||
// break
|
||||
//
|
||||
// default:
|
||||
// throw new Error('Unknown video event type.')
|
||||
// }
|
||||
//
|
||||
// const query = {}
|
||||
// query[columnToUpdate] = eventData.count
|
||||
//
|
||||
// await videoInstance.increment(query, sequelizeOptions)
|
||||
//
|
||||
// const qadusParams = [
|
||||
// {
|
||||
// videoId: videoInstance.id,
|
||||
// type: qaduType
|
||||
// }
|
||||
// ]
|
||||
// await quickAndDirtyUpdatesVideoToFriends(qadusParams, t)
|
||||
// })
|
||||
//
|
||||
// logger.info('Remote video event processed for video with uuid %s.', eventData.uuid)
|
||||
// }
|
||||
//
|
||||
// async function quickAndDirtyUpdateVideoRetryWrapper (videoData: RemoteQaduVideoData, fromPod: PodInstance) {
|
||||
// const options = {
|
||||
// arguments: [ videoData, fromPod ],
|
||||
// errorMessage: 'Cannot update quick and dirty the remote video with many retries.'
|
||||
// }
|
||||
//
|
||||
// await retryTransactionWrapper(quickAndDirtyUpdateVideo, options)
|
||||
// }
|
||||
//
|
||||
// async function quickAndDirtyUpdateVideo (videoData: RemoteQaduVideoData, fromPod: PodInstance) {
|
||||
// let videoUUID = ''
|
||||
//
|
||||
// await db.sequelize.transaction(async t => {
|
||||
// const videoInstance = await fetchVideoByHostAndUUID(fromPod.host, videoData.uuid, t)
|
||||
// const sequelizeOptions = { transaction: t }
|
||||
//
|
||||
// videoUUID = videoInstance.uuid
|
||||
//
|
||||
// if (videoData.views) {
|
||||
// videoInstance.set('views', videoData.views)
|
||||
// }
|
||||
//
|
||||
// if (videoData.likes) {
|
||||
// videoInstance.set('likes', videoData.likes)
|
||||
// }
|
||||
//
|
||||
// if (videoData.dislikes) {
|
||||
// videoInstance.set('dislikes', videoData.dislikes)
|
||||
// }
|
||||
//
|
||||
// await videoInstance.save(sequelizeOptions)
|
||||
// })
|
||||
//
|
||||
// logger.info('Remote video with uuid %s quick and dirty updated', videoUUID)
|
||||
// }
|
||||
//
|
||||
// async function reportAbuseRemoteVideoRetryWrapper (reportData: RemoteVideoReportAbuseData, fromPod: PodInstance) {
|
||||
// const options = {
|
||||
// arguments: [ reportData, fromPod ],
|
||||
// errorMessage: 'Cannot create remote abuse video with many retries.'
|
||||
// }
|
||||
//
|
||||
// await retryTransactionWrapper(reportAbuseRemoteVideo, options)
|
||||
// }
|
||||
//
|
||||
// async function reportAbuseRemoteVideo (reportData: RemoteVideoReportAbuseData, fromPod: PodInstance) {
|
||||
// logger.debug('Reporting remote abuse for video %s.', reportData.videoUUID)
|
||||
//
|
||||
// await db.sequelize.transaction(async t => {
|
||||
// const videoInstance = await fetchLocalVideoByUUID(reportData.videoUUID, t)
|
||||
// const videoAbuseData = {
|
||||
// reporterUsername: reportData.reporterUsername,
|
||||
// reason: reportData.reportReason,
|
||||
// reporterPodId: fromPod.id,
|
||||
// videoId: videoInstance.id
|
||||
// }
|
||||
//
|
||||
// await db.VideoAbuse.create(videoAbuseData)
|
||||
//
|
||||
// })
|
||||
//
|
||||
// logger.info('Remote abuse for video uuid %s created', reportData.videoUUID)
|
||||
// }
|
||||
//
|
||||
// async function fetchLocalVideoByUUID (id: string, t: Sequelize.Transaction) {
|
||||
// try {
|
||||
// const video = await db.Video.loadLocalVideoByUUID(id, t)
|
||||
//
|
||||
// if (!video) throw new Error('Video ' + id + ' not found')
|
||||
//
|
||||
// return video
|
||||
// } catch (err) {
|
||||
// logger.error('Cannot load owned video from id.', { error: err.stack, id })
|
||||
// throw err
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// async function fetchVideoByHostAndUUID (podHost: string, uuid: string, t: Sequelize.Transaction) {
|
||||
// try {
|
||||
// const video = await db.Video.loadByHostAndUUID(podHost, uuid, t)
|
||||
// if (!video) throw new Error('Video not found')
|
||||
//
|
||||
// return video
|
||||
// } catch (err) {
|
||||
// logger.error('Cannot load video from host and uuid.', { error: err.stack, podHost, uuid })
|
||||
// throw err
|
||||
// }
|
||||
// }
|
|
@ -4,7 +4,7 @@ import { badRequest } from '../../helpers'
|
|||
|
||||
import { oauthClientsRouter } from './oauth-clients'
|
||||
import { configRouter } from './config'
|
||||
import { applicationRouter } from './application'
|
||||
import { applicationRouter } from './server'
|
||||
import { usersRouter } from './users'
|
||||
import { videosRouter } from './videos'
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ import { database as db } from '../../../initializers/database'
|
|||
import { sendFollow } from '../../../lib/activitypub/send-request'
|
||||
import { asyncMiddleware, paginationValidator, setFollowersSort, setPagination } from '../../../middlewares'
|
||||
import { authenticate } from '../../../middlewares/oauth'
|
||||
import { setBodyHostsPort } from '../../../middlewares/pods'
|
||||
import { setBodyHostsPort } from '../../../middlewares/servers'
|
||||
import { setFollowingSort } from '../../../middlewares/sort'
|
||||
import { ensureUserHasRight } from '../../../middlewares/user-right'
|
||||
import { followValidator } from '../../../middlewares/validators/pods'
|
||||
import { followValidator } from '../../../middlewares/validators/servers'
|
||||
import { followersSortValidator, followingSortValidator } from '../../../middlewares/validators/sort'
|
||||
|
||||
const applicationFollowsRouter = express.Router()
|
|
@ -70,12 +70,12 @@ async function reportVideoAbuse (req: express.Request, res: express.Response) {
|
|||
reporterUsername,
|
||||
reason: body.reason,
|
||||
videoId: videoInstance.id,
|
||||
reporterPodId: null // This is our pod that reported this abuse
|
||||
reporterServerId: null // This is our server that reported this abuse
|
||||
}
|
||||
|
||||
await db.sequelize.transaction(async t => {
|
||||
const abuse = await db.VideoAbuse.create(abuseToCreate, { transaction: t })
|
||||
// We send the information to the destination pod
|
||||
// We send the information to the destination server
|
||||
if (videoInstance.isOwned() === false) {
|
||||
const reportData = {
|
||||
reporterUsername,
|
||||
|
@ -84,7 +84,7 @@ async function reportVideoAbuse (req: express.Request, res: express.Response) {
|
|||
}
|
||||
|
||||
// await friends.reportAbuseVideoToFriend(reportData, videoInstance, t)
|
||||
// TODO: send abuse to origin pod
|
||||
// TODO: send abuse to origin server
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -233,7 +233,7 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
|
|||
|
||||
// Let transcoding job send the video to friends because the video file extension might change
|
||||
if (CONFIG.TRANSCODING.ENABLED === true) return undefined
|
||||
// Don't send video to remote pods, it is private
|
||||
// Don't send video to remote servers, it is private
|
||||
if (video.privacy === VideoPrivacy.PRIVATE) return undefined
|
||||
|
||||
await sendAddVideo(video, t)
|
||||
|
@ -287,7 +287,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
|
|||
await sendUpdateVideoChannel(videoInstance, t)
|
||||
}
|
||||
|
||||
// Video is not private anymore, send a create action to remote pods
|
||||
// Video is not private anymore, send a create action to remote servers
|
||||
if (wasPrivateVideo === true && videoInstance.privacy !== VideoPrivacy.PRIVATE) {
|
||||
await sendAddVideo(videoInstance, t)
|
||||
}
|
||||
|
@ -365,7 +365,7 @@ async function removeVideo (req: express.Request, res: express.Response) {
|
|||
}
|
||||
|
||||
async function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
const resultList = await db.Video.searchAndPopulateAccountAndPodAndTags(
|
||||
const resultList = await db.Video.searchAndPopulateAccountAndServerAndTags(
|
||||
req.params.value,
|
||||
req.query.field,
|
||||
req.query.start,
|
||||
|
|
|
@ -83,7 +83,7 @@ async function rateVideo (req: express.Request, res: express.Response) {
|
|||
await videoInstance.increment(incrementQuery, sequelizeOptions)
|
||||
|
||||
if (videoInstance.isOwned() === false) {
|
||||
// TODO: Send a event to original pod
|
||||
// TODO: Send a event to original server
|
||||
} else {
|
||||
// TODO: Send update to followers
|
||||
}
|
||||
|
|
|
@ -110,9 +110,9 @@ async function generateWatchHtmlPage (req: express.Request, res: express.Respons
|
|||
|
||||
// Let Angular application handle errors
|
||||
if (validator.isUUID(videoId, 4)) {
|
||||
videoPromise = db.Video.loadByUUIDAndPopulateAccountAndPodAndTags(videoId)
|
||||
videoPromise = db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(videoId)
|
||||
} else if (validator.isInt(videoId)) {
|
||||
videoPromise = db.Video.loadAndPopulateAccountAndPodAndTags(+videoId)
|
||||
videoPromise = db.Video.loadAndPopulateAccountAndServerAndTags(+videoId)
|
||||
} else {
|
||||
return res.sendFile(indexPath)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import { asyncMiddleware } from '../middlewares'
|
|||
const staticRouter = express.Router()
|
||||
|
||||
/*
|
||||
Cors is very important to let other pods access torrent and video files
|
||||
Cors is very important to let other servers access torrent and video files
|
||||
*/
|
||||
|
||||
const torrentsPhysicalPath = CONFIG.STORAGE.TORRENTS_DIR
|
||||
|
|
|
@ -35,7 +35,7 @@ async function getOrCreateAccount (accountUrl: string) {
|
|||
|
||||
// We don't have this account in our database, fetch it on remote
|
||||
if (!account) {
|
||||
const res = await fetchRemoteAccountAndCreatePod(accountUrl)
|
||||
const res = await fetchRemoteAccountAndCreateServer(accountUrl)
|
||||
if (res === undefined) throw new Error('Cannot fetch remote account.')
|
||||
|
||||
// Save our new account in database
|
||||
|
@ -46,7 +46,7 @@ async function getOrCreateAccount (accountUrl: string) {
|
|||
return account
|
||||
}
|
||||
|
||||
async function fetchRemoteAccountAndCreatePod (accountUrl: string) {
|
||||
async function fetchRemoteAccountAndCreateServer (accountUrl: string) {
|
||||
const options = {
|
||||
uri: accountUrl,
|
||||
method: 'GET',
|
||||
|
@ -90,7 +90,7 @@ async function fetchRemoteAccountAndCreatePod (accountUrl: string) {
|
|||
})
|
||||
|
||||
const accountHost = url.parse(account.url).host
|
||||
const podOptions = {
|
||||
const serverOptions = {
|
||||
where: {
|
||||
host: accountHost
|
||||
},
|
||||
|
@ -98,15 +98,15 @@ async function fetchRemoteAccountAndCreatePod (accountUrl: string) {
|
|||
host: accountHost
|
||||
}
|
||||
}
|
||||
const [ pod ] = await db.Pod.findOrCreate(podOptions)
|
||||
account.set('podId', pod.id)
|
||||
const [ server ] = await db.Server.findOrCreate(serverOptions)
|
||||
account.set('serverId', server.id)
|
||||
|
||||
return { account, pod }
|
||||
return { account, server }
|
||||
}
|
||||
|
||||
function fetchRemoteVideoPreview (video: VideoInstance) {
|
||||
// FIXME: use url
|
||||
const host = video.VideoChannel.Account.Pod.host
|
||||
const host = video.VideoChannel.Account.Server.host
|
||||
const path = join(STATIC_PATHS.PREVIEWS, video.getPreviewName())
|
||||
|
||||
return request.get(REMOTE_SCHEME.HTTP + '://' + host + path)
|
||||
|
@ -163,7 +163,7 @@ function activityPubCollectionPagination (url: string, page: number, result: Res
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
fetchRemoteAccountAndCreatePod,
|
||||
fetchRemoteAccountAndCreateServer,
|
||||
activityPubContextify,
|
||||
activityPubCollectionPagination,
|
||||
getActivityPubUrl,
|
||||
|
|
|
@ -8,7 +8,7 @@ import { AccountInstance } from '../../models'
|
|||
import { logger } from '../logger'
|
||||
|
||||
import { isUserUsernameValid } from './users'
|
||||
import { isHostValid } from './pods'
|
||||
import { isHostValid } from './servers'
|
||||
|
||||
function isAccountNameValid (value: string) {
|
||||
return isUserUsernameValid(value)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export * from './activitypub'
|
||||
export * from './misc'
|
||||
export * from './pods'
|
||||
export * from './pods'
|
||||
export * from './servers'
|
||||
export * from './servers'
|
||||
export * from './users'
|
||||
export * from './accounts'
|
||||
export * from './video-channels'
|
||||
|
|
|
@ -171,9 +171,9 @@ function isVideoFileInfoHashValid (value: string) {
|
|||
function checkVideoExists (id: string, res: express.Response, callback: () => void) {
|
||||
let promise: Promise<VideoInstance>
|
||||
if (validator.isInt(id)) {
|
||||
promise = db.Video.loadAndPopulateAccountAndPodAndTags(+id)
|
||||
promise = db.Video.loadAndPopulateAccountAndServerAndTags(+id)
|
||||
} else { // UUID
|
||||
promise = db.Video.loadByUUIDAndPopulateAccountAndPodAndTags(id)
|
||||
promise = db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(id)
|
||||
}
|
||||
|
||||
promise.then(video => {
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as WebFinger from 'webfinger.js'
|
|||
import { isTestInstance } from './core-utils'
|
||||
import { isActivityPubUrlValid } from './custom-validators'
|
||||
import { WebFingerData } from '../../shared'
|
||||
import { fetchRemoteAccountAndCreatePod } from './activitypub'
|
||||
import { fetchRemoteAccountAndCreateServer } from './activitypub'
|
||||
|
||||
const webfinger = new WebFinger({
|
||||
webfist_fallback: false,
|
||||
|
@ -22,8 +22,8 @@ async function getAccountFromWebfinger (nameWithHost: string) {
|
|||
throw new Error('Cannot find self link or href is not a valid URL.')
|
||||
}
|
||||
|
||||
const res = await fetchRemoteAccountAndCreatePod(selfLink.href)
|
||||
if (res === undefined) throw new Error('Cannot fetch and create pod of remote account ' + selfLink.href)
|
||||
const res = await fetchRemoteAccountAndCreateServer(selfLink.href)
|
||||
if (res === undefined) throw new Error('Cannot fetch and create server of remote account ' + selfLink.href)
|
||||
|
||||
return res.account
|
||||
}
|
||||
|
|
|
@ -6,10 +6,6 @@ import { root, isTestInstance } from '../helpers/core-utils'
|
|||
|
||||
import {
|
||||
VideoRateType,
|
||||
RequestEndpoint,
|
||||
RequestVideoEventType,
|
||||
RequestVideoQaduType,
|
||||
RemoteVideoRequestType,
|
||||
JobState,
|
||||
JobCategory
|
||||
} from '../../shared/models'
|
||||
|
@ -220,7 +216,7 @@ const VIDEO_MIMETYPE_EXT = {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Score a pod has when we create it as a friend
|
||||
// Score a server has when we create it as a friend
|
||||
const FRIEND_SCORE = {
|
||||
BASE: 100,
|
||||
MAX: 1000
|
||||
|
@ -243,7 +239,7 @@ const ACTIVITY_PUB = {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Number of points we add/remove from a friend after a successful/bad request
|
||||
const PODS_SCORE = {
|
||||
const SERVERS_SCORE = {
|
||||
PENALTY: -10,
|
||||
BONUS: 10
|
||||
}
|
||||
|
@ -352,7 +348,7 @@ export {
|
|||
OAUTH_LIFETIME,
|
||||
OPENGRAPH_AND_OEMBED_COMMENT,
|
||||
PAGINATION_COUNT_DEFAULT,
|
||||
PODS_SCORE,
|
||||
SERVERS_SCORE,
|
||||
PREVIEWS_SIZE,
|
||||
REMOTE_SCHEME,
|
||||
ACTIVITY_PUB_ACCEPT_HEADER,
|
||||
|
|
|
@ -18,7 +18,7 @@ import { UserModel } from '../models/account/user-interface'
|
|||
import { AccountVideoRateModel } from '../models/account/account-video-rate-interface'
|
||||
import { AccountFollowModel } from '../models/account/account-follow-interface'
|
||||
import { TagModel } from './../models/video/tag-interface'
|
||||
import { PodModel } from './../models/pod/pod-interface'
|
||||
import { ServerModel } from '../models/server/server-interface'
|
||||
import { OAuthTokenModel } from './../models/oauth/oauth-token-interface'
|
||||
import { OAuthClientModel } from './../models/oauth/oauth-client-interface'
|
||||
import { JobModel } from './../models/job/job-interface'
|
||||
|
@ -38,7 +38,7 @@ const database: {
|
|||
Job?: JobModel,
|
||||
OAuthClient?: OAuthClientModel,
|
||||
OAuthToken?: OAuthTokenModel,
|
||||
Pod?: PodModel,
|
||||
Server?: ServerModel,
|
||||
Tag?: TagModel,
|
||||
AccountVideoRate?: AccountVideoRateModel,
|
||||
AccountFollow?: AccountFollowModel,
|
||||
|
|
2
server/lib/cache/videos-preview-cache.ts
vendored
2
server/lib/cache/videos-preview-cache.ts
vendored
|
@ -42,7 +42,7 @@ class VideosPreviewCache {
|
|||
}
|
||||
|
||||
private async loadPreviews (key: string) {
|
||||
const video = await db.Video.loadByUUIDAndPopulateAccountAndPodAndTags(key)
|
||||
const video = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(key)
|
||||
if (!video) return undefined
|
||||
|
||||
if (video.isOwned()) return join(CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName())
|
||||
|
|
|
@ -8,7 +8,7 @@ import { JobScheduler } from '../job-scheduler'
|
|||
import { TranscodingJobPayload } from './transcoding-job-scheduler'
|
||||
|
||||
async function process (data: TranscodingJobPayload, jobId: number) {
|
||||
const video = await db.Video.loadByUUIDAndPopulateAccountAndPodAndTags(data.videoUUID)
|
||||
const video = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(data.videoUUID)
|
||||
// No video, maybe deleted?
|
||||
if (!video) {
|
||||
logger.info('Do not process job %d, video does not exist.', jobId, { videoUUID: video.uuid })
|
||||
|
@ -31,7 +31,7 @@ async function onSuccess (jobId: number, video: VideoInstance, jobScheduler: Job
|
|||
logger.info('Job %d is a success.', jobId)
|
||||
|
||||
// Maybe the video changed in database, refresh it
|
||||
const videoDatabase = await db.Video.loadByUUIDAndPopulateAccountAndPodAndTags(video.uuid)
|
||||
const videoDatabase = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(video.uuid)
|
||||
// Video does not exist anymore
|
||||
if (!videoDatabase) return undefined
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import { VideoInstance } from '../../../models'
|
|||
import { sendUpdateVideo } from '../../activitypub/send-request'
|
||||
|
||||
async function process (data: { videoUUID: string, resolution: VideoResolution }, jobId: number) {
|
||||
const video = await db.Video.loadByUUIDAndPopulateAccountAndPodAndTags(data.videoUUID)
|
||||
const video = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(data.videoUUID)
|
||||
// No video, maybe deleted?
|
||||
if (!video) {
|
||||
logger.info('Do not process job %d, video does not exist.', jobId, { videoUUID: video.uuid })
|
||||
|
@ -28,7 +28,7 @@ async function onSuccess (jobId: number, video: VideoInstance) {
|
|||
logger.info('Job %d is a success.', jobId)
|
||||
|
||||
// Maybe the video changed in database, refresh it
|
||||
const videoDatabase = await db.Video.loadByUUIDAndPopulateAccountAndPodAndTags(video.uuid)
|
||||
const videoDatabase = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(video.uuid)
|
||||
// Video does not exist anymore
|
||||
if (!videoDatabase) return undefined
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ async function createLocalAccount (name: string, userId: number, applicationId:
|
|||
followingUrl: url + '/following',
|
||||
userId,
|
||||
applicationId,
|
||||
podId: null // It is our pod
|
||||
serverId: null // It is our server
|
||||
})
|
||||
|
||||
return accountInstance.save({ transaction: t })
|
||||
|
|
|
@ -30,14 +30,14 @@ async function createVideoChannel (videoChannelInfo: VideoChannelCreate, account
|
|||
return videoChannelCreated
|
||||
}
|
||||
|
||||
async function fetchVideoChannelByHostAndUUID (podHost: string, uuid: string, t: Sequelize.Transaction) {
|
||||
async function fetchVideoChannelByHostAndUUID (serverHost: string, uuid: string, t: Sequelize.Transaction) {
|
||||
try {
|
||||
const videoChannel = await db.VideoChannel.loadByHostAndUUID(podHost, uuid, t)
|
||||
const videoChannel = await db.VideoChannel.loadByHostAndUUID(serverHost, uuid, t)
|
||||
if (!videoChannel) throw new Error('Video channel not found')
|
||||
|
||||
return videoChannel
|
||||
} catch (err) {
|
||||
logger.error('Cannot load video channel from host and uuid.', { error: err.stack, podHost, uuid })
|
||||
logger.error('Cannot load video channel from host and uuid.', { error: err.stack, serverHost, uuid })
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { NextFunction, Request, Response, RequestHandler } from 'express'
|
||||
import { ActivityPubSignature } from '../../shared'
|
||||
import { isSignatureVerified, logger } from '../helpers'
|
||||
import { fetchRemoteAccountAndCreatePod } from '../helpers/activitypub'
|
||||
import { fetchRemoteAccountAndCreateServer } from '../helpers/activitypub'
|
||||
import { database as db, ACTIVITY_PUB_ACCEPT_HEADER } from '../initializers'
|
||||
import { each, eachSeries, waterfall } from 'async'
|
||||
|
||||
|
@ -14,7 +14,7 @@ async function checkSignature (req: Request, res: Response, next: NextFunction)
|
|||
|
||||
// We don't have this account in our database, fetch it on remote
|
||||
if (!account) {
|
||||
const accountResult = await fetchRemoteAccountAndCreatePod(signatureObject.creator)
|
||||
const accountResult = await fetchRemoteAccountAndCreateServer(signatureObject.creator)
|
||||
|
||||
if (!accountResult) {
|
||||
return res.sendStatus(403)
|
||||
|
|
|
@ -3,7 +3,7 @@ export * from './activitypub'
|
|||
export * from './async'
|
||||
export * from './oauth'
|
||||
export * from './pagination'
|
||||
export * from './pods'
|
||||
export * from './servers'
|
||||
export * from './search'
|
||||
export * from './sort'
|
||||
export * from './user-right'
|
||||
|
|
|
@ -4,12 +4,6 @@ import * as express from 'express'
|
|||
import { SortType } from '../helpers'
|
||||
import { database } from '../initializers'
|
||||
|
||||
function setPodsSort (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
if (!req.query.sort) req.query.sort = '-createdAt'
|
||||
|
||||
return next()
|
||||
}
|
||||
|
||||
function setUsersSort (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
if (!req.query.sort) req.query.sort = '-createdAt'
|
||||
|
||||
|
@ -70,7 +64,6 @@ function setBlacklistSort (req: express.Request, res: express.Response, next: ex
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
setPodsSort,
|
||||
setUsersSort,
|
||||
setVideoAbusesSort,
|
||||
setVideoChannelsSort,
|
||||
|
|
|
@ -2,7 +2,7 @@ export * from './account'
|
|||
export * from './oembed'
|
||||
export * from './activitypub'
|
||||
export * from './pagination'
|
||||
export * from './pods'
|
||||
export * from './servers'
|
||||
export * from './sort'
|
||||
export * from './users'
|
||||
export * from './videos'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as express from 'express'
|
||||
import { body } from 'express-validator/check'
|
||||
import { isEachUniqueHostValid } from '../../helpers/custom-validators/pods'
|
||||
import { isEachUniqueHostValid } from '../../helpers/custom-validators/servers'
|
||||
import { isTestInstance } from '../../helpers/core-utils'
|
||||
import { CONFIG } from '../../initializers/constants'
|
||||
import { logger } from '../../helpers/logger'
|
|
@ -50,7 +50,7 @@ const videoChannelsUpdateValidator = [
|
|||
// We need to make additional checks
|
||||
if (res.locals.videoChannel.isOwned() === false) {
|
||||
return res.status(403)
|
||||
.json({ error: 'Cannot update video channel of another pod' })
|
||||
.json({ error: 'Cannot update video channel of another server' })
|
||||
.end()
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ function checkUserCanDeleteVideoChannel (res: express.Response, callback: () =>
|
|||
// Retrieve the user who did the request
|
||||
if (res.locals.videoChannel.isOwned() === false) {
|
||||
return res.status(403)
|
||||
.json({ error: 'Cannot remove video channel of another pod.' })
|
||||
.json({ error: 'Cannot remove video channel of another server.' })
|
||||
.end()
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ const videosUpdateValidator = [
|
|||
// We need to make additional checks
|
||||
if (video.isOwned() === false) {
|
||||
return res.status(403)
|
||||
.json({ error: 'Cannot update video of another pod' })
|
||||
.json({ error: 'Cannot update video of another server' })
|
||||
.end()
|
||||
}
|
||||
|
||||
|
@ -250,7 +250,7 @@ function checkUserCanDeleteVideo (userId: number, res: express.Response, callbac
|
|||
// Retrieve the user who did the request
|
||||
if (res.locals.video.isOwned() === false) {
|
||||
return res.status(403)
|
||||
.json({ error: 'Cannot remove video of another pod, blacklist it' })
|
||||
.json({ error: 'Cannot remove video of another server, blacklist it' })
|
||||
.end()
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ listFollowingForApi = function (id: number, start: number, count: number, sort:
|
|||
model: AccountFollow['sequelize'].models.Account,
|
||||
as: 'AccountFollowing',
|
||||
required: true,
|
||||
include: [ AccountFollow['sequelize'].models.Pod ]
|
||||
include: [ AccountFollow['sequelize'].models.Server ]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ listFollowersForApi = function (id: number, start: number, count: number, sort:
|
|||
model: AccountFollow[ 'sequelize' ].models.Account,
|
||||
required: true,
|
||||
as: 'AccountFollower',
|
||||
include: [ AccountFollow['sequelize'].models.Pod ]
|
||||
include: [ AccountFollow['sequelize'].models.Server ]
|
||||
},
|
||||
{
|
||||
model: AccountFollow['sequelize'].models.Account,
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import * as Bluebird from 'bluebird'
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { Account as FormattedAccount, ActivityPubActor } from '../../../shared'
|
||||
import { ResultList } from '../../../shared/models/result-list.model'
|
||||
import { PodInstance } from '../pod/pod-interface'
|
||||
import { ServerInstance } from '../server/server-interface'
|
||||
import { VideoChannelInstance } from '../video/video-channel-interface'
|
||||
|
||||
export namespace AccountMethods {
|
||||
|
@ -11,7 +10,7 @@ export namespace AccountMethods {
|
|||
export type Load = (id: number) => Bluebird<AccountInstance>
|
||||
export type LoadByUUID = (uuid: string) => Bluebird<AccountInstance>
|
||||
export type LoadByUrl = (url: string, transaction?: Sequelize.Transaction) => Bluebird<AccountInstance>
|
||||
export type LoadAccountByPodAndUUID = (uuid: string, podId: number, transaction: Sequelize.Transaction) => Bluebird<AccountInstance>
|
||||
export type LoadAccountByServerAndUUID = (uuid: string, serverId: number, transaction: Sequelize.Transaction) => Bluebird<AccountInstance>
|
||||
export type LoadLocalByName = (name: string) => Bluebird<AccountInstance>
|
||||
export type LoadByNameAndHost = (name: string, host: string) => Bluebird<AccountInstance>
|
||||
export type ListOwned = () => Bluebird<AccountInstance[]>
|
||||
|
@ -27,7 +26,7 @@ export namespace AccountMethods {
|
|||
|
||||
export interface AccountClass {
|
||||
loadApplication: AccountMethods.LoadApplication
|
||||
loadAccountByPodAndUUID: AccountMethods.LoadAccountByPodAndUUID
|
||||
loadAccountByServerAndUUID: AccountMethods.LoadAccountByServerAndUUID
|
||||
load: AccountMethods.Load
|
||||
loadByUUID: AccountMethods.LoadByUUID
|
||||
loadByUrl: AccountMethods.LoadByUrl
|
||||
|
@ -51,7 +50,7 @@ export interface AccountAttributes {
|
|||
|
||||
uuid?: string
|
||||
|
||||
podId?: number
|
||||
serverId?: number
|
||||
userId?: number
|
||||
applicationId?: number
|
||||
}
|
||||
|
@ -69,7 +68,7 @@ export interface AccountInstance extends AccountClass, AccountAttributes, Sequel
|
|||
createdAt: Date
|
||||
updatedAt: Date
|
||||
|
||||
Pod: PodInstance
|
||||
Server: ServerInstance
|
||||
VideoChannels: VideoChannelInstance[]
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import { sendDeleteAccount } from '../../lib/activitypub/send-request'
|
|||
import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers/constants'
|
||||
|
||||
let Account: Sequelize.Model<AccountInstance, AccountAttributes>
|
||||
let loadAccountByPodAndUUID: AccountMethods.LoadAccountByPodAndUUID
|
||||
let loadAccountByServerAndUUID: AccountMethods.LoadAccountByServerAndUUID
|
||||
let load: AccountMethods.Load
|
||||
let loadApplication: AccountMethods.LoadApplication
|
||||
let loadByUUID: AccountMethods.LoadByUUID
|
||||
|
@ -170,7 +170,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes
|
|||
fields: [ 'name' ]
|
||||
},
|
||||
{
|
||||
fields: [ 'podId' ]
|
||||
fields: [ 'serverId' ]
|
||||
},
|
||||
{
|
||||
fields: [ 'userId' ],
|
||||
|
@ -181,7 +181,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes
|
|||
unique: true
|
||||
},
|
||||
{
|
||||
fields: [ 'name', 'podId', 'applicationId' ],
|
||||
fields: [ 'name', 'serverId', 'applicationId' ],
|
||||
unique: true
|
||||
}
|
||||
],
|
||||
|
@ -191,7 +191,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes
|
|||
|
||||
const classMethods = [
|
||||
associate,
|
||||
loadAccountByPodAndUUID,
|
||||
loadAccountByServerAndUUID,
|
||||
loadApplication,
|
||||
load,
|
||||
loadByUUID,
|
||||
|
@ -217,9 +217,9 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
function associate (models) {
|
||||
Account.belongsTo(models.Pod, {
|
||||
Account.belongsTo(models.Server, {
|
||||
foreignKey: {
|
||||
name: 'podId',
|
||||
name: 'serverId',
|
||||
allowNull: true
|
||||
},
|
||||
onDelete: 'cascade'
|
||||
|
@ -278,19 +278,28 @@ function afterDestroy (account: AccountInstance) {
|
|||
}
|
||||
|
||||
toFormattedJSON = function (this: AccountInstance) {
|
||||
let host = this.Pod ? this.Pod.host : CONFIG.WEBSERVER.HOST
|
||||
let host = CONFIG.WEBSERVER.HOST
|
||||
let score: number
|
||||
|
||||
if (this.Server) {
|
||||
host = this.Server.host
|
||||
score = this.Server.score as number
|
||||
}
|
||||
|
||||
const json = {
|
||||
id: this.id,
|
||||
host,
|
||||
name: this.name
|
||||
score,
|
||||
name: this.name,
|
||||
createdAt: this.createdAt,
|
||||
updatedAt: this.updatedAt
|
||||
}
|
||||
|
||||
return json
|
||||
}
|
||||
|
||||
toActivityPubObject = function (this: AccountInstance) {
|
||||
const type = this.podId ? 'Application' as 'Application' : 'Person' as 'Person'
|
||||
const type = this.serverId ? 'Application' as 'Application' : 'Person' as 'Person'
|
||||
|
||||
const json = {
|
||||
type,
|
||||
|
@ -317,7 +326,7 @@ toActivityPubObject = function (this: AccountInstance) {
|
|||
}
|
||||
|
||||
isOwned = function (this: AccountInstance) {
|
||||
return this.podId === null
|
||||
return this.serverId === null
|
||||
}
|
||||
|
||||
getFollowerSharedInboxUrls = function (this: AccountInstance) {
|
||||
|
@ -356,7 +365,7 @@ getPublicKeyUrl = function (this: AccountInstance) {
|
|||
listOwned = function () {
|
||||
const query: Sequelize.FindOptions<AccountAttributes> = {
|
||||
where: {
|
||||
podId: null
|
||||
serverId: null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,7 +426,7 @@ loadByNameAndHost = function (name: string, host: string) {
|
|||
},
|
||||
include: [
|
||||
{
|
||||
model: Account['sequelize'].models.Pod,
|
||||
model: Account['sequelize'].models.Server,
|
||||
required: true,
|
||||
where: {
|
||||
host
|
||||
|
@ -440,10 +449,10 @@ loadByUrl = function (url: string, transaction?: Sequelize.Transaction) {
|
|||
return Account.findOne(query)
|
||||
}
|
||||
|
||||
loadAccountByPodAndUUID = function (uuid: string, podId: number, transaction: Sequelize.Transaction) {
|
||||
loadAccountByServerAndUUID = function (uuid: string, serverId: number, transaction: Sequelize.Transaction) {
|
||||
const query: Sequelize.FindOptions<AccountAttributes> = {
|
||||
where: {
|
||||
podId,
|
||||
serverId,
|
||||
uuid
|
||||
},
|
||||
transaction
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export * from './application'
|
||||
export * from './job'
|
||||
export * from './oauth'
|
||||
export * from './pod'
|
||||
export * from './server'
|
||||
export * from './account'
|
||||
export * from './video'
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export * from './pod-interface'
|
|
@ -1,61 +0,0 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import * as Promise from 'bluebird'
|
||||
|
||||
// Don't use barrel, import just what we need
|
||||
import { Pod as FormattedPod } from '../../../shared/models/pods/pod.model'
|
||||
import { ResultList } from '../../../shared/models/result-list.model'
|
||||
|
||||
export namespace PodMethods {
|
||||
export type ToFormattedJSON = (this: PodInstance) => FormattedPod
|
||||
|
||||
export type CountAll = () => Promise<number>
|
||||
|
||||
export type IncrementScores = (ids: number[], value: number) => Promise<[ number, PodInstance[] ]>
|
||||
|
||||
export type List = () => Promise<PodInstance[]>
|
||||
|
||||
export type ListForApi = (start: number, count: number, sort: string) => Promise< ResultList<PodInstance> >
|
||||
|
||||
export type ListAllIds = (transaction: Sequelize.Transaction) => Promise<number[]>
|
||||
|
||||
export type ListRandomPodIdsWithRequest = (limit: number, tableWithPods: string, tableWithPodsJoins: string) => Promise<number[]>
|
||||
|
||||
export type ListBadPods = () => Promise<PodInstance[]>
|
||||
|
||||
export type Load = (id: number) => Promise<PodInstance>
|
||||
|
||||
export type LoadByHost = (host: string) => Promise<PodInstance>
|
||||
|
||||
export type RemoveAll = () => Promise<number>
|
||||
|
||||
export type UpdatePodsScore = (goodPods: number[], badPods: number[]) => void
|
||||
}
|
||||
|
||||
export interface PodClass {
|
||||
countAll: PodMethods.CountAll
|
||||
incrementScores: PodMethods.IncrementScores
|
||||
list: PodMethods.List
|
||||
listForApi: PodMethods.ListForApi
|
||||
listAllIds: PodMethods.ListAllIds
|
||||
listRandomPodIdsWithRequest: PodMethods.ListRandomPodIdsWithRequest
|
||||
listBadPods: PodMethods.ListBadPods
|
||||
load: PodMethods.Load
|
||||
loadByHost: PodMethods.LoadByHost
|
||||
removeAll: PodMethods.RemoveAll
|
||||
updatePodsScore: PodMethods.UpdatePodsScore
|
||||
}
|
||||
|
||||
export interface PodAttributes {
|
||||
id?: number
|
||||
host?: string
|
||||
score?: number | Sequelize.literal // Sequelize literal for 'score +' + value
|
||||
}
|
||||
|
||||
export interface PodInstance extends PodClass, PodAttributes, Sequelize.Instance<PodAttributes> {
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
|
||||
toFormattedJSON: PodMethods.ToFormattedJSON,
|
||||
}
|
||||
|
||||
export interface PodModel extends PodClass, Sequelize.Model<PodInstance, PodAttributes> {}
|
|
@ -1,248 +0,0 @@
|
|||
import { map } from 'lodash'
|
||||
import * as Sequelize from 'sequelize'
|
||||
|
||||
import { FRIEND_SCORE, PODS_SCORE } from '../../initializers'
|
||||
import { logger, isHostValid } from '../../helpers'
|
||||
|
||||
import { addMethodsToModel, getSort } from '../utils'
|
||||
import {
|
||||
PodInstance,
|
||||
PodAttributes,
|
||||
|
||||
PodMethods
|
||||
} from './pod-interface'
|
||||
|
||||
let Pod: Sequelize.Model<PodInstance, PodAttributes>
|
||||
let toFormattedJSON: PodMethods.ToFormattedJSON
|
||||
let countAll: PodMethods.CountAll
|
||||
let incrementScores: PodMethods.IncrementScores
|
||||
let list: PodMethods.List
|
||||
let listForApi: PodMethods.ListForApi
|
||||
let listAllIds: PodMethods.ListAllIds
|
||||
let listRandomPodIdsWithRequest: PodMethods.ListRandomPodIdsWithRequest
|
||||
let listBadPods: PodMethods.ListBadPods
|
||||
let load: PodMethods.Load
|
||||
let loadByHost: PodMethods.LoadByHost
|
||||
let removeAll: PodMethods.RemoveAll
|
||||
let updatePodsScore: PodMethods.UpdatePodsScore
|
||||
|
||||
export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
|
||||
Pod = sequelize.define<PodInstance, PodAttributes>('Pod',
|
||||
{
|
||||
host: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
validate: {
|
||||
isHost: value => {
|
||||
const res = isHostValid(value)
|
||||
if (res === false) throw new Error('Host not valid.')
|
||||
}
|
||||
}
|
||||
},
|
||||
score: {
|
||||
type: DataTypes.INTEGER,
|
||||
defaultValue: FRIEND_SCORE.BASE,
|
||||
allowNull: false,
|
||||
validate: {
|
||||
isInt: true,
|
||||
max: FRIEND_SCORE.MAX
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
indexes: [
|
||||
{
|
||||
fields: [ 'host' ],
|
||||
unique: true
|
||||
},
|
||||
{
|
||||
fields: [ 'score' ]
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
const classMethods = [
|
||||
countAll,
|
||||
incrementScores,
|
||||
list,
|
||||
listForApi,
|
||||
listAllIds,
|
||||
listRandomPodIdsWithRequest,
|
||||
listBadPods,
|
||||
load,
|
||||
loadByHost,
|
||||
updatePodsScore,
|
||||
removeAll
|
||||
]
|
||||
const instanceMethods = [ toFormattedJSON ]
|
||||
addMethodsToModel(Pod, classMethods, instanceMethods)
|
||||
|
||||
return Pod
|
||||
}
|
||||
|
||||
// ------------------------------ METHODS ------------------------------
|
||||
|
||||
toFormattedJSON = function (this: PodInstance) {
|
||||
const json = {
|
||||
id: this.id,
|
||||
host: this.host,
|
||||
score: this.score as number,
|
||||
createdAt: this.createdAt
|
||||
}
|
||||
|
||||
return json
|
||||
}
|
||||
|
||||
// ------------------------------ Statics ------------------------------
|
||||
|
||||
countAll = function () {
|
||||
return Pod.count()
|
||||
}
|
||||
|
||||
incrementScores = function (ids: number[], value: number) {
|
||||
const update = {
|
||||
score: Sequelize.literal('score +' + value)
|
||||
}
|
||||
|
||||
const options = {
|
||||
where: {
|
||||
id: {
|
||||
[Sequelize.Op.in]: ids
|
||||
}
|
||||
},
|
||||
// In this case score is a literal and not an integer so we do not validate it
|
||||
validate: false
|
||||
}
|
||||
|
||||
return Pod.update(update, options)
|
||||
}
|
||||
|
||||
list = function () {
|
||||
return Pod.findAll()
|
||||
}
|
||||
|
||||
listForApi = function (start: number, count: number, sort: string) {
|
||||
const query = {
|
||||
offset: start,
|
||||
limit: count,
|
||||
order: [ getSort(sort) ]
|
||||
}
|
||||
|
||||
return Pod.findAndCountAll(query).then(({ rows, count }) => {
|
||||
return {
|
||||
data: rows,
|
||||
total: count
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
listAllIds = function (transaction: Sequelize.Transaction) {
|
||||
const query = {
|
||||
attributes: [ 'id' ],
|
||||
transaction
|
||||
}
|
||||
|
||||
return Pod.findAll(query).then(pods => {
|
||||
return map(pods, 'id')
|
||||
})
|
||||
}
|
||||
|
||||
listRandomPodIdsWithRequest = function (limit: number, tableWithPods: string, tableWithPodsJoins: string) {
|
||||
return Pod.count().then(count => {
|
||||
// Optimization...
|
||||
if (count === 0) return []
|
||||
|
||||
let start = Math.floor(Math.random() * count) - limit
|
||||
if (start < 0) start = 0
|
||||
|
||||
const subQuery = `(SELECT DISTINCT "${tableWithPods}"."podId" FROM "${tableWithPods}" ${tableWithPodsJoins})`
|
||||
const query = {
|
||||
attributes: [ 'id' ],
|
||||
order: [
|
||||
[ 'id', 'ASC' ]
|
||||
],
|
||||
offset: start,
|
||||
limit: limit,
|
||||
where: {
|
||||
id: {
|
||||
[Sequelize.Op.in]: Sequelize.literal(subQuery)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Pod.findAll(query).then(pods => {
|
||||
return map(pods, 'id')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
listBadPods = function () {
|
||||
const query = {
|
||||
where: {
|
||||
score: {
|
||||
[Sequelize.Op.lte]: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Pod.findAll(query)
|
||||
}
|
||||
|
||||
load = function (id: number) {
|
||||
return Pod.findById(id)
|
||||
}
|
||||
|
||||
loadByHost = function (host: string) {
|
||||
const query = {
|
||||
where: {
|
||||
host: host
|
||||
}
|
||||
}
|
||||
|
||||
return Pod.findOne(query)
|
||||
}
|
||||
|
||||
removeAll = function () {
|
||||
return Pod.destroy()
|
||||
}
|
||||
|
||||
updatePodsScore = function (goodPods: number[], badPods: number[]) {
|
||||
logger.info('Updating %d good pods and %d bad pods scores.', goodPods.length, badPods.length)
|
||||
|
||||
if (goodPods.length !== 0) {
|
||||
incrementScores(goodPods, PODS_SCORE.BONUS).catch(err => {
|
||||
logger.error('Cannot increment scores of good pods.', err)
|
||||
})
|
||||
}
|
||||
|
||||
if (badPods.length !== 0) {
|
||||
incrementScores(badPods, PODS_SCORE.PENALTY)
|
||||
.then(() => removeBadPods())
|
||||
.catch(err => {
|
||||
if (err) logger.error('Cannot decrement scores of bad pods.', err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Remove pods with a score of 0 (too many requests where they were unreachable)
|
||||
async function removeBadPods () {
|
||||
try {
|
||||
const pods = await listBadPods()
|
||||
|
||||
const podsRemovePromises = pods.map(pod => pod.destroy())
|
||||
await Promise.all(podsRemovePromises)
|
||||
|
||||
const numberOfPodsRemoved = pods.length
|
||||
|
||||
if (numberOfPodsRemoved) {
|
||||
logger.info('Removed %d pods.', numberOfPodsRemoved)
|
||||
} else {
|
||||
logger.info('No need to remove bad pods.')
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error('Cannot remove bad pods.', err)
|
||||
}
|
||||
}
|
1
server/models/server/index.ts
Normal file
1
server/models/server/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './server-interface'
|
56
server/models/server/server-interface.ts
Normal file
56
server/models/server/server-interface.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import * as Promise from 'bluebird'
|
||||
|
||||
// Don't use barrel, import just what we need
|
||||
import { ResultList } from '../../../shared/models/result-list.model'
|
||||
|
||||
export namespace ServerMethods {
|
||||
export type CountAll = () => Promise<number>
|
||||
|
||||
export type IncrementScores = (ids: number[], value: number) => Promise<[ number, ServerInstance[] ]>
|
||||
|
||||
export type List = () => Promise<ServerInstance[]>
|
||||
|
||||
export type ListForApi = (start: number, count: number, sort: string) => Promise< ResultList<ServerInstance> >
|
||||
|
||||
export type ListAllIds = (transaction: Sequelize.Transaction) => Promise<number[]>
|
||||
|
||||
export type ListRandomServerIdsWithRequest = (limit: number, tableWithServers: string, tableWithServersJoins: string) => Promise<number[]>
|
||||
|
||||
export type ListBadServers = () => Promise<ServerInstance[]>
|
||||
|
||||
export type Load = (id: number) => Promise<ServerInstance>
|
||||
|
||||
export type LoadByHost = (host: string) => Promise<ServerInstance>
|
||||
|
||||
export type RemoveAll = () => Promise<number>
|
||||
|
||||
export type UpdateServersScore = (goodServers: number[], badServers: number[]) => void
|
||||
}
|
||||
|
||||
export interface ServerClass {
|
||||
countAll: ServerMethods.CountAll
|
||||
incrementScores: ServerMethods.IncrementScores
|
||||
list: ServerMethods.List
|
||||
listForApi: ServerMethods.ListForApi
|
||||
listAllIds: ServerMethods.ListAllIds
|
||||
listRandomServerIdsWithRequest: ServerMethods.ListRandomServerIdsWithRequest
|
||||
listBadServers: ServerMethods.ListBadServers
|
||||
load: ServerMethods.Load
|
||||
loadByHost: ServerMethods.LoadByHost
|
||||
removeAll: ServerMethods.RemoveAll
|
||||
updateServersScore: ServerMethods.UpdateServersScore
|
||||
}
|
||||
|
||||
export interface ServerAttributes {
|
||||
id?: number
|
||||
host?: string
|
||||
score?: number | Sequelize.literal // Sequelize literal for 'score +' + value
|
||||
}
|
||||
|
||||
export interface ServerInstance extends ServerClass, ServerAttributes, Sequelize.Instance<ServerAttributes> {
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
}
|
||||
|
||||
export interface ServerModel extends ServerClass, Sequelize.Model<ServerInstance, ServerAttributes> {}
|
233
server/models/server/server.ts
Normal file
233
server/models/server/server.ts
Normal file
|
@ -0,0 +1,233 @@
|
|||
import { map } from 'lodash'
|
||||
import * as Sequelize from 'sequelize'
|
||||
|
||||
import { FRIEND_SCORE, SERVERS_SCORE } from '../../initializers'
|
||||
import { logger, isHostValid } from '../../helpers'
|
||||
|
||||
import { addMethodsToModel, getSort } from '../utils'
|
||||
import {
|
||||
ServerInstance,
|
||||
ServerAttributes,
|
||||
|
||||
ServerMethods
|
||||
} from './server-interface'
|
||||
|
||||
let Server: Sequelize.Model<ServerInstance, ServerAttributes>
|
||||
let countAll: ServerMethods.CountAll
|
||||
let incrementScores: ServerMethods.IncrementScores
|
||||
let list: ServerMethods.List
|
||||
let listForApi: ServerMethods.ListForApi
|
||||
let listAllIds: ServerMethods.ListAllIds
|
||||
let listRandomServerIdsWithRequest: ServerMethods.ListRandomServerIdsWithRequest
|
||||
let listBadServers: ServerMethods.ListBadServers
|
||||
let load: ServerMethods.Load
|
||||
let loadByHost: ServerMethods.LoadByHost
|
||||
let removeAll: ServerMethods.RemoveAll
|
||||
let updateServersScore: ServerMethods.UpdateServersScore
|
||||
|
||||
export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
|
||||
Server = sequelize.define<ServerInstance, ServerAttributes>('Server',
|
||||
{
|
||||
host: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
validate: {
|
||||
isHost: value => {
|
||||
const res = isHostValid(value)
|
||||
if (res === false) throw new Error('Host not valid.')
|
||||
}
|
||||
}
|
||||
},
|
||||
score: {
|
||||
type: DataTypes.INTEGER,
|
||||
defaultValue: FRIEND_SCORE.BASE,
|
||||
allowNull: false,
|
||||
validate: {
|
||||
isInt: true,
|
||||
max: FRIEND_SCORE.MAX
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
indexes: [
|
||||
{
|
||||
fields: [ 'host' ],
|
||||
unique: true
|
||||
},
|
||||
{
|
||||
fields: [ 'score' ]
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
const classMethods = [
|
||||
countAll,
|
||||
incrementScores,
|
||||
list,
|
||||
listForApi,
|
||||
listAllIds,
|
||||
listRandomServerIdsWithRequest,
|
||||
listBadServers,
|
||||
load,
|
||||
loadByHost,
|
||||
updateServersScore,
|
||||
removeAll
|
||||
]
|
||||
addMethodsToModel(Server, classMethods)
|
||||
|
||||
return Server
|
||||
}
|
||||
|
||||
// ------------------------------ Statics ------------------------------
|
||||
|
||||
countAll = function () {
|
||||
return Server.count()
|
||||
}
|
||||
|
||||
incrementScores = function (ids: number[], value: number) {
|
||||
const update = {
|
||||
score: Sequelize.literal('score +' + value)
|
||||
}
|
||||
|
||||
const options = {
|
||||
where: {
|
||||
id: {
|
||||
[Sequelize.Op.in]: ids
|
||||
}
|
||||
},
|
||||
// In this case score is a literal and not an integer so we do not validate it
|
||||
validate: false
|
||||
}
|
||||
|
||||
return Server.update(update, options)
|
||||
}
|
||||
|
||||
list = function () {
|
||||
return Server.findAll()
|
||||
}
|
||||
|
||||
listForApi = function (start: number, count: number, sort: string) {
|
||||
const query = {
|
||||
offset: start,
|
||||
limit: count,
|
||||
order: [ getSort(sort) ]
|
||||
}
|
||||
|
||||
return Server.findAndCountAll(query).then(({ rows, count }) => {
|
||||
return {
|
||||
data: rows,
|
||||
total: count
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
listAllIds = function (transaction: Sequelize.Transaction) {
|
||||
const query = {
|
||||
attributes: [ 'id' ],
|
||||
transaction
|
||||
}
|
||||
|
||||
return Server.findAll(query).then(servers => {
|
||||
return map(servers, 'id')
|
||||
})
|
||||
}
|
||||
|
||||
listRandomServerIdsWithRequest = function (limit: number, tableWithServers: string, tableWithServersJoins: string) {
|
||||
return Server.count().then(count => {
|
||||
// Optimization...
|
||||
if (count === 0) return []
|
||||
|
||||
let start = Math.floor(Math.random() * count) - limit
|
||||
if (start < 0) start = 0
|
||||
|
||||
const subQuery = `(SELECT DISTINCT "${tableWithServers}"."serverId" FROM "${tableWithServers}" ${tableWithServersJoins})`
|
||||
const query = {
|
||||
attributes: [ 'id' ],
|
||||
order: [
|
||||
[ 'id', 'ASC' ]
|
||||
],
|
||||
offset: start,
|
||||
limit: limit,
|
||||
where: {
|
||||
id: {
|
||||
[Sequelize.Op.in]: Sequelize.literal(subQuery)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Server.findAll(query).then(servers => {
|
||||
return map(servers, 'id')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
listBadServers = function () {
|
||||
const query = {
|
||||
where: {
|
||||
score: {
|
||||
[Sequelize.Op.lte]: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Server.findAll(query)
|
||||
}
|
||||
|
||||
load = function (id: number) {
|
||||
return Server.findById(id)
|
||||
}
|
||||
|
||||
loadByHost = function (host: string) {
|
||||
const query = {
|
||||
where: {
|
||||
host: host
|
||||
}
|
||||
}
|
||||
|
||||
return Server.findOne(query)
|
||||
}
|
||||
|
||||
removeAll = function () {
|
||||
return Server.destroy()
|
||||
}
|
||||
|
||||
updateServersScore = function (goodServers: number[], badServers: number[]) {
|
||||
logger.info('Updating %d good servers and %d bad servers scores.', goodServers.length, badServers.length)
|
||||
|
||||
if (goodServers.length !== 0) {
|
||||
incrementScores(goodServers, SERVERS_SCORE.BONUS).catch(err => {
|
||||
logger.error('Cannot increment scores of good servers.', err)
|
||||
})
|
||||
}
|
||||
|
||||
if (badServers.length !== 0) {
|
||||
incrementScores(badServers, SERVERS_SCORE.PENALTY)
|
||||
.then(() => removeBadServers())
|
||||
.catch(err => {
|
||||
if (err) logger.error('Cannot decrement scores of bad servers.', err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Remove servers with a score of 0 (too many requests where they were unreachable)
|
||||
async function removeBadServers () {
|
||||
try {
|
||||
const servers = await listBadServers()
|
||||
|
||||
const serversRemovePromises = servers.map(server => server.destroy())
|
||||
await Promise.all(serversRemovePromises)
|
||||
|
||||
const numberOfServersRemoved = servers.length
|
||||
|
||||
if (numberOfServersRemoved) {
|
||||
logger.info('Removed %d servers.', numberOfServersRemoved)
|
||||
} else {
|
||||
logger.info('No need to remove bad servers.')
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error('Cannot remove bad servers.', err)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import * as Promise from 'bluebird'
|
||||
|
||||
import { PodInstance } from '../pod/pod-interface'
|
||||
import { ServerInstance } from '../server/server-interface'
|
||||
import { ResultList } from '../../../shared'
|
||||
|
||||
// Don't use barrel, import just what we need
|
||||
|
@ -28,7 +28,7 @@ export interface VideoAbuseInstance extends VideoAbuseClass, VideoAbuseAttribute
|
|||
createdAt: Date
|
||||
updatedAt: Date
|
||||
|
||||
Pod: PodInstance
|
||||
Server: ServerInstance
|
||||
|
||||
toFormattedJSON: VideoAbuseMethods.ToFormattedJSON
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
|||
fields: [ 'videoId' ]
|
||||
},
|
||||
{
|
||||
fields: [ 'reporterPodId' ]
|
||||
fields: [ 'reporterServerId' ]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -67,18 +67,18 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
|||
// ------------------------------ METHODS ------------------------------
|
||||
|
||||
toFormattedJSON = function (this: VideoAbuseInstance) {
|
||||
let reporterPodHost
|
||||
let reporterServerHost
|
||||
|
||||
if (this.Pod) {
|
||||
reporterPodHost = this.Pod.host
|
||||
if (this.Server) {
|
||||
reporterServerHost = this.Server.host
|
||||
} else {
|
||||
// It means it's our video
|
||||
reporterPodHost = CONFIG.WEBSERVER.HOST
|
||||
reporterServerHost = CONFIG.WEBSERVER.HOST
|
||||
}
|
||||
|
||||
const json = {
|
||||
id: this.id,
|
||||
reporterPodHost,
|
||||
reporterServerHost,
|
||||
reason: this.reason,
|
||||
reporterUsername: this.reporterUsername,
|
||||
videoId: this.videoId,
|
||||
|
@ -91,9 +91,9 @@ toFormattedJSON = function (this: VideoAbuseInstance) {
|
|||
// ------------------------------ STATICS ------------------------------
|
||||
|
||||
function associate (models) {
|
||||
VideoAbuse.belongsTo(models.Pod, {
|
||||
VideoAbuse.belongsTo(models.Server, {
|
||||
foreignKey: {
|
||||
name: 'reporterPodId',
|
||||
name: 'reporterServerId',
|
||||
allowNull: true
|
||||
},
|
||||
onDelete: 'CASCADE'
|
||||
|
@ -115,7 +115,7 @@ listForApi = function (start: number, count: number, sort: string) {
|
|||
order: [ getSort(sort) ],
|
||||
include: [
|
||||
{
|
||||
model: VideoAbuse['sequelize'].models.Pod,
|
||||
model: VideoAbuse['sequelize'].models.Server,
|
||||
required: false
|
||||
}
|
||||
]
|
||||
|
|
|
@ -22,7 +22,7 @@ export namespace VideoChannelMethods {
|
|||
export type LoadAndPopulateAccount = (id: number) => Promise<VideoChannelInstance>
|
||||
export type LoadByUUIDAndPopulateAccount = (uuid: string) => Promise<VideoChannelInstance>
|
||||
export type LoadByUUID = (uuid: string, t?: Sequelize.Transaction) => Promise<VideoChannelInstance>
|
||||
export type LoadByHostAndUUID = (uuid: string, podHost: string, t?: Sequelize.Transaction) => Promise<VideoChannelInstance>
|
||||
export type LoadByHostAndUUID = (uuid: string, serverHost: string, t?: Sequelize.Transaction) => Promise<VideoChannelInstance>
|
||||
export type LoadAndPopulateAccountAndVideos = (id: number) => Promise<VideoChannelInstance>
|
||||
export type LoadByUrl = (uuid: string, t?: Sequelize.Transaction) => Promise<VideoChannelInstance>
|
||||
export type LoadByUUIDOrUrl = (uuid: string, url: string, t?: Sequelize.Transaction) => Promise<VideoChannelInstance>
|
||||
|
|
|
@ -218,7 +218,7 @@ listForApi = function (start: number, count: number, sort: string) {
|
|||
{
|
||||
model: VideoChannel['sequelize'].models.Account,
|
||||
required: true,
|
||||
include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
|
||||
include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ listByAccount = function (accountId: number) {
|
|||
id: accountId
|
||||
},
|
||||
required: true,
|
||||
include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
|
||||
include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ loadByHostAndUUID = function (fromHost: string, uuid: string, t?: Sequelize.Tran
|
|||
model: VideoChannel['sequelize'].models.Account,
|
||||
include: [
|
||||
{
|
||||
model: VideoChannel['sequelize'].models.Pod,
|
||||
model: VideoChannel['sequelize'].models.Server,
|
||||
required: true,
|
||||
where: {
|
||||
host: fromHost
|
||||
|
@ -322,7 +322,7 @@ loadByIdAndAccount = function (id: number, accountId: number) {
|
|||
include: [
|
||||
{
|
||||
model: VideoChannel['sequelize'].models.Account,
|
||||
include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
|
||||
include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ loadAndPopulateAccount = function (id: number) {
|
|||
include: [
|
||||
{
|
||||
model: VideoChannel['sequelize'].models.Account,
|
||||
include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
|
||||
include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -351,7 +351,7 @@ loadByUUIDAndPopulateAccount = function (uuid: string) {
|
|||
include: [
|
||||
{
|
||||
model: VideoChannel['sequelize'].models.Account,
|
||||
include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
|
||||
include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -364,7 +364,7 @@ loadAndPopulateAccountAndVideos = function (id: number) {
|
|||
include: [
|
||||
{
|
||||
model: VideoChannel['sequelize'].models.Account,
|
||||
include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
|
||||
include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
|
||||
},
|
||||
VideoChannel['sequelize'].models.Video
|
||||
]
|
||||
|
|
|
@ -46,7 +46,7 @@ export namespace VideoMethods {
|
|||
|
||||
export type ListForApi = (start: number, count: number, sort: string) => Bluebird< ResultList<VideoInstance> >
|
||||
export type ListUserVideosForApi = (userId: number, start: number, count: number, sort: string) => Bluebird< ResultList<VideoInstance> >
|
||||
export type SearchAndPopulateAccountAndPodAndTags = (
|
||||
export type SearchAndPopulateAccountAndServerAndTags = (
|
||||
value: string,
|
||||
field: string,
|
||||
start: number,
|
||||
|
@ -60,8 +60,8 @@ export namespace VideoMethods {
|
|||
export type LoadLocalVideoByUUID = (uuid: string, t?: Sequelize.Transaction) => Bluebird<VideoInstance>
|
||||
export type LoadByHostAndUUID = (fromHost: string, uuid: string, t?: Sequelize.Transaction) => Bluebird<VideoInstance>
|
||||
export type LoadAndPopulateAccount = (id: number) => Bluebird<VideoInstance>
|
||||
export type LoadAndPopulateAccountAndPodAndTags = (id: number) => Bluebird<VideoInstance>
|
||||
export type LoadByUUIDAndPopulateAccountAndPodAndTags = (uuid: string) => Bluebird<VideoInstance>
|
||||
export type LoadAndPopulateAccountAndServerAndTags = (id: number) => Bluebird<VideoInstance>
|
||||
export type LoadByUUIDAndPopulateAccountAndServerAndTags = (uuid: string) => Bluebird<VideoInstance>
|
||||
export type LoadByUUIDOrURL = (uuid: string, url: string, t?: Sequelize.Transaction) => Bluebird<VideoInstance>
|
||||
|
||||
export type RemoveThumbnail = (this: VideoInstance) => Promise<void>
|
||||
|
@ -79,14 +79,14 @@ export interface VideoClass {
|
|||
listOwnedByAccount: VideoMethods.ListOwnedByAccount
|
||||
load: VideoMethods.Load
|
||||
loadAndPopulateAccount: VideoMethods.LoadAndPopulateAccount
|
||||
loadAndPopulateAccountAndPodAndTags: VideoMethods.LoadAndPopulateAccountAndPodAndTags
|
||||
loadAndPopulateAccountAndServerAndTags: VideoMethods.LoadAndPopulateAccountAndServerAndTags
|
||||
loadByHostAndUUID: VideoMethods.LoadByHostAndUUID
|
||||
loadByUUID: VideoMethods.LoadByUUID
|
||||
loadByUrl: VideoMethods.LoadByUrl
|
||||
loadByUUIDOrURL: VideoMethods.LoadByUUIDOrURL
|
||||
loadLocalVideoByUUID: VideoMethods.LoadLocalVideoByUUID
|
||||
loadByUUIDAndPopulateAccountAndPodAndTags: VideoMethods.LoadByUUIDAndPopulateAccountAndPodAndTags
|
||||
searchAndPopulateAccountAndPodAndTags: VideoMethods.SearchAndPopulateAccountAndPodAndTags
|
||||
loadByUUIDAndPopulateAccountAndServerAndTags: VideoMethods.LoadByUUIDAndPopulateAccountAndServerAndTags
|
||||
searchAndPopulateAccountAndServerAndTags: VideoMethods.SearchAndPopulateAccountAndServerAndTags
|
||||
}
|
||||
|
||||
export interface VideoAttributes {
|
||||
|
|
|
@ -88,9 +88,9 @@ let loadByUUID: VideoMethods.LoadByUUID
|
|||
let loadByUUIDOrURL: VideoMethods.LoadByUUIDOrURL
|
||||
let loadLocalVideoByUUID: VideoMethods.LoadLocalVideoByUUID
|
||||
let loadAndPopulateAccount: VideoMethods.LoadAndPopulateAccount
|
||||
let loadAndPopulateAccountAndPodAndTags: VideoMethods.LoadAndPopulateAccountAndPodAndTags
|
||||
let loadByUUIDAndPopulateAccountAndPodAndTags: VideoMethods.LoadByUUIDAndPopulateAccountAndPodAndTags
|
||||
let searchAndPopulateAccountAndPodAndTags: VideoMethods.SearchAndPopulateAccountAndPodAndTags
|
||||
let loadAndPopulateAccountAndServerAndTags: VideoMethods.LoadAndPopulateAccountAndServerAndTags
|
||||
let loadByUUIDAndPopulateAccountAndServerAndTags: VideoMethods.LoadByUUIDAndPopulateAccountAndServerAndTags
|
||||
let searchAndPopulateAccountAndServerAndTags: VideoMethods.SearchAndPopulateAccountAndServerAndTags
|
||||
let removeThumbnail: VideoMethods.RemoveThumbnail
|
||||
let removePreview: VideoMethods.RemovePreview
|
||||
let removeFile: VideoMethods.RemoveFile
|
||||
|
@ -275,13 +275,13 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
|||
listOwnedByAccount,
|
||||
load,
|
||||
loadAndPopulateAccount,
|
||||
loadAndPopulateAccountAndPodAndTags,
|
||||
loadAndPopulateAccountAndServerAndTags,
|
||||
loadByHostAndUUID,
|
||||
loadByUUIDOrURL,
|
||||
loadByUUID,
|
||||
loadLocalVideoByUUID,
|
||||
loadByUUIDAndPopulateAccountAndPodAndTags,
|
||||
searchAndPopulateAccountAndPodAndTags
|
||||
loadByUUIDAndPopulateAccountAndServerAndTags,
|
||||
searchAndPopulateAccountAndServerAndTags
|
||||
]
|
||||
const instanceMethods = [
|
||||
createPreview,
|
||||
|
@ -477,13 +477,13 @@ getPreviewPath = function (this: VideoInstance) {
|
|||
}
|
||||
|
||||
toFormattedJSON = function (this: VideoInstance) {
|
||||
let podHost
|
||||
let serverHost
|
||||
|
||||
if (this.VideoChannel.Account.Pod) {
|
||||
podHost = this.VideoChannel.Account.Pod.host
|
||||
if (this.VideoChannel.Account.Server) {
|
||||
serverHost = this.VideoChannel.Account.Server.host
|
||||
} else {
|
||||
// It means it's our video
|
||||
podHost = CONFIG.WEBSERVER.HOST
|
||||
serverHost = CONFIG.WEBSERVER.HOST
|
||||
}
|
||||
|
||||
const json = {
|
||||
|
@ -498,7 +498,7 @@ toFormattedJSON = function (this: VideoInstance) {
|
|||
languageLabel: this.getLanguageLabel(),
|
||||
nsfw: this.nsfw,
|
||||
description: this.getTruncatedDescription(),
|
||||
podHost,
|
||||
serverHost,
|
||||
isLocal: this.isOwned(),
|
||||
account: this.VideoChannel.Account.name,
|
||||
duration: this.duration,
|
||||
|
@ -519,7 +519,7 @@ toFormattedJSON = function (this: VideoInstance) {
|
|||
toFormattedDetailsJSON = function (this: VideoInstance) {
|
||||
const formattedJson = this.toFormattedJSON()
|
||||
|
||||
// Maybe our pod is not up to date and there are new privacy settings since our version
|
||||
// Maybe our server is not up to date and there are new privacy settings since our version
|
||||
let privacyLabel = VIDEO_PRIVACIES[this.privacy]
|
||||
if (!privacyLabel) privacyLabel = 'Unknown'
|
||||
|
||||
|
@ -721,7 +721,7 @@ getDescriptionPath = function (this: VideoInstance) {
|
|||
getCategoryLabel = function (this: VideoInstance) {
|
||||
let categoryLabel = VIDEO_CATEGORIES[this.category]
|
||||
|
||||
// Maybe our pod is not up to date and there are new categories since our version
|
||||
// Maybe our server is not up to date and there are new categories since our version
|
||||
if (!categoryLabel) categoryLabel = 'Misc'
|
||||
|
||||
return categoryLabel
|
||||
|
@ -730,7 +730,7 @@ getCategoryLabel = function (this: VideoInstance) {
|
|||
getLicenceLabel = function (this: VideoInstance) {
|
||||
let licenceLabel = VIDEO_LICENCES[this.licence]
|
||||
|
||||
// Maybe our pod is not up to date and there are new licences since our version
|
||||
// Maybe our server is not up to date and there are new licences since our version
|
||||
if (!licenceLabel) licenceLabel = 'Unknown'
|
||||
|
||||
return licenceLabel
|
||||
|
@ -830,7 +830,7 @@ listForApi = function (start: number, count: number, sort: string) {
|
|||
model: Video['sequelize'].models.Account,
|
||||
include: [
|
||||
{
|
||||
model: Video['sequelize'].models.Pod,
|
||||
model: Video['sequelize'].models.Server,
|
||||
required: false
|
||||
}
|
||||
]
|
||||
|
@ -866,7 +866,7 @@ loadByHostAndUUID = function (fromHost: string, uuid: string, t?: Sequelize.Tran
|
|||
model: Video['sequelize'].models.Account,
|
||||
include: [
|
||||
{
|
||||
model: Video['sequelize'].models.Pod,
|
||||
model: Video['sequelize'].models.Server,
|
||||
required: true,
|
||||
where: {
|
||||
host: fromHost
|
||||
|
@ -989,7 +989,7 @@ loadAndPopulateAccount = function (id: number) {
|
|||
return Video.findById(id, options)
|
||||
}
|
||||
|
||||
loadAndPopulateAccountAndPodAndTags = function (id: number) {
|
||||
loadAndPopulateAccountAndServerAndTags = function (id: number) {
|
||||
const options = {
|
||||
include: [
|
||||
{
|
||||
|
@ -997,7 +997,7 @@ loadAndPopulateAccountAndPodAndTags = function (id: number) {
|
|||
include: [
|
||||
{
|
||||
model: Video['sequelize'].models.Account,
|
||||
include: [ { model: Video['sequelize'].models.Pod, required: false } ]
|
||||
include: [ { model: Video['sequelize'].models.Server, required: false } ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1009,7 +1009,7 @@ loadAndPopulateAccountAndPodAndTags = function (id: number) {
|
|||
return Video.findById(id, options)
|
||||
}
|
||||
|
||||
loadByUUIDAndPopulateAccountAndPodAndTags = function (uuid: string) {
|
||||
loadByUUIDAndPopulateAccountAndServerAndTags = function (uuid: string) {
|
||||
const options = {
|
||||
where: {
|
||||
uuid
|
||||
|
@ -1020,7 +1020,7 @@ loadByUUIDAndPopulateAccountAndPodAndTags = function (uuid: string) {
|
|||
include: [
|
||||
{
|
||||
model: Video['sequelize'].models.Account,
|
||||
include: [ { model: Video['sequelize'].models.Pod, required: false } ]
|
||||
include: [ { model: Video['sequelize'].models.Server, required: false } ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1032,15 +1032,15 @@ loadByUUIDAndPopulateAccountAndPodAndTags = function (uuid: string) {
|
|||
return Video.findOne(options)
|
||||
}
|
||||
|
||||
searchAndPopulateAccountAndPodAndTags = function (value: string, field: string, start: number, count: number, sort: string) {
|
||||
const podInclude: Sequelize.IncludeOptions = {
|
||||
model: Video['sequelize'].models.Pod,
|
||||
searchAndPopulateAccountAndServerAndTags = function (value: string, field: string, start: number, count: number, sort: string) {
|
||||
const serverInclude: Sequelize.IncludeOptions = {
|
||||
model: Video['sequelize'].models.Server,
|
||||
required: false
|
||||
}
|
||||
|
||||
const accountInclude: Sequelize.IncludeOptions = {
|
||||
model: Video['sequelize'].models.Account,
|
||||
include: [ podInclude ]
|
||||
include: [ serverInclude ]
|
||||
}
|
||||
|
||||
const videoChannelInclude: Sequelize.IncludeOptions = {
|
||||
|
@ -1071,13 +1071,13 @@ searchAndPopulateAccountAndPodAndTags = function (value: string, field: string,
|
|||
)`
|
||||
)
|
||||
} else if (field === 'host') {
|
||||
// FIXME: Include our pod? (not stored in the database)
|
||||
podInclude.where = {
|
||||
// FIXME: Include our server? (not stored in the database)
|
||||
serverInclude.where = {
|
||||
host: {
|
||||
[Sequelize.Op.iLike]: '%' + value + '%'
|
||||
}
|
||||
}
|
||||
podInclude.required = true
|
||||
serverInclude.required = true
|
||||
} else if (field === 'account') {
|
||||
accountInclude.where = {
|
||||
name: {
|
||||
|
@ -1123,8 +1123,8 @@ function getBaseUrls (video: VideoInstance) {
|
|||
baseUrlHttp = CONFIG.WEBSERVER.URL
|
||||
baseUrlWs = CONFIG.WEBSERVER.WS + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
|
||||
} else {
|
||||
baseUrlHttp = REMOTE_SCHEME.HTTP + '://' + video.VideoChannel.Account.Pod.host
|
||||
baseUrlWs = REMOTE_SCHEME.WS + '://' + video.VideoChannel.Account.Pod.host
|
||||
baseUrlHttp = REMOTE_SCHEME.HTTP + '://' + video.VideoChannel.Account.Server.host
|
||||
baseUrlWs = REMOTE_SCHEME.WS + '://' + video.VideoChannel.Account.Server.host
|
||||
}
|
||||
|
||||
return { baseUrlHttp, baseUrlWs }
|
||||
|
|
|
@ -1 +1,8 @@
|
|||
export type FollowState = 'pending' | 'accepted'
|
||||
|
||||
export interface AccountFollow {
|
||||
id: number
|
||||
name: string
|
||||
score?: number // Used for followers
|
||||
host: string
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
export * from './accounts'
|
||||
export * from './activitypub'
|
||||
export * from './pods'
|
||||
export * from './users'
|
||||
export * from './videos'
|
||||
export * from './job.model'
|
||||
export * from './oauth-client-local.model'
|
||||
export * from './result-list.model'
|
||||
export * from './request-scheduler.model'
|
||||
export * from './server-config.model'
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
export * from './pod-signature.model'
|
||||
export * from './pod.model'
|
||||
export * from './remote-video'
|
|
@ -1,4 +0,0 @@
|
|||
export interface PodSignature {
|
||||
host: string
|
||||
signature: string
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
export interface Pod {
|
||||
id: number,
|
||||
host: string,
|
||||
score: number,
|
||||
createdAt: Date
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
export * from './remote-qadu-video-request.model'
|
||||
export * from './remote-video-author-create-request.model'
|
||||
export * from './remote-video-author-remove-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-channel-create-request.model'
|
||||
export * from './remote-video-channel-update-request.model'
|
||||
export * from './remote-video-channel-remove-request.model'
|
||||
export * from './remote-video-report-abuse-request.model'
|
|
@ -1,10 +0,0 @@
|
|||
export interface RemoteQaduVideoData {
|
||||
uuid: string
|
||||
views?: number
|
||||
likes?: number
|
||||
dislikes?: number
|
||||
}
|
||||
|
||||
export interface RemoteQaduVideoRequest {
|
||||
data: RemoteQaduVideoData
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||
|
||||
export interface RemoteVideoAuthorCreateData {
|
||||
uuid: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface RemoteVideoAuthorCreateRequest extends RemoteVideoRequest {
|
||||
type: 'add-author'
|
||||
data: RemoteVideoAuthorCreateData
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||
|
||||
export interface RemoteVideoAuthorRemoveData {
|
||||
uuid: string
|
||||
}
|
||||
|
||||
export interface RemoteVideoAuthorRemoveRequest extends RemoteVideoRequest {
|
||||
type: 'remove-author'
|
||||
data: RemoteVideoAuthorRemoveData
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||
|
||||
export interface RemoteVideoChannelCreateData {
|
||||
uuid: string
|
||||
name: string
|
||||
description: string
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
ownerUUID: string
|
||||
}
|
||||
|
||||
export interface RemoteVideoChannelCreateRequest extends RemoteVideoRequest {
|
||||
type: 'add-channel'
|
||||
data: RemoteVideoChannelCreateData
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||
|
||||
export interface RemoteVideoChannelRemoveData {
|
||||
uuid: string
|
||||
}
|
||||
|
||||
export interface RemoteVideoChannelRemoveRequest extends RemoteVideoRequest {
|
||||
type: 'remove-channel'
|
||||
data: RemoteVideoChannelRemoveData
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||
|
||||
export interface RemoteVideoChannelUpdateData {
|
||||
uuid: string
|
||||
name: string
|
||||
description: string
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
ownerUUID: string
|
||||
}
|
||||
|
||||
export interface RemoteVideoChannelUpdateRequest extends RemoteVideoRequest {
|
||||
type: 'update-channel'
|
||||
data: RemoteVideoChannelUpdateData
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||
|
||||
export interface RemoteVideoCreateData {
|
||||
uuid: string
|
||||
channelUUID: string
|
||||
tags: string[]
|
||||
name: string
|
||||
category: number
|
||||
licence: number
|
||||
language: number
|
||||
nsfw: boolean
|
||||
truncatedDescription: string
|
||||
duration: number
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
views: number
|
||||
likes: number
|
||||
dislikes: number
|
||||
privacy: number
|
||||
thumbnailData: string
|
||||
files: {
|
||||
infoHash: string
|
||||
extname: string
|
||||
resolution: number
|
||||
size: number
|
||||
}[]
|
||||
}
|
||||
|
||||
export interface RemoteVideoCreateRequest extends RemoteVideoRequest {
|
||||
type: 'add-video'
|
||||
data: RemoteVideoCreateData
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
export type RemoteVideoEventType = 'views' | 'likes' | 'dislikes'
|
||||
|
||||
export interface RemoteVideoEventData {
|
||||
uuid: string
|
||||
eventType: RemoteVideoEventType
|
||||
count: number
|
||||
}
|
||||
|
||||
export interface RemoteVideoEventRequest {
|
||||
data: RemoteVideoEventData
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||
|
||||
export interface RemoteVideoRemoveData {
|
||||
uuid: string
|
||||
}
|
||||
|
||||
export interface RemoteVideoRemoveRequest extends RemoteVideoRequest {
|
||||
type: 'remove-video'
|
||||
data: RemoteVideoRemoveData
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||
|
||||
export interface RemoteVideoReportAbuseData {
|
||||
videoUUID: string
|
||||
reporterUsername: string
|
||||
reportReason: string
|
||||
}
|
||||
|
||||
export interface RemoteVideoReportAbuseRequest extends RemoteVideoRequest {
|
||||
type: 'report-abuse'
|
||||
data: RemoteVideoReportAbuseData
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
export interface RemoteVideoRequest {
|
||||
type: RemoteVideoRequestType
|
||||
data: any
|
||||
}
|
||||
|
||||
export type RemoteVideoRequestType = 'add-video' | 'update-video' | 'remove-video' |
|
||||
'add-channel' | 'update-channel' | 'remove-channel' |
|
||||
'report-abuse' |
|
||||
'add-author' | 'remove-author'
|
|
@ -1,30 +0,0 @@
|
|||
import { RemoteVideoRequest } from './remote-video-request.model'
|
||||
|
||||
export interface RemoteVideoUpdateData {
|
||||
uuid: string
|
||||
tags: string[]
|
||||
name: string
|
||||
category: number
|
||||
licence: number
|
||||
language: number
|
||||
nsfw: boolean
|
||||
truncatedDescription: string
|
||||
duration: number
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
views: number
|
||||
likes: number
|
||||
dislikes: number
|
||||
privacy: number
|
||||
files: {
|
||||
infoHash: string
|
||||
extname: string
|
||||
resolution: number
|
||||
size: number
|
||||
}[]
|
||||
}
|
||||
|
||||
export interface RemoteVideoUpdateRequest extends RemoteVideoRequest {
|
||||
type: 'update-video'
|
||||
data: RemoteVideoUpdateData
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
export type RequestEndpoint = 'videos'
|
||||
|
||||
export type RequestVideoQaduType = 'likes' | 'dislikes' | 'views'
|
||||
|
||||
export type RequestVideoEventType = 'likes' | 'dislikes' | 'views'
|
||||
|
||||
export type RequestSchedulerStatsAttributes = {
|
||||
totalRequests: number
|
||||
requestsLimitPods: number
|
||||
requestsLimitPerPod: number
|
||||
remainingMilliSeconds: number
|
||||
milliSecondsInterval: number
|
||||
}
|
||||
|
||||
export interface RequestSchedulerStats {
|
||||
requestScheduler: RequestSchedulerStatsAttributes
|
||||
requestVideoQaduScheduler: RequestSchedulerStatsAttributes
|
||||
requestVideoEventScheduler: RequestSchedulerStatsAttributes
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
export interface VideoAbuse {
|
||||
id: number
|
||||
reporterPodHost: string
|
||||
reporterServerHost: string
|
||||
reason: string
|
||||
reporterUsername: string
|
||||
videoId: number
|
||||
|
|
|
@ -26,7 +26,7 @@ export interface Video {
|
|||
duration: number
|
||||
isLocal: boolean
|
||||
name: string
|
||||
podHost: string
|
||||
serverHost: string
|
||||
tags: string[]
|
||||
thumbnailPath: string
|
||||
previewPath: string
|
||||
|
|
Loading…
Reference in a new issue