diff --git a/lib/comments.py b/lib/comments.py new file mode 100644 index 0000000..134a909 --- /dev/null +++ b/lib/comments.py @@ -0,0 +1,99 @@ +import xbmc +import xbmcgui + +import requests + +from lib.general import * +from lib.rumble_user import RumbleUser + +RUMBLE_USER = RumbleUser() + +class CommentWindow(xbmcgui.WindowXML): + + def __init__(self, *args, **kwargs): + self.video_id = kwargs['video_id'] + xbmcgui.WindowXML.__init__(self, args, kwargs) + + def onInit(self): + self.refresh() + + def fetch_comment_list(self): + + """ fetches comment list from rumble """ + + return RUMBLE_USER.get_comments( self.video_id ) + + def refresh(self): + + """ Refreshes comment list """ + + ccl = self.get_comment_control_list() + + results = self.fetch_comment_list() + + if results: + for comment_author_url, comment_author_name, comment_id, \ + comment_post_day, comment_post_month, comment_post_date, comment_post_year, \ + comment_post_hour, comment_post_minute, comment_post_meridiem, \ + comment_post_time_ago, comment in results: + + ccl.addItem( + self.create_list_item( + comment_id, + comment_author_name, + comment_post_time_ago, + comment + ) + ) + else: + if ccl.size() == 0: + ccl.addItem(xbmcgui.ListItem(label="No Comments Found")) + + def get_comment_control_list(self): + + """ gets comment control list """ + + return self.getControl(1) + + def create_list_item(self, comment_id, comment_author_name, comment_post_time_ago, comment): + + """ creates list that will view comment """ + + line_item = xbmcgui.ListItem( + label=self.create_label( + comment_id, + comment_author_name, + comment_post_time_ago, + comment + ) + ) + line_item.setProperty('id', comment_id) + line_item.setProperty('comment_author_name', comment_author_name) + line_item.setProperty('comment_post_time_ago', comment_post_time_ago) + line_item.setProperty('comment', comment) + return line_item + + def refresh_label(self, line_item, selected=True): + + """ Refreshes comment label """ + + comment_id = line_item.getProperty('id') + comment_author_name = line_item.getProperty('comment_author_name') + comment_post_time_ago = line_item.getProperty('comment_post_time_ago') + comment = line_item.getProperty('comment') + line_item.setLabel( + self.create_label( + comment_id, + comment_author_name, + comment_post_time_ago, + comment, + selected + ) + ) + + def create_label(self, comment_id, comment_author_name, comment_post_time_ago, comment, selected=False): + + """ Creates label to view comments """ + + return comment_author_name + ' [COLOR white]' + clean_text( comment ) \ + + '[/COLOR] [COLOR orange](' + comment_post_time_ago + ')[/COLOR]' diff --git a/lib/rumble_user.py b/lib/rumble_user.py index ba978ed..8c5b165 100644 --- a/lib/rumble_user.py +++ b/lib/rumble_user.py @@ -6,6 +6,7 @@ Class to handle all the rumble subscription methods import math import time +import re import xbmcaddon @@ -143,16 +144,20 @@ class RumbleUser: 'Content-type': 'application/x-www-form-urlencoded' } + # for some strange reason the first letter needs to be removed data = request_get( - self.base_url + '/service.php?name=comment.list&video=' + video_id, + self.base_url + '/service.php?name=comment.list&video=' + video_id[1:], None, headers ) if data: - comments = json.loads(data)['js_code'] - #([^\<]+)(?:[\s|\n||\\n|\\t]+)([^\<]+)(?:[\s|\n||\\n|\\t]+)(?:[\s|\n||\\n|\\t]+)

([^\<]+)

- + comment_data = json.loads(data) + if comment_data.get('html'): + return re.compile( + r"([^\<]+)(?:[\s|\n||\\n|\\t]+)([^\<]+)(?:[\s|\n||\\n|\\t]+)(?:[\s|\n||\\n|\\t]+)

([^\<]+)

", + re.MULTILINE|re.DOTALL|re.IGNORECASE + ).findall(comment_data.get('html','')) return {} def set_session_cookie( self ): diff --git a/main.py b/main.py index 58dd958..2555c90 100644 --- a/main.py +++ b/main.py @@ -14,6 +14,7 @@ from six.moves import urllib from lib.general import * from lib.rumble_user import RumbleUser +from lib.comments import CommentWindow try: import json @@ -300,6 +301,21 @@ def dir_list_create( data, cat, video_type='video', search = False, play=False ) return amount +def get_video_id( url ): + + """ gets a video id from a URL, helps in resolving """ + + data = request_get(url) + + # gets embed id from embed url + video_id = re.compile( + ',\"embedUrl\":\"' + BASE_URL + '/embed/(.*?)\/\",', + re.MULTILINE|re.DOTALL|re.IGNORECASE + ).findall(data) + + if video_id: + return video_id[0] + return False def resolver( url ): @@ -313,19 +329,13 @@ def resolver( url ): if playback_method == '2': urls = [] - data = request_get(url) + video_id = get_video_id( url ) - # gets embed id from embed url - embed_id = re.compile( - ',\"embedUrl\":\"' + BASE_URL + '/embed/(.*?)\/\",', - re.MULTILINE|re.DOTALL|re.IGNORECASE - ).findall(data) - - if embed_id: + if video_id: # use site api to get video urls # TODO: use as dict / array instead of using regex to get URLs - data = request_get(BASE_URL + '/embedJS/u3/?request=video&ver=2&v=' + embed_id[0]) + data = request_get(BASE_URL + '/embedJS/u3/?request=video&ver=2&v=' + video_id) sizes = [ '1080', '720', '480', '360', 'hls' ] # reverses array - small to large @@ -582,6 +592,7 @@ def add_dir(name, url, mode, iconimage, fanart, description, cat, folder=True, f list_item.setArt({'icon': 'DefaultFolder.png', 'thumb': iconimage}) else: list_item.setArt({'icon': 'DefaultVideo.png', 'thumb': iconimage}) + if play == 2 and mode == 4: list_item.setProperty('IsPlayable', 'true') context_menu.append((get_string(30158), 'Action(Queue)')) @@ -600,12 +611,16 @@ def add_dir(name, url, mode, iconimage, fanart, description, cat, folder=True, f list_item.setProperty('fanart_image', HOME_DIR + 'fanart.jpg') if RUMBLE_USER.has_login_details(): + if subscribe_context: if subscribe_context['subscribe']: context_menu.append(('Subscribe to ' + subscribe_context['name'],'RunPlugin(%s)' % build_url( {'mode': '11','name': subscribe_context['name'], 'cat': 'subscribe'} ))) else: context_menu.append(('Unsubscribe to ' + subscribe_context['name'],'RunPlugin(%s)' % build_url( {'mode': '11','name': subscribe_context['name'], 'cat': 'unsubscribe'} ))) + if play == 2 and mode == 4: + context_menu.append(('Comments','RunPlugin(%s)' % build_url( {'mode': '12','url': url} ))) + if fav_context: favorite_str = favorites_load( True ) @@ -617,7 +632,7 @@ def add_dir(name, url, mode, iconimage, fanart, description, cat, folder=True, f try: - # checks fav name via string ( I do not like how this is done, so will try redo in future ) + # checks fav name via string (I do not like how this is done, so will redo in future) if name_fav in favorite_str: context_menu.append((get_string(30153),'RunPlugin(%s)' % build_url( {'mode': '6','name': name} ))) else: @@ -643,6 +658,23 @@ def add_dir(name, url, mode, iconimage, fanart, description, cat, folder=True, f xbmcplugin.addDirectoryItem(handle=PLUGIN_ID, url=link, listitem=list_item, isFolder=folder) +def comments_show( url ): + + """ Retrieves and shows video's comments in a modal """ + + video_id = get_video_id( url ) + + if video_id: + win = CommentWindow( + 'addon-rumble-comments.xml', + ADDON.getAddonInfo('path'), + 'default', + video_id=video_id + ) + win.doModal() + del win + else: + notify( "Cannot find comments", "Comments" ) def main(): @@ -728,6 +760,8 @@ def main(): login_session_reset() elif mode==11: subscribe(name, cat) + elif mode==12: + comments_show(url) if __name__ == "__main__": main() diff --git a/resources/skins/default/720p/addon-rumble-comments.xml b/resources/skins/default/720p/addon-rumble-comments.xml new file mode 100644 index 0000000..50c3337 --- /dev/null +++ b/resources/skins/default/720p/addon-rumble-comments.xml @@ -0,0 +1,48 @@ + + + 1 + 1 + 0xff000000 + WindowOpen + WindowClose + 1 + + 0 + 0 + + + + Comment list + 0 + 0 + true + list + vertical + 25 + + + 0 + 24 + font14 + center + blue + left + + + + + + 0 + 24 + font14 + center + red + left + + true + 250 + + + + +