aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-08-23 17:58:39 +0200
committerChocobozzz <me@florianbigard.com>2018-08-27 09:41:54 +0200
commitf37dc0dd14d9ce0b59c454c2c1b935fcbe9727e9 (patch)
tree2050443febcdb2a3eec68b7bbf9687e26dcb24dc /server/controllers
parent240085d0056fd97ac3c7fa8fa4ce9bc32afc4d6e (diff)
downloadPeerTube-f37dc0dd14d9ce0b59c454c2c1b935fcbe9727e9.tar.gz
PeerTube-f37dc0dd14d9ce0b59c454c2c1b935fcbe9727e9.tar.zst
PeerTube-f37dc0dd14d9ce0b59c454c2c1b935fcbe9727e9.zip
Add ability to search video channels
Diffstat (limited to 'server/controllers')
-rw-r--r--server/controllers/api/search.ts96
-rw-r--r--server/controllers/api/users/me.ts41
-rw-r--r--server/controllers/api/video-channel.ts5
3 files changed, 123 insertions, 19 deletions
diff --git a/server/controllers/api/search.ts b/server/controllers/api/search.ts
index f408e7932..87aa5d76f 100644
--- a/server/controllers/api/search.ts
+++ b/server/controllers/api/search.ts
@@ -1,22 +1,26 @@
1import * as express from 'express' 1import * as express from 'express'
2import { buildNSFWFilter } from '../../helpers/express-utils' 2import { buildNSFWFilter } from '../../helpers/express-utils'
3import { getFormattedObjects } from '../../helpers/utils' 3import { getFormattedObjects, getServerActor } from '../../helpers/utils'
4import { VideoModel } from '../../models/video/video' 4import { VideoModel } from '../../models/video/video'
5import { 5import {
6 asyncMiddleware, 6 asyncMiddleware,
7 commonVideosFiltersValidator, 7 commonVideosFiltersValidator,
8 optionalAuthenticate, 8 optionalAuthenticate,
9 paginationValidator, 9 paginationValidator,
10 searchValidator,
11 setDefaultPagination, 10 setDefaultPagination,
12 setDefaultSearchSort, 11 setDefaultSearchSort,
13 videosSearchSortValidator 12 videoChannelsSearchSortValidator,
13 videoChannelsSearchValidator,
14 videosSearchSortValidator,
15 videosSearchValidator
14} from '../../middlewares' 16} from '../../middlewares'
15import { VideosSearchQuery } from '../../../shared/models/search' 17import { VideoChannelsSearchQuery, VideosSearchQuery } from '../../../shared/models/search'
16import { getOrCreateVideoAndAccountAndChannel } from '../../lib/activitypub' 18import { getOrCreateActorAndServerAndModel, getOrCreateVideoAndAccountAndChannel } from '../../lib/activitypub'
17import { logger } from '../../helpers/logger' 19import { logger } from '../../helpers/logger'
18import { User } from '../../../shared/models/users' 20import { User } from '../../../shared/models/users'
19import { CONFIG } from '../../initializers/constants' 21import { CONFIG } from '../../initializers/constants'
22import { VideoChannelModel } from '../../models/video/video-channel'
23import { loadActorUrlOrGetFromWebfinger } from '../../helpers/webfinger'
20 24
21const searchRouter = express.Router() 25const searchRouter = express.Router()
22 26
@@ -27,21 +31,80 @@ searchRouter.get('/videos',
27 setDefaultSearchSort, 31 setDefaultSearchSort,
28 optionalAuthenticate, 32 optionalAuthenticate,
29 commonVideosFiltersValidator, 33 commonVideosFiltersValidator,
30 searchValidator, 34 videosSearchValidator,
31 asyncMiddleware(searchVideos) 35 asyncMiddleware(searchVideos)
32) 36)
33 37
38searchRouter.get('/video-channels',
39 paginationValidator,
40 setDefaultPagination,
41 videoChannelsSearchSortValidator,
42 setDefaultSearchSort,
43 optionalAuthenticate,
44 commonVideosFiltersValidator,
45 videoChannelsSearchValidator,
46 asyncMiddleware(searchVideoChannels)
47)
48
34// --------------------------------------------------------------------------- 49// ---------------------------------------------------------------------------
35 50
36export { searchRouter } 51export { searchRouter }
37 52
38// --------------------------------------------------------------------------- 53// ---------------------------------------------------------------------------
39 54
55function searchVideoChannels (req: express.Request, res: express.Response) {
56 const query: VideoChannelsSearchQuery = req.query
57 const search = query.search
58
59 const isURISearch = search.startsWith('http://') || search.startsWith('https://')
60
61 const parts = search.split('@')
62 const isHandleSearch = parts.length === 2 && parts.every(p => p.indexOf(' ') === -1)
63
64 if (isURISearch || isHandleSearch) return searchVideoChannelURI(search, isHandleSearch, res)
65
66 return searchVideoChannelsDB(query, res)
67}
68
69async function searchVideoChannelsDB (query: VideoChannelsSearchQuery, res: express.Response) {
70 const serverActor = await getServerActor()
71
72 const options = {
73 actorId: serverActor.id,
74 search: query.search,
75 start: query.start,
76 count: query.count,
77 sort: query.sort
78 }
79 const resultList = await VideoChannelModel.searchForApi(options)
80
81 return res.json(getFormattedObjects(resultList.data, resultList.total))
82}
83
84async function searchVideoChannelURI (search: string, isHandleSearch: boolean, res: express.Response) {
85 let videoChannel: VideoChannelModel
86
87 if (isUserAbleToSearchRemoteURI(res)) {
88 let uri = search
89 if (isHandleSearch) uri = await loadActorUrlOrGetFromWebfinger(search)
90
91 const actor = await getOrCreateActorAndServerAndModel(uri)
92 videoChannel = actor.VideoChannel
93 } else {
94 videoChannel = await VideoChannelModel.loadByUrlAndPopulateAccount(search)
95 }
96
97 return res.json({
98 total: videoChannel ? 1 : 0,
99 data: videoChannel ? [ videoChannel.toFormattedJSON() ] : []
100 })
101}
102
40function searchVideos (req: express.Request, res: express.Response) { 103function searchVideos (req: express.Request, res: express.Response) {
41 const query: VideosSearchQuery = req.query 104 const query: VideosSearchQuery = req.query
42 const search = query.search 105 const search = query.search
43 if (search && (search.startsWith('http://') || search.startsWith('https://'))) { 106 if (search && (search.startsWith('http://') || search.startsWith('https://'))) {
44 return searchVideoUrl(search, res) 107 return searchVideoURI(search, res)
45 } 108 }
46 109
47 return searchVideosDB(query, res) 110 return searchVideosDB(query, res)
@@ -57,15 +120,11 @@ async function searchVideosDB (query: VideosSearchQuery, res: express.Response)
57 return res.json(getFormattedObjects(resultList.data, resultList.total)) 120 return res.json(getFormattedObjects(resultList.data, resultList.total))
58} 121}
59 122
60async function searchVideoUrl (url: string, res: express.Response) { 123async function searchVideoURI (url: string, res: express.Response) {
61 let video: VideoModel 124 let video: VideoModel
62 const user: User = res.locals.oauth ? res.locals.oauth.token.User : undefined
63 125
64 // Check if we can fetch a remote video with the URL 126 // Check if we can fetch a remote video with the URL
65 if ( 127 if (isUserAbleToSearchRemoteURI(res)) {
66 CONFIG.SEARCH.REMOTE_URI.ANONYMOUS === true ||
67 (CONFIG.SEARCH.REMOTE_URI.USERS === true && user !== undefined)
68 ) {
69 try { 128 try {
70 const syncParam = { 129 const syncParam = {
71 likes: false, 130 likes: false,
@@ -76,8 +135,8 @@ async function searchVideoUrl (url: string, res: express.Response) {
76 refreshVideo: false 135 refreshVideo: false
77 } 136 }
78 137
79 const res = await getOrCreateVideoAndAccountAndChannel(url, syncParam) 138 const result = await getOrCreateVideoAndAccountAndChannel(url, syncParam)
80 video = res ? res.video : undefined 139 video = result ? result.video : undefined
81 } catch (err) { 140 } catch (err) {
82 logger.info('Cannot search remote video %s.', url) 141 logger.info('Cannot search remote video %s.', url)
83 } 142 }
@@ -90,3 +149,10 @@ async function searchVideoUrl (url: string, res: express.Response) {
90 data: video ? [ video.toFormattedJSON() ] : [] 149 data: video ? [ video.toFormattedJSON() ] : []
91 }) 150 })
92} 151}
152
153function isUserAbleToSearchRemoteURI (res: express.Response) {
154 const user: User = res.locals.oauth ? res.locals.oauth.token.User : undefined
155
156 return CONFIG.SEARCH.REMOTE_URI.ANONYMOUS === true ||
157 (CONFIG.SEARCH.REMOTE_URI.USERS === true && user !== undefined)
158}
diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts
index 2300f5dbe..000c706b5 100644
--- a/server/controllers/api/users/me.ts
+++ b/server/controllers/api/users/me.ts
@@ -20,7 +20,8 @@ import {
20 deleteMeValidator, 20 deleteMeValidator,
21 userSubscriptionsSortValidator, 21 userSubscriptionsSortValidator,
22 videoImportsSortValidator, 22 videoImportsSortValidator,
23 videosSortValidator 23 videosSortValidator,
24 areSubscriptionsExistValidator
24} from '../../../middlewares/validators' 25} from '../../../middlewares/validators'
25import { AccountVideoRateModel } from '../../../models/account/account-video-rate' 26import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
26import { UserModel } from '../../../models/account/user' 27import { UserModel } from '../../../models/account/user'
@@ -99,7 +100,6 @@ meRouter.post('/me/avatar/pick',
99 100
100meRouter.get('/me/subscriptions/videos', 101meRouter.get('/me/subscriptions/videos',
101 authenticate, 102 authenticate,
102 authenticate,
103 paginationValidator, 103 paginationValidator,
104 videosSortValidator, 104 videosSortValidator,
105 setDefaultSort, 105 setDefaultSort,
@@ -108,6 +108,12 @@ meRouter.get('/me/subscriptions/videos',
108 asyncMiddleware(getUserSubscriptionVideos) 108 asyncMiddleware(getUserSubscriptionVideos)
109) 109)
110 110
111meRouter.get('/me/subscriptions/exist',
112 authenticate,
113 areSubscriptionsExistValidator,
114 asyncMiddleware(areSubscriptionsExist)
115)
116
111meRouter.get('/me/subscriptions', 117meRouter.get('/me/subscriptions',
112 authenticate, 118 authenticate,
113 paginationValidator, 119 paginationValidator,
@@ -143,6 +149,37 @@ export {
143 149
144// --------------------------------------------------------------------------- 150// ---------------------------------------------------------------------------
145 151
152async function areSubscriptionsExist (req: express.Request, res: express.Response) {
153 const uris = req.query.uris as string[]
154 const user = res.locals.oauth.token.User as UserModel
155
156 const handles = uris.map(u => {
157 let [ name, host ] = u.split('@')
158 if (host === CONFIG.WEBSERVER.HOST) host = null
159
160 return { name, host, uri: u }
161 })
162
163 const results = await ActorFollowModel.listSubscribedIn(user.Account.Actor.id, handles)
164
165 const existObject: { [id: string ]: boolean } = {}
166 for (const handle of handles) {
167 const obj = results.find(r => {
168 const server = r.ActorFollowing.Server
169
170 return r.ActorFollowing.preferredUsername === handle.name &&
171 (
172 (!server && !handle.host) ||
173 (server.host === handle.host)
174 )
175 })
176
177 existObject[handle.uri] = obj !== undefined
178 }
179
180 return res.json(existObject)
181}
182
146async function addUserSubscription (req: express.Request, res: express.Response) { 183async function addUserSubscription (req: express.Request, res: express.Response) {
147 const user = res.locals.oauth.token.User as UserModel 184 const user = res.locals.oauth.token.User as UserModel
148 const [ name, host ] = req.body.uri.split('@') 185 const [ name, host ] = req.body.uri.split('@')
diff --git a/server/controllers/api/video-channel.ts b/server/controllers/api/video-channel.ts
index 3f51f03f4..bd08d7a08 100644
--- a/server/controllers/api/video-channel.ts
+++ b/server/controllers/api/video-channel.ts
@@ -1,5 +1,5 @@
1import * as express from 'express' 1import * as express from 'express'
2import { getFormattedObjects } from '../../helpers/utils' 2import { getFormattedObjects, getServerActor } from '../../helpers/utils'
3import { 3import {
4 asyncMiddleware, 4 asyncMiddleware,
5 asyncRetryTransactionMiddleware, 5 asyncRetryTransactionMiddleware,
@@ -95,7 +95,8 @@ export {
95// --------------------------------------------------------------------------- 95// ---------------------------------------------------------------------------
96 96
97async function listVideoChannels (req: express.Request, res: express.Response, next: express.NextFunction) { 97async function listVideoChannels (req: express.Request, res: express.Response, next: express.NextFunction) {
98 const resultList = await VideoChannelModel.listForApi(req.query.start, req.query.count, req.query.sort) 98 const serverActor = await getServerActor()
99 const resultList = await VideoChannelModel.listForApi(serverActor.id, req.query.start, req.query.count, req.query.sort)
99 100
100 return res.json(getFormattedObjects(resultList.data, resultList.total)) 101 return res.json(getFormattedObjects(resultList.data, resultList.total))
101} 102}