+
+ def _get_comments(self, vid):
+ for page in itertools.count(1):
+ comments_json = self._call_api(vid, data={
+ 'operationName': 'public_CommentProxyService_GetCommentList',
+ 'variables': {
+ 'params': {
+ 'appInfo': {
+ 'postID': vid,
+ },
+ 'preview': {},
+ 'pageSize': 99,
+ 'page': page,
+ },
+ },
+ 'extensions': {
+ 'singleReq': 'true',
+ },
+ })
+ for comment in comments_json['commentList']:
+ content = comment.get('content')
+ if not content:
+ continue
+ author = comment.get('author') or {}
+ parent = comment.get('parentID')
+ yield {
+ 'author': author.get('nickName'),
+ 'author_id': str_or_none(author.get('uid')),
+ 'id': str_or_none(comment.get('commentID')),
+ 'text': content,
+ 'timestamp': int_or_none(comment.get('createdAt')),
+ 'parent': 'root' if parent == 0 else str_or_none(parent),
+ }
+
+ if comments_json['lastPage']:
+ break
+
+
+class TrovoChannelBaseIE(TrovoBaseIE):
+ def _entries(self, spacename):
+ for page in itertools.count(1):
+ vod_json = self._call_api(spacename, data={
+ 'operationName': self._OPERATION,
+ 'variables': {
+ 'params': {
+ 'terminalSpaceID': {
+ 'spaceName': spacename,
+ },
+ 'currPage': page,
+ 'pageSize': 99,
+ },
+ },
+ 'extensions': {
+ 'singleReq': 'true',
+ },
+ })
+ vods = vod_json.get('vodInfos', [])
+ for vod in vods:
+ vid = vod.get('vid')
+ room = traverse_obj(vod, ('spaceInfo', 'roomID'))
+ yield self.url_result(
+ f'https://trovo.live/s/{spacename}/{room}?vid={vid}',
+ ie=TrovoVodIE.ie_key())
+ has_more = vod_json.get('hasMore')
+ if not has_more:
+ break
+
+ def _real_extract(self, url):
+ spacename = self._match_id(url)
+ return self.playlist_result(self._entries(spacename), playlist_id=spacename)
+
+
+class TrovoChannelVodIE(TrovoChannelBaseIE):
+ _VALID_URL = r'trovovod:(?P<id>[^\s]+)'
+ IE_DESC = 'All VODs of a trovo.live channel; "trovovod:" prefix'
+
+ _TESTS = [{
+ 'url': 'trovovod:OneTappedYou',
+ 'playlist_mincount': 24,
+ 'info_dict': {
+ 'id': 'OneTappedYou',
+ },
+ }]
+
+ _OPERATION = 'vod_VodReaderService_GetChannelLtvVideoInfos'
+
+
+class TrovoChannelClipIE(TrovoChannelBaseIE):
+ _VALID_URL = r'trovoclip:(?P<id>[^\s]+)'
+ IE_DESC = 'All Clips of a trovo.live channel; "trovoclip:" prefix'
+
+ _TESTS = [{
+ 'url': 'trovoclip:OneTappedYou',
+ 'playlist_mincount': 29,
+ 'info_dict': {
+ 'id': 'OneTappedYou',
+ },
+ }]
+
+ _OPERATION = 'vod_VodReaderService_GetChannelClipVideoInfos'