]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Add ability to search by URL with query params
authorChocobozzz <me@florianbigard.com>
Wed, 20 Oct 2021 13:01:17 +0000 (15:01 +0200)
committerChocobozzz <me@florianbigard.com>
Wed, 20 Oct 2021 13:26:38 +0000 (15:26 +0200)
server/controllers/api/search/search-video-channels.ts
server/controllers/api/search/search-video-playlists.ts
server/controllers/api/search/search-videos.ts
server/controllers/api/search/shared/index.ts [new file with mode: 0644]
server/controllers/api/search/shared/utils.ts [new file with mode: 0644]
server/helpers/express-utils.ts
server/lib/activitypub/playlists/get.ts
server/tests/api/search/search-activitypub-video-channels.ts
server/tests/api/search/search-activitypub-video-playlists.ts
server/tests/api/search/search-activitypub-videos.ts

index 089feed65bb81a3bd8d964b0e9a082a7d6f9fa9f..c9e81bffad6d12eae553db5685ef48753d26f0e9 100644 (file)
@@ -25,6 +25,7 @@ import {
 } from '../../../middlewares'
 import { VideoChannelModel } from '../../../models/video/video-channel'
 import { MChannelAccountDefault } from '../../../types/models'
+import { searchLocalUrl } from './shared'
 
 const searchChannelsRouter = express.Router()
 
@@ -131,7 +132,7 @@ async function searchVideoChannelURI (search: string, isWebfingerSearch: boolean
       logger.info('Cannot search remote video channel %s.', uri, { err })
     }
   } else {
-    videoChannel = await VideoChannelModel.loadByUrlAndPopulateAccount(sanitizeLocalUrl(uri))
+    videoChannel = await searchLocalUrl(sanitizeLocalUrl(uri), url => VideoChannelModel.loadByUrlAndPopulateAccount(url))
   }
 
   return res.json({
index b28f11c792a694288ac307b03f6b991284068c6e..61a11c74a96a2cb493bec309872ff51ef540a9f0 100644 (file)
@@ -24,6 +24,7 @@ import {
   videoPlaylistsListSearchValidator,
   videoPlaylistsSearchSortValidator
 } from '../../../middlewares'
+import { searchLocalUrl } from './shared'
 
 const searchPlaylistsRouter = express.Router()
 
@@ -109,7 +110,7 @@ async function searchVideoPlaylistsURI (search: string, res: express.Response) {
       logger.info('Cannot search remote video playlist %s.', search, { err })
     }
   } else {
-    videoPlaylist = await VideoPlaylistModel.loadByUrlWithAccountAndChannelSummary(sanitizeLocalUrl(search))
+    videoPlaylist = await searchLocalUrl(sanitizeLocalUrl(search), url => VideoPlaylistModel.loadByUrlWithAccountAndChannelSummary(url))
   }
 
   return res.json({
index eb7ce08414c578b6364bdec184ad565d573c8a6e..90946cb7499c21fc0d6ce6b2503a481867e2efb0 100644 (file)
@@ -25,6 +25,7 @@ import {
 } from '../../../middlewares'
 import { VideoModel } from '../../../models/video/video'
 import { MVideoAccountLightBlacklistAllFiles } from '../../../types/models'
+import { searchLocalUrl } from './shared'
 
 const searchVideosRouter = express.Router()
 
@@ -141,7 +142,7 @@ async function searchVideoURI (url: string, res: express.Response) {
       logger.info('Cannot search remote video %s.', url, { err })
     }
   } else {
-    video = await VideoModel.loadByUrlAndPopulateAccount(sanitizeLocalUrl(url))
+    video = await searchLocalUrl(sanitizeLocalUrl(url), url => VideoModel.loadByUrlAndPopulateAccount(url))
   }
 
   return res.json({
diff --git a/server/controllers/api/search/shared/index.ts b/server/controllers/api/search/shared/index.ts
new file mode 100644 (file)
index 0000000..9c56149
--- /dev/null
@@ -0,0 +1 @@
+export * from './utils'
diff --git a/server/controllers/api/search/shared/utils.ts b/server/controllers/api/search/shared/utils.ts
new file mode 100644 (file)
index 0000000..e02e84f
--- /dev/null
@@ -0,0 +1,16 @@
+async function searchLocalUrl <T> (url: string, finder: (url: string) => Promise<T>) {
+  const data = await finder(url)
+  if (data) return data
+
+  return finder(removeQueryParams(url))
+}
+
+export {
+  searchLocalUrl
+}
+
+// ---------------------------------------------------------------------------
+
+function removeQueryParams (url: string) {
+  return url.split('?').shift()
+}
index 38fe6926baed2708b4cd2192a794893a28028131..7b81ed71b03e091f1be20707322a8bbe326ae461 100644 (file)
@@ -59,7 +59,7 @@ function getHostWithPort (host: string) {
   return host
 }
 
-function badRequest (req: express.Request, res: express.Response) {
+function badRequest (_req: express.Request, res: express.Response) {
   return res.type('json')
             .status(HttpStatusCode.BAD_REQUEST_400)
             .end()
index 2c19c503a2cab73da77fc7ceb234a12dd1f786d9..be8456b19bcad284d494f9d0140901a48380e96d 100644 (file)
@@ -20,7 +20,7 @@ async function getOrCreateAPVideoPlaylist (playlistObjectArg: APObject): Promise
   const { playlistObject } = await fetchRemoteVideoPlaylist(playlistUrl)
   if (!playlistObject) throw new Error('Cannot fetch remote playlist with url: ' + playlistUrl)
 
-  // playlistUrl is just an alias/rediraction, so process object id instead
+  // playlistUrl is just an alias/redirection, so process object id instead
   if (playlistObject.id !== playlistUrl) return getOrCreateAPVideoPlaylist(playlistObject)
 
   const playlistCreated = await createOrUpdateVideoPlaylist(playlistObject)
index 426cbc8e1bec1f61eb4489c2a69d1280b3e344fb..efcdb33dcf7301d5a27821bc07c41e2661e2b42f 100644 (file)
@@ -64,7 +64,7 @@ describe('Test ActivityPub video channels search', function () {
     this.timeout(15000)
 
     {
-      const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server3'
+      const search = servers[1].url + '/video-channels/channel1_server3'
       const body = await command.searchChannels({ search, token: servers[0].accessToken })
 
       expect(body.total).to.equal(0)
@@ -74,7 +74,7 @@ describe('Test ActivityPub video channels search', function () {
 
     {
       // Without token
-      const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2'
+      const search = servers[1].url + '/video-channels/channel1_server2'
       const body = await command.searchChannels({ search })
 
       expect(body.total).to.equal(0)
@@ -85,7 +85,7 @@ describe('Test ActivityPub video channels search', function () {
 
   it('Should search a local video channel', async function () {
     const searches = [
-      'http://localhost:' + servers[0].port + '/video-channels/channel1_server1',
+      servers[0].url + '/video-channels/channel1_server1',
       'channel1_server1@localhost:' + servers[0].port
     ]
 
@@ -101,7 +101,7 @@ describe('Test ActivityPub video channels search', function () {
   })
 
   it('Should search a local video channel with an alternative URL', async function () {
-    const search = 'http://localhost:' + servers[0].port + '/c/channel1_server1'
+    const search = servers[0].url + '/c/channel1_server1'
 
     for (const token of [ undefined, servers[0].accessToken ]) {
       const body = await command.searchChannels({ search, token })
@@ -114,11 +114,30 @@ describe('Test ActivityPub video channels search', function () {
     }
   })
 
+  it('Should search a local video channel with a query in URL', async function () {
+    const searches = [
+      servers[0].url + '/video-channels/channel1_server1',
+      servers[0].url + '/c/channel1_server1'
+    ]
+
+    for (const search of searches) {
+      for (const token of [ undefined, servers[0].accessToken ]) {
+        const body = await command.searchChannels({ search: search + '?param=2', token })
+
+        expect(body.total).to.equal(1)
+        expect(body.data).to.be.an('array')
+        expect(body.data).to.have.lengthOf(1)
+        expect(body.data[0].name).to.equal('channel1_server1')
+        expect(body.data[0].displayName).to.equal('Channel 1 server 1')
+      }
+    }
+  })
+
   it('Should search a remote video channel with URL or handle', async function () {
     const searches = [
-      'http://localhost:' + servers[1].port + '/video-channels/channel1_server2',
-      'http://localhost:' + servers[1].port + '/c/channel1_server2',
-      'http://localhost:' + servers[1].port + '/c/channel1_server2/videos',
+      servers[1].url + '/video-channels/channel1_server2',
+      servers[1].url + '/c/channel1_server2',
+      servers[1].url + '/c/channel1_server2/videos',
       'channel1_server2@localhost:' + servers[1].port
     ]
 
@@ -178,7 +197,7 @@ describe('Test ActivityPub video channels search', function () {
     // Expire video channel
     await wait(10000)
 
-    const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2'
+    const search = servers[1].url + '/video-channels/channel1_server2'
     const body = await command.searchChannels({ search, token: servers[0].accessToken })
     expect(body.total).to.equal(1)
     expect(body.data).to.have.lengthOf(1)
@@ -201,7 +220,7 @@ describe('Test ActivityPub video channels search', function () {
     // Expire video channel
     await wait(10000)
 
-    const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2'
+    const search = servers[1].url + '/video-channels/channel1_server2'
     await command.searchChannels({ search, token: servers[0].accessToken })
 
     await waitJobs(servers)
@@ -223,7 +242,7 @@ describe('Test ActivityPub video channels search', function () {
     // Expire video
     await wait(10000)
 
-    const search = 'http://localhost:' + servers[1].port + '/video-channels/channel1_server2'
+    const search = servers[1].url + '/video-channels/channel1_server2'
     const body = await command.searchChannels({ search, token: servers[0].accessToken })
     expect(body.total).to.equal(0)
     expect(body.data).to.have.lengthOf(0)
index 33ca7be12af1af82cc8197bfb75d04e94daba50c..34b318268124e852b8bcd24b473b2100aa1d2ee2 100644 (file)
@@ -71,7 +71,7 @@ describe('Test ActivityPub playlists search', function () {
 
   it('Should not find a remote playlist', async function () {
     {
-      const search = 'http://localhost:' + servers[1].port + '/video-playlists/43'
+      const search = servers[1].url + '/video-playlists/43'
       const body = await command.searchPlaylists({ search, token: servers[0].accessToken })
 
       expect(body.total).to.equal(0)
@@ -81,7 +81,7 @@ describe('Test ActivityPub playlists search', function () {
 
     {
       // Without token
-      const search = 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID
+      const search = servers[1].url + '/video-playlists/' + playlistServer2UUID
       const body = await command.searchPlaylists({ search })
 
       expect(body.total).to.equal(0)
@@ -91,7 +91,7 @@ describe('Test ActivityPub playlists search', function () {
   })
 
   it('Should search a local playlist', async function () {
-    const search = 'http://localhost:' + servers[0].port + '/video-playlists/' + playlistServer1UUID
+    const search = servers[0].url + '/video-playlists/' + playlistServer1UUID
     const body = await command.searchPlaylists({ search })
 
     expect(body.total).to.equal(1)
@@ -103,8 +103,8 @@ describe('Test ActivityPub playlists search', function () {
 
   it('Should search a local playlist with an alternative URL', async function () {
     const searches = [
-      'http://localhost:' + servers[0].port + '/videos/watch/playlist/' + playlistServer1UUID,
-      'http://localhost:' + servers[0].port + '/w/p/' + playlistServer1UUID
+      servers[0].url + '/videos/watch/playlist/' + playlistServer1UUID,
+      servers[0].url + '/w/p/' + playlistServer1UUID
     ]
 
     for (const search of searches) {
@@ -120,11 +120,30 @@ describe('Test ActivityPub playlists search', function () {
     }
   })
 
+  it('Should search a local playlist with a query in URL', async function () {
+    const searches = [
+      servers[0].url + '/videos/watch/playlist/' + playlistServer1UUID,
+      servers[0].url + '/w/p/' + playlistServer1UUID
+    ]
+
+    for (const search of searches) {
+      for (const token of [ undefined, servers[0].accessToken ]) {
+        const body = await command.searchPlaylists({ search: search + '?param=1', token })
+
+        expect(body.total).to.equal(1)
+        expect(body.data).to.be.an('array')
+        expect(body.data).to.have.lengthOf(1)
+        expect(body.data[0].displayName).to.equal('playlist 1 on server 1')
+        expect(body.data[0].videosLength).to.equal(2)
+      }
+    }
+  })
+
   it('Should search a remote playlist', async function () {
     const searches = [
-      'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID,
-      'http://localhost:' + servers[1].port + '/videos/watch/playlist/' + playlistServer2UUID,
-      'http://localhost:' + servers[1].port + '/w/p/' + playlistServer2UUID
+      servers[1].url + '/video-playlists/' + playlistServer2UUID,
+      servers[1].url + '/videos/watch/playlist/' + playlistServer2UUID,
+      servers[1].url + '/w/p/' + playlistServer2UUID
     ]
 
     for (const search of searches) {
@@ -155,7 +174,7 @@ describe('Test ActivityPub playlists search', function () {
     await wait(10000)
 
     // Will run refresh async
-    const search = 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID
+    const search = servers[1].url + '/video-playlists/' + playlistServer2UUID
     await command.searchPlaylists({ search, token: servers[0].accessToken })
 
     // Wait refresh
@@ -179,7 +198,7 @@ describe('Test ActivityPub playlists search', function () {
     await wait(10000)
 
     // Will run refresh async
-    const search = 'http://localhost:' + servers[1].port + '/video-playlists/' + playlistServer2UUID
+    const search = servers[1].url + '/video-playlists/' + playlistServer2UUID
     await command.searchPlaylists({ search, token: servers[0].accessToken })
 
     // Wait refresh
index b3cfcacca99e796faab0b0c746b0a3a6857a44f2..a2e6e70fea5533e7107c1ab2edef8619a70d122b 100644 (file)
@@ -46,7 +46,7 @@ describe('Test ActivityPub videos search', function () {
 
   it('Should not find a remote video', async function () {
     {
-      const search = 'http://localhost:' + servers[1].port + '/videos/watch/43'
+      const search = servers[1].url + '/videos/watch/43'
       const body = await command.searchVideos({ search, token: servers[0].accessToken })
 
       expect(body.total).to.equal(0)
@@ -56,7 +56,7 @@ describe('Test ActivityPub videos search', function () {
 
     {
       // Without token
-      const search = 'http://localhost:' + servers[1].port + '/videos/watch/' + videoServer2UUID
+      const search = servers[1].url + '/videos/watch/' + videoServer2UUID
       const body = await command.searchVideos({ search })
 
       expect(body.total).to.equal(0)
@@ -66,7 +66,7 @@ describe('Test ActivityPub videos search', function () {
   })
 
   it('Should search a local video', async function () {
-    const search = 'http://localhost:' + servers[0].port + '/videos/watch/' + videoServer1UUID
+    const search = servers[0].url + '/videos/watch/' + videoServer1UUID
     const body = await command.searchVideos({ search })
 
     expect(body.total).to.equal(1)
@@ -76,7 +76,7 @@ describe('Test ActivityPub videos search', function () {
   })
 
   it('Should search a local video with an alternative URL', async function () {
-    const search = 'http://localhost:' + servers[0].port + '/w/' + videoServer1UUID
+    const search = servers[0].url + '/w/' + videoServer1UUID
     const body1 = await command.searchVideos({ search })
     const body2 = await command.searchVideos({ search, token: servers[0].accessToken })
 
@@ -88,10 +88,28 @@ describe('Test ActivityPub videos search', function () {
     }
   })
 
+  it('Should search a local video with a query in URL', async function () {
+    const searches = [
+      servers[0].url + '/w/' + videoServer1UUID,
+      servers[0].url + '/videos/watch/' + videoServer1UUID
+    ]
+
+    for (const search of searches) {
+      for (const token of [ undefined, servers[0].accessToken ]) {
+        const body = await command.searchVideos({ search: search + '?startTime=4', token })
+
+        expect(body.total).to.equal(1)
+        expect(body.data).to.be.an('array')
+        expect(body.data).to.have.lengthOf(1)
+        expect(body.data[0].name).to.equal('video 1 on server 1')
+      }
+    }
+  })
+
   it('Should search a remote video', async function () {
     const searches = [
-      'http://localhost:' + servers[1].port + '/w/' + videoServer2UUID,
-      'http://localhost:' + servers[1].port + '/videos/watch/' + videoServer2UUID
+      servers[1].url + '/w/' + videoServer2UUID,
+      servers[1].url + '/videos/watch/' + videoServer2UUID
     ]
 
     for (const search of searches) {
@@ -134,7 +152,7 @@ describe('Test ActivityPub videos search', function () {
     await wait(10000)
 
     // Will run refresh async
-    const search = 'http://localhost:' + servers[1].port + '/videos/watch/' + videoServer2UUID
+    const search = servers[1].url + '/videos/watch/' + videoServer2UUID
     await command.searchVideos({ search, token: servers[0].accessToken })
 
     // Wait refresh
@@ -160,7 +178,7 @@ describe('Test ActivityPub videos search', function () {
     await wait(10000)
 
     // Will run refresh async
-    const search = 'http://localhost:' + servers[1].port + '/videos/watch/' + videoServer2UUID
+    const search = servers[1].url + '/videos/watch/' + videoServer2UUID
     await command.searchVideos({ search, token: servers[0].accessToken })
 
     // Wait refresh