]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/controllers/api/accounts.ts
Add channel filters for my videos/followers
[github/Chocobozzz/PeerTube.git] / server / controllers / api / accounts.ts
1 import express from 'express'
2 import { pickCommonVideoQuery } from '@server/helpers/query'
3 import { ActorFollowModel } from '@server/models/actor/actor-follow'
4 import { getServerActor } from '@server/models/application/application'
5 import { buildNSFWFilter, getCountVideos, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils'
6 import { getFormattedObjects } from '../../helpers/utils'
7 import { JobQueue } from '../../lib/job-queue'
8 import { Hooks } from '../../lib/plugins/hooks'
9 import {
10 asyncMiddleware,
11 authenticate,
12 commonVideosFiltersValidator,
13 optionalAuthenticate,
14 paginationValidator,
15 setDefaultPagination,
16 setDefaultSort,
17 setDefaultVideosSort,
18 videoPlaylistsSortValidator,
19 videoRatesSortValidator,
20 videoRatingValidator
21 } from '../../middlewares'
22 import {
23 accountNameWithHostGetValidator,
24 accountsFollowersSortValidator,
25 accountsSortValidator,
26 ensureAuthUserOwnsAccountValidator,
27 videoChannelsSortValidator,
28 videoChannelStatsValidator,
29 videosSortValidator
30 } from '../../middlewares/validators'
31 import { commonVideoPlaylistFiltersValidator, videoPlaylistsSearchValidator } from '../../middlewares/validators/videos/video-playlists'
32 import { AccountModel } from '../../models/account/account'
33 import { AccountVideoRateModel } from '../../models/account/account-video-rate'
34 import { VideoModel } from '../../models/video/video'
35 import { VideoChannelModel } from '../../models/video/video-channel'
36 import { VideoPlaylistModel } from '../../models/video/video-playlist'
37
38 const accountsRouter = express.Router()
39
40 accountsRouter.get('/',
41 paginationValidator,
42 accountsSortValidator,
43 setDefaultSort,
44 setDefaultPagination,
45 asyncMiddleware(listAccounts)
46 )
47
48 accountsRouter.get('/:accountName',
49 asyncMiddleware(accountNameWithHostGetValidator),
50 getAccount
51 )
52
53 accountsRouter.get('/:accountName/videos',
54 asyncMiddleware(accountNameWithHostGetValidator),
55 paginationValidator,
56 videosSortValidator,
57 setDefaultVideosSort,
58 setDefaultPagination,
59 optionalAuthenticate,
60 commonVideosFiltersValidator,
61 asyncMiddleware(listAccountVideos)
62 )
63
64 accountsRouter.get('/:accountName/video-channels',
65 asyncMiddleware(accountNameWithHostGetValidator),
66 videoChannelStatsValidator,
67 paginationValidator,
68 videoChannelsSortValidator,
69 setDefaultSort,
70 setDefaultPagination,
71 asyncMiddleware(listAccountChannels)
72 )
73
74 accountsRouter.get('/:accountName/video-playlists',
75 optionalAuthenticate,
76 asyncMiddleware(accountNameWithHostGetValidator),
77 paginationValidator,
78 videoPlaylistsSortValidator,
79 setDefaultSort,
80 setDefaultPagination,
81 commonVideoPlaylistFiltersValidator,
82 videoPlaylistsSearchValidator,
83 asyncMiddleware(listAccountPlaylists)
84 )
85
86 accountsRouter.get('/:accountName/ratings',
87 authenticate,
88 asyncMiddleware(accountNameWithHostGetValidator),
89 ensureAuthUserOwnsAccountValidator,
90 paginationValidator,
91 videoRatesSortValidator,
92 setDefaultSort,
93 setDefaultPagination,
94 videoRatingValidator,
95 asyncMiddleware(listAccountRatings)
96 )
97
98 accountsRouter.get('/:accountName/followers',
99 authenticate,
100 asyncMiddleware(accountNameWithHostGetValidator),
101 ensureAuthUserOwnsAccountValidator,
102 paginationValidator,
103 accountsFollowersSortValidator,
104 setDefaultSort,
105 setDefaultPagination,
106 asyncMiddleware(listAccountFollowers)
107 )
108
109 // ---------------------------------------------------------------------------
110
111 export {
112 accountsRouter
113 }
114
115 // ---------------------------------------------------------------------------
116
117 function getAccount (req: express.Request, res: express.Response) {
118 const account = res.locals.account
119
120 if (account.isOutdated()) {
121 JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'actor', url: account.Actor.url } })
122 }
123
124 return res.json(account.toFormattedJSON())
125 }
126
127 async function listAccounts (req: express.Request, res: express.Response) {
128 const resultList = await AccountModel.listForApi(req.query.start, req.query.count, req.query.sort)
129
130 return res.json(getFormattedObjects(resultList.data, resultList.total))
131 }
132
133 async function listAccountChannels (req: express.Request, res: express.Response) {
134 const options = {
135 accountId: res.locals.account.id,
136 start: req.query.start,
137 count: req.query.count,
138 sort: req.query.sort,
139 withStats: req.query.withStats,
140 search: req.query.search
141 }
142
143 const resultList = await VideoChannelModel.listByAccountForAPI(options)
144
145 return res.json(getFormattedObjects(resultList.data, resultList.total))
146 }
147
148 async function listAccountPlaylists (req: express.Request, res: express.Response) {
149 const serverActor = await getServerActor()
150
151 // Allow users to see their private/unlisted video playlists
152 let listMyPlaylists = false
153 if (res.locals.oauth && res.locals.oauth.token.User.Account.id === res.locals.account.id) {
154 listMyPlaylists = true
155 }
156
157 const resultList = await VideoPlaylistModel.listForApi({
158 search: req.query.search,
159 followerActorId: serverActor.id,
160 start: req.query.start,
161 count: req.query.count,
162 sort: req.query.sort,
163 accountId: res.locals.account.id,
164 listMyPlaylists,
165 type: req.query.playlistType
166 })
167
168 return res.json(getFormattedObjects(resultList.data, resultList.total))
169 }
170
171 async function listAccountVideos (req: express.Request, res: express.Response) {
172 const account = res.locals.account
173 const followerActorId = isUserAbleToSearchRemoteURI(res) ? null : undefined
174 const countVideos = getCountVideos(req)
175 const query = pickCommonVideoQuery(req.query)
176
177 const apiOptions = await Hooks.wrapObject({
178 ...query,
179
180 followerActorId,
181 search: req.query.search,
182 includeLocalVideos: true,
183 nsfw: buildNSFWFilter(res, query.nsfw),
184 withFiles: false,
185 accountId: account.id,
186 user: res.locals.oauth ? res.locals.oauth.token.User : undefined,
187 countVideos
188 }, 'filter:api.accounts.videos.list.params')
189
190 const resultList = await Hooks.wrapPromiseFun(
191 VideoModel.listForApi,
192 apiOptions,
193 'filter:api.accounts.videos.list.result'
194 )
195
196 return res.json(getFormattedObjects(resultList.data, resultList.total))
197 }
198
199 async function listAccountRatings (req: express.Request, res: express.Response) {
200 const account = res.locals.account
201
202 const resultList = await AccountVideoRateModel.listByAccountForApi({
203 accountId: account.id,
204 start: req.query.start,
205 count: req.query.count,
206 sort: req.query.sort,
207 type: req.query.rating
208 })
209 return res.json(getFormattedObjects(resultList.rows, resultList.count))
210 }
211
212 async function listAccountFollowers (req: express.Request, res: express.Response) {
213 const account = res.locals.account
214
215 const channels = await VideoChannelModel.listAllByAccount(account.id)
216 const actorIds = [ account.actorId ].concat(channels.map(c => c.actorId))
217
218 const resultList = await ActorFollowModel.listFollowersForApi({
219 actorIds,
220 start: req.query.start,
221 count: req.query.count,
222 sort: req.query.sort,
223 search: req.query.search,
224 state: 'accepted'
225 })
226
227 return res.json(getFormattedObjects(resultList.data, resultList.total))
228 }