1
0
Fork 0
mirror of https://github.com/Chocobozzz/PeerTube.git synced 2025-10-05 19:42:24 +02:00

Add ability to search video channels

This commit is contained in:
Chocobozzz 2018-08-23 17:58:39 +02:00
parent 240085d005
commit f37dc0dd14
35 changed files with 670 additions and 145 deletions

View file

@ -1,22 +1,26 @@
import * as express from 'express'
import { buildNSFWFilter } from '../../helpers/express-utils'
import { getFormattedObjects } from '../../helpers/utils'
import { getFormattedObjects, getServerActor } from '../../helpers/utils'
import { VideoModel } from '../../models/video/video'
import {
asyncMiddleware,
commonVideosFiltersValidator,
optionalAuthenticate,
paginationValidator,
searchValidator,
setDefaultPagination,
setDefaultSearchSort,
videosSearchSortValidator
videoChannelsSearchSortValidator,
videoChannelsSearchValidator,
videosSearchSortValidator,
videosSearchValidator
} from '../../middlewares'
import { VideosSearchQuery } from '../../../shared/models/search'
import { getOrCreateVideoAndAccountAndChannel } from '../../lib/activitypub'
import { VideoChannelsSearchQuery, VideosSearchQuery } from '../../../shared/models/search'
import { getOrCreateActorAndServerAndModel, getOrCreateVideoAndAccountAndChannel } from '../../lib/activitypub'
import { logger } from '../../helpers/logger'
import { User } from '../../../shared/models/users'
import { CONFIG } from '../../initializers/constants'
import { VideoChannelModel } from '../../models/video/video-channel'
import { loadActorUrlOrGetFromWebfinger } from '../../helpers/webfinger'
const searchRouter = express.Router()
@ -27,21 +31,80 @@ searchRouter.get('/videos',
setDefaultSearchSort,
optionalAuthenticate,
commonVideosFiltersValidator,
searchValidator,
videosSearchValidator,
asyncMiddleware(searchVideos)
)
searchRouter.get('/video-channels',
paginationValidator,
setDefaultPagination,
videoChannelsSearchSortValidator,
setDefaultSearchSort,
optionalAuthenticate,
commonVideosFiltersValidator,
videoChannelsSearchValidator,
asyncMiddleware(searchVideoChannels)
)
// ---------------------------------------------------------------------------
export { searchRouter }
// ---------------------------------------------------------------------------
function searchVideoChannels (req: express.Request, res: express.Response) {
const query: VideoChannelsSearchQuery = req.query
const search = query.search
const isURISearch = search.startsWith('http://') || search.startsWith('https://')
const parts = search.split('@')
const isHandleSearch = parts.length === 2 && parts.every(p => p.indexOf(' ') === -1)
if (isURISearch || isHandleSearch) return searchVideoChannelURI(search, isHandleSearch, res)
return searchVideoChannelsDB(query, res)
}
async function searchVideoChannelsDB (query: VideoChannelsSearchQuery, res: express.Response) {
const serverActor = await getServerActor()
const options = {
actorId: serverActor.id,
search: query.search,
start: query.start,
count: query.count,
sort: query.sort
}
const resultList = await VideoChannelModel.searchForApi(options)
return res.json(getFormattedObjects(resultList.data, resultList.total))
}
async function searchVideoChannelURI (search: string, isHandleSearch: boolean, res: express.Response) {
let videoChannel: VideoChannelModel
if (isUserAbleToSearchRemoteURI(res)) {
let uri = search
if (isHandleSearch) uri = await loadActorUrlOrGetFromWebfinger(search)
const actor = await getOrCreateActorAndServerAndModel(uri)
videoChannel = actor.VideoChannel
} else {
videoChannel = await VideoChannelModel.loadByUrlAndPopulateAccount(search)
}
return res.json({
total: videoChannel ? 1 : 0,
data: videoChannel ? [ videoChannel.toFormattedJSON() ] : []
})
}
function searchVideos (req: express.Request, res: express.Response) {
const query: VideosSearchQuery = req.query
const search = query.search
if (search && (search.startsWith('http://') || search.startsWith('https://'))) {
return searchVideoUrl(search, res)
return searchVideoURI(search, res)
}
return searchVideosDB(query, res)
@ -57,15 +120,11 @@ async function searchVideosDB (query: VideosSearchQuery, res: express.Response)
return res.json(getFormattedObjects(resultList.data, resultList.total))
}
async function searchVideoUrl (url: string, res: express.Response) {
async function searchVideoURI (url: string, res: express.Response) {
let video: VideoModel
const user: User = res.locals.oauth ? res.locals.oauth.token.User : undefined
// Check if we can fetch a remote video with the URL
if (
CONFIG.SEARCH.REMOTE_URI.ANONYMOUS === true ||
(CONFIG.SEARCH.REMOTE_URI.USERS === true && user !== undefined)
) {
if (isUserAbleToSearchRemoteURI(res)) {
try {
const syncParam = {
likes: false,
@ -76,8 +135,8 @@ async function searchVideoUrl (url: string, res: express.Response) {
refreshVideo: false
}
const res = await getOrCreateVideoAndAccountAndChannel(url, syncParam)
video = res ? res.video : undefined
const result = await getOrCreateVideoAndAccountAndChannel(url, syncParam)
video = result ? result.video : undefined
} catch (err) {
logger.info('Cannot search remote video %s.', url)
}
@ -90,3 +149,10 @@ async function searchVideoUrl (url: string, res: express.Response) {
data: video ? [ video.toFormattedJSON() ] : []
})
}
function isUserAbleToSearchRemoteURI (res: express.Response) {
const user: User = res.locals.oauth ? res.locals.oauth.token.User : undefined
return CONFIG.SEARCH.REMOTE_URI.ANONYMOUS === true ||
(CONFIG.SEARCH.REMOTE_URI.USERS === true && user !== undefined)
}

View file

@ -20,7 +20,8 @@ import {
deleteMeValidator,
userSubscriptionsSortValidator,
videoImportsSortValidator,
videosSortValidator
videosSortValidator,
areSubscriptionsExistValidator
} from '../../../middlewares/validators'
import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
import { UserModel } from '../../../models/account/user'
@ -98,7 +99,6 @@ meRouter.post('/me/avatar/pick',
// ##### Subscriptions part #####
meRouter.get('/me/subscriptions/videos',
authenticate,
authenticate,
paginationValidator,
videosSortValidator,
@ -108,6 +108,12 @@ meRouter.get('/me/subscriptions/videos',
asyncMiddleware(getUserSubscriptionVideos)
)
meRouter.get('/me/subscriptions/exist',
authenticate,
areSubscriptionsExistValidator,
asyncMiddleware(areSubscriptionsExist)
)
meRouter.get('/me/subscriptions',
authenticate,
paginationValidator,
@ -143,6 +149,37 @@ export {
// ---------------------------------------------------------------------------
async function areSubscriptionsExist (req: express.Request, res: express.Response) {
const uris = req.query.uris as string[]
const user = res.locals.oauth.token.User as UserModel
const handles = uris.map(u => {
let [ name, host ] = u.split('@')
if (host === CONFIG.WEBSERVER.HOST) host = null
return { name, host, uri: u }
})
const results = await ActorFollowModel.listSubscribedIn(user.Account.Actor.id, handles)
const existObject: { [id: string ]: boolean } = {}
for (const handle of handles) {
const obj = results.find(r => {
const server = r.ActorFollowing.Server
return r.ActorFollowing.preferredUsername === handle.name &&
(
(!server && !handle.host) ||
(server.host === handle.host)
)
})
existObject[handle.uri] = obj !== undefined
}
return res.json(existObject)
}
async function addUserSubscription (req: express.Request, res: express.Response) {
const user = res.locals.oauth.token.User as UserModel
const [ name, host ] = req.body.uri.split('@')

View file

@ -1,5 +1,5 @@
import * as express from 'express'
import { getFormattedObjects } from '../../helpers/utils'
import { getFormattedObjects, getServerActor } from '../../helpers/utils'
import {
asyncMiddleware,
asyncRetryTransactionMiddleware,
@ -95,7 +95,8 @@ export {
// ---------------------------------------------------------------------------
async function listVideoChannels (req: express.Request, res: express.Response, next: express.NextFunction) {
const resultList = await VideoChannelModel.listForApi(req.query.start, req.query.count, req.query.sort)
const serverActor = await getServerActor()
const resultList = await VideoChannelModel.listForApi(serverActor.id, req.query.start, req.query.count, req.query.sort)
return res.json(getFormattedObjects(resultList.data, resultList.total))
}