]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/shared/video/video.service.ts
Add get subscription endpoint
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / video / video.service.ts
CommitLineData
7ce44a74 1import { catchError, map, switchMap } from 'rxjs/operators'
7a8032bb 2import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http'
202f6b6c 3import { Injectable } from '@angular/core'
db400f44 4import { Observable } from 'rxjs'
202f6b6c
C
5import { Video as VideoServerModel, VideoDetails as VideoDetailsServerModel } from '../../../../../shared'
6import { ResultList } from '../../../../../shared/models/result-list.model'
e63dbd42
C
7import {
8 UserVideoRate,
9 UserVideoRateUpdate,
10 VideoChannel,
11 VideoFilter,
12 VideoRateType,
13 VideoUpdate
14} from '../../../../../shared/models/videos'
244e76a5 15import { FeedFormat } from '../../../../../shared/models/feeds/feed-format.enum'
63c4db6d 16import { environment } from '../../../environments/environment'
4635f59d 17import { ComponentPagination } from '../rest/component-pagination.model'
202f6b6c
C
18import { RestExtractor } from '../rest/rest-extractor.service'
19import { RestService } from '../rest/rest.service'
202f6b6c 20import { UserService } from '../users/user.service'
7b87d2d5 21import { VideoSortField } from './sort-field.type'
404b54e1
C
22import { VideoDetails } from './video-details.model'
23import { VideoEdit } from './video-edit.model'
202f6b6c 24import { Video } from './video.model'
6de36768 25import { objectToFormData } from '@app/shared/misc/utils'
0626e7af
C
26import { Account } from '@app/shared/account/account.model'
27import { AccountService } from '@app/shared/account/account.service'
170726f5 28import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
7ce44a74 29import { ServerService } from '@app/core'
dc8bc31b
C
30
31@Injectable()
41a2aee3 32export class VideoService {
40e87e9e
C
33 static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/'
34 static BASE_FEEDS_URL = environment.apiUrl + '/feeds/videos.'
dc8bc31b 35
df98563e 36 constructor (
d592e0a9 37 private authHttp: HttpClient,
de59c48f 38 private restExtractor: RestExtractor,
7ce44a74
C
39 private restService: RestService,
40 private serverService: ServerService
4fd8aa32
C
41 ) {}
42
8cac1b64
C
43 getVideoViewUrl (uuid: string) {
44 return VideoService.BASE_VIDEO_URL + uuid + '/views'
45 }
46
9d9597df 47 getVideo (uuid: string): Observable<VideoDetails> {
7ce44a74 48 return this.serverService.localeObservable
db400f44 49 .pipe(
7ce44a74 50 switchMap(translations => {
74b7c6d4
C
51 return this.authHttp.get<VideoDetailsServerModel>(VideoService.BASE_VIDEO_URL + uuid)
52 .pipe(map(videoHash => ({ videoHash, translations })))
7ce44a74
C
53 }),
54 map(({ videoHash, translations }) => new VideoDetails(videoHash, translations)),
e4f0e92e 55 catchError(err => this.restExtractor.handleError(err))
db400f44 56 )
4fd8aa32 57 }
dc8bc31b 58
5fcbd898 59 viewVideo (uuid: string): Observable<boolean> {
8cac1b64 60 return this.authHttp.post(this.getVideoViewUrl(uuid), {})
db400f44
C
61 .pipe(
62 map(this.restExtractor.extractDataBool),
e4f0e92e 63 catchError(err => this.restExtractor.handleError(err))
db400f44 64 )
1f3e9fec
C
65 }
66
404b54e1 67 updateVideo (video: VideoEdit) {
360329cc
C
68 const language = video.language || null
69 const licence = video.licence || null
70 const category = video.category || null
71 const description = video.description || null
72 const support = video.support || null
e94fc297 73 const scheduleUpdate = video.scheduleUpdate || null
c24ac1c1 74
4771e000 75 const body: VideoUpdate = {
d8e689b8 76 name: video.name,
cadb46d8
C
77 category,
78 licence,
c24ac1c1 79 language,
3bf1ec2e 80 support,
cadb46d8 81 description,
0f320037 82 channelId: video.channelId,
fd45e8f4 83 privacy: video.privacy,
4771e000 84 tags: video.tags,
47564bbe 85 nsfw: video.nsfw,
2186386c 86 waitTranscoding: video.waitTranscoding,
6de36768
C
87 commentsEnabled: video.commentsEnabled,
88 thumbnailfile: video.thumbnailfile,
bbe0f064 89 previewfile: video.previewfile,
e94fc297 90 scheduleUpdate
df98563e 91 }
c24ac1c1 92
6de36768
C
93 const data = objectToFormData(body)
94
95 return this.authHttp.put(VideoService.BASE_VIDEO_URL + video.id, data)
db400f44
C
96 .pipe(
97 map(this.restExtractor.extractDataBool),
e4f0e92e 98 catchError(err => this.restExtractor.handleError(err))
db400f44 99 )
d8e689b8
C
100 }
101
db7af09b 102 uploadVideo (video: FormData) {
334ddfa4 103 const req = new HttpRequest('POST', VideoService.BASE_VIDEO_URL + 'upload', video, { reportProgress: true })
bfb3a98f 104
fd45e8f4 105 return this.authHttp
2186386c 106 .request<{ video: { id: number, uuid: string } }>(req)
e4f0e92e 107 .pipe(catchError(err => this.restExtractor.handleError(err)))
bfb3a98f
C
108 }
109
2186386c 110 getMyVideos (videoPagination: ComponentPagination, sort: VideoSortField): Observable<{ videos: Video[], totalVideos: number }> {
4635f59d 111 const pagination = this.restService.componentPaginationToRestPagination(videoPagination)
cf20596c 112
d592e0a9
C
113 let params = new HttpParams()
114 params = this.restService.addRestGetParams(params, pagination, sort)
dc8bc31b 115
7ce44a74
C
116 return this.authHttp
117 .get<ResultList<Video>>(UserService.BASE_USERS_URL + '/me/videos', { params })
db400f44 118 .pipe(
7ce44a74 119 switchMap(res => this.extractVideos(res)),
e4f0e92e 120 catchError(err => this.restExtractor.handleError(err))
db400f44 121 )
dc8bc31b
C
122 }
123
0626e7af
C
124 getAccountVideos (
125 account: Account,
126 videoPagination: ComponentPagination,
127 sort: VideoSortField
2186386c 128 ): Observable<{ videos: Video[], totalVideos: number }> {
0626e7af
C
129 const pagination = this.restService.componentPaginationToRestPagination(videoPagination)
130
131 let params = new HttpParams()
132 params = this.restService.addRestGetParams(params, pagination, sort)
133
134 return this.authHttp
7ce44a74 135 .get<ResultList<Video>>(AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/videos', { params })
db400f44 136 .pipe(
7ce44a74 137 switchMap(res => this.extractVideos(res)),
e4f0e92e 138 catchError(err => this.restExtractor.handleError(err))
db400f44 139 )
0626e7af
C
140 }
141
170726f5
C
142 getVideoChannelVideos (
143 videoChannel: VideoChannel,
144 videoPagination: ComponentPagination,
145 sort: VideoSortField
2186386c 146 ): Observable<{ videos: Video[], totalVideos: number }> {
170726f5
C
147 const pagination = this.restService.componentPaginationToRestPagination(videoPagination)
148
149 let params = new HttpParams()
150 params = this.restService.addRestGetParams(params, pagination, sort)
151
152 return this.authHttp
8a19bee1 153 .get<ResultList<Video>>(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.name + '/videos', { params })
db400f44 154 .pipe(
7ce44a74 155 switchMap(res => this.extractVideos(res)),
e4f0e92e 156 catchError(err => this.restExtractor.handleError(err))
db400f44 157 )
170726f5
C
158 }
159
066e94c5
C
160 getVideos (
161 videoPagination: ComponentPagination,
7b87d2d5 162 sort: VideoSortField,
61b909b9 163 filter?: VideoFilter,
d59cba29 164 categoryOneOf?: number
2186386c 165 ): Observable<{ videos: Video[], totalVideos: number }> {
4635f59d 166 const pagination = this.restService.componentPaginationToRestPagination(videoPagination)
fd45e8f4
C
167
168 let params = new HttpParams()
169 params = this.restService.addRestGetParams(params, pagination, sort)
170
066e94c5
C
171 if (filter) {
172 params = params.set('filter', filter)
173 }
174
d59cba29
C
175 if (categoryOneOf) {
176 params = params.set('categoryOneOf', categoryOneOf + '')
61b909b9
P
177 }
178
fd45e8f4 179 return this.authHttp
7ce44a74 180 .get<ResultList<Video>>(VideoService.BASE_VIDEO_URL, { params })
db400f44 181 .pipe(
7ce44a74 182 switchMap(res => this.extractVideos(res)),
e4f0e92e 183 catchError(err => this.restExtractor.handleError(err))
db400f44 184 )
fd45e8f4
C
185 }
186
7b87d2d5 187 buildBaseFeedUrls (params: HttpParams) {
cc1561f9
C
188 const feeds = [
189 {
190 label: 'rss 2.0',
191 url: VideoService.BASE_FEEDS_URL + FeedFormat.RSS.toLowerCase()
192 },
193 {
194 label: 'atom 1.0',
195 url: VideoService.BASE_FEEDS_URL + FeedFormat.ATOM.toLowerCase()
196 },
197 {
198 label: 'json 1.0',
199 url: VideoService.BASE_FEEDS_URL + FeedFormat.JSON.toLowerCase()
200 }
201 ]
202
7b87d2d5
C
203 if (params && params.keys().length !== 0) {
204 for (const feed of feeds) {
205 feed.url += '?' + params.toString()
206 }
207 }
208
cc1561f9 209 return feeds
244e76a5
RK
210 }
211
d59cba29 212 getVideoFeedUrls (sort: VideoSortField, filter?: VideoFilter, categoryOneOf?: number) {
7b87d2d5 213 let params = this.restService.addRestGetParams(new HttpParams(), undefined, sort)
244e76a5 214
cc1561f9
C
215 if (filter) params = params.set('filter', filter)
216
d59cba29 217 if (categoryOneOf) params = params.set('categoryOneOf', categoryOneOf + '')
61b909b9 218
7b87d2d5 219 return this.buildBaseFeedUrls(params)
244e76a5
RK
220 }
221
cc1561f9 222 getAccountFeedUrls (accountId: number) {
244e76a5 223 let params = this.restService.addRestGetParams(new HttpParams())
244e76a5 224 params = params.set('accountId', accountId.toString())
cc1561f9 225
7b87d2d5 226 return this.buildBaseFeedUrls(params)
244e76a5
RK
227 }
228
170726f5
C
229 getVideoChannelFeedUrls (videoChannelId: number) {
230 let params = this.restService.addRestGetParams(new HttpParams())
231 params = params.set('videoChannelId', videoChannelId.toString())
232
233 return this.buildBaseFeedUrls(params)
234 }
235
d592e0a9 236 removeVideo (id: number) {
fd45e8f4 237 return this.authHttp
db400f44
C
238 .delete(VideoService.BASE_VIDEO_URL + id)
239 .pipe(
240 map(this.restExtractor.extractDataBool),
e4f0e92e 241 catchError(err => this.restExtractor.handleError(err))
db400f44 242 )
4fd8aa32
C
243 }
244
2de96f4d
C
245 loadCompleteDescription (descriptionPath: string) {
246 return this.authHttp
db400f44
C
247 .get(environment.apiUrl + descriptionPath)
248 .pipe(
249 map(res => res[ 'description' ]),
e4f0e92e 250 catchError(err => this.restExtractor.handleError(err))
db400f44 251 )
d38b8281
C
252 }
253
0a6658fd 254 setVideoLike (id: number) {
df98563e 255 return this.setVideoRate(id, 'like')
d38b8281
C
256 }
257
0a6658fd 258 setVideoDislike (id: number) {
df98563e 259 return this.setVideoRate(id, 'dislike')
d38b8281
C
260 }
261
57a49263
BB
262 unsetVideoLike (id: number) {
263 return this.setVideoRate(id, 'none')
264 }
265
5fcbd898 266 getUserVideoRating (id: number) {
334ddfa4 267 const url = UserService.BASE_USERS_URL + 'me/videos/' + id + '/rating'
d38b8281 268
5fcbd898 269 return this.authHttp.get<UserVideoRate>(url)
e4f0e92e 270 .pipe(catchError(err => this.restExtractor.handleError(err)))
d38b8281
C
271 }
272
57c36b27 273 extractVideos (result: ResultList<VideoServerModel>) {
7ce44a74 274 return this.serverService.localeObservable
2186386c
C
275 .pipe(
276 map(translations => {
277 const videosJson = result.data
278 const totalVideos = result.total
279 const videos: Video[] = []
280
281 for (const videoJson of videosJson) {
282 videos.push(new Video(videoJson, translations))
283 }
284
285 return { videos, totalVideos }
286 })
287 )
501bc6c2 288 }
57c36b27
C
289
290 private setVideoRate (id: number, rateType: VideoRateType) {
291 const url = VideoService.BASE_VIDEO_URL + id + '/rate'
292 const body: UserVideoRateUpdate = {
293 rating: rateType
294 }
295
296 return this.authHttp
297 .put(url, body)
298 .pipe(
299 map(this.restExtractor.extractDataBool),
300 catchError(err => this.restExtractor.handleError(err))
301 )
302 }
dc8bc31b 303}