X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=client%2Fsrc%2Fapp%2Fshared%2Fshared-main%2Fvideo%2Fvideo.service.ts;h=819847ac6975dcb0cb8f1136ed46bf444b206bba;hb=7e7d8e485356402e7652c61c9f004e850b0a1607;hp=4a97719fa96858749800dabf244eddc4642766e0;hpb=ff4de38385049bf8f6e1d76d8511854fcfabc71c;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 4a97719fa..819847ac6 100644 --- a/client/src/app/shared/shared-main/video/video.service.ts +++ b/client/src/app/shared/shared-main/video/video.service.ts @@ -1,10 +1,12 @@ -import { Observable } from 'rxjs' -import { catchError, map, switchMap } from 'rxjs/operators' +import { SortMeta } from 'primeng/api' +import { from, Observable } 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, RestService, ServerService, UserService } from '@app/core' +import { ComponentPaginationLight, RestExtractor, RestPagination, RestService, ServerService, UserService } from '@app/core' import { objectToFormData } from '@app/helpers' import { + BooleanBothQuery, FeedFormat, NSFWPolicyType, ResultList, @@ -12,10 +14,11 @@ import { UserVideoRateType, UserVideoRateUpdate, Video as VideoServerModel, + VideoChannel as VideoChannelServerModel, VideoConstant, VideoDetails as VideoDetailsServerModel, VideoFileMetadata, - VideoFilter, + VideoInclude, VideoPrivacy, VideoSortField, VideoUpdate @@ -28,20 +31,24 @@ import { VideoDetails } from './video-details.model' import { VideoEdit } from './video-edit.model' import { Video } from './video.model' -export interface VideosProvider { - getVideos (parameters: { - videoPagination: ComponentPaginationLight, - sort: VideoSortField, - filter?: VideoFilter, - categoryOneOf?: number[], - languageOneOf?: string[] - nsfwPolicy: NSFWPolicyType - }): Observable> +export type CommonVideoParams = { + videoPagination?: ComponentPaginationLight + sort: VideoSortField | SortMeta + include?: VideoInclude + isLocal?: boolean + categoryOneOf?: number[] + languageOneOf?: string[] + isLive?: boolean + skipCount?: boolean + + // FIXME: remove? + nsfwPolicy?: NSFWPolicyType + nsfw?: BooleanBothQuery } @Injectable() -export class VideoService implements VideosProvider { - static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/' +export class VideoService { + 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.' @@ -53,18 +60,18 @@ export class VideoService implements VideosProvider { ) {} getVideoViewUrl (uuid: string) { - return VideoService.BASE_VIDEO_URL + uuid + '/views' + return VideoService.BASE_VIDEO_URL + '/' + uuid + '/views' } getUserWatchingVideoUrl (uuid: string) { - return VideoService.BASE_VIDEO_URL + uuid + '/watching' + return VideoService.BASE_VIDEO_URL + '/' + uuid + '/watching' } 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)), @@ -104,7 +111,7 @@ export class VideoService implements VideosProvider { const data = objectToFormData(body) - return this.authHttp.put(VideoService.BASE_VIDEO_URL + video.id, data) + return this.authHttp.put(VideoService.BASE_VIDEO_URL + '/' + video.id, data) .pipe( map(this.restExtractor.extractDataBool), catchError(err => this.restExtractor.handleError(err)) @@ -112,15 +119,22 @@ export class VideoService implements VideosProvider { } 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) .pipe(catchError(err => this.restExtractor.handleError(err))) } - getMyVideos (videoPagination: ComponentPaginationLight, sort: VideoSortField, search?: string): Observable> { - const pagination = this.restService.componentPaginationToRestPagination(videoPagination) + getMyVideos (options: { + videoPagination: ComponentPaginationLight + sort: VideoSortField + userChannels?: VideoChannelServerModel[] + search?: string + }): Observable> { + const { videoPagination, sort, userChannels = [], search } = options + + const pagination = this.restService.componentToRestPagination(videoPagination) let params = new HttpParams() params = this.restService.addRestGetParams(params, pagination, sort) @@ -130,6 +144,16 @@ export class VideoService implements VideosProvider { isLive: { prefix: 'isLive:', isBoolean: true + }, + channelId: { + prefix: 'channel:', + handler: (name: string) => { + const channel = userChannels.find(c => c.name === name) + + if (channel) return channel.id + + return undefined + } } }) @@ -144,32 +168,16 @@ export class VideoService implements VideosProvider { ) } - getAccountVideos (parameters: { - account: Pick, - videoPagination: ComponentPaginationLight, - sort: VideoSortField - nsfwPolicy?: NSFWPolicyType - videoFilter?: VideoFilter + getAccountVideos (parameters: CommonVideoParams & { + account: Pick search?: string }): Observable> { - const { account, videoPagination, sort, videoFilter, nsfwPolicy, search } = parameters - - const pagination = this.restService.componentPaginationToRestPagination(videoPagination) + const { account, search } = parameters let params = new HttpParams() - params = this.restService.addRestGetParams(params, pagination, sort) - - if (nsfwPolicy) { - params = params.set('nsfw', this.nsfwPolicyToParam(nsfwPolicy)) - } - - if (videoFilter) { - params = params.set('filter', videoFilter) - } + params = this.buildCommonVideosParams({ params, ...parameters }) - if (search) { - params = params.set('search', search) - } + if (search) params = params.set('search', search) return this.authHttp .get>(AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/videos', { params }) @@ -179,27 +187,13 @@ export class VideoService implements VideosProvider { ) } - getVideoChannelVideos (parameters: { - videoChannel: Pick, - videoPagination: ComponentPaginationLight, - sort: VideoSortField, - nsfwPolicy?: NSFWPolicyType - videoFilter?: VideoFilter + getVideoChannelVideos (parameters: CommonVideoParams & { + videoChannel: Pick }): Observable> { - const { videoChannel, videoPagination, sort, nsfwPolicy, videoFilter } = parameters - - const pagination = this.restService.componentPaginationToRestPagination(videoPagination) + const { videoChannel } = parameters let params = new HttpParams() - params = this.restService.addRestGetParams(params, pagination, sort) - - if (nsfwPolicy) { - params = params.set('nsfw', this.nsfwPolicyToParam(nsfwPolicy)) - } - - if (videoFilter) { - params = params.set('filter', videoFilter) - } + params = this.buildCommonVideosParams({ params, ...parameters }) return this.authHttp .get>(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.nameWithHost + '/videos', { params }) @@ -209,30 +203,38 @@ export class VideoService implements VideosProvider { ) } - getVideos (parameters: { - videoPagination: ComponentPaginationLight - sort: VideoSortField - filter?: VideoFilter - categoryOneOf?: number[] - languageOneOf?: string[] - isLive?: boolean - skipCount?: boolean - nsfwPolicy?: NSFWPolicyType - }): Observable> { - const { videoPagination, sort, filter, categoryOneOf, languageOneOf, skipCount, nsfwPolicy, isLive } = parameters + getAdminVideos ( + parameters: CommonVideoParams & { pagination: RestPagination, search?: string } + ): Observable> { + const { pagination, search } = parameters - const pagination = this.restService.componentPaginationToRestPagination(videoPagination) + const include = VideoInclude.BLACKLISTED | + VideoInclude.BLOCKED_OWNER | + VideoInclude.HIDDEN_PRIVACY | + VideoInclude.NOT_PUBLISHED_STATE | + VideoInclude.FILES let params = new HttpParams() - params = this.restService.addRestGetParams(params, pagination, sort) + params = this.buildCommonVideosParams({ params, include, ...parameters }) - if (filter) params = params.set('filter', filter) - if (skipCount) params = params.set('skipCount', skipCount + '') + params = params.set('start', pagination.start.toString()) + .set('count', pagination.count.toString()) - if (isLive) params = params.set('isLive', isLive) - if (nsfwPolicy) params = params.set('nsfw', this.nsfwPolicyToParam(nsfwPolicy)) - if (languageOneOf) this.restService.addArrayParams(params, 'languageOneOf', languageOneOf) - if (categoryOneOf) this.restService.addArrayParams(params, 'categoryOneOf', categoryOneOf) + if (search) { + params = this.buildAdminParamsFromSearch(search, params) + } + + 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 }) return this.authHttp .get>(VideoService.BASE_VIDEO_URL, { params }) @@ -270,10 +272,10 @@ export class VideoService implements VideosProvider { 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) { @@ -314,13 +316,15 @@ export class VideoService implements VideosProvider { ) } - removeVideo (id: number) { - return this.authHttp - .delete(VideoService.BASE_VIDEO_URL + id) - .pipe( - map(this.restExtractor.extractDataBool), - catchError(err => this.restExtractor.handleError(err)) - ) + removeVideo (idArg: number | number[]) { + const ids = Array.isArray(idArg) ? idArg : [ idArg ] + + return from(ids) + .pipe( + concatMap(id => this.authHttp.delete(VideoService.BASE_VIDEO_URL + '/' + id)), + toArray(), + catchError(err => this.restExtractor.handleError(err)) + ) } loadCompleteDescription (descriptionPath: string) { @@ -409,7 +413,7 @@ export class VideoService implements VideosProvider { } private setVideoRate (id: number, rateType: UserVideoRateType) { - const url = VideoService.BASE_VIDEO_URL + id + '/rate' + const url = VideoService.BASE_VIDEO_URL + '/' + id + '/rate' const body: UserVideoRateUpdate = { rating: rateType } @@ -421,4 +425,49 @@ export class VideoService implements VideosProvider { catchError(err => this.restExtractor.handleError(err)) ) } + + private buildCommonVideosParams (options: CommonVideoParams & { params: HttpParams }) { + const { + params, + videoPagination, + sort, + isLocal, + include, + categoryOneOf, + languageOneOf, + skipCount, + nsfwPolicy, + isLive, + nsfw + } = options + + const pagination = videoPagination + ? this.restService.componentToRestPagination(videoPagination) + : undefined + + let newParams = this.restService.addRestGetParams(params, pagination, sort) + + if (skipCount) newParams = newParams.set('skipCount', skipCount + '') + + if (isLocal) newParams = newParams.set('isLocal', isLocal) + if (include) newParams = newParams.set('include', include) + 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) + + return newParams + } + + private buildAdminParamsFromSearch (search: string, params: HttpParams) { + const filters = this.restService.parseQueryStringFilter(search, { + isLocal: { + prefix: 'isLocal:', + isBoolean: true + } + }) + + return this.restService.addObjectParams(params, filters) + } }