Share models between server and client
This commit is contained in:
parent
df98563e21
commit
154898b0b7
|
@ -5,7 +5,7 @@ import { ServerDataSource } from 'ng2-smart-table'
|
|||
|
||||
import { ConfirmService } from '../../../core'
|
||||
import { Utils } from '../../../shared'
|
||||
import { Friend, FriendService } from '../shared'
|
||||
import { FriendService } from '../shared'
|
||||
|
||||
@Component({
|
||||
selector: 'my-friend-list',
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
export interface Friend {
|
||||
id: string
|
||||
host: string
|
||||
score: number
|
||||
email: string
|
||||
createdAt: Date
|
||||
}
|
|
@ -5,7 +5,6 @@ import 'rxjs/add/operator/map'
|
|||
|
||||
import { ServerDataSource } from 'ng2-smart-table'
|
||||
|
||||
import { Friend } from './friend.model'
|
||||
import { AuthHttp, RestExtractor, RestDataSource, ResultList } from '../../../shared'
|
||||
|
||||
@Injectable()
|
||||
|
|
|
@ -2,7 +2,8 @@ import { Component, OnInit, OnDestroy } from '@angular/core'
|
|||
|
||||
import { NotificationsService } from 'angular2-notifications'
|
||||
|
||||
import { RequestService, RequestStats } from '../shared'
|
||||
import { RequestService, RequestSchedulerStatsAttributes } from '../shared'
|
||||
import { RequestScheduler } from '../../../../../../shared'
|
||||
|
||||
@Component({
|
||||
selector: 'my-request-stats',
|
||||
|
@ -16,11 +17,7 @@ export class RequestStatsComponent implements OnInit, OnDestroy {
|
|||
requestVideoQaduScheduler: 'Quick and dirty video updates request scheduler'
|
||||
}
|
||||
|
||||
stats: { [ id: string ]: RequestStats } = {
|
||||
requestScheduler: null,
|
||||
requestVideoEventScheduler: null,
|
||||
requestVideoQaduScheduler: null
|
||||
}
|
||||
stats: RequestScheduler
|
||||
|
||||
private intervals: { [ id: string ]: number } = {
|
||||
requestScheduler: null,
|
||||
|
@ -67,7 +64,7 @@ export class RequestStatsComponent implements OnInit, OnDestroy {
|
|||
private runIntervals () {
|
||||
Object.keys(this.intervals).forEach(requestSchedulerName => {
|
||||
this.intervals[requestSchedulerName] = window.setInterval(() => {
|
||||
const stats = this.stats[requestSchedulerName]
|
||||
const stats: RequestSchedulerStatsAttributes = this.stats[requestSchedulerName]
|
||||
|
||||
stats.remainingMilliSeconds -= 1000
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export * from './request-stats.model'
|
||||
export * from './request-stats-attributes.model'
|
||||
export * from './request.service'
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { RequestSchedulerAttributes as FormatedRequestSchedulerAttributes } from '../../../../../../shared'
|
||||
|
||||
export interface Request {
|
||||
request: any
|
||||
to: any
|
||||
}
|
||||
|
||||
export class RequestStats {
|
||||
export class RequestSchedulerStatsAttributes implements FormatedRequestSchedulerAttributes {
|
||||
requestsLimitPods: number
|
||||
requestsLimitPerPod: number
|
||||
milliSecondsInterval: number
|
|
@ -3,8 +3,9 @@ import { Observable } from 'rxjs/Observable'
|
|||
import 'rxjs/add/operator/catch'
|
||||
import 'rxjs/add/operator/map'
|
||||
|
||||
import { RequestStats } from './request-stats.model'
|
||||
import { RequestScheduler } from '../../../../../../shared'
|
||||
import { AuthHttp, RestExtractor } from '../../../shared'
|
||||
import { RequestSchedulerStatsAttributes } from './request-stats-attributes.model'
|
||||
|
||||
@Injectable()
|
||||
export class RequestService {
|
||||
|
@ -15,18 +16,18 @@ export class RequestService {
|
|||
private restExtractor: RestExtractor
|
||||
) {}
|
||||
|
||||
getStats (): Observable<{ [ id: string ]: RequestStats }> {
|
||||
getStats (): Observable<RequestScheduler> {
|
||||
return this.authHttp.get(RequestService.BASE_REQUEST_URL + 'stats')
|
||||
.map(this.restExtractor.extractDataGet)
|
||||
.map(this.buildRequestObjects)
|
||||
.catch((res) => this.restExtractor.handleError(res))
|
||||
}
|
||||
|
||||
private buildRequestObjects (data: any) {
|
||||
private buildRequestObjects (data: RequestScheduler) {
|
||||
const requestSchedulers = {}
|
||||
|
||||
Object.keys(data).forEach(requestSchedulerName => {
|
||||
requestSchedulers[requestSchedulerName] = new RequestStats(data[requestSchedulerName])
|
||||
requestSchedulers[requestSchedulerName] = new RequestSchedulerStatsAttributes(data[requestSchedulerName])
|
||||
})
|
||||
|
||||
return requestSchedulers
|
||||
|
|
|
@ -2,7 +2,8 @@ import { Component } from '@angular/core'
|
|||
|
||||
import { NotificationsService } from 'angular2-notifications'
|
||||
|
||||
import { Utils, VideoAbuseService, VideoAbuse } from '../../../shared'
|
||||
import { Utils, VideoAbuseService } from '../../../shared'
|
||||
import { VideoAbuse } from '../../../../../shared'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-abuse-list',
|
||||
|
|
|
@ -11,6 +11,7 @@ import { NotificationsService } from 'angular2-notifications'
|
|||
|
||||
import { AuthStatus } from './auth-status.model'
|
||||
import { AuthUser } from './auth-user.model'
|
||||
import { ClientLocal } from '../../../../../shared'
|
||||
// Do not use the barrel (dependency loop)
|
||||
import { RestExtractor } from '../../shared/rest'
|
||||
|
||||
|
@ -40,9 +41,9 @@ export class AuthService {
|
|||
// FIXME: save in local storage?
|
||||
this.http.get(AuthService.BASE_CLIENT_URL)
|
||||
.map(this.restExtractor.extractDataGet)
|
||||
.catch((res) => this.restExtractor.handleError(res))
|
||||
.catch(res => this.restExtractor.handleError(res))
|
||||
.subscribe(
|
||||
result => {
|
||||
(result: ClientLocal) => {
|
||||
this.clientId = result.client_id
|
||||
this.clientSecret = result.client_secret
|
||||
console.log('Client credentials loaded.')
|
||||
|
|
|
@ -2,16 +2,13 @@ import { Injectable } from '@angular/core'
|
|||
import { Http } from '@angular/http'
|
||||
|
||||
import { RestExtractor } from '../../shared/rest'
|
||||
import { ServerConfig } from '../../../../../shared'
|
||||
|
||||
@Injectable()
|
||||
export class ConfigService {
|
||||
private static BASE_CONFIG_URL = API_URL + '/api/v1/config/'
|
||||
|
||||
private config: {
|
||||
signup: {
|
||||
enabled: boolean
|
||||
}
|
||||
} = {
|
||||
private config: ServerConfig = {
|
||||
signup: {
|
||||
enabled: false
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
export interface VideoAbuse {
|
||||
id: string
|
||||
reason: string
|
||||
reporterPodHost: string
|
||||
reporterUsername: string
|
||||
videoId: string
|
||||
createdAt: Date
|
||||
}
|
|
@ -7,7 +7,7 @@ import 'rxjs/add/operator/map'
|
|||
import { AuthService } from '../core'
|
||||
import { AuthHttp } from '../auth'
|
||||
import { RestDataSource, RestExtractor, ResultList } from '../rest'
|
||||
import { VideoAbuse } from './video-abuse.model'
|
||||
import { VideoAbuse } from '../../../../../shared'
|
||||
|
||||
@Injectable()
|
||||
export class VideoAbuseService {
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export type RateType = 'like' | 'dislike'
|
|
@ -6,7 +6,6 @@ import 'rxjs/add/operator/map'
|
|||
|
||||
import { Search } from '../../shared'
|
||||
import { SortField } from './sort-field.type'
|
||||
import { RateType } from './rate-type.type'
|
||||
import { AuthService } from '../../core'
|
||||
import {
|
||||
AuthHttp,
|
||||
|
@ -17,6 +16,7 @@ import {
|
|||
UserService
|
||||
} from '../../shared'
|
||||
import { Video } from './video.model'
|
||||
import { VideoRateType } from '../../../../../shared'
|
||||
|
||||
@Injectable()
|
||||
export class VideoService {
|
||||
|
@ -145,7 +145,7 @@ export class VideoService {
|
|||
return this.setVideoRate(id, 'dislike')
|
||||
}
|
||||
|
||||
getUserVideoRating (id: string) {
|
||||
getUserVideoRating (id: string): Observable<VideoRateType> {
|
||||
const url = UserService.BASE_USERS_URL + '/me/videos/' + id + '/rating'
|
||||
|
||||
return this.authHttp.get(url)
|
||||
|
@ -159,7 +159,7 @@ export class VideoService {
|
|||
.catch((res) => this.restExtractor.handleError(res))
|
||||
}
|
||||
|
||||
private setVideoRate (id: string, rateType: RateType) {
|
||||
private setVideoRate (id: string, rateType: VideoRateType) {
|
||||
const url = VideoService.BASE_VIDEO_URL + id + '/rate'
|
||||
const body = {
|
||||
rating: rateType
|
||||
|
|
|
@ -11,15 +11,15 @@ import { AuthService, ConfirmService } from '../../core'
|
|||
import { VideoMagnetComponent } from './video-magnet.component'
|
||||
import { VideoShareComponent } from './video-share.component'
|
||||
import { VideoReportComponent } from './video-report.component'
|
||||
import { RateType, Video, VideoService } from '../shared'
|
||||
import { Video, VideoService } from '../shared'
|
||||
import { WebTorrentService } from './webtorrent.service'
|
||||
import { UserVideoRateType, VideoRateType, UserVideoRate } from '../../../../../shared'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-watch',
|
||||
templateUrl: './video-watch.component.html',
|
||||
styleUrls: [ './video-watch.component.scss' ]
|
||||
})
|
||||
|
||||
export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||
private static LOADTIME_TOO_LONG = 20000
|
||||
|
||||
|
@ -34,7 +34,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
player: videojs.Player
|
||||
playerElement: Element
|
||||
uploadSpeed: number
|
||||
userRating: RateType = null
|
||||
userRating: UserVideoRateType = null
|
||||
video: Video = null
|
||||
videoNotFound = false
|
||||
|
||||
|
@ -249,7 +249,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
|
||||
this.videoService.getUserVideoRating(this.video.id)
|
||||
.subscribe(
|
||||
ratingObject => {
|
||||
(ratingObject: UserVideoRate) => {
|
||||
if (ratingObject) {
|
||||
this.userRating = ratingObject.rating
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
)
|
||||
}
|
||||
|
||||
private updateVideoRating (oldRating: RateType, newRating: RateType) {
|
||||
private updateVideoRating (oldRating: UserVideoRateType, newRating: VideoRateType) {
|
||||
let likesToIncrement = 0
|
||||
let dislikesToIncrement = 0
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import * as express from 'express'
|
|||
import { CONFIG } from '../../initializers'
|
||||
import { logger } from '../../helpers'
|
||||
import { database as db } from '../../initializers/database'
|
||||
import { ClientLocal } from '../../../shared'
|
||||
|
||||
const clientsRouter = express.Router()
|
||||
|
||||
|
@ -27,10 +28,11 @@ function getLocalClient (req: express.Request, res: express.Response, next: expr
|
|||
if (err) return next(err)
|
||||
if (!client) return next(new Error('No client available.'))
|
||||
|
||||
res.json({
|
||||
const json: ClientLocal = {
|
||||
client_id: client.clientId,
|
||||
client_secret: client.clientSecret
|
||||
})
|
||||
}
|
||||
res.json(json)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import * as express from 'express'
|
||||
|
||||
import { CONFIG } from '../../initializers'
|
||||
import { ServerConfig } from '../../../shared'
|
||||
|
||||
const configRouter = express.Router()
|
||||
|
||||
|
@ -8,11 +9,12 @@ configRouter.get('/', getConfig)
|
|||
|
||||
// Get the client credentials for the PeerTube front end
|
||||
function getConfig (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
res.json({
|
||||
const json: ServerConfig = {
|
||||
signup: {
|
||||
enabled: CONFIG.SIGNUP.ENABLED
|
||||
}
|
||||
})
|
||||
}
|
||||
res.json(json)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
setUsersSort,
|
||||
token
|
||||
} from '../../middlewares'
|
||||
import { UserVideoRate as FormatedUserVideoRate } from '../../../shared'
|
||||
|
||||
const usersRouter = express.Router()
|
||||
|
||||
|
@ -119,10 +120,11 @@ function getUserVideoRating (req: express.Request, res: express.Response, next:
|
|||
|
||||
const rating = ratingObj ? ratingObj.type : 'none'
|
||||
|
||||
res.json({
|
||||
const json: FormatedUserVideoRate = {
|
||||
videoId,
|
||||
rating
|
||||
})
|
||||
}
|
||||
res.json(json)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,12 @@ function createEmptyCallback () {
|
|||
}
|
||||
}
|
||||
|
||||
function getFormatedObjects (objects: any[], objectsTotal: number) {
|
||||
const formatedObjects = []
|
||||
interface FormatableToJSON {
|
||||
toFormatedJSON()
|
||||
}
|
||||
|
||||
function getFormatedObjects<U, T extends FormatableToJSON> (objects: T[], objectsTotal: number) {
|
||||
const formatedObjects: U[] = []
|
||||
|
||||
objects.forEach(function (object) {
|
||||
formatedObjects.push(object.toFormatedJSON())
|
||||
|
|
|
@ -58,6 +58,10 @@ export interface UserInstance extends UserClass, UserAttributes, Sequelize.Insta
|
|||
id: number
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
|
||||
isPasswordMatch: UserMethods.IsPasswordMatch
|
||||
toFormatedJSON: UserMethods.ToFormatedJSON
|
||||
isAdmin: UserMethods.IsAdmin
|
||||
}
|
||||
|
||||
export interface UserModel extends UserClass, Sequelize.Model<UserInstance, UserAttributes> {}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
User rates per video.
|
||||
|
||||
*/
|
||||
import { values } from 'lodash'
|
||||
import * as Sequelize from 'sequelize'
|
||||
|
|
|
@ -6,7 +6,7 @@ import { PodInstance } from '../pod'
|
|||
import { VideoAbuse as FormatedVideoAbuse } from '../../../shared/models/video-abuse.model'
|
||||
|
||||
export namespace VideoAbuseMethods {
|
||||
export type toFormatedJSON = () => FormatedVideoAbuse
|
||||
export type ToFormatedJSON = (this: VideoAbuseInstance) => FormatedVideoAbuse
|
||||
|
||||
export type ListForApiCallback = (err: Error, videoAbuseInstances?: VideoAbuseInstance[], total?: number) => void
|
||||
export type ListForApi = (start: number, count: number, sort: string, callback: ListForApiCallback) => void
|
||||
|
@ -28,6 +28,8 @@ export interface VideoAbuseInstance extends VideoAbuseClass, VideoAbuseAttribute
|
|||
updatedAt: Date
|
||||
|
||||
Pod: PodInstance
|
||||
|
||||
toFormatedJSON: VideoAbuseMethods.ToFormatedJSON
|
||||
}
|
||||
|
||||
export interface VideoAbuseModel extends VideoAbuseClass, Sequelize.Model<VideoAbuseInstance, VideoAbuseAttributes> {}
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
} from './video-abuse-interface'
|
||||
|
||||
let VideoAbuse: Sequelize.Model<VideoAbuseInstance, VideoAbuseAttributes>
|
||||
let toFormatedJSON: VideoAbuseMethods.ToFormatedJSON
|
||||
let listForApi: VideoAbuseMethods.ListForApi
|
||||
|
||||
export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
|
||||
|
@ -66,7 +67,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
|||
|
||||
// ------------------------------ METHODS ------------------------------
|
||||
|
||||
function toFormatedJSON (this: VideoAbuseInstance) {
|
||||
toFormatedJSON = function (this: VideoAbuseInstance) {
|
||||
let reporterPodHost
|
||||
|
||||
if (this.Pod) {
|
||||
|
@ -108,7 +109,7 @@ function associate (models) {
|
|||
})
|
||||
}
|
||||
|
||||
listForApi = function (start, count, sort, callback) {
|
||||
listForApi = function (start: number, count: number, sort: string, callback: VideoAbuseMethods.ListForApiCallback) {
|
||||
const query = {
|
||||
offset: start,
|
||||
limit: count,
|
||||
|
|
|
@ -39,6 +39,8 @@ export interface BlacklistedVideoInstance extends BlacklistedVideoClass, Blackli
|
|||
id: number
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
|
||||
toFormatedJSON: BlacklistedVideoMethods.ToFormatedJSON
|
||||
}
|
||||
|
||||
export interface BlacklistedVideoModel extends BlacklistedVideoClass, Sequelize.Model<BlacklistedVideoInstance, BlacklistedVideoAttributes> {}
|
||||
|
|
|
@ -146,6 +146,17 @@ export interface VideoInstance extends VideoClass, VideoAttributes, Sequelize.In
|
|||
id: string
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
|
||||
generateMagnetUri: VideoMethods.GenerateMagnetUri
|
||||
getVideoFilename: VideoMethods.GetVideoFilename
|
||||
getThumbnailName: VideoMethods.GetThumbnailName
|
||||
getPreviewName: VideoMethods.GetPreviewName
|
||||
getTorrentName: VideoMethods.GetTorrentName
|
||||
isOwned: VideoMethods.IsOwned
|
||||
toFormatedJSON: VideoMethods.ToFormatedJSON
|
||||
toAddRemoteJSON: VideoMethods.ToAddRemoteJSON
|
||||
toUpdateRemoteJSON: VideoMethods.ToUpdateRemoteJSON
|
||||
transcodeVideofile: VideoMethods.TranscodeVideofile
|
||||
}
|
||||
|
||||
export interface VideoModel extends VideoClass, Sequelize.Model<VideoInstance, VideoAttributes> {}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
export interface ClientLocal {
|
||||
client_id: string
|
||||
client_secret: string
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
export * from './client-local.model'
|
||||
export * from './job.model'
|
||||
export * from './pod.model'
|
||||
export * from './request-scheduler.model'
|
||||
|
@ -6,3 +7,4 @@ export * from './user.model'
|
|||
export * from './video-abuse.model'
|
||||
export * from './video-blacklist.model'
|
||||
export * from './video.model'
|
||||
export * from './server-config.model'
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
export interface ServerConfig {
|
||||
signup: {
|
||||
enabled: boolean
|
||||
}
|
||||
}
|
|
@ -1 +1,7 @@
|
|||
export type VideoRateType = 'like' | 'dislike'
|
||||
export type UserVideoRateType = 'like' | 'dislike' | 'none'
|
||||
|
||||
export interface UserVideoRate {
|
||||
videoId: string
|
||||
rating: UserVideoRateType
|
||||
}
|
||||
|
|
|
@ -3,6 +3,6 @@ export interface VideoAbuse {
|
|||
reporterPodHost: string
|
||||
reason: string
|
||||
reporterUsername: string
|
||||
videoId: number
|
||||
videoId: string
|
||||
createdAt: Date
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue