Merge branch 'develop' of https://github.com/Chocobozzz/PeerTube into move-utils-to-shared
This commit is contained in:
commit
bc22d60899
|
@ -87,15 +87,19 @@
|
||||||
|
|
||||||
<div i18n class="inner-form-title">Signup</div>
|
<div i18n class="inner-form-title">Signup</div>
|
||||||
|
|
||||||
<my-peertube-checkbox
|
<div class="form-group">
|
||||||
inputName="signupEnabled" formControlName="signupEnabled"
|
<my-peertube-checkbox
|
||||||
i18n-labelText labelText="Signup enabled"
|
inputName="signupEnabled" formControlName="signupEnabled"
|
||||||
></my-peertube-checkbox>
|
i18n-labelText labelText="Signup enabled"
|
||||||
|
></my-peertube-checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
<my-peertube-checkbox *ngIf="isSignupEnabled()"
|
<div class="form-group">
|
||||||
inputName="signupRequiresEmailVerification" formControlName="signupRequiresEmailVerification"
|
<my-peertube-checkbox *ngIf="isSignupEnabled()"
|
||||||
i18n-labelText labelText="Signup requires email verification"
|
inputName="signupRequiresEmailVerification" formControlName="signupRequiresEmailVerification"
|
||||||
></my-peertube-checkbox>
|
i18n-labelText labelText="Signup requires email verification"
|
||||||
|
></my-peertube-checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div *ngIf="isSignupEnabled()" class="form-group">
|
<div *ngIf="isSignupEnabled()" class="form-group">
|
||||||
<label i18n for="signupLimit">Signup limit</label>
|
<label i18n for="signupLimit">Signup limit</label>
|
||||||
|
@ -110,15 +114,19 @@
|
||||||
|
|
||||||
<div i18n class="inner-form-title">Import</div>
|
<div i18n class="inner-form-title">Import</div>
|
||||||
|
|
||||||
<my-peertube-checkbox
|
<div class="form-group">
|
||||||
inputName="importVideosHttpEnabled" formControlName="importVideosHttpEnabled"
|
<my-peertube-checkbox
|
||||||
i18n-labelText labelText="Video import with HTTP URL (i.e. YouTube) enabled"
|
inputName="importVideosHttpEnabled" formControlName="importVideosHttpEnabled"
|
||||||
></my-peertube-checkbox>
|
i18n-labelText labelText="Video import with HTTP URL (i.e. YouTube) enabled"
|
||||||
|
></my-peertube-checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
<my-peertube-checkbox
|
<div class="form-group">
|
||||||
inputName="importVideosTorrentEnabled" formControlName="importVideosTorrentEnabled"
|
<my-peertube-checkbox
|
||||||
i18n-labelText labelText="Video import with a torrent file or a magnet URI enabled"
|
inputName="importVideosTorrentEnabled" formControlName="importVideosTorrentEnabled"
|
||||||
></my-peertube-checkbox>
|
i18n-labelText labelText="Video import with a torrent file or a magnet URI enabled"
|
||||||
|
></my-peertube-checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div i18n class="inner-form-title">Administrator</div>
|
<div i18n class="inner-form-title">Administrator</div>
|
||||||
|
|
||||||
|
@ -184,13 +192,15 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<my-peertube-checkbox
|
<div class="form-group">
|
||||||
inputName="servicesTwitterWhitelisted" formControlName="servicesTwitterWhitelisted"
|
<my-peertube-checkbox
|
||||||
i18n-labelText labelText="Instance whitelisted by Twitter"
|
inputName="servicesTwitterWhitelisted" formControlName="servicesTwitterWhitelisted"
|
||||||
i18n-helpHtml helpHtml="If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br />
|
i18n-labelText labelText="Instance whitelisted by Twitter"
|
||||||
If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br />
|
i18n-helpHtml helpHtml="If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br />
|
||||||
Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> to see if you instance is whitelisted."
|
If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br />
|
||||||
></my-peertube-checkbox>
|
Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> to see if you instance is whitelisted."
|
||||||
|
></my-peertube-checkbox>
|
||||||
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</ngb-tab>
|
</ngb-tab>
|
||||||
|
|
||||||
|
@ -199,11 +209,13 @@
|
||||||
|
|
||||||
<div i18n class="inner-form-title">Transcoding</div>
|
<div i18n class="inner-form-title">Transcoding</div>
|
||||||
|
|
||||||
<my-peertube-checkbox
|
<div class="form-group">
|
||||||
inputName="transcodingEnabled" formControlName="transcodingEnabled"
|
<my-peertube-checkbox
|
||||||
i18n-labelText labelText="Transcoding enabled"
|
inputName="transcodingEnabled" formControlName="transcodingEnabled"
|
||||||
i18n-helpHtml helpHtml="If you disable transcoding, many videos from your users will not work!"
|
i18n-labelText labelText="Transcoding enabled"
|
||||||
></my-peertube-checkbox>
|
i18n-helpHtml helpHtml="If you disable transcoding, many videos from your users will not work!"
|
||||||
|
></my-peertube-checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ng-template [ngIf]="isTranscodingEnabled()">
|
<ng-template [ngIf]="isTranscodingEnabled()">
|
||||||
|
|
||||||
|
@ -226,7 +238,6 @@
|
||||||
[inputName]="getResolutionKey(resolution)" [formControlName]="getResolutionKey(resolution)"
|
[inputName]="getResolutionKey(resolution)" [formControlName]="getResolutionKey(resolution)"
|
||||||
i18n-labelText labelText="Resolution {{resolution}} enabled"
|
i18n-labelText labelText="Resolution {{resolution}} enabled"
|
||||||
></my-peertube-checkbox>
|
></my-peertube-checkbox>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
|
|
@ -15,15 +15,19 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<my-peertube-checkbox
|
<div class="form-group">
|
||||||
inputName="webTorrentEnabled" formControlName="webTorrentEnabled"
|
<my-peertube-checkbox
|
||||||
i18n-labelText labelText="Use WebTorrent to exchange parts of the video with others"
|
inputName="webTorrentEnabled" formControlName="webTorrentEnabled"
|
||||||
></my-peertube-checkbox>
|
i18n-labelText labelText="Use WebTorrent to exchange parts of the video with others"
|
||||||
|
></my-peertube-checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
<my-peertube-checkbox
|
<div class="form-group">
|
||||||
inputName="autoPlayVideo" formControlName="autoPlayVideo"
|
<my-peertube-checkbox
|
||||||
i18n-labelText labelText="Automatically plays video"
|
inputName="autoPlayVideo" formControlName="autoPlayVideo"
|
||||||
></my-peertube-checkbox>
|
i18n-labelText labelText="Automatically plays video"
|
||||||
|
></my-peertube-checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
<input type="submit" i18n-value value="Save" [disabled]="!form.valid">
|
<input type="submit" i18n-value value="Save" [disabled]="!form.valid">
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -25,7 +25,6 @@ export class VerifyAccountEmailComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
|
|
||||||
this.userId = this.route.snapshot.queryParams['userId']
|
this.userId = this.route.snapshot.queryParams['userId']
|
||||||
this.verificationString = this.route.snapshot.queryParams['verificationString']
|
this.verificationString = this.route.snapshot.queryParams['verificationString']
|
||||||
|
|
||||||
|
|
|
@ -11,28 +11,25 @@ killall -q peertube || true
|
||||||
|
|
||||||
if [ "$1" = "misc" ]; then
|
if [ "$1" = "misc" ]; then
|
||||||
npm run build -- --light-fr
|
npm run build -- --light-fr
|
||||||
mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/client.ts \
|
mocha --timeout 5000 --exit --require ts-node/register --bail server/tests/client.ts \
|
||||||
server/tests/feeds/index.ts \
|
server/tests/feeds/index.ts \
|
||||||
server/tests/misc-endpoints.ts \
|
server/tests/misc-endpoints.ts \
|
||||||
server/tests/helpers/index.ts
|
server/tests/helpers/index.ts
|
||||||
elif [ "$1" = "api" ]; then
|
|
||||||
npm run build:server
|
|
||||||
mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/api/index.ts
|
|
||||||
elif [ "$1" = "cli" ]; then
|
elif [ "$1" = "cli" ]; then
|
||||||
npm run build:server
|
npm run build:server
|
||||||
mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/cli/index.ts
|
mocha --timeout 5000 --exit --require ts-node/register --bail server/tests/cli/index.ts
|
||||||
elif [ "$1" = "api-1" ]; then
|
elif [ "$1" = "api-1" ]; then
|
||||||
npm run build:server
|
npm run build:server
|
||||||
mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/api/index-1.ts
|
mocha --timeout 5000 --exit --require ts-node/register --bail server/tests/api/index-1.ts
|
||||||
elif [ "$1" = "api-2" ]; then
|
elif [ "$1" = "api-2" ]; then
|
||||||
npm run build:server
|
npm run build:server
|
||||||
mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/api/index-2.ts
|
mocha --timeout 5000 --exit --require ts-node/register --bail server/tests/api/index-2.ts
|
||||||
elif [ "$1" = "api-3" ]; then
|
elif [ "$1" = "api-3" ]; then
|
||||||
npm run build:server
|
npm run build:server
|
||||||
mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/api/index-3.ts
|
mocha --timeout 5000 --exit --require ts-node/register --bail server/tests/api/index-3.ts
|
||||||
elif [ "$1" = "api-4" ]; then
|
elif [ "$1" = "api-4" ]; then
|
||||||
npm run build:server
|
npm run build:server
|
||||||
mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/api/index-4.ts
|
mocha --timeout 5000 --exit --require ts-node/register --bail server/tests/api/index-4.ts
|
||||||
elif [ "$1" = "lint" ]; then
|
elif [ "$1" = "lint" ]; then
|
||||||
npm run tslint -- --project ./tsconfig.json -c ./tslint.json server.ts "server/**/*.ts" "shared/**/*.ts"
|
npm run tslint -- --project ./tsconfig.json -c ./tslint.json server.ts "server/**/*.ts" "shared/**/*.ts"
|
||||||
|
|
||||||
|
|
|
@ -204,9 +204,11 @@ async function startApplication () {
|
||||||
|
|
||||||
// Email initialization
|
// Email initialization
|
||||||
Emailer.Instance.init()
|
Emailer.Instance.init()
|
||||||
await Emailer.Instance.checkConnectionOrDie()
|
|
||||||
|
|
||||||
await JobQueue.Instance.init()
|
await Promise.all([
|
||||||
|
Emailer.Instance.checkConnectionOrDie(),
|
||||||
|
JobQueue.Instance.init()
|
||||||
|
])
|
||||||
|
|
||||||
// Caches initializations
|
// Caches initializations
|
||||||
VideosPreviewCache.Instance.init(CONFIG.CACHE.PREVIEWS.SIZE, CACHE.PREVIEWS.MAX_AGE)
|
VideosPreviewCache.Instance.init(CONFIG.CACHE.PREVIEWS.SIZE, CACHE.PREVIEWS.MAX_AGE)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as Bluebird from 'bluebird'
|
import * as Bluebird from 'bluebird'
|
||||||
import * as validator from 'validator'
|
import * as validator from 'validator'
|
||||||
import { ResultList } from '../../shared/models'
|
import { ResultList } from '../../shared/models'
|
||||||
import { Activity, ActivityPubActor } from '../../shared/models/activitypub'
|
import { Activity } from '../../shared/models/activitypub'
|
||||||
import { ACTIVITY_PUB } from '../initializers'
|
import { ACTIVITY_PUB } from '../initializers'
|
||||||
import { ActorModel } from '../models/activitypub/actor'
|
import { ActorModel } from '../models/activitypub/actor'
|
||||||
import { signJsonLDObject } from './peertube-crypto'
|
import { signJsonLDObject } from './peertube-crypto'
|
||||||
|
@ -106,10 +106,10 @@ function buildSignedActivity (byActor: ActorModel, data: Object) {
|
||||||
return signJsonLDObject(byActor, activity) as Promise<Activity>
|
return signJsonLDObject(byActor, activity) as Promise<Activity>
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActorUrl (activityActor: string | ActivityPubActor) {
|
function getAPUrl (activity: string | { id: string }) {
|
||||||
if (typeof activityActor === 'string') return activityActor
|
if (typeof activity === 'string') return activity
|
||||||
|
|
||||||
return activityActor.id
|
return activity.id
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkUrlsSameHost (url1: string, url2: string) {
|
function checkUrlsSameHost (url1: string, url2: string) {
|
||||||
|
@ -123,7 +123,7 @@ function checkUrlsSameHost (url1: string, url2: string) {
|
||||||
|
|
||||||
export {
|
export {
|
||||||
checkUrlsSameHost,
|
checkUrlsSameHost,
|
||||||
getActorUrl,
|
getAPUrl,
|
||||||
activityPubContextify,
|
activityPubContextify,
|
||||||
activityPubCollectionPagination,
|
activityPubCollectionPagination,
|
||||||
buildSignedActivity
|
buildSignedActivity
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as ffmpeg from 'fluent-ffmpeg'
|
import * as ffmpeg from 'fluent-ffmpeg'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { getTargetBitrate, VideoResolution } from '../../shared/models/videos'
|
import { getTargetBitrate, VideoResolution } from '../../shared/models/videos'
|
||||||
import { CONFIG, FFMPEG_NICE, VIDEO_TRANSCODING_FPS } from '../initializers'
|
import { CONFIG, FFMPEG_NICE, VIDEO_TRANSCODING_FPS } from '../initializers/constants'
|
||||||
import { processImage } from './image-utils'
|
import { processImage } from './image-utils'
|
||||||
import { logger } from './logger'
|
import { logger } from './logger'
|
||||||
import { checkFFmpegEncoders } from '../initializers/checker-before-init'
|
import { checkFFmpegEncoders } from '../initializers/checker-before-init'
|
||||||
|
|
|
@ -1,13 +1,28 @@
|
||||||
import 'multer'
|
import 'multer'
|
||||||
import * as sharp from 'sharp'
|
import * as sharp from 'sharp'
|
||||||
import { remove } from 'fs-extra'
|
import { move, remove } from 'fs-extra'
|
||||||
|
|
||||||
async function processImage (
|
async function processImage (
|
||||||
physicalFile: { path: string },
|
physicalFile: { path: string },
|
||||||
destination: string,
|
destination: string,
|
||||||
newSize: { width: number, height: number }
|
newSize: { width: number, height: number }
|
||||||
) {
|
) {
|
||||||
await sharp(physicalFile.path)
|
if (physicalFile.path === destination) {
|
||||||
|
throw new Error('Sharp needs an input path different that the output path.')
|
||||||
|
}
|
||||||
|
|
||||||
|
const sharpInstance = sharp(physicalFile.path)
|
||||||
|
const metadata = await sharpInstance.metadata()
|
||||||
|
|
||||||
|
// No need to resize
|
||||||
|
if (metadata.width === newSize.width && metadata.height === newSize.height) {
|
||||||
|
await move(physicalFile.path, destination, { overwrite: true })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await remove(destination)
|
||||||
|
|
||||||
|
await sharpInstance
|
||||||
.resize(newSize.width, newSize.height)
|
.resize(newSize.width, newSize.height)
|
||||||
.toFile(destination)
|
.toFile(destination)
|
||||||
|
|
||||||
|
|
|
@ -119,25 +119,27 @@ export {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
async function checkPostgresExtensions () {
|
async function checkPostgresExtensions () {
|
||||||
const extensions = [
|
const promises = [
|
||||||
'pg_trgm',
|
checkPostgresExtension('pg_trgm'),
|
||||||
'unaccent'
|
checkPostgresExtension('unaccent')
|
||||||
]
|
]
|
||||||
|
|
||||||
for (const extension of extensions) {
|
return Promise.all(promises)
|
||||||
const query = `SELECT true AS enabled FROM pg_available_extensions WHERE name = '${extension}' AND installed_version IS NOT NULL;`
|
}
|
||||||
const [ res ] = await sequelizeTypescript.query(query, { raw: true })
|
|
||||||
|
|
||||||
if (!res || res.length === 0 || res[ 0 ][ 'enabled' ] !== true) {
|
async function checkPostgresExtension (extension: string) {
|
||||||
// Try to create the extension ourself
|
const query = `SELECT true AS enabled FROM pg_available_extensions WHERE name = '${extension}' AND installed_version IS NOT NULL;`
|
||||||
try {
|
const [ res ] = await sequelizeTypescript.query(query, { raw: true })
|
||||||
await sequelizeTypescript.query(`CREATE EXTENSION ${extension};`, { raw: true })
|
|
||||||
|
|
||||||
} catch {
|
if (!res || res.length === 0 || res[ 0 ][ 'enabled' ] !== true) {
|
||||||
const errorMessage = `You need to enable ${extension} extension in PostgreSQL. ` +
|
// Try to create the extension ourself
|
||||||
`You can do so by running 'CREATE EXTENSION ${extension};' as a PostgreSQL super user in ${CONFIG.DATABASE.DBNAME} database.`
|
try {
|
||||||
throw new Error(errorMessage)
|
await sequelizeTypescript.query(`CREATE EXTENSION ${extension};`, { raw: true })
|
||||||
}
|
|
||||||
|
} catch {
|
||||||
|
const errorMessage = `You need to enable ${extension} extension in PostgreSQL. ` +
|
||||||
|
`You can do so by running 'CREATE EXTENSION ${extension};' as a PostgreSQL super user in ${CONFIG.DATABASE.DBNAME} database.`
|
||||||
|
throw new Error(errorMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,21 @@ import { remove, ensureDir } from 'fs-extra'
|
||||||
|
|
||||||
async function installApplication () {
|
async function installApplication () {
|
||||||
try {
|
try {
|
||||||
await sequelizeTypescript.sync()
|
await Promise.all([
|
||||||
await removeCacheDirectories()
|
// Database related
|
||||||
await createDirectoriesIfNotExist()
|
sequelizeTypescript.sync()
|
||||||
await createApplicationIfNotExist()
|
.then(() => {
|
||||||
await createOAuthClientIfNotExist()
|
return Promise.all([
|
||||||
await createOAuthAdminIfNotExist()
|
createApplicationIfNotExist(),
|
||||||
|
createOAuthClientIfNotExist(),
|
||||||
|
createOAuthAdminIfNotExist()
|
||||||
|
])
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Directories
|
||||||
|
removeCacheDirectories()
|
||||||
|
.then(() => createDirectoriesIfNotExist())
|
||||||
|
])
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Cannot install application.', { err })
|
logger.error('Cannot install application.', { err })
|
||||||
process.exit(-1)
|
process.exit(-1)
|
||||||
|
|
|
@ -5,15 +5,15 @@ import * as url from 'url'
|
||||||
import * as uuidv4 from 'uuid/v4'
|
import * as uuidv4 from 'uuid/v4'
|
||||||
import { ActivityPubActor, ActivityPubActorType } from '../../../shared/models/activitypub'
|
import { ActivityPubActor, ActivityPubActorType } from '../../../shared/models/activitypub'
|
||||||
import { ActivityPubAttributedTo } from '../../../shared/models/activitypub/objects'
|
import { ActivityPubAttributedTo } from '../../../shared/models/activitypub/objects'
|
||||||
import { checkUrlsSameHost, getActorUrl } from '../../helpers/activitypub'
|
import { checkUrlsSameHost, getAPUrl } from '../../helpers/activitypub'
|
||||||
import { isActorObjectValid, normalizeActor } from '../../helpers/custom-validators/activitypub/actor'
|
import { isActorObjectValid, normalizeActor } from '../../helpers/custom-validators/activitypub/actor'
|
||||||
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
||||||
import { retryTransactionWrapper, updateInstanceWithAnother } from '../../helpers/database-utils'
|
import { retryTransactionWrapper, updateInstanceWithAnother } from '../../helpers/database-utils'
|
||||||
import { logger } from '../../helpers/logger'
|
import { logger } from '../../helpers/logger'
|
||||||
import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto'
|
import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto'
|
||||||
import { doRequest, doRequestAndSaveToFile, downloadImage } from '../../helpers/requests'
|
import { doRequest, downloadImage } from '../../helpers/requests'
|
||||||
import { getUrlFromWebfinger } from '../../helpers/webfinger'
|
import { getUrlFromWebfinger } from '../../helpers/webfinger'
|
||||||
import { AVATARS_SIZE, CONFIG, IMAGE_MIMETYPE_EXT, PREVIEWS_SIZE, sequelizeTypescript } from '../../initializers'
|
import { AVATARS_SIZE, CONFIG, IMAGE_MIMETYPE_EXT, sequelizeTypescript } from '../../initializers'
|
||||||
import { AccountModel } from '../../models/account/account'
|
import { AccountModel } from '../../models/account/account'
|
||||||
import { ActorModel } from '../../models/activitypub/actor'
|
import { ActorModel } from '../../models/activitypub/actor'
|
||||||
import { AvatarModel } from '../../models/avatar/avatar'
|
import { AvatarModel } from '../../models/avatar/avatar'
|
||||||
|
@ -43,7 +43,7 @@ async function getOrCreateActorAndServerAndModel (
|
||||||
recurseIfNeeded = true,
|
recurseIfNeeded = true,
|
||||||
updateCollections = false
|
updateCollections = false
|
||||||
) {
|
) {
|
||||||
const actorUrl = getActorUrl(activityActor)
|
const actorUrl = getAPUrl(activityActor)
|
||||||
let created = false
|
let created = false
|
||||||
|
|
||||||
let actor = await fetchActorByUrl(actorUrl, fetchType)
|
let actor = await fetchActorByUrl(actorUrl, fetchType)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Activity, ActivityType } from '../../../../shared/models/activitypub'
|
import { Activity, ActivityType } from '../../../../shared/models/activitypub'
|
||||||
import { checkUrlsSameHost, getActorUrl } from '../../../helpers/activitypub'
|
import { checkUrlsSameHost, getAPUrl } from '../../../helpers/activitypub'
|
||||||
import { logger } from '../../../helpers/logger'
|
import { logger } from '../../../helpers/logger'
|
||||||
import { ActorModel } from '../../../models/activitypub/actor'
|
import { ActorModel } from '../../../models/activitypub/actor'
|
||||||
import { processAcceptActivity } from './process-accept'
|
import { processAcceptActivity } from './process-accept'
|
||||||
|
@ -40,7 +40,7 @@ async function processActivities (
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const actorUrl = getActorUrl(activity.actor)
|
const actorUrl = getAPUrl(activity.actor)
|
||||||
|
|
||||||
// When we fetch remote data, we don't have signature
|
// When we fetch remote data, we don't have signature
|
||||||
if (options.signatureActor && actorUrl !== options.signatureActor.url) {
|
if (options.signatureActor && actorUrl !== options.signatureActor.url) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { doRequest } from '../../helpers/requests'
|
||||||
import { getOrCreateActorAndServerAndModel } from './actor'
|
import { getOrCreateActorAndServerAndModel } from './actor'
|
||||||
import { logger } from '../../helpers/logger'
|
import { logger } from '../../helpers/logger'
|
||||||
import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers'
|
import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers'
|
||||||
import { checkUrlsSameHost, getActorUrl } from '../../helpers/activitypub'
|
import { checkUrlsSameHost, getAPUrl } from '../../helpers/activitypub'
|
||||||
|
|
||||||
async function shareVideoByServerAndChannel (video: VideoModel, t: Transaction) {
|
async function shareVideoByServerAndChannel (video: VideoModel, t: Transaction) {
|
||||||
if (video.privacy === VideoPrivacy.PRIVATE) return undefined
|
if (video.privacy === VideoPrivacy.PRIVATE) return undefined
|
||||||
|
@ -41,7 +41,7 @@ async function addVideoShares (shareUrls: string[], instance: VideoModel) {
|
||||||
})
|
})
|
||||||
if (!body || !body.actor) throw new Error('Body or body actor is invalid')
|
if (!body || !body.actor) throw new Error('Body or body actor is invalid')
|
||||||
|
|
||||||
const actorUrl = getActorUrl(body.actor)
|
const actorUrl = getAPUrl(body.actor)
|
||||||
if (checkUrlsSameHost(shareUrl, actorUrl) !== true) {
|
if (checkUrlsSameHost(shareUrl, actorUrl) !== true) {
|
||||||
throw new Error(`Actor url ${actorUrl} has not the same host than the share url ${shareUrl}`)
|
throw new Error(`Actor url ${actorUrl} has not the same host than the share url ${shareUrl}`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { AccountVideoRateModel } from '../../models/account/account-video-rate'
|
||||||
import { logger } from '../../helpers/logger'
|
import { logger } from '../../helpers/logger'
|
||||||
import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers'
|
import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers'
|
||||||
import { doRequest } from '../../helpers/requests'
|
import { doRequest } from '../../helpers/requests'
|
||||||
import { checkUrlsSameHost, getActorUrl } from '../../helpers/activitypub'
|
import { checkUrlsSameHost, getAPUrl } from '../../helpers/activitypub'
|
||||||
import { ActorModel } from '../../models/activitypub/actor'
|
import { ActorModel } from '../../models/activitypub/actor'
|
||||||
import { getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from './url'
|
import { getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from './url'
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ async function createRates (ratesUrl: string[], video: VideoModel, rate: VideoRa
|
||||||
})
|
})
|
||||||
if (!body || !body.actor) throw new Error('Body or body actor is invalid')
|
if (!body || !body.actor) throw new Error('Body or body actor is invalid')
|
||||||
|
|
||||||
const actorUrl = getActorUrl(body.actor)
|
const actorUrl = getAPUrl(body.actor)
|
||||||
if (checkUrlsSameHost(actorUrl, rateUrl) !== true) {
|
if (checkUrlsSameHost(actorUrl, rateUrl) !== true) {
|
||||||
throw new Error(`Rate url ${rateUrl} has not the same host than actor url ${actorUrl}`)
|
throw new Error(`Rate url ${rateUrl} has not the same host than actor url ${actorUrl}`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import { createRates } from './video-rates'
|
||||||
import { addVideoShares, shareVideoByServerAndChannel } from './share'
|
import { addVideoShares, shareVideoByServerAndChannel } from './share'
|
||||||
import { AccountModel } from '../../models/account/account'
|
import { AccountModel } from '../../models/account/account'
|
||||||
import { fetchVideoByUrl, VideoFetchByUrlType } from '../../helpers/video'
|
import { fetchVideoByUrl, VideoFetchByUrlType } from '../../helpers/video'
|
||||||
import { checkUrlsSameHost } from '../../helpers/activitypub'
|
import { checkUrlsSameHost, getAPUrl } from '../../helpers/activitypub'
|
||||||
|
|
||||||
async function federateVideoIfNeeded (video: VideoModel, isNewVideo: boolean, transaction?: sequelize.Transaction) {
|
async function federateVideoIfNeeded (video: VideoModel, isNewVideo: boolean, transaction?: sequelize.Transaction) {
|
||||||
// If the video is not private and published, we federate it
|
// If the video is not private and published, we federate it
|
||||||
|
@ -167,7 +167,7 @@ async function getOrCreateVideoAndAccountAndChannel (options: {
|
||||||
const refreshViews = options.refreshViews || false
|
const refreshViews = options.refreshViews || false
|
||||||
|
|
||||||
// Get video url
|
// Get video url
|
||||||
const videoUrl = typeof options.videoObject === 'string' ? options.videoObject : options.videoObject.id
|
const videoUrl = getAPUrl(options.videoObject)
|
||||||
|
|
||||||
let videoFromDatabase = await fetchVideoByUrl(videoUrl, fetchType)
|
let videoFromDatabase = await fetchVideoByUrl(videoUrl, fetchType)
|
||||||
if (videoFromDatabase) {
|
if (videoFromDatabase) {
|
||||||
|
@ -242,10 +242,6 @@ async function updateVideoFromAP (options: {
|
||||||
if (options.updateViews === true) options.video.set('views', videoData.views)
|
if (options.updateViews === true) options.video.set('views', videoData.views)
|
||||||
await options.video.save(sequelizeOptions)
|
await options.video.save(sequelizeOptions)
|
||||||
|
|
||||||
// Don't block on request
|
|
||||||
generateThumbnailFromUrl(options.video, options.videoObject.icon)
|
|
||||||
.catch(err => logger.warn('Cannot generate thumbnail of %s.', options.videoObject.id, { err }))
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const videoFileAttributes = videoFileActivityUrlToDBAttributes(options.video, options.videoObject)
|
const videoFileAttributes = videoFileActivityUrlToDBAttributes(options.video, options.videoObject)
|
||||||
const newVideoFiles = videoFileAttributes.map(a => new VideoFileModel(a))
|
const newVideoFiles = videoFileAttributes.map(a => new VideoFileModel(a))
|
||||||
|
@ -293,6 +289,12 @@ async function updateVideoFromAP (options: {
|
||||||
logger.debug('Cannot update the remote video.', { err })
|
logger.debug('Cannot update the remote video.', { err })
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await generateThumbnailFromUrl(options.video, options.videoObject.icon)
|
||||||
|
} catch (err) {
|
||||||
|
logger.warn('Cannot generate thumbnail of %s.', options.videoObject.id, { err })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -18,7 +18,7 @@ async function createUserAccountAndChannel (userToCreate: UserModel, validateUse
|
||||||
}
|
}
|
||||||
|
|
||||||
const userCreated = await userToCreate.save(userOptions)
|
const userCreated = await userToCreate.save(userOptions)
|
||||||
const accountCreated = await createLocalAccountWithoutKeys(userToCreate.username, userToCreate.id, null, t)
|
const accountCreated = await createLocalAccountWithoutKeys(userCreated.username, userCreated.id, null, t)
|
||||||
userCreated.Account = accountCreated
|
userCreated.Account = accountCreated
|
||||||
|
|
||||||
let channelName = userCreated.username + '_channel'
|
let channelName = userCreated.username + '_channel'
|
||||||
|
@ -37,8 +37,13 @@ async function createUserAccountAndChannel (userToCreate: UserModel, validateUse
|
||||||
return { user: userCreated, account: accountCreated, videoChannel }
|
return { user: userCreated, account: accountCreated, videoChannel }
|
||||||
})
|
})
|
||||||
|
|
||||||
account.Actor = await setAsyncActorKeys(account.Actor)
|
const [ accountKeys, channelKeys ] = await Promise.all([
|
||||||
videoChannel.Actor = await setAsyncActorKeys(videoChannel.Actor)
|
setAsyncActorKeys(account.Actor),
|
||||||
|
setAsyncActorKeys(videoChannel.Actor)
|
||||||
|
])
|
||||||
|
|
||||||
|
account.Actor = accountKeys
|
||||||
|
videoChannel.Actor = channelKeys
|
||||||
|
|
||||||
return { user, account, videoChannel } as { user: UserModel, account: AccountModel, videoChannel: VideoChannelModel }
|
return { user, account, videoChannel } as { user: UserModel, account: AccountModel, videoChannel: VideoChannelModel }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
import {
|
import {
|
||||||
AfterDelete,
|
AfterDestroy,
|
||||||
AfterUpdate,
|
AfterUpdate,
|
||||||
AllowNull,
|
AllowNull,
|
||||||
BeforeCreate,
|
BeforeCreate,
|
||||||
|
@ -179,7 +179,7 @@ export class UserModel extends Model<UserModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterUpdate
|
@AfterUpdate
|
||||||
@AfterDelete
|
@AfterDestroy
|
||||||
static removeTokenCache (instance: UserModel) {
|
static removeTokenCache (instance: UserModel) {
|
||||||
return clearCacheByUserId(instance.id)
|
return clearCacheByUserId(instance.id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {
|
import {
|
||||||
AfterDelete,
|
AfterDestroy,
|
||||||
AfterUpdate,
|
AfterUpdate,
|
||||||
AllowNull,
|
AllowNull,
|
||||||
BelongsTo,
|
BelongsTo,
|
||||||
|
@ -126,7 +126,7 @@ export class OAuthTokenModel extends Model<OAuthTokenModel> {
|
||||||
OAuthClients: OAuthClientModel[]
|
OAuthClients: OAuthClientModel[]
|
||||||
|
|
||||||
@AfterUpdate
|
@AfterUpdate
|
||||||
@AfterDelete
|
@AfterDestroy
|
||||||
static removeTokenCache (token: OAuthTokenModel) {
|
static removeTokenCache (token: OAuthTokenModel) {
|
||||||
return clearCacheByToken(token.accessToken)
|
return clearCacheByToken(token.accessToken)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,12 @@ import {
|
||||||
killallServers,
|
killallServers,
|
||||||
ServerInfo
|
ServerInfo
|
||||||
} from '../../../../shared/utils'
|
} from '../../../../shared/utils'
|
||||||
import {
|
|
||||||
makePOSTAPRequest,
|
|
||||||
makeFollowRequest,
|
|
||||||
} from '../../utils/requests/activitypub'
|
|
||||||
import { HTTP_SIGNATURE } from '../../../initializers'
|
import { HTTP_SIGNATURE } from '../../../initializers'
|
||||||
import { buildDigest, buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils'
|
import { buildDigest, buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils'
|
||||||
import * as chai from 'chai'
|
import * as chai from 'chai'
|
||||||
import { setActorField } from '../../utils/miscs/sql'
|
import { setActorField } from '../../utils/miscs/sql'
|
||||||
import { activityPubContextify, buildSignedActivity } from '../../../helpers/activitypub'
|
import { activityPubContextify, buildSignedActivity } from '../../../helpers/activitypub'
|
||||||
|
import { makeFollowRequest, makePOSTAPRequest } from '../../utils/requests/activitypub'
|
||||||
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import './blocklist'
|
import './blocklist'
|
||||||
import './user-subscriptions'
|
import './user-subscriptions'
|
||||||
import './users'
|
import './users'
|
||||||
import './users-verification'
|
|
||||||
import './users-multiple-servers'
|
import './users-multiple-servers'
|
||||||
|
import './users-verification'
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* tslint:disable:no-unused-expression */
|
/* tslint:disable:no-unused-expression */
|
||||||
|
|
||||||
import * as chai from 'chai'
|
import * as chai from 'chai'
|
||||||
import * as lodash from 'lodash'
|
import { orderBy } from 'lodash'
|
||||||
import 'mocha'
|
import 'mocha'
|
||||||
import {
|
import {
|
||||||
addVideoToBlacklist,
|
addVideoToBlacklist,
|
||||||
|
@ -22,7 +22,6 @@ import { waitJobs } from '../../../../shared/utils/server/jobs'
|
||||||
import { VideoAbuse } from '../../../../shared/models/videos'
|
import { VideoAbuse } from '../../../../shared/models/videos'
|
||||||
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
const orderBy = lodash.orderBy
|
|
||||||
|
|
||||||
describe('Test video blacklist management', function () {
|
describe('Test video blacklist management', function () {
|
||||||
let servers: ServerInfo[] = []
|
let servers: ServerInfo[] = []
|
||||||
|
|
|
@ -7,10 +7,12 @@ import {
|
||||||
createUser,
|
createUser,
|
||||||
doubleFollow,
|
doubleFollow,
|
||||||
flushAndRunMultipleServers,
|
flushAndRunMultipleServers,
|
||||||
getVideoChannelVideos, serverLogin, testImage,
|
getVideoChannelVideos,
|
||||||
|
testImage,
|
||||||
updateVideo,
|
updateVideo,
|
||||||
updateVideoChannelAvatar,
|
updateVideoChannelAvatar,
|
||||||
uploadVideo, wait, userLogin
|
uploadVideo,
|
||||||
|
userLogin
|
||||||
} from '../../../../shared/utils'
|
} from '../../../../shared/utils'
|
||||||
import {
|
import {
|
||||||
addVideoChannel,
|
addVideoChannel,
|
||||||
|
|
|
@ -16,7 +16,6 @@ import {
|
||||||
uploadVideo,
|
uploadVideo,
|
||||||
wait
|
wait
|
||||||
} from '../../../../shared/utils'
|
} from '../../../../shared/utils'
|
||||||
import { join } from 'path'
|
|
||||||
import { waitJobs } from '../../../../shared/utils/server/jobs'
|
import { waitJobs } from '../../../../shared/utils/server/jobs'
|
||||||
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
import * as chai from 'chai'
|
import * as chai from 'chai'
|
||||||
import 'mocha'
|
import 'mocha'
|
||||||
import { omit } from 'lodash'
|
import { omit } from 'lodash'
|
||||||
import * as ffmpeg from 'fluent-ffmpeg'
|
|
||||||
import { getMaxBitrate, VideoDetails, VideoResolution, VideoState } from '../../../../shared/models/videos'
|
import { getMaxBitrate, VideoDetails, VideoResolution, VideoState } from '../../../../shared/models/videos'
|
||||||
import { audio, getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffmpeg-utils'
|
import { audio, getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffmpeg-utils'
|
||||||
import {
|
import {
|
||||||
buildAbsoluteFixturePath,
|
buildAbsoluteFixturePath,
|
||||||
doubleFollow,
|
doubleFollow,
|
||||||
flushAndRunMultipleServers,
|
flushAndRunMultipleServers,
|
||||||
|
generateHighBitrateVideo,
|
||||||
getMyVideos,
|
getMyVideos,
|
||||||
getVideo,
|
getVideo,
|
||||||
getVideosList,
|
getVideosList,
|
||||||
|
@ -18,8 +18,7 @@ import {
|
||||||
ServerInfo,
|
ServerInfo,
|
||||||
setAccessTokensToServers,
|
setAccessTokensToServers,
|
||||||
uploadVideo,
|
uploadVideo,
|
||||||
webtorrentAdd,
|
webtorrentAdd
|
||||||
generateHighBitrateVideo
|
|
||||||
} from '../../../../shared/utils'
|
} from '../../../../shared/utils'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { waitJobs } from '../../../../shared/utils/server/jobs'
|
import { waitJobs } from '../../../../shared/utils/server/jobs'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { makeGetRequest } from './requests'
|
import { makeGetRequest } from './requests'
|
||||||
import { immutableAssign } from '..'
|
import { immutableAssign } from '../miscs/miscs'
|
||||||
|
|
||||||
function checkBadStartPagination (url: string, path: string, token?: string, query = {}) {
|
function checkBadStartPagination (url: string, path: string, token?: string, query = {}) {
|
||||||
return makeGetRequest({
|
return makeGetRequest({
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import * as request from 'supertest'
|
import * as request from 'supertest'
|
||||||
import { VideosSearchQuery } from '../../models/search'
|
import { VideosSearchQuery } from '../../models/search'
|
||||||
import { immutableAssign } from '..'
|
import { immutableAssign } from '../miscs/miscs'
|
||||||
|
|
||||||
function searchVideo (url: string, search: string) {
|
function searchVideo (url: string, search: string) {
|
||||||
const path = '/api/v1/search/videos'
|
const path = '/api/v1/search/videos'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { makeDeleteRequest, makeGetRequest, makePutBodyRequest } from '../'
|
import { makeDeleteRequest, makeGetRequest, makePutBodyRequest } from '../requests/requests'
|
||||||
import { CustomConfig } from '../../models/server/custom-config.model'
|
import { CustomConfig } from '../../models/server/custom-config.model'
|
||||||
|
|
||||||
function getConfig (url: string) {
|
function getConfig (url: string) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import * as request from 'supertest'
|
import * as request from 'supertest'
|
||||||
import { Job, JobState } from '../../models'
|
import { Job, JobState } from '../../models'
|
||||||
import { ServerInfo, wait } from '../index'
|
import { wait } from '../miscs/miscs'
|
||||||
|
import { ServerInfo } from './servers'
|
||||||
|
|
||||||
function getJobsList (url: string, accessToken: string, state: JobState) {
|
function getJobsList (url: string, accessToken: string, state: JobState) {
|
||||||
const path = '/api/v1/jobs/' + state
|
const path = '/api/v1/jobs/' + state
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { makeGetRequest } from '../'
|
import { makeGetRequest } from '../requests/requests'
|
||||||
|
|
||||||
function getStats (url: string, useCache = false) {
|
function getStats (url: string, useCache = false) {
|
||||||
const path = '/api/v1/server/stats'
|
const path = '/api/v1/server/stats'
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { expect } from 'chai'
|
||||||
import { existsSync, readdir } from 'fs-extra'
|
import { existsSync, readdir } from 'fs-extra'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { Account } from '../../models/actors'
|
import { Account } from '../../models/actors'
|
||||||
import { root } from '../index'
|
import { root } from '../miscs/miscs'
|
||||||
import { makeGetRequest } from '../requests/requests'
|
import { makeGetRequest } from '../requests/requests'
|
||||||
|
|
||||||
function getAccountsList (url: string, sort = '-createdAt', statusCodeExpected = 200) {
|
function getAccountsList (url: string, sort = '-createdAt', statusCodeExpected = 200) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* tslint:disable:no-unused-expression */
|
/* tslint:disable:no-unused-expression */
|
||||||
|
|
||||||
import { makeDeleteRequest, makePostBodyRequest } from '../index'
|
import { makeDeleteRequest, makePostBodyRequest } from '../requests/requests'
|
||||||
import { makeGetRequest } from '../requests/requests'
|
import { makeGetRequest } from '../requests/requests'
|
||||||
|
|
||||||
function getAccountBlocklistByAccount (
|
function getAccountBlocklistByAccount (
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { makeDeleteRequest, makeGetRequest, makePostBodyRequest } from '../'
|
import { makeDeleteRequest, makeGetRequest, makePostBodyRequest } from '../requests/requests'
|
||||||
|
|
||||||
function addUserSubscription (url: string, token: string, targetUri: string, statusCodeExpected = 204) {
|
function addUserSubscription (url: string, token: string, targetUri: string, statusCodeExpected = 204) {
|
||||||
const path = '/api/v1/users/me/subscriptions'
|
const path = '/api/v1/users/me/subscriptions'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as request from 'supertest'
|
import * as request from 'supertest'
|
||||||
import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../'
|
import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../requests/requests'
|
||||||
|
|
||||||
import { UserRole } from '../../index'
|
import { UserRole } from '../../index'
|
||||||
import { NSFWPolicyType } from '../../models/videos/nsfw-policy.type'
|
import { NSFWPolicyType } from '../../models/videos/nsfw-policy.type'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as request from 'supertest'
|
import * as request from 'supertest'
|
||||||
import { VideoAbuseUpdate } from '../../models/videos/abuse/video-abuse-update.model'
|
import { VideoAbuseUpdate } from '../../models/videos/abuse/video-abuse-update.model'
|
||||||
import { makeDeleteRequest, makePutBodyRequest } from '..'
|
import { makeDeleteRequest, makePutBodyRequest } from '../requests/requests'
|
||||||
|
|
||||||
function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 200) {
|
function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 200) {
|
||||||
const path = '/api/v1/videos/' + videoId + '/abuse'
|
const path = '/api/v1/videos/' + videoId + '/abuse'
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { makeDeleteRequest, makeGetRequest } from '../'
|
import { makeDeleteRequest, makeGetRequest, makeUploadRequest } from '../requests/requests'
|
||||||
import { buildAbsoluteFixturePath, makeUploadRequest } from '../index'
|
|
||||||
import * as request from 'supertest'
|
import * as request from 'supertest'
|
||||||
import * as chai from 'chai'
|
import * as chai from 'chai'
|
||||||
|
import { buildAbsoluteFixturePath } from '../miscs/miscs'
|
||||||
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as request from 'supertest'
|
import * as request from 'supertest'
|
||||||
import { VideoChannelCreate, VideoChannelUpdate } from '../../models/videos'
|
import { VideoChannelCreate, VideoChannelUpdate } from '../../models/videos'
|
||||||
import { updateAvatarRequest } from '../index'
|
import { updateAvatarRequest } from '../requests/requests'
|
||||||
|
|
||||||
function getVideoChannelsList (url: string, start: number, count: number, sort?: string) {
|
function getVideoChannelsList (url: string, start: number, count: number, sort?: string) {
|
||||||
const path = '/api/v1/video-channels'
|
const path = '/api/v1/video-channels'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as request from 'supertest'
|
import * as request from 'supertest'
|
||||||
import { makeDeleteRequest } from '../'
|
import { makeDeleteRequest } from '../requests/requests'
|
||||||
|
|
||||||
function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string, token?: string) {
|
function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string, token?: string) {
|
||||||
const path = '/api/v1/videos/' + videoId + '/comment-threads'
|
const path = '/api/v1/videos/' + videoId + '/comment-threads'
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
import { VideoImportCreate } from '../../models/videos'
|
import { VideoImportCreate } from '../../models/videos'
|
||||||
import { makeGetRequest, makeUploadRequest } from '..'
|
import { makeGetRequest, makeUploadRequest } from '../requests/requests'
|
||||||
|
|
||||||
function getYoutubeVideoUrl () {
|
function getYoutubeVideoUrl () {
|
||||||
return 'https://youtu.be/msX3jv1XdvM'
|
return 'https://youtu.be/msX3jv1XdvM'
|
||||||
|
|
|
@ -16,9 +16,10 @@ import {
|
||||||
ServerInfo,
|
ServerInfo,
|
||||||
testImage
|
testImage
|
||||||
} from '../'
|
} from '../'
|
||||||
|
|
||||||
import { VideoDetails, VideoPrivacy } from '../../models/videos'
|
import { VideoDetails, VideoPrivacy } from '../../models/videos'
|
||||||
import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers'
|
import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants'
|
||||||
import { dateIsValid, webtorrentAdd } from '../index'
|
import { dateIsValid, webtorrentAdd } from '../miscs/miscs'
|
||||||
|
|
||||||
type VideoAttributes = {
|
type VideoAttributes = {
|
||||||
name?: string
|
name?: string
|
||||||
|
|
|
@ -101,14 +101,13 @@ x-tagGroups:
|
||||||
- Video
|
- Video
|
||||||
- Video Channel
|
- Video Channel
|
||||||
- Video Comment
|
- Video Comment
|
||||||
- Video Abuse
|
|
||||||
- Video Following
|
- Video Following
|
||||||
- Video Rate
|
- Video Rate
|
||||||
- name: Moderation
|
- name: Moderation
|
||||||
tags:
|
tags:
|
||||||
- Video Abuse
|
- Video Abuse
|
||||||
- Video Blacklist
|
- Video Blacklist
|
||||||
- name: Public Instance Information
|
- name: Instance Configuration
|
||||||
tags:
|
tags:
|
||||||
- Config
|
- Config
|
||||||
- Server Following
|
- Server Following
|
||||||
|
@ -301,7 +300,7 @@ paths:
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: successful operation
|
description: successful operation
|
||||||
/jobs:
|
/jobs/{state}:
|
||||||
get:
|
get:
|
||||||
summary: Get list of jobs
|
summary: Get list of jobs
|
||||||
security:
|
security:
|
||||||
|
@ -316,6 +315,12 @@ paths:
|
||||||
description: The state of the job
|
description: The state of the job
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
enum:
|
||||||
|
- active
|
||||||
|
- completed
|
||||||
|
- failed
|
||||||
|
- waiting
|
||||||
|
- delayed
|
||||||
- $ref: '#/components/parameters/start'
|
- $ref: '#/components/parameters/start'
|
||||||
- $ref: '#/components/parameters/count'
|
- $ref: '#/components/parameters/count'
|
||||||
- $ref: '#/components/parameters/sort'
|
- $ref: '#/components/parameters/sort'
|
||||||
|
|
|
@ -43,7 +43,7 @@ Response example:
|
||||||
Just use the `access_token` in the `Authorization` header:
|
Just use the `access_token` in the `Authorization` header:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ curl -H 'Authorization: Bearer 90286a0bdf0f7315d9d3fe8dabf9e1d2be9c97d0' https://peertube.example.com/api/v1/jobs/complete
|
$ curl -H 'Authorization: Bearer 90286a0bdf0f7315d9d3fe8dabf9e1d2be9c97d0' https://peertube.example.com/api/v1/jobs/completed
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,4 +51,4 @@ $ curl -H 'Authorization: Bearer 90286a0bdf0f7315d9d3fe8dabf9e1d2be9c97d0' https
|
||||||
|
|
||||||
```
|
```
|
||||||
$ curl https://peertube.example.com/api/v1/videos
|
$ curl https://peertube.example.com/api/v1/videos
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in New Issue