Pod URL -> pod host. HTTPS is required to make friends.
Reason: in a network with mix http/https pods, https pods won't be able to play videos from http pod (insecure requests).
This commit is contained in:
parent
41b5da1d8c
commit
49abbbbedc
|
@ -3,13 +3,13 @@
|
||||||
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
|
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
|
||||||
|
|
||||||
<form (ngSubmit)="makeFriends()" [formGroup]="form">
|
<form (ngSubmit)="makeFriends()" [formGroup]="form">
|
||||||
<div class="form-group" *ngFor="let url of urls; let id = index; trackBy:customTrackBy">
|
<div class="form-group" *ngFor="let host of hosts; let id = index; trackBy:customTrackBy">
|
||||||
<label for="username">Url</label>
|
<label for="username">Host</label>
|
||||||
|
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input
|
<input
|
||||||
type="text" class="form-control" placeholder="http://domain.com"
|
type="text" class="form-control" placeholder="domain.tld"
|
||||||
[id]="'url-' + id" [formControlName]="'url-' + id"
|
[id]="'host-' + id" [formControlName]="'host-' + id"
|
||||||
/>
|
/>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button *ngIf="displayAddField(id)" (click)="addField()" class="btn btn-default" type="button">+</button>
|
<button *ngIf="displayAddField(id)" (click)="addField()" class="btn btn-default" type="button">+</button>
|
||||||
|
@ -17,8 +17,8 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div [hidden]="form.controls['url-' + id].valid || form.controls['url-' + id].pristine" class="alert alert-warning">
|
<div [hidden]="form.controls['host-' + id].valid || form.controls['host-' + id].pristine" class="alert alert-warning">
|
||||||
It should be a valid url.
|
It should be a valid host.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
|
||||||
import { FormControl, FormGroup } from '@angular/forms';
|
import { FormControl, FormGroup } from '@angular/forms';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
import { validateUrl } from '../../../shared';
|
import { validateHost } from '../../../shared';
|
||||||
import { FriendService } from '../shared';
|
import { FriendService } from '../shared';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -12,7 +12,7 @@ import { FriendService } from '../shared';
|
||||||
})
|
})
|
||||||
export class FriendAddComponent implements OnInit {
|
export class FriendAddComponent implements OnInit {
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
urls = [ ];
|
hosts = [ ];
|
||||||
error: string = null;
|
error: string = null;
|
||||||
|
|
||||||
constructor(private router: Router, private friendService: FriendService) {}
|
constructor(private router: Router, private friendService: FriendService) {}
|
||||||
|
@ -23,8 +23,8 @@ export class FriendAddComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
addField() {
|
addField() {
|
||||||
this.form.addControl(`url-${this.urls.length}`, new FormControl('', [ validateUrl ]));
|
this.form.addControl(`host-${this.hosts.length}`, new FormControl('', [ validateHost ]));
|
||||||
this.urls.push('');
|
this.hosts.push('');
|
||||||
}
|
}
|
||||||
|
|
||||||
customTrackBy(index: number, obj: any): any {
|
customTrackBy(index: number, obj: any): any {
|
||||||
|
@ -32,52 +32,52 @@ export class FriendAddComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
displayAddField(index: number) {
|
displayAddField(index: number) {
|
||||||
return index === (this.urls.length - 1);
|
return index === (this.hosts.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
displayRemoveField(index: number) {
|
displayRemoveField(index: number) {
|
||||||
return (index !== 0 || this.urls.length > 1) && index !== (this.urls.length - 1);
|
return (index !== 0 || this.hosts.length > 1) && index !== (this.hosts.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
isFormValid() {
|
isFormValid() {
|
||||||
// Do not check the last input
|
// Do not check the last input
|
||||||
for (let i = 0; i < this.urls.length - 1; i++) {
|
for (let i = 0; i < this.hosts.length - 1; i++) {
|
||||||
if (!this.form.controls[`url-${i}`].valid) return false;
|
if (!this.form.controls[`host-${i}`].valid) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastIndex = this.urls.length - 1;
|
const lastIndex = this.hosts.length - 1;
|
||||||
// If the last input (which is not the first) is empty, it's ok
|
// If the last input (which is not the first) is empty, it's ok
|
||||||
if (this.urls[lastIndex] === '' && lastIndex !== 0) {
|
if (this.hosts[lastIndex] === '' && lastIndex !== 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return this.form.controls[`url-${lastIndex}`].valid;
|
return this.form.controls[`host-${lastIndex}`].valid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeField(index: number) {
|
removeField(index: number) {
|
||||||
// Remove the last control
|
// Remove the last control
|
||||||
this.form.removeControl(`url-${this.urls.length - 1}`);
|
this.form.removeControl(`host-${this.hosts.length - 1}`);
|
||||||
this.urls.splice(index, 1);
|
this.hosts.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
makeFriends() {
|
makeFriends() {
|
||||||
this.error = '';
|
this.error = '';
|
||||||
|
|
||||||
const notEmptyUrls = this.getNotEmptyUrls();
|
const notEmptyHosts = this.getNotEmptyHosts();
|
||||||
if (notEmptyUrls.length === 0) {
|
if (notEmptyHosts.length === 0) {
|
||||||
this.error = 'You need to specify at less 1 url.';
|
this.error = 'You need to specify at least 1 host.';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.isUrlsUnique(notEmptyUrls)) {
|
if (!this.isHostsUnique(notEmptyHosts)) {
|
||||||
this.error = 'Urls need to be unique.';
|
this.error = 'Hosts need to be unique.';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const confirmMessage = 'Are you sure to make friends with:\n - ' + notEmptyUrls.join('\n - ');
|
const confirmMessage = 'Are you sure to make friends with:\n - ' + notEmptyHosts.join('\n - ');
|
||||||
if (!confirm(confirmMessage)) return;
|
if (!confirm(confirmMessage)) return;
|
||||||
|
|
||||||
this.friendService.makeFriends(notEmptyUrls).subscribe(
|
this.friendService.makeFriends(notEmptyHosts).subscribe(
|
||||||
status => {
|
status => {
|
||||||
// TODO: extractdatastatus
|
// TODO: extractdatastatus
|
||||||
// if (status === 409) {
|
// if (status === 409) {
|
||||||
|
@ -91,18 +91,18 @@ export class FriendAddComponent implements OnInit {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getNotEmptyUrls() {
|
private getNotEmptyHosts() {
|
||||||
const notEmptyUrls = [];
|
const notEmptyHosts = [];
|
||||||
|
|
||||||
Object.keys(this.form.value).forEach((urlKey) => {
|
Object.keys(this.form.value).forEach((hostKey) => {
|
||||||
const url = this.form.value[urlKey];
|
const host = this.form.value[hostKey];
|
||||||
if (url !== '') notEmptyUrls.push(url);
|
if (host !== '') notEmptyHosts.push(host);
|
||||||
});
|
});
|
||||||
|
|
||||||
return notEmptyUrls;
|
return notEmptyHosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private isUrlsUnique(urls: string[]) {
|
private isHostsUnique(hosts: string[]) {
|
||||||
return urls.every(url => urls.indexOf(url) === urls.lastIndexOf(url));
|
return hosts.every(host => hosts.indexOf(host) === hosts.lastIndexOf(host));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="table-column-id">ID</th>
|
<th class="table-column-id">ID</th>
|
||||||
<th>Url</th>
|
<th>Host</th>
|
||||||
<th>Score</th>
|
<th>Score</th>
|
||||||
<th>Created Date</th>
|
<th>Created Date</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr *ngFor="let friend of friends">
|
<tr *ngFor="let friend of friends">
|
||||||
<td>{{ friend.id }}</td>
|
<td>{{ friend.id }}</td>
|
||||||
<td>{{ friend.url }}</td>
|
<td>{{ friend.host }}</td>
|
||||||
<td>{{ friend.score }}</td>
|
<td>{{ friend.score }}</td>
|
||||||
<td>{{ friend.createdDate | date: 'medium' }}</td>
|
<td>{{ friend.createdDate | date: 'medium' }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
export interface Friend {
|
export interface Friend {
|
||||||
id: string;
|
id: string;
|
||||||
url: string;
|
host: string;
|
||||||
score: number;
|
score: number;
|
||||||
createdDate: Date;
|
createdDate: Date;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,9 @@ export class FriendService {
|
||||||
.catch((res) => this.restExtractor.handleError(res));
|
.catch((res) => this.restExtractor.handleError(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
makeFriends(notEmptyUrls) {
|
makeFriends(notEmptyHosts) {
|
||||||
const body = {
|
const body = {
|
||||||
urls: notEmptyUrls
|
hosts: notEmptyHosts
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.authHttp.post(FriendService.BASE_FRIEND_URL + 'makefriends', body)
|
return this.authHttp.post(FriendService.BASE_FRIEND_URL + 'makefriends', body)
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { FormControl } from '@angular/forms';
|
||||||
|
|
||||||
|
export function validateHost(c: FormControl) {
|
||||||
|
let HOST_REGEXP = new RegExp('^(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$');
|
||||||
|
|
||||||
|
return HOST_REGEXP.test(c.value) ? null : {
|
||||||
|
validateHost: {
|
||||||
|
valid: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
export * from './url.validator';
|
export * from './host.validator';
|
||||||
export * from './user';
|
export * from './user';
|
||||||
export * from './video';
|
export * from './video';
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
import { FormControl } from '@angular/forms';
|
|
||||||
|
|
||||||
export function validateUrl(c: FormControl) {
|
|
||||||
let URL_REGEXP = new RegExp('^https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$');
|
|
||||||
|
|
||||||
return URL_REGEXP.test(c.value) ? null : {
|
|
||||||
validateUrl: {
|
|
||||||
valid: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -8,21 +8,12 @@ export class Video {
|
||||||
isLocal: boolean;
|
isLocal: boolean;
|
||||||
magnetUri: string;
|
magnetUri: string;
|
||||||
name: string;
|
name: string;
|
||||||
podUrl: string;
|
podHost: string;
|
||||||
tags: string[];
|
tags: string[];
|
||||||
thumbnailPath: string;
|
thumbnailPath: string;
|
||||||
|
|
||||||
private static createByString(author: string, podUrl: string) {
|
private static createByString(author: string, podHost: string) {
|
||||||
let [ host, port ] = podUrl.replace(/^https?:\/\//, '').split(':');
|
return author + '@' + podHost;
|
||||||
|
|
||||||
if (port === '80' || port === '443') {
|
|
||||||
port = '';
|
|
||||||
} else {
|
|
||||||
port = ':' + port;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return author + '@' + host + port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createDurationString(duration: number) {
|
private static createDurationString(duration: number) {
|
||||||
|
@ -43,7 +34,7 @@ export class Video {
|
||||||
isLocal: boolean,
|
isLocal: boolean,
|
||||||
magnetUri: string,
|
magnetUri: string,
|
||||||
name: string,
|
name: string,
|
||||||
podUrl: string,
|
podHost: string,
|
||||||
tags: string[],
|
tags: string[],
|
||||||
thumbnailPath: string
|
thumbnailPath: string
|
||||||
}) {
|
}) {
|
||||||
|
@ -55,11 +46,11 @@ export class Video {
|
||||||
this.isLocal = hash.isLocal;
|
this.isLocal = hash.isLocal;
|
||||||
this.magnetUri = hash.magnetUri;
|
this.magnetUri = hash.magnetUri;
|
||||||
this.name = hash.name;
|
this.name = hash.name;
|
||||||
this.podUrl = hash.podUrl;
|
this.podHost = hash.podHost;
|
||||||
this.tags = hash.tags;
|
this.tags = hash.tags;
|
||||||
this.thumbnailPath = hash.thumbnailPath;
|
this.thumbnailPath = hash.thumbnailPath;
|
||||||
|
|
||||||
this.by = Video.createByString(hash.author, hash.podUrl);
|
this.by = Video.createByString(hash.author, hash.podHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
isRemovableBy(user) {
|
isRemovableBy(user) {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="alert alert-danger">
|
<div class="alert alert-danger">
|
||||||
The video load seems to be abnormally long.
|
The video load seems to be abnormally long.
|
||||||
<ul>
|
<ul>
|
||||||
<li>Maybe the server {{ video.podUrl }} is down :(</li>
|
<li>Maybe the server {{ video.podHost }} is down :(</li>
|
||||||
<li>
|
<li>
|
||||||
If not, you can report an issue on
|
If not, you can report an issue on
|
||||||
<a href="https://github.com/Chocobozzz/PeerTube/issues" title="Report an issue">
|
<a href="https://github.com/Chocobozzz/PeerTube/issues" title="Report an issue">
|
||||||
|
|
|
@ -20,14 +20,14 @@ const Pod = mongoose.model('Pod')
|
||||||
router.get('/', listPods)
|
router.get('/', listPods)
|
||||||
router.post('/',
|
router.post('/',
|
||||||
validators.podsAdd,
|
validators.podsAdd,
|
||||||
podsMiddleware.setBodyUrlPort,
|
podsMiddleware.setBodyHostPort,
|
||||||
addPods
|
addPods
|
||||||
)
|
)
|
||||||
router.post('/makefriends',
|
router.post('/makefriends',
|
||||||
oAuth.authenticate,
|
oAuth.authenticate,
|
||||||
admin.ensureIsAdmin,
|
admin.ensureIsAdmin,
|
||||||
validators.makeFriends,
|
validators.makeFriends,
|
||||||
podsMiddleware.setBodyUrlsPort,
|
podsMiddleware.setBodyHostsPort,
|
||||||
makeFriends
|
makeFriends
|
||||||
)
|
)
|
||||||
router.get('/quitfriends',
|
router.get('/quitfriends',
|
||||||
|
@ -84,17 +84,17 @@ function addPods (req, res, next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function listPods (req, res, next) {
|
function listPods (req, res, next) {
|
||||||
Pod.list(function (err, podsUrlList) {
|
Pod.list(function (err, podsList) {
|
||||||
if (err) return next(err)
|
if (err) return next(err)
|
||||||
|
|
||||||
res.json(getFormatedPods(podsUrlList))
|
res.json(getFormatedPods(podsList))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeFriends (req, res, next) {
|
function makeFriends (req, res, next) {
|
||||||
const urls = req.body.urls
|
const hosts = req.body.hosts
|
||||||
|
|
||||||
friends.makeFriends(urls, function (err) {
|
friends.makeFriends(hosts, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error('Could not make friends.', { error: err })
|
logger.error('Could not make friends.', { error: err })
|
||||||
return
|
return
|
||||||
|
@ -107,11 +107,11 @@ function makeFriends (req, res, next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function removePods (req, res, next) {
|
function removePods (req, res, next) {
|
||||||
const url = req.body.signature.url
|
const host = req.body.signature.host
|
||||||
|
|
||||||
waterfall([
|
waterfall([
|
||||||
function loadPod (callback) {
|
function loadPod (callback) {
|
||||||
Pod.loadByUrl(url, callback)
|
Pod.loadByHost(host, callback)
|
||||||
},
|
},
|
||||||
|
|
||||||
function removePod (pod, callback) {
|
function removePod (pod, callback) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ module.exports = router
|
||||||
|
|
||||||
function remoteVideos (req, res, next) {
|
function remoteVideos (req, res, next) {
|
||||||
const requests = req.body.data
|
const requests = req.body.data
|
||||||
const fromUrl = req.body.signature.url
|
const fromHost = req.body.signature.host
|
||||||
|
|
||||||
// We need to process in the same order to keep consistency
|
// We need to process in the same order to keep consistency
|
||||||
// TODO: optimization
|
// TODO: optimization
|
||||||
|
@ -40,7 +40,7 @@ function remoteVideos (req, res, next) {
|
||||||
if (request.type === 'add') {
|
if (request.type === 'add') {
|
||||||
addRemoteVideo(videoData, callbackEach)
|
addRemoteVideo(videoData, callbackEach)
|
||||||
} else if (request.type === 'remove') {
|
} else if (request.type === 'remove') {
|
||||||
removeRemoteVideo(videoData, fromUrl, callbackEach)
|
removeRemoteVideo(videoData, fromHost, callbackEach)
|
||||||
} else {
|
} else {
|
||||||
logger.error('Unkown remote request type %s.', request.type)
|
logger.error('Unkown remote request type %s.', request.type)
|
||||||
}
|
}
|
||||||
|
@ -62,16 +62,16 @@ function addRemoteVideo (videoToCreateData, callback) {
|
||||||
video.save(callback)
|
video.save(callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeRemoteVideo (videoToRemoveData, fromUrl, callback) {
|
function removeRemoteVideo (videoToRemoveData, fromHost, callback) {
|
||||||
// We need the list because we have to remove some other stuffs (thumbnail etc)
|
// We need the list because we have to remove some other stuffs (thumbnail etc)
|
||||||
Video.listByUrlAndRemoteId(fromUrl, videoToRemoveData.remoteId, function (err, videosList) {
|
Video.listByHostAndRemoteId(fromHost, videoToRemoveData.remoteId, function (err, videosList) {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error('Cannot list videos from url and magnets.', { error: err })
|
logger.error('Cannot list videos from host and magnets.', { error: err })
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (videosList.length === 0) {
|
if (videosList.length === 0) {
|
||||||
logger.error('No remote video was found for this pod.', { magnetUri: videoToRemoveData.magnetUri, podUrl: fromUrl })
|
logger.error('No remote video was found for this pod.', { magnetUri: videoToRemoveData.magnetUri, podHost: fromHost })
|
||||||
}
|
}
|
||||||
|
|
||||||
each(videosList, function (video, callbackEach) {
|
each(videosList, function (video, callbackEach) {
|
||||||
|
|
|
@ -5,14 +5,14 @@ const validator = require('express-validator').validator
|
||||||
const miscValidators = require('./misc')
|
const miscValidators = require('./misc')
|
||||||
|
|
||||||
const podsValidators = {
|
const podsValidators = {
|
||||||
isEachUniqueUrlValid
|
isEachUniqueHostValid
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEachUniqueUrlValid (urls) {
|
function isEachUniqueHostValid (hosts) {
|
||||||
return miscValidators.isArray(urls) &&
|
return miscValidators.isArray(hosts) &&
|
||||||
urls.length !== 0 &&
|
hosts.length !== 0 &&
|
||||||
urls.every(function (url) {
|
hosts.every(function (host) {
|
||||||
return validator.isURL(url) && urls.indexOf(url) === urls.lastIndexOf(url)
|
return validator.isURL(host) && host.split('://').length === 1 && hosts.indexOf(host) === hosts.lastIndexOf(host)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ const videosValidators = {
|
||||||
isVideoDurationValid,
|
isVideoDurationValid,
|
||||||
isVideoMagnetValid,
|
isVideoMagnetValid,
|
||||||
isVideoNameValid,
|
isVideoNameValid,
|
||||||
isVideoPodUrlValid,
|
isVideoPodHostValid,
|
||||||
isVideoTagsValid,
|
isVideoTagsValid,
|
||||||
isVideoThumbnailValid,
|
isVideoThumbnailValid,
|
||||||
isVideoThumbnail64Valid
|
isVideoThumbnail64Valid
|
||||||
|
@ -33,7 +33,7 @@ function isEachRemoteVideosValid (requests) {
|
||||||
isVideoDurationValid(video.duration) &&
|
isVideoDurationValid(video.duration) &&
|
||||||
isVideoMagnetValid(video.magnet) &&
|
isVideoMagnetValid(video.magnet) &&
|
||||||
isVideoNameValid(video.name) &&
|
isVideoNameValid(video.name) &&
|
||||||
isVideoPodUrlValid(video.podUrl) &&
|
isVideoPodHostValid(video.podHost) &&
|
||||||
isVideoTagsValid(video.tags) &&
|
isVideoTagsValid(video.tags) &&
|
||||||
isVideoThumbnail64Valid(video.thumbnailBase64) &&
|
isVideoThumbnail64Valid(video.thumbnailBase64) &&
|
||||||
isVideoRemoteIdValid(video.remoteId)
|
isVideoRemoteIdValid(video.remoteId)
|
||||||
|
@ -70,7 +70,7 @@ function isVideoNameValid (value) {
|
||||||
return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
|
return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isVideoPodUrlValid (value) {
|
function isVideoPodHostValid (value) {
|
||||||
// TODO: set options (TLD...)
|
// TODO: set options (TLD...)
|
||||||
return validator.isURL(value)
|
return validator.isURL(value)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ function makeRetryRequest (params, callback) {
|
||||||
|
|
||||||
function makeSecureRequest (params, callback) {
|
function makeSecureRequest (params, callback) {
|
||||||
const requestParams = {
|
const requestParams = {
|
||||||
url: params.toPod.url + params.path
|
url: constants.REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add data with POST requst ?
|
// Add data with POST requst ?
|
||||||
|
@ -34,9 +34,11 @@ function makeSecureRequest (params, callback) {
|
||||||
|
|
||||||
// Add signature if it is specified in the params
|
// Add signature if it is specified in the params
|
||||||
if (params.sign === true) {
|
if (params.sign === true) {
|
||||||
|
const host = constants.CONFIG.WEBSERVER.HOST
|
||||||
|
|
||||||
requestParams.json.signature = {
|
requestParams.json.signature = {
|
||||||
url: constants.CONFIG.WEBSERVER.URL,
|
host,
|
||||||
signature: peertubeCrypto.sign(constants.CONFIG.WEBSERVER.URL)
|
signature: peertubeCrypto.sign(host)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ const PAGINATION_COUNT_DEFAULT = 15
|
||||||
|
|
||||||
// Sortable columns per schema
|
// Sortable columns per schema
|
||||||
const SEARCHABLE_COLUMNS = {
|
const SEARCHABLE_COLUMNS = {
|
||||||
VIDEOS: [ 'name', 'magnetUri', 'podUrl', 'author', 'tags' ]
|
VIDEOS: [ 'name', 'magnetUri', 'podHost', 'author', 'tags' ]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sortable columns per schema
|
// Sortable columns per schema
|
||||||
|
@ -55,6 +55,7 @@ const CONFIG = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
|
CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
|
||||||
|
CONFIG.WEBSERVER.HOST = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ const eachSeries = require('async/eachSeries')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const mongoose = require('mongoose')
|
const mongoose = require('mongoose')
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
const urlUtil = require('url')
|
|
||||||
const waterfall = require('async/waterfall')
|
const waterfall = require('async/waterfall')
|
||||||
|
|
||||||
const constants = require('../initializers/constants')
|
const constants = require('../initializers/constants')
|
||||||
|
@ -44,7 +43,7 @@ function getMyCertificate (callback) {
|
||||||
fs.readFile(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.pub', 'utf8', callback)
|
fs.readFile(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.pub', 'utf8', callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeFriends (urls, callback) {
|
function makeFriends (hosts, callback) {
|
||||||
const podsScore = {}
|
const podsScore = {}
|
||||||
|
|
||||||
logger.info('Make friends!')
|
logger.info('Make friends!')
|
||||||
|
@ -54,13 +53,13 @@ function makeFriends (urls, callback) {
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
eachSeries(urls, function (url, callbackEach) {
|
eachSeries(hosts, function (host, callbackEach) {
|
||||||
computeForeignPodsList(url, podsScore, callbackEach)
|
computeForeignPodsList(host, podsScore, callbackEach)
|
||||||
}, function (err) {
|
}, function (err) {
|
||||||
if (err) return callback(err)
|
if (err) return callback(err)
|
||||||
|
|
||||||
logger.debug('Pods scores computed.', { podsScore: podsScore })
|
logger.debug('Pods scores computed.', { podsScore: podsScore })
|
||||||
const podsList = computeWinningPods(urls, podsScore)
|
const podsList = computeWinningPods(hosts, podsScore)
|
||||||
logger.debug('Pods that we keep.', { podsToKeep: podsList })
|
logger.debug('Pods that we keep.', { podsToKeep: podsList })
|
||||||
|
|
||||||
makeRequestsToWinningPods(cert, podsList, callback)
|
makeRequestsToWinningPods(cert, podsList, callback)
|
||||||
|
@ -149,45 +148,45 @@ module.exports = friends
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function computeForeignPodsList (url, podsScore, callback) {
|
function computeForeignPodsList (host, podsScore, callback) {
|
||||||
getForeignPodsList(url, function (err, foreignPodsList) {
|
getForeignPodsList(host, function (err, foreignPodsList) {
|
||||||
if (err) return callback(err)
|
if (err) return callback(err)
|
||||||
|
|
||||||
if (!foreignPodsList) foreignPodsList = []
|
if (!foreignPodsList) foreignPodsList = []
|
||||||
|
|
||||||
// Let's give 1 point to the pod we ask the friends list
|
// Let's give 1 point to the pod we ask the friends list
|
||||||
foreignPodsList.push({ url: url })
|
foreignPodsList.push({ host })
|
||||||
|
|
||||||
foreignPodsList.forEach(function (foreignPod) {
|
foreignPodsList.forEach(function (foreignPod) {
|
||||||
const foreignPodUrl = foreignPod.url
|
const foreignPodHost = foreignPod.host
|
||||||
|
|
||||||
if (podsScore[foreignPodUrl]) podsScore[foreignPodUrl]++
|
if (podsScore[foreignPodHost]) podsScore[foreignPodHost]++
|
||||||
else podsScore[foreignPodUrl] = 1
|
else podsScore[foreignPodHost] = 1
|
||||||
})
|
})
|
||||||
|
|
||||||
callback()
|
callback()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeWinningPods (urls, podsScore) {
|
function computeWinningPods (hosts, podsScore) {
|
||||||
// Build the list of pods to add
|
// Build the list of pods to add
|
||||||
// Only add a pod if it exists in more than a half base pods
|
// Only add a pod if it exists in more than a half base pods
|
||||||
const podsList = []
|
const podsList = []
|
||||||
const baseScore = urls.length / 2
|
const baseScore = hosts.length / 2
|
||||||
Object.keys(podsScore).forEach(function (podUrl) {
|
Object.keys(podsScore).forEach(function (podHost) {
|
||||||
// If the pod is not me and with a good score we add it
|
// If the pod is not me and with a good score we add it
|
||||||
if (isMe(podUrl) === false && podsScore[podUrl] > baseScore) {
|
if (isMe(podHost) === false && podsScore[podHost] > baseScore) {
|
||||||
podsList.push({ url: podUrl })
|
podsList.push({ host: podHost })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return podsList
|
return podsList
|
||||||
}
|
}
|
||||||
|
|
||||||
function getForeignPodsList (url, callback) {
|
function getForeignPodsList (host, callback) {
|
||||||
const path = '/api/' + constants.API_VERSION + '/pods'
|
const path = '/api/' + constants.API_VERSION + '/pods'
|
||||||
|
|
||||||
request.get(url + path, function (err, response, body) {
|
request.get(constants.REMOTE_SCHEME.HTTP + '://' + host + path, function (err, response, body) {
|
||||||
if (err) return callback(err)
|
if (err) return callback(err)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -207,26 +206,26 @@ function makeRequestsToWinningPods (cert, podsList, callback) {
|
||||||
|
|
||||||
eachLimit(podsList, constants.REQUESTS_IN_PARALLEL, function (pod, callbackEach) {
|
eachLimit(podsList, constants.REQUESTS_IN_PARALLEL, function (pod, callbackEach) {
|
||||||
const params = {
|
const params = {
|
||||||
url: pod.url + '/api/' + constants.API_VERSION + '/pods/',
|
url: constants.REMOTE_SCHEME.HTTP + '://' + pod.host + '/api/' + constants.API_VERSION + '/pods/',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
json: {
|
json: {
|
||||||
url: constants.CONFIG.WEBSERVER.URL,
|
host: constants.CONFIG.WEBSERVER.HOST,
|
||||||
publicKey: cert
|
publicKey: cert
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
requests.makeRetryRequest(params, function (err, res, body) {
|
requests.makeRetryRequest(params, function (err, res, body) {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error('Error with adding %s pod.', pod.url, { error: err })
|
logger.error('Error with adding %s pod.', pod.host, { error: err })
|
||||||
// Don't break the process
|
// Don't break the process
|
||||||
return callbackEach()
|
return callbackEach()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.statusCode === 200) {
|
if (res.statusCode === 200) {
|
||||||
const podObj = new Pod({ url: pod.url, publicKey: body.cert })
|
const podObj = new Pod({ host: pod.host, publicKey: body.cert })
|
||||||
podObj.save(function (err, podCreated) {
|
podObj.save(function (err, podCreated) {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error('Cannot add friend %s pod.', pod.url, { error: err })
|
logger.error('Cannot add friend %s pod.', pod.host, { error: err })
|
||||||
return callbackEach()
|
return callbackEach()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +235,7 @@ function makeRequestsToWinningPods (cert, podsList, callback) {
|
||||||
return callbackEach()
|
return callbackEach()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
logger.error('Status not 200 for %s pod.', pod.url)
|
logger.error('Status not 200 for %s pod.', pod.host)
|
||||||
return callbackEach()
|
return callbackEach()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -268,14 +267,6 @@ function createRequest (type, endpoint, data, to) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMe (url) {
|
function isMe (host) {
|
||||||
const parsedUrl = urlUtil.parse(url)
|
return host === constants.CONFIG.WEBSERVER.HOST
|
||||||
|
|
||||||
const hostname = parsedUrl.hostname
|
|
||||||
const port = parseInt(parsedUrl.port)
|
|
||||||
|
|
||||||
const myHostname = constants.CONFIG.WEBSERVER.HOSTNAME
|
|
||||||
const myPort = constants.CONFIG.WEBSERVER.PORT
|
|
||||||
|
|
||||||
return hostname === myHostname && port === myPort
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,36 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const urlModule = require('url')
|
const constants = require('../initializers/constants')
|
||||||
|
|
||||||
const logger = require('../helpers/logger')
|
|
||||||
|
|
||||||
const podsMiddleware = {
|
const podsMiddleware = {
|
||||||
setBodyUrlsPort,
|
setBodyHostsPort,
|
||||||
setBodyUrlPort
|
setBodyHostPort
|
||||||
}
|
}
|
||||||
|
|
||||||
function setBodyUrlsPort (req, res, next) {
|
function setBodyHostsPort (req, res, next) {
|
||||||
for (let i = 0; i < req.body.urls.length; i++) {
|
for (let i = 0; i < req.body.hosts.length; i++) {
|
||||||
const urlWithPort = getUrlWithPort(req.body.urls[i])
|
const hostWithPort = getHostWithPort(req.body.hosts[i])
|
||||||
|
|
||||||
// Problem with the url parsing?
|
// Problem with the url parsing?
|
||||||
if (urlWithPort === null) {
|
if (hostWithPort === null) {
|
||||||
return res.sendStatus(500)
|
return res.sendStatus(500)
|
||||||
}
|
}
|
||||||
|
|
||||||
req.body.urls[i] = urlWithPort
|
req.body.hosts[i] = hostWithPort
|
||||||
}
|
}
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setBodyUrlPort (req, res, next) {
|
function setBodyHostPort (req, res, next) {
|
||||||
const urlWithPort = getUrlWithPort(req.body.url)
|
const hostWithPort = getHostWithPort(req.body.host)
|
||||||
|
|
||||||
// Problem with the url parsing?
|
// Problem with the url parsing?
|
||||||
if (urlWithPort === null) {
|
if (hostWithPort === null) {
|
||||||
return res.sendStatus(500)
|
return res.sendStatus(500)
|
||||||
}
|
}
|
||||||
|
|
||||||
req.body.url = urlWithPort
|
req.body.host = hostWithPort
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
@ -43,20 +41,16 @@ module.exports = podsMiddleware
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function getUrlWithPort (url) {
|
function getHostWithPort (host) {
|
||||||
const urlObj = urlModule.parse(url)
|
const splitted = host.split(':')
|
||||||
|
|
||||||
// Add the port if it is not specified
|
console.log(splitted)
|
||||||
if (urlObj.port === null) {
|
// The port was not specified
|
||||||
if (urlObj.protocol === 'http:') {
|
if (splitted.length === 1) {
|
||||||
return url + ':80'
|
if (constants.REMOTE_SCHEME.HTTP === 'https') return host + ':443'
|
||||||
} else if (urlObj.protocol === 'https:') {
|
|
||||||
return url + ':443'
|
return host + ':80'
|
||||||
} else {
|
|
||||||
logger.error('Unknown url protocol: ' + urlObj.protocol)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return url
|
return host
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,27 +12,27 @@ const secureMiddleware = {
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSignature (req, res, next) {
|
function checkSignature (req, res, next) {
|
||||||
const url = req.body.signature.url
|
const host = req.body.signature.host
|
||||||
Pod.loadByUrl(url, function (err, pod) {
|
Pod.loadByHost(host, function (err, pod) {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error('Cannot get signed url in decryptBody.', { error: err })
|
logger.error('Cannot get signed host in decryptBody.', { error: err })
|
||||||
return res.sendStatus(500)
|
return res.sendStatus(500)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pod === null) {
|
if (pod === null) {
|
||||||
logger.error('Unknown pod %s.', url)
|
logger.error('Unknown pod %s.', host)
|
||||||
return res.sendStatus(403)
|
return res.sendStatus(403)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug('Decrypting body from %s.', url)
|
logger.debug('Decrypting body from %s.', host)
|
||||||
|
|
||||||
const signatureOk = peertubeCrypto.checkSignature(pod.publicKey, url, req.body.signature.signature)
|
const signatureOk = peertubeCrypto.checkSignature(pod.publicKey, host, req.body.signature.signature)
|
||||||
|
|
||||||
if (signatureOk === true) {
|
if (signatureOk === true) {
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.error('Signature is not okay in decryptBody for %s.', req.body.signature.url)
|
logger.error('Signature is not okay in decryptBody for %s.', req.body.signature.host)
|
||||||
return res.sendStatus(403)
|
return res.sendStatus(403)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ const validatorsPod = {
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeFriends (req, res, next) {
|
function makeFriends (req, res, next) {
|
||||||
req.checkBody('urls', 'Should have an array of unique urls').isEachUniqueUrlValid()
|
req.checkBody('hosts', 'Should have an array of unique hosts').isEachUniqueHostValid()
|
||||||
|
|
||||||
logger.debug('Checking makeFriends parameters', { parameters: req.body })
|
logger.debug('Checking makeFriends parameters', { parameters: req.body })
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ function makeFriends (req, res, next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function podsAdd (req, res, next) {
|
function podsAdd (req, res, next) {
|
||||||
req.checkBody('url', 'Should have an url').notEmpty().isURL({ require_protocol: true })
|
req.checkBody('host', 'Should have an host').notEmpty().isURL()
|
||||||
req.checkBody('publicKey', 'Should have a public key').notEmpty()
|
req.checkBody('publicKey', 'Should have a public key').notEmpty()
|
||||||
|
|
||||||
// TODO: check we don't have it already
|
// TODO: check we don't have it already
|
||||||
|
|
|
@ -27,10 +27,10 @@ function remoteVideos (req, res, next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function signature (req, res, next) {
|
function signature (req, res, next) {
|
||||||
req.checkBody('signature.url', 'Should have a signature url').isURL()
|
req.checkBody('signature.host', 'Should have a signature host').isURL()
|
||||||
req.checkBody('signature.signature', 'Should have a signature').notEmpty()
|
req.checkBody('signature.signature', 'Should have a signature').notEmpty()
|
||||||
|
|
||||||
logger.debug('Checking signature parameters', { parameters: { signatureUrl: req.body.signature.url } })
|
logger.debug('Checking signature parameters', { parameters: { signatureHost: req.body.signature.host } })
|
||||||
|
|
||||||
checkErrors(req, res, next)
|
checkErrors(req, res, next)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ const Video = mongoose.model('Video')
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const PodSchema = mongoose.Schema({
|
const PodSchema = mongoose.Schema({
|
||||||
url: String,
|
host: String,
|
||||||
publicKey: String,
|
publicKey: String,
|
||||||
score: { type: Number, max: constants.FRIEND_SCORE.MAX },
|
score: { type: Number, max: constants.FRIEND_SCORE.MAX },
|
||||||
createdDate: {
|
createdDate: {
|
||||||
|
@ -21,8 +21,7 @@ const PodSchema = mongoose.Schema({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: set options (TLD...)
|
PodSchema.path('host').validate(validator.isURL)
|
||||||
PodSchema.path('url').validate(validator.isURL)
|
|
||||||
PodSchema.path('publicKey').required(true)
|
PodSchema.path('publicKey').required(true)
|
||||||
PodSchema.path('score').validate(function (value) { return !isNaN(value) })
|
PodSchema.path('score').validate(function (value) { return !isNaN(value) })
|
||||||
|
|
||||||
|
@ -37,14 +36,14 @@ PodSchema.statics = {
|
||||||
listAllIds,
|
listAllIds,
|
||||||
listBadPods,
|
listBadPods,
|
||||||
load,
|
load,
|
||||||
loadByUrl,
|
loadByHost,
|
||||||
removeAll
|
removeAll
|
||||||
}
|
}
|
||||||
|
|
||||||
PodSchema.pre('save', function (next) {
|
PodSchema.pre('save', function (next) {
|
||||||
const self = this
|
const self = this
|
||||||
|
|
||||||
Pod.loadByUrl(this.url, function (err, pod) {
|
Pod.loadByHost(this.host, function (err, pod) {
|
||||||
if (err) return next(err)
|
if (err) return next(err)
|
||||||
|
|
||||||
if (pod) return next(new Error('Pod already exists.'))
|
if (pod) return next(new Error('Pod already exists.'))
|
||||||
|
@ -56,7 +55,7 @@ PodSchema.pre('save', function (next) {
|
||||||
|
|
||||||
PodSchema.pre('remove', function (next) {
|
PodSchema.pre('remove', function (next) {
|
||||||
// Remove the videos owned by this pod too
|
// Remove the videos owned by this pod too
|
||||||
Video.listByUrl(this.url, function (err, videos) {
|
Video.listByHost(this.host, function (err, videos) {
|
||||||
if (err) return next(err)
|
if (err) return next(err)
|
||||||
|
|
||||||
each(videos, function (video, callbackEach) {
|
each(videos, function (video, callbackEach) {
|
||||||
|
@ -72,7 +71,7 @@ const Pod = mongoose.model('Pod', PodSchema)
|
||||||
function toFormatedJSON () {
|
function toFormatedJSON () {
|
||||||
const json = {
|
const json = {
|
||||||
id: this._id,
|
id: this._id,
|
||||||
url: this.url,
|
host: this.host,
|
||||||
score: this.score,
|
score: this.score,
|
||||||
createdDate: this.createdDate
|
createdDate: this.createdDate
|
||||||
}
|
}
|
||||||
|
@ -111,8 +110,8 @@ function load (id, callback) {
|
||||||
return this.findById(id, callback)
|
return this.findById(id, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadByUrl (url, callback) {
|
function loadByHost (host, callback) {
|
||||||
return this.findOne({ url: url }, callback)
|
return this.findOne({ host }, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeAll (callback) {
|
function removeAll (callback) {
|
||||||
|
|
|
@ -121,7 +121,7 @@ function makeRequest (toPod, requestEndpoint, requestsToMake, callback) {
|
||||||
if (err || (res.statusCode !== 200 && res.statusCode !== 201 && res.statusCode !== 204)) {
|
if (err || (res.statusCode !== 200 && res.statusCode !== 201 && res.statusCode !== 204)) {
|
||||||
logger.error(
|
logger.error(
|
||||||
'Error sending secure request to %s pod.',
|
'Error sending secure request to %s pod.',
|
||||||
toPod.url,
|
toPod.host,
|
||||||
{
|
{
|
||||||
error: err || new Error('Status code not 20x : ' + res.statusCode)
|
error: err || new Error('Status code not 20x : ' + res.statusCode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,9 @@ const VideoSchema = mongoose.Schema({
|
||||||
magnet: {
|
magnet: {
|
||||||
infoHash: String
|
infoHash: String
|
||||||
},
|
},
|
||||||
podUrl: String,
|
podHost: String,
|
||||||
author: String,
|
author: String,
|
||||||
duration: Number,
|
duration: Number,
|
||||||
thumbnail: String,
|
|
||||||
tags: [ String ],
|
tags: [ String ],
|
||||||
createdDate: {
|
createdDate: {
|
||||||
type: Date,
|
type: Date,
|
||||||
|
@ -41,14 +40,9 @@ const VideoSchema = mongoose.Schema({
|
||||||
|
|
||||||
VideoSchema.path('name').validate(customVideosValidators.isVideoNameValid)
|
VideoSchema.path('name').validate(customVideosValidators.isVideoNameValid)
|
||||||
VideoSchema.path('description').validate(customVideosValidators.isVideoDescriptionValid)
|
VideoSchema.path('description').validate(customVideosValidators.isVideoDescriptionValid)
|
||||||
VideoSchema.path('podUrl').validate(customVideosValidators.isVideoPodUrlValid)
|
VideoSchema.path('podHost').validate(customVideosValidators.isVideoPodHostValid)
|
||||||
VideoSchema.path('author').validate(customVideosValidators.isVideoAuthorValid)
|
VideoSchema.path('author').validate(customVideosValidators.isVideoAuthorValid)
|
||||||
VideoSchema.path('duration').validate(customVideosValidators.isVideoDurationValid)
|
VideoSchema.path('duration').validate(customVideosValidators.isVideoDurationValid)
|
||||||
// The tumbnail can be the path or the data in base 64
|
|
||||||
// The pre save hook will convert the base 64 data in a file on disk and replace the thumbnail key by the filename
|
|
||||||
VideoSchema.path('thumbnail').validate(function (value) {
|
|
||||||
return customVideosValidators.isVideoThumbnailValid(value) || customVideosValidators.isVideoThumbnail64Valid(value)
|
|
||||||
})
|
|
||||||
VideoSchema.path('tags').validate(customVideosValidators.isVideoTagsValid)
|
VideoSchema.path('tags').validate(customVideosValidators.isVideoTagsValid)
|
||||||
|
|
||||||
VideoSchema.methods = {
|
VideoSchema.methods = {
|
||||||
|
@ -65,8 +59,8 @@ VideoSchema.methods = {
|
||||||
VideoSchema.statics = {
|
VideoSchema.statics = {
|
||||||
getDurationFromFile,
|
getDurationFromFile,
|
||||||
listForApi,
|
listForApi,
|
||||||
listByUrlAndRemoteId,
|
listByHostAndRemoteId,
|
||||||
listByUrl,
|
listByHost,
|
||||||
listOwned,
|
listOwned,
|
||||||
listOwnedByAuthor,
|
listOwnedByAuthor,
|
||||||
listRemotes,
|
listRemotes,
|
||||||
|
@ -107,7 +101,7 @@ VideoSchema.pre('save', function (next) {
|
||||||
|
|
||||||
if (video.isOwned()) {
|
if (video.isOwned()) {
|
||||||
const videoPath = pathUtils.join(constants.CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename())
|
const videoPath = pathUtils.join(constants.CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename())
|
||||||
this.podUrl = constants.CONFIG.WEBSERVER.HOSTNAME + ':' + constants.CONFIG.WEBSERVER.PORT
|
this.podHost = constants.CONFIG.WEBSERVER.HOST
|
||||||
|
|
||||||
tasks.push(
|
tasks.push(
|
||||||
// TODO: refractoring
|
// TODO: refractoring
|
||||||
|
@ -160,8 +154,8 @@ function generateMagnetUri () {
|
||||||
baseUrlHttp = constants.CONFIG.WEBSERVER.URL
|
baseUrlHttp = constants.CONFIG.WEBSERVER.URL
|
||||||
baseUrlWs = constants.CONFIG.WEBSERVER.WS + '://' + constants.CONFIG.WEBSERVER.HOSTNAME + ':' + constants.CONFIG.WEBSERVER.PORT
|
baseUrlWs = constants.CONFIG.WEBSERVER.WS + '://' + constants.CONFIG.WEBSERVER.HOSTNAME + ':' + constants.CONFIG.WEBSERVER.PORT
|
||||||
} else {
|
} else {
|
||||||
baseUrlHttp = constants.REMOTE_SCHEME.HTTP + '://' + this.podUrl
|
baseUrlHttp = constants.REMOTE_SCHEME.HTTP + '://' + this.podHost
|
||||||
baseUrlWs = constants.REMOTE_SCHEME.WS + this.podUrl
|
baseUrlWs = constants.REMOTE_SCHEME.WS + this.podHost
|
||||||
}
|
}
|
||||||
|
|
||||||
const xs = baseUrlHttp + constants.STATIC_PATHS.TORRENTS + this.getTorrentName()
|
const xs = baseUrlHttp + constants.STATIC_PATHS.TORRENTS + this.getTorrentName()
|
||||||
|
@ -215,7 +209,7 @@ function toFormatedJSON () {
|
||||||
id: this._id,
|
id: this._id,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
description: this.description,
|
description: this.description,
|
||||||
podUrl: this.podUrl,
|
podHost: this.podHost,
|
||||||
isLocal: this.isOwned(),
|
isLocal: this.isOwned(),
|
||||||
magnetUri: this.generateMagnetUri(),
|
magnetUri: this.generateMagnetUri(),
|
||||||
author: this.author,
|
author: this.author,
|
||||||
|
@ -249,7 +243,7 @@ function toRemoteJSON (callback) {
|
||||||
thumbnailBase64: new Buffer(thumbnailData).toString('base64'),
|
thumbnailBase64: new Buffer(thumbnailData).toString('base64'),
|
||||||
tags: self.tags,
|
tags: self.tags,
|
||||||
createdDate: self.createdDate,
|
createdDate: self.createdDate,
|
||||||
podUrl: self.podUrl
|
podHost: self.podHost
|
||||||
}
|
}
|
||||||
|
|
||||||
return callback(null, remoteVideo)
|
return callback(null, remoteVideo)
|
||||||
|
@ -271,12 +265,12 @@ function listForApi (start, count, sort, callback) {
|
||||||
return modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback)
|
return modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
function listByUrlAndRemoteId (fromUrl, remoteId, callback) {
|
function listByHostAndRemoteId (fromHost, remoteId, callback) {
|
||||||
this.find({ podUrl: fromUrl, remoteId: remoteId }, callback)
|
this.find({ podHost: fromHost, remoteId: remoteId }, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
function listByUrl (fromUrl, callback) {
|
function listByHost (fromHost, callback) {
|
||||||
this.find({ podUrl: fromUrl }, callback)
|
this.find({ podHost: fromHost }, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
function listOwned (callback) {
|
function listOwned (callback) {
|
||||||
|
|
Loading…
Reference in New Issue