Share models between server and client

pull/71/head
Chocobozzz 2017-06-17 11:28:11 +02:00
parent df98563e21
commit 154898b0b7
30 changed files with 89 additions and 61 deletions

View File

@ -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',

View File

@ -1,7 +0,0 @@
export interface Friend {
id: string
host: string
score: number
email: string
createdAt: Date
}

View File

@ -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()

View File

@ -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

View File

@ -1,2 +1,2 @@
export * from './request-stats.model'
export * from './request-stats-attributes.model'
export * from './request.service'

View File

@ -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

View File

@ -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

View File

@ -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',

View File

@ -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.')

View File

@ -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
}

View File

@ -1,8 +0,0 @@
export interface VideoAbuse {
id: string
reason: string
reporterPodHost: string
reporterUsername: string
videoId: string
createdAt: Date
}

View File

@ -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 {

View File

@ -1 +0,0 @@
export type RateType = 'like' | 'dislike'

View File

@ -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

View File

@ -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

View File

@ -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)
})
}

View File

@ -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)
}
// ---------------------------------------------------------------------------

View File

@ -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)
})
}

View File

@ -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())

View File

@ -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> {}

View File

@ -1,6 +1,5 @@
/*
User rates per video.
*/
import { values } from 'lodash'
import * as Sequelize from 'sequelize'

View File

@ -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> {}

View File

@ -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,

View File

@ -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> {}

View File

@ -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> {}

View File

@ -0,0 +1,4 @@
export interface ClientLocal {
client_id: string
client_secret: string
}

View File

@ -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'

View File

@ -0,0 +1,5 @@
export interface ServerConfig {
signup: {
enabled: boolean
}
}

View File

@ -1 +1,7 @@
export type VideoRateType = 'like' | 'dislike'
export type UserVideoRateType = 'like' | 'dislike' | 'none'
export interface UserVideoRate {
videoId: string
rating: UserVideoRateType
}

View File

@ -3,6 +3,6 @@ export interface VideoAbuse {
reporterPodHost: string
reason: string
reporterUsername: string
videoId: number
videoId: string
createdAt: Date
}