X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=client%2Fsrc%2Fapp%2Fshared%2Fshared-main%2Fvideo%2Fvideo.service.ts;h=4fbc4f7f62ae3389177a9cd0f11c9459bf3770a8;hb=a2fb5fb8b1007e3ce82e707917f5d9a37374e99b;hp=9e3aa1e6a0093847d7c9be53838ce3d3ecf0bc91;hpb=33f6dce136ca6e969fe374efa099bee3f2a3599d;p=github%2FChocobozzz%2FPeerTube.git diff --git a/client/src/app/shared/shared-main/video/video.service.ts b/client/src/app/shared/shared-main/video/video.service.ts index 9e3aa1e6a..4fbc4f7f6 100644 --- a/client/src/app/shared/shared-main/video/video.service.ts +++ b/client/src/app/shared/shared-main/video/video.service.ts @@ -1,9 +1,9 @@ import { SortMeta } from 'primeng/api' -import { from, Observable } from 'rxjs' +import { from, Observable, of } from 'rxjs' import { catchError, concatMap, map, switchMap, toArray } from 'rxjs/operators' import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http' import { Injectable } from '@angular/core' -import { ComponentPaginationLight, RestExtractor, RestPagination, RestService, ServerService, UserService } from '@app/core' +import { AuthService, ComponentPaginationLight, RestExtractor, RestService, ServerService, UserService } from '@app/core' import { objectToFormData } from '@app/helpers' import { BooleanBothQuery, @@ -18,11 +18,13 @@ import { VideoConstant, VideoDetails as VideoDetailsServerModel, VideoFileMetadata, - VideoFilter, + VideoInclude, VideoPrivacy, VideoSortField, + VideoTranscodingCreate, VideoUpdate } from '@shared/models' +import { VideoSource } from '@shared/models/videos/video-source' import { environment } from '../../../../environments/environment' import { Account } from '../account/account.model' import { AccountService } from '../account/account.service' @@ -34,11 +36,14 @@ import { Video } from './video.model' export type CommonVideoParams = { videoPagination?: ComponentPaginationLight sort: VideoSortField | SortMeta - filter?: VideoFilter + include?: VideoInclude + isLocal?: boolean categoryOneOf?: number[] languageOneOf?: string[] + privacyOneOf?: VideoPrivacy[] isLive?: boolean skipCount?: boolean + // FIXME: remove? nsfwPolicy?: NSFWPolicyType nsfw?: BooleanBothQuery @@ -46,11 +51,12 @@ export type CommonVideoParams = { @Injectable() export class VideoService { - static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/' + static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos' static BASE_FEEDS_URL = environment.apiUrl + '/feeds/videos.' static BASE_SUBSCRIPTION_FEEDS_URL = environment.apiUrl + '/feeds/subscriptions.' constructor ( + private auth: AuthService, private authHttp: HttpClient, private restExtractor: RestExtractor, private restService: RestService, @@ -58,18 +64,14 @@ export class VideoService { ) {} getVideoViewUrl (uuid: string) { - return VideoService.BASE_VIDEO_URL + uuid + '/views' - } - - getUserWatchingVideoUrl (uuid: string) { - return VideoService.BASE_VIDEO_URL + uuid + '/watching' + return `${VideoService.BASE_VIDEO_URL}/${uuid}/views` } getVideo (options: { videoId: string }): Observable { return this.serverService.getServerLocale() .pipe( switchMap(translations => { - return this.authHttp.get(VideoService.BASE_VIDEO_URL + options.videoId) + return this.authHttp.get(`${VideoService.BASE_VIDEO_URL}/${options.videoId}`) .pipe(map(videoHash => ({ videoHash, translations }))) }), map(({ videoHash, translations }) => new VideoDetails(videoHash, translations)), @@ -109,15 +111,12 @@ export class VideoService { const data = objectToFormData(body) - return this.authHttp.put(VideoService.BASE_VIDEO_URL + video.id, data) - .pipe( - map(this.restExtractor.extractDataBool), - catchError(err => this.restExtractor.handleError(err)) - ) + return this.authHttp.put(`${VideoService.BASE_VIDEO_URL}/${video.id}`, data) + .pipe(catchError(err => this.restExtractor.handleError(err))) } uploadVideo (video: FormData) { - const req = new HttpRequest('POST', VideoService.BASE_VIDEO_URL + 'upload', video, { reportProgress: true }) + const req = new HttpRequest('POST', `${VideoService.BASE_VIDEO_URL}/upload`, video, { reportProgress: true }) return this.authHttp .request<{ video: { id: number, uuid: string } }>(req) @@ -201,31 +200,6 @@ export class VideoService { ) } - getAdminVideos ( - parameters: Omit & { pagination: RestPagination, search?: string } - ): Observable> { - const { pagination, search } = parameters - - let params = new HttpParams() - params = this.buildCommonVideosParams({ params, ...parameters }) - - params = params.set('start', pagination.start.toString()) - .set('count', pagination.count.toString()) - - if (search) { - params = this.buildAdminParamsFromSearch(search, params) - } - - if (!params.has('filter')) params = params.set('filter', 'all') - - return this.authHttp - .get>(VideoService.BASE_VIDEO_URL, { params }) - .pipe( - switchMap(res => this.extractVideos(res)), - catchError(err => this.restExtractor.handleError(err)) - ) - } - getVideos (parameters: CommonVideoParams): Observable> { let params = new HttpParams() params = this.buildCommonVideosParams({ params, ...parameters }) @@ -266,10 +240,10 @@ export class VideoService { return feeds } - getVideoFeedUrls (sort: VideoSortField, filter?: VideoFilter, categoryOneOf?: number[]) { + getVideoFeedUrls (sort: VideoSortField, isLocal: boolean, categoryOneOf?: number[]) { let params = this.restService.addRestGetParams(new HttpParams(), undefined, sort) - if (filter) params = params.set('filter', filter) + if (isLocal) params = params.set('isLocal', isLocal) if (categoryOneOf) { for (const c of categoryOneOf) { @@ -315,7 +289,27 @@ export class VideoService { return from(ids) .pipe( - concatMap(id => this.authHttp.delete(VideoService.BASE_VIDEO_URL + id)), + concatMap(id => this.authHttp.delete(`${VideoService.BASE_VIDEO_URL}/${id}`)), + toArray(), + catchError(err => this.restExtractor.handleError(err)) + ) + } + + removeVideoFiles (videoIds: (number | string)[], type: 'hls' | 'webtorrent') { + return from(videoIds) + .pipe( + concatMap(id => this.authHttp.delete(VideoService.BASE_VIDEO_URL + '/' + id + '/' + type)), + toArray(), + catchError(err => this.restExtractor.handleError(err)) + ) + } + + runTranscoding (videoIds: (number | string)[], type: 'hls' | 'webtorrent') { + const body: VideoTranscodingCreate = { transcodingType: type } + + return from(videoIds) + .pipe( + concatMap(id => this.authHttp.post(VideoService.BASE_VIDEO_URL + '/' + id + '/transcoding', body)), toArray(), catchError(err => this.restExtractor.handleError(err)) ) @@ -330,19 +324,33 @@ export class VideoService { ) } - setVideoLike (id: number) { + getSource (videoId: number) { + return this.authHttp + .get<{ source: VideoSource }>(VideoService.BASE_VIDEO_URL + '/' + videoId + '/source') + .pipe( + catchError(err => { + if (err.status === 404) { + return of(undefined) + } + + this.restExtractor.handleError(err) + }) + ) + } + + setVideoLike (id: string) { return this.setVideoRate(id, 'like') } - setVideoDislike (id: number) { + setVideoDislike (id: string) { return this.setVideoRate(id, 'dislike') } - unsetVideoLike (id: number) { + unsetVideoLike (id: string) { return this.setVideoRate(id, 'none') } - getUserVideoRating (id: number) { + getUserVideoRating (id: string) { const url = UserService.BASE_USERS_URL + 'me/videos/' + id + '/rating' return this.authHttp.get(url) @@ -406,28 +414,16 @@ export class VideoService { : 'both' } - private setVideoRate (id: number, rateType: UserVideoRateType) { - const url = VideoService.BASE_VIDEO_URL + id + '/rate' - const body: UserVideoRateUpdate = { - rating: rateType - } - - return this.authHttp - .put(url, body) - .pipe( - map(this.restExtractor.extractDataBool), - catchError(err => this.restExtractor.handleError(err)) - ) - } - - private buildCommonVideosParams (options: CommonVideoParams & { params: HttpParams }) { + buildCommonVideosParams (options: CommonVideoParams & { params: HttpParams }) { const { params, videoPagination, sort, - filter, + isLocal, + include, categoryOneOf, languageOneOf, + privacyOneOf, skipCount, nsfwPolicy, isLive, @@ -438,32 +434,46 @@ export class VideoService { ? this.restService.componentToRestPagination(videoPagination) : undefined - let newParams = this.restService.addRestGetParams(params, pagination, sort) + let newParams = this.restService.addRestGetParams(params, pagination, this.buildListSort(sort)) - if (filter) newParams = newParams.set('filter', filter) if (skipCount) newParams = newParams.set('skipCount', skipCount + '') - if (isLive) newParams = newParams.set('isLive', isLive) - if (nsfw) newParams = newParams.set('nsfw', nsfw) - if (nsfwPolicy) newParams = newParams.set('nsfw', this.nsfwPolicyToParam(nsfwPolicy)) - if (languageOneOf) newParams = this.restService.addArrayParams(newParams, 'languageOneOf', languageOneOf) - if (categoryOneOf) newParams = this.restService.addArrayParams(newParams, 'categoryOneOf', categoryOneOf) + if (isLocal !== undefined) newParams = newParams.set('isLocal', isLocal) + if (include !== undefined) newParams = newParams.set('include', include) + if (isLive !== undefined) newParams = newParams.set('isLive', isLive) + if (nsfw !== undefined) newParams = newParams.set('nsfw', nsfw) + if (nsfwPolicy !== undefined) newParams = newParams.set('nsfw', this.nsfwPolicyToParam(nsfwPolicy)) + if (languageOneOf !== undefined) newParams = this.restService.addArrayParams(newParams, 'languageOneOf', languageOneOf) + if (categoryOneOf !== undefined) newParams = this.restService.addArrayParams(newParams, 'categoryOneOf', categoryOneOf) + if (privacyOneOf !== undefined) newParams = this.restService.addArrayParams(newParams, 'privacyOneOf', privacyOneOf) return newParams } - private buildAdminParamsFromSearch (search: string, params: HttpParams) { - const filters = this.restService.parseQueryStringFilter(search, { - filter: { - prefix: 'local:', - handler: v => { - if (v === 'true') return 'all-local' + private buildListSort (sortArg: VideoSortField | SortMeta) { + const sort = this.restService.buildSortString(sortArg) - return 'all' - } + if (typeof sort === 'string') { + // Silently use the best algorithm for logged in users if they chose the hot algorithm + if ( + this.auth.isLoggedIn() && + (sort === 'hot' || sort === '-hot') + ) { + return sort.replace('hot', 'best') } - }) - return this.restService.addObjectParams(params, filters) + return sort + } + } + + private setVideoRate (id: string, rateType: UserVideoRateType) { + const url = `${VideoService.BASE_VIDEO_URL}/${id}/rate` + const body: UserVideoRateUpdate = { + rating: rateType + } + + return this.authHttp + .put(url, body) + .pipe(catchError(err => this.restExtractor.handleError(err))) } }