aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-07-09 14:15:11 +0200
committerChocobozzz <me@florianbigard.com>2021-07-20 15:27:18 +0200
commit12edc1495a36b2199f1bf1ba37f50c7b694be382 (patch)
tree3abfe2e5b54076de73fbfa25386d0313fc3b7242 /shared
parenta54618880c394ad7571f3f3222dc96ec2dd10d9a (diff)
downloadPeerTube-12edc1495a36b2199f1bf1ba37f50c7b694be382.tar.gz
PeerTube-12edc1495a36b2199f1bf1ba37f50c7b694be382.tar.zst
PeerTube-12edc1495a36b2199f1bf1ba37f50c7b694be382.zip
Introduce comments command
Diffstat (limited to 'shared')
-rw-r--r--shared/extra-utils/server/servers.ts3
-rw-r--r--shared/extra-utils/videos/comments-command.ts132
-rw-r--r--shared/extra-utils/videos/index.ts3
-rw-r--r--shared/extra-utils/videos/streaming-playlists-command.ts2
-rw-r--r--shared/extra-utils/videos/video-comments.ts138
-rw-r--r--shared/models/videos/comment/index.ts1
-rw-r--r--shared/models/videos/comment/video-comment-create.model.ts3
-rw-r--r--shared/models/videos/comment/video-comment.model.ts7
8 files changed, 145 insertions, 144 deletions
diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts
index 68e10af5f..8e80a9842 100644
--- a/shared/extra-utils/server/servers.ts
+++ b/shared/extra-utils/server/servers.ts
@@ -30,6 +30,7 @@ import {
30 ServicesCommand, 30 ServicesCommand,
31 StreamingPlaylistsCommand 31 StreamingPlaylistsCommand
32} from '../videos' 32} from '../videos'
33import { CommentsCommand } from '../videos/comments-command'
33import { ConfigCommand } from './config-command' 34import { ConfigCommand } from './config-command'
34import { ContactFormCommand } from './contact-form-command' 35import { ContactFormCommand } from './contact-form-command'
35import { DebugCommand } from './debug-command' 36import { DebugCommand } from './debug-command'
@@ -121,6 +122,7 @@ interface ServerInfo {
121 importsCommand?: ImportsCommand 122 importsCommand?: ImportsCommand
122 streamingPlaylistsCommand?: StreamingPlaylistsCommand 123 streamingPlaylistsCommand?: StreamingPlaylistsCommand
123 channelsCommand?: ChannelsCommand 124 channelsCommand?: ChannelsCommand
125 commentsCommand?: CommentsCommand
124} 126}
125 127
126function parallelTests () { 128function parallelTests () {
@@ -356,6 +358,7 @@ async function runServer (server: ServerInfo, configOverrideArg?: any, args = []
356 server.importsCommand = new ImportsCommand(server) 358 server.importsCommand = new ImportsCommand(server)
357 server.streamingPlaylistsCommand = new StreamingPlaylistsCommand(server) 359 server.streamingPlaylistsCommand = new StreamingPlaylistsCommand(server)
358 server.channelsCommand = new ChannelsCommand(server) 360 server.channelsCommand = new ChannelsCommand(server)
361 server.commentsCommand = new CommentsCommand(server)
359 362
360 res(server) 363 res(server)
361 }) 364 })
diff --git a/shared/extra-utils/videos/comments-command.ts b/shared/extra-utils/videos/comments-command.ts
new file mode 100644
index 000000000..b31f3e2dd
--- /dev/null
+++ b/shared/extra-utils/videos/comments-command.ts
@@ -0,0 +1,132 @@
1import { pick } from 'lodash'
2import { ResultList, VideoComment, VideoCommentThreads, VideoCommentThreadTree } from '@shared/models'
3import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes'
4import { unwrapBody } from '../requests'
5import { AbstractCommand, OverrideCommandOptions } from '../shared'
6
7export class CommentsCommand extends AbstractCommand {
8
9 listForAdmin (options: OverrideCommandOptions & {
10 start?: number
11 count?: number
12 sort?: string
13 isLocal?: boolean
14 search?: string
15 searchAccount?: string
16 searchVideo?: string
17 } = {}) {
18 const { sort = '-createdAt' } = options
19 const path = '/api/v1/videos/comments'
20
21 const query = { sort, ...pick(options, [ 'start', 'count', 'isLocal', 'search', 'searchAccount', 'searchVideo' ]) }
22
23 return this.getRequestBody<ResultList<VideoComment>>({
24 ...options,
25
26 path,
27 query,
28 implicitToken: true,
29 defaultExpectedStatus: HttpStatusCode.OK_200
30 })
31 }
32
33 listThreads (options: OverrideCommandOptions & {
34 videoId: number | string
35 start?: number
36 count?: number
37 sort?: string
38 }) {
39 const { start, count, sort, videoId } = options
40 const path = '/api/v1/videos/' + videoId + '/comment-threads'
41
42 return this.getRequestBody<VideoCommentThreads>({
43 ...options,
44
45 path,
46 query: { start, count, sort },
47 implicitToken: false,
48 defaultExpectedStatus: HttpStatusCode.OK_200
49 })
50 }
51
52 getThread (options: OverrideCommandOptions & {
53 videoId: number | string
54 threadId: number
55 }) {
56 const { videoId, threadId } = options
57 const path = '/api/v1/videos/' + videoId + '/comment-threads/' + threadId
58
59 return this.getRequestBody<VideoCommentThreadTree>({
60 ...options,
61
62 path,
63 implicitToken: false,
64 defaultExpectedStatus: HttpStatusCode.OK_200
65 })
66 }
67
68 async createThread (options: OverrideCommandOptions & {
69 videoId: number | string
70 text: string
71 }) {
72 const { videoId, text } = options
73 const path = '/api/v1/videos/' + videoId + '/comment-threads'
74
75 const body = await unwrapBody<{ comment: VideoComment }>(this.postBodyRequest({
76 ...options,
77
78 path,
79 fields: { text },
80 implicitToken: true,
81 defaultExpectedStatus: HttpStatusCode.OK_200
82 }))
83
84 return body.comment
85 }
86
87 async addReply (options: OverrideCommandOptions & {
88 videoId: number | string
89 toCommentId: number
90 text: string
91 }) {
92 const { videoId, toCommentId, text } = options
93 const path = '/api/v1/videos/' + videoId + '/comments/' + toCommentId
94
95 const body = await unwrapBody<{ comment: VideoComment }>(this.postBodyRequest({
96 ...options,
97
98 path,
99 fields: { text },
100 implicitToken: true,
101 defaultExpectedStatus: HttpStatusCode.OK_200
102 }))
103
104 return body.comment
105 }
106
107 async findCommentId (options: OverrideCommandOptions & {
108 videoId: number | string
109 text: string
110 }) {
111 const { videoId, text } = options
112 const { data } = await this.listThreads({ videoId, count: 25, sort: '-createdAt' })
113
114 return data.find(c => c.text === text).id
115 }
116
117 delete (options: OverrideCommandOptions & {
118 videoId: number | string
119 commentId: number
120 }) {
121 const { videoId, commentId } = options
122 const path = '/api/v1/videos/' + videoId + '/comments/' + commentId
123
124 return this.deleteRequest({
125 ...options,
126
127 path,
128 implicitToken: true,
129 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
130 })
131 }
132}
diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts
index 3bc219281..652d82842 100644
--- a/shared/extra-utils/videos/index.ts
+++ b/shared/extra-utils/videos/index.ts
@@ -4,6 +4,7 @@ export * from './captions'
4export * from './change-ownership-command' 4export * from './change-ownership-command'
5export * from './channels' 5export * from './channels'
6export * from './channels-command' 6export * from './channels-command'
7export * from './comments-command'
7export * from './history-command' 8export * from './history-command'
8export * from './imports-command' 9export * from './imports-command'
9export * from './live-command' 10export * from './live-command'
@@ -13,5 +14,5 @@ export * from './playlists'
13export * from './services-command' 14export * from './services-command'
14export * from './streaming-playlists-command' 15export * from './streaming-playlists-command'
15export * from './streaming-playlists' 16export * from './streaming-playlists'
16export * from './video-comments' 17export * from './comments-command'
17export * from './videos' 18export * from './videos'
diff --git a/shared/extra-utils/videos/streaming-playlists-command.ts b/shared/extra-utils/videos/streaming-playlists-command.ts
index 4caec7137..b109597c9 100644
--- a/shared/extra-utils/videos/streaming-playlists-command.ts
+++ b/shared/extra-utils/videos/streaming-playlists-command.ts
@@ -27,7 +27,7 @@ export class StreamingPlaylistsCommand extends AbstractCommand {
27 url: options.url, 27 url: options.url,
28 range: options.range, 28 range: options.range,
29 implicitToken: false, 29 implicitToken: false,
30 defaultExpectedStatus: HttpStatusCode.OK_200, 30 defaultExpectedStatus: HttpStatusCode.OK_200
31 })) 31 }))
32 } 32 }
33 33
diff --git a/shared/extra-utils/videos/video-comments.ts b/shared/extra-utils/videos/video-comments.ts
deleted file mode 100644
index 71b9f875a..000000000
--- a/shared/extra-utils/videos/video-comments.ts
+++ /dev/null
@@ -1,138 +0,0 @@
1/* eslint-disable @typescript-eslint/no-floating-promises */
2
3import * as request from 'supertest'
4import { makeDeleteRequest, makeGetRequest } from '../requests/requests'
5import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
6
7function getAdminVideoComments (options: {
8 url: string
9 token: string
10 start: number
11 count: number
12 sort?: string
13 isLocal?: boolean
14 search?: string
15 searchAccount?: string
16 searchVideo?: string
17}) {
18 const { url, token, start, count, sort, isLocal, search, searchAccount, searchVideo } = options
19 const path = '/api/v1/videos/comments'
20
21 const query = {
22 start,
23 count,
24 sort: sort || '-createdAt'
25 }
26
27 if (isLocal !== undefined) Object.assign(query, { isLocal })
28 if (search !== undefined) Object.assign(query, { search })
29 if (searchAccount !== undefined) Object.assign(query, { searchAccount })
30 if (searchVideo !== undefined) Object.assign(query, { searchVideo })
31
32 return makeGetRequest({
33 url,
34 path,
35 token,
36 query,
37 statusCodeExpected: HttpStatusCode.OK_200
38 })
39}
40
41function getVideoCommentThreads (url: string, videoId: number | string, start: number, count: number, sort?: string, token?: string) {
42 const path = '/api/v1/videos/' + videoId + '/comment-threads'
43
44 const req = request(url)
45 .get(path)
46 .query({ start: start })
47 .query({ count: count })
48
49 if (sort) req.query({ sort })
50 if (token) req.set('Authorization', 'Bearer ' + token)
51
52 return req.set('Accept', 'application/json')
53 .expect(HttpStatusCode.OK_200)
54 .expect('Content-Type', /json/)
55}
56
57function getVideoThreadComments (url: string, videoId: number | string, threadId: number, token?: string) {
58 const path = '/api/v1/videos/' + videoId + '/comment-threads/' + threadId
59
60 const req = request(url)
61 .get(path)
62 .set('Accept', 'application/json')
63
64 if (token) req.set('Authorization', 'Bearer ' + token)
65
66 return req.expect(HttpStatusCode.OK_200)
67 .expect('Content-Type', /json/)
68}
69
70function addVideoCommentThread (
71 url: string,
72 token: string,
73 videoId: number | string,
74 text: string,
75 expectedStatus = HttpStatusCode.OK_200
76) {
77 const path = '/api/v1/videos/' + videoId + '/comment-threads'
78
79 return request(url)
80 .post(path)
81 .send({ text })
82 .set('Accept', 'application/json')
83 .set('Authorization', 'Bearer ' + token)
84 .expect(expectedStatus)
85}
86
87function addVideoCommentReply (
88 url: string,
89 token: string,
90 videoId: number | string,
91 inReplyToCommentId: number,
92 text: string,
93 expectedStatus = HttpStatusCode.OK_200
94) {
95 const path = '/api/v1/videos/' + videoId + '/comments/' + inReplyToCommentId
96
97 return request(url)
98 .post(path)
99 .send({ text })
100 .set('Accept', 'application/json')
101 .set('Authorization', 'Bearer ' + token)
102 .expect(expectedStatus)
103}
104
105async function findCommentId (url: string, videoId: number | string, text: string) {
106 const res = await getVideoCommentThreads(url, videoId, 0, 25, '-createdAt')
107
108 return res.body.data.find(c => c.text === text).id as number
109}
110
111function deleteVideoComment (
112 url: string,
113 token: string,
114 videoId: number | string,
115 commentId: number,
116 statusCodeExpected = HttpStatusCode.NO_CONTENT_204
117) {
118 const path = '/api/v1/videos/' + videoId + '/comments/' + commentId
119
120 return makeDeleteRequest({
121 url,
122 path,
123 token,
124 statusCodeExpected
125 })
126}
127
128// ---------------------------------------------------------------------------
129
130export {
131 getVideoCommentThreads,
132 getAdminVideoComments,
133 getVideoThreadComments,
134 addVideoCommentThread,
135 addVideoCommentReply,
136 findCommentId,
137 deleteVideoComment
138}
diff --git a/shared/models/videos/comment/index.ts b/shared/models/videos/comment/index.ts
index 7b9261a36..80c6c0724 100644
--- a/shared/models/videos/comment/index.ts
+++ b/shared/models/videos/comment/index.ts
@@ -1 +1,2 @@
1export * from './video-comment-create.model'
1export * from './video-comment.model' 2export * from './video-comment.model'
diff --git a/shared/models/videos/comment/video-comment-create.model.ts b/shared/models/videos/comment/video-comment-create.model.ts
new file mode 100644
index 000000000..1f0135405
--- /dev/null
+++ b/shared/models/videos/comment/video-comment-create.model.ts
@@ -0,0 +1,3 @@
1export interface VideoCommentCreate {
2 text: string
3}
diff --git a/shared/models/videos/comment/video-comment.model.ts b/shared/models/videos/comment/video-comment.model.ts
index 79c0e4c0a..5a96f9d4a 100644
--- a/shared/models/videos/comment/video-comment.model.ts
+++ b/shared/models/videos/comment/video-comment.model.ts
@@ -1,3 +1,4 @@
1import { ResultList } from '@shared/models/common'
1import { Account } from '../../actors' 2import { Account } from '../../actors'
2 3
3export interface VideoComment { 4export interface VideoComment {
@@ -36,11 +37,9 @@ export interface VideoCommentAdmin {
36 } 37 }
37} 38}
38 39
40export type VideoCommentThreads = ResultList<VideoComment> & { totalNotDeletedComments: number }
41
39export interface VideoCommentThreadTree { 42export interface VideoCommentThreadTree {
40 comment: VideoComment 43 comment: VideoComment
41 children: VideoCommentThreadTree[] 44 children: VideoCommentThreadTree[]
42} 45}
43
44export interface VideoCommentCreate {
45 text: string
46}