You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
plugin.video.rumble/main.py

999 lines
33 KiB
Python

# -*- coding: utf-8 -*-
import sys
import re
import os
import xbmc
import xbmcplugin
import xbmcgui
import xbmcaddon
import xbmcvfs
import six
from six.moves import urllib
from lib.general import *
from lib.rumble_user import RumbleUser
from lib.comments import CommentWindow
1 year ago
try:
import json
except ImportError:
1 year ago
import simplejson as json
BASE_URL = 'https://rumble.com'
PLUGIN_URL = sys.argv[0]
PLUGIN_ID = int(sys.argv[1])
PLUGIN_NAME = PLUGIN_URL.replace('plugin://','')
1 year ago
ADDON = xbmcaddon.Addon()
ADDON_ICON = ADDON.getAddonInfo('icon')
ADDON_NAME = ADDON.getAddonInfo('name')
HOME_DIR = 'special://home/addons/' + PLUGIN_NAME
1 year ago
RESOURCE_DIR = HOME_DIR + 'resources/'
MEDIA_DIR = RESOURCE_DIR + 'media/'
1 year ago
DATE_FORMAT = ADDON.getSetting('date_format')
RUMBLE_USER = RumbleUser()
if six.PY2:
favorites = xbmc.translatePath(os.path.join(ADDON.getAddonInfo('profile'), 'favorites.dat'))
1 year ago
else:
favorites = xbmcvfs.translatePath(os.path.join(ADDON.getAddonInfo('profile'), 'favorites.dat'))
def favorites_create():
""" creates favorite directory if doesn't exist """
if six.PY2:
addon_data_path = xbmc.translatePath(ADDON.getAddonInfo('profile'))
else:
addon_data_path = xbmcvfs.translatePath(ADDON.getAddonInfo('profile'))
if os.path.exists(addon_data_path) is False:
os.mkdir(addon_data_path)
xbmc.sleep(1)
def favorites_load( return_string = False ):
""" load favourites from file into variable """
if os.path.exists( favorites ):
fav_str = open( favorites ).read()
if return_string:
return fav_str
if fav_str:
return json.loads( fav_str )
else:
favorites_create()
# nothing to load, return type necessary
if return_string:
return ''
return []
1 year ago
def to_unicode( text, encoding='utf-8', errors='strict' ):
""" Forces text to unicode """
1 year ago
if isinstance(text, bytes):
return text.decode(encoding, errors=errors)
1 year ago
return text
def get_search_string( heading='', message='' ):
""" Ask the user for a search string """
1 year ago
search_string = None
1 year ago
keyboard = xbmc.Keyboard(message, heading)
keyboard.doModal()
1 year ago
if keyboard.isConfirmed():
search_string = to_unicode(keyboard.getText())
1 year ago
return search_string
def home_menu():
""" Creates home menu """
1 year ago
# Search
add_dir( get_string(137), '', 1, { 'thumb': 'search.png' } )
1 year ago
# Favorites
add_dir( get_string(1036), '', 7, { 'thumb': 'favorite.png' } )
if RUMBLE_USER.has_login_details():
# Subscriptions
add_dir( 'Subscriptions', BASE_URL + '/subscriptions', 3, { 'thumb': 'favorite.png' }, {}, 'subscriptions' )
# Following
add_dir( 'Following', BASE_URL + '/followed-channels', 3, { 'thumb': 'favorite.png' }, {}, 'following' )
# Watch Later
add_dir( 'Watch Later', BASE_URL + '/playlists/watch-later', 3, { 'thumb': 'favorite.png' }, {}, 'playlist' )
# Battle Leaderboard
add_dir( get_string(30050), BASE_URL + '/battle-leaderboard/recorded', 3, { 'thumb': 'leader.png' }, {}, 'top' )
# Categories
add_dir( get_string(30051), BASE_URL + '/browse', 3, { 'thumb': 'viral.png' }, {}, 'cat_list' )
# Live Streams
add_dir( get_string(30052), BASE_URL + '/browse/live', 3, { 'thumb': 'viral.png' }, {}, 'live_stream' )
1 year ago
# Settings
add_dir( get_string(5), '', 8, { 'thumb': 'settings.png' } )
xbmcplugin.endOfDirectory( PLUGIN_ID, cacheToDisc=False )
1 year ago
def search_menu():
""" Creates search menu """
1 year ago
# Search Video
add_dir( get_string(30100), BASE_URL + '/search/video?q=', 2, { 'thumb': 'search.png' }, {}, 'video' )
1 year ago
# Search Channel
add_dir( get_string(30101), BASE_URL + '/search/channel?q=', 2, { 'thumb': 'search.png' }, {}, 'channel' )
# Search User
add_dir( get_string(30102), BASE_URL + '/search/channel?q=', 2, { 'thumb': 'search.png' }, {}, 'user' )
1 year ago
xbmcplugin.endOfDirectory(PLUGIN_ID)
def pagination( url, page, cat, search=False ):
""" list directory items then show pagination """
1 year ago
if url > '':
page = int(page)
page_url = url
paginated = True
if page == 1:
1 year ago
if search:
page_url = url + search
elif search and cat == 'video':
page_url = url + search + "&page=" + str( page )
elif cat in {'channel', 'cat_video', 'user', 'other', 'subscriptions', 'live_stream' }:
page_url = url + "?page=" + str( page )
if cat in { 'following', 'top', 'cat_list' }:
paginated = False
amount = list_rumble( page_url, cat )
if paginated and amount > 15 and page < 10:
# for next page
page = page + 1
name = get_string(30150) + " " + str( page )
list_item = xbmcgui.ListItem(name)
link_params = {
'url': url,
'mode': '3',
'name': name,
'page': str( page ),
'cat': cat,
}
link = build_url( link_params )
if search and cat == 'video':
link = link + "&search=" + urllib.parse.quote_plus(search)
xbmcplugin.addDirectoryItem(PLUGIN_ID, link, list_item, True)
1 year ago
xbmcplugin.endOfDirectory(PLUGIN_ID)
def get_image( data, image_id ):
""" method to get an image from scraped page's CSS from the image ID """
image_re = re.compile(
9 months ago
"i.user-image--img--id-" + str( image_id ) + ".+?{\s*background-image: url(.+?);",
re.MULTILINE|re.DOTALL|re.IGNORECASE
).findall(data)
if image_re != []:
1 year ago
image = str(image_re[0]).replace('(', '').replace(')', '')
else:
image = ''
1 year ago
return image
def list_rumble( url, cat ):
""" Method to get and display items from Rumble """
amount = 0
headers = None
if 'subscriptions' in url or cat == 'following':
# make sure there is a session
# result is stored in a cookie
RUMBLE_USER.has_session()
data = request_get(url, None, headers)
# Fix for favorites & search
if cat in { 'other', 'channel' } and '/c/' in url:
cat = 'channel_video'
if 'search' in url:
if cat == 'video':
amount = dir_list_create( data, cat, 'video', True, 1 )
else:
amount = dir_list_create( data, cat, 'channel', True )
elif cat in { 'subscriptions', 'cat_video', 'live_stream', 'playlist' }:
amount = dir_list_create( data, cat, cat, False, 2 )
elif cat in { 'channel', 'top', 'other' }:
amount = dir_list_create( data, cat, 'video', False, 2 )
elif cat in { 'channel_video', 'user' }:
amount = dir_list_create( data, cat, 'channel_video', False, 2 )
elif cat == 'following':
amount = dir_list_create( data, cat, 'following', False, 2 )
elif cat == 'cat_list':
amount = dir_list_create( data, cat, cat, False )
return amount
def dir_list_create( data, cat, video_type='video', search = False, play=0 ):
""" create and display dir list based upon type """
amount = 0
if video_type == 'video':
videos = re.compile(r'href=\"([^\"]+)\"><div class=\"(?:[^\"]+)\"><img\s*class=\"video-item--img\"\s*src=\"([^\"]+)\"\s*alt=\"(?:[^\"]+)\"\s*>(?:<span class=\"video-item--watching\">[^\<]+</span>)?(?:<div class=video-item--overlay-rank>(?:[0-9]+)</div>)?</div><(?:[^\>]+)></span></a><div class=\"video-item--info\"><time class=\"video-item--meta video-item--time\" datetime=(.+?)-(.+?)-(.+?)T(?:.+?) title\=\"(?:[^\"]+)\">(?:[^\<]+)</time><h3 class=video-item--title>(.+?)</h3><address(?:[^\>]+)><a rel=author class=\"(?:[^\=]+)=(.+?)><div class=ellipsis-1>(.+?)</div>', re.MULTILINE|re.DOTALL|re.IGNORECASE).findall(data)
if videos:
amount = len(videos)
for link, img, year, month, day, title, channel_link, channel_name in videos:
info_labels = {}
if '<svg' in channel_name:
channel_name = channel_name.split('<svg')[0] + " (Verified)"
info_labels[ 'year' ] = year
11 months ago
video_title = '[B]' + clean_text( title ) + '[/B]\n[COLOR gold]' + channel_name + '[/COLOR] - [COLOR lime]' + get_date_formatted( DATE_FORMAT, year, month, day ) + '[/COLOR]'
images = { 'thumb': str(img), 'fanart': str(img) }
#open get url and open player
add_dir( video_title, BASE_URL + link, 4, images, info_labels, cat, False, True, play, { 'name' : channel_link, 'subscribe': True } )
elif video_type in { 'cat_video', 'subscriptions', 'live_stream', 'channel_video', 'playlist' }:
if video_type == 'live_stream':
videos_regex = r'<div class=\"thumbnail__grid\"\s*role=\"list\">(.*)<nav class=\"paginator\">'
elif video_type == 'playlist':
videos_regex = r'<ol\s*class=\"videostream__list\"(?:[^>]+)>(.*)</ol>'
else:
videos_regex = r'<ol\s*class=\"thumbnail__grid\">(.*)</ol>'
videos = re.compile(videos_regex, re.DOTALL|re.IGNORECASE).findall(data)
11 months ago
if videos:
if video_type == 'playlist':
videos = videos[0].split('"videostream videostream__list-item')
else:
videos = videos[0].split('"videostream thumbnail__grid-')
videos.pop(0)
11 months ago
amount = len(videos)
for video in videos:
video_title = ''
images = {}
info_labels = {}
subscribe_context = False
title = re.compile(r'<h3(?:[^\>]+)?>(.*)</h3>', re.DOTALL|re.IGNORECASE).findall(video)
link = re.compile(r'<a\sclass="videostream__link link"\sdraggable="false"\shref="([^\"]+)">', re.DOTALL|re.IGNORECASE).findall(video)
img = re.compile(r'<img\s*class=\"thumbnail__image\"\s*draggable=\"false\"\s*src=\"([^\"]+)\"', re.DOTALL|re.IGNORECASE).findall(video)
if title:
video_title = '[B]' + clean_text( title[0] ) + '[/B]'
if 'videostream__status--live' in video:
video_title += ' [COLOR red](Live)[/COLOR]'
if 'videostream__status--upcoming' in video:
video_title += ' [COLOR yellow](Upcoming)[/COLOR]'
channel_name = re.compile(r'<span\sclass="channel__name(?:[^\"]+)" title="(?:[^\"]+)">([^\<]+)</span>(\s*<svg class=channel__verified)?', re.DOTALL|re.IGNORECASE).findall(video)
channel_link = re.compile(r'<a\s*rel=\"author\"\s*class=\"channel__link\slink\s(?:[^\"]+)\"\s*href=\"([^\"]+)\"\s*>', re.DOTALL|re.IGNORECASE).findall(video)
if channel_name:
video_title += '\n[COLOR gold]' + clean_text( channel_name[0][0] )
if channel_name[0][1]:
video_title += " (Verified)"
video_title += '[/COLOR]'
11 months ago
if channel_link:
subscribe_context = { 'name' : channel_link[0], 'subscribe': True }
3 months ago
date_time = re.compile(r'<time\s*class=\"(?:[^\"]+)\"\s*datetime=\"(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})-(\d{2}):(\d{2})\"', re.DOTALL|re.IGNORECASE).findall(video)
if date_time:
info_labels[ 'year' ] = date_time[0][0]
3 months ago
video_title += ' - [COLOR lime]' + get_date_formatted( DATE_FORMAT, date_time[0][0], date_time[0][1], date_time[0][2] ) + '[/COLOR]'
if img:
images = { 'thumb': str(img[0]), 'fanart': str(img[0]) }
duration = re.compile(r'videostream__status--duration\"\s*>([^<]+)</div>', re.DOTALL|re.IGNORECASE).findall(video)
if duration:
info_labels[ 'duration' ] = duration_to_secs( duration[0].strip() )
11 months ago
#open get url and open player
add_dir( video_title, BASE_URL + link[0], 4, images, info_labels, cat, False, True, play, subscribe_context )
return amount
11 months ago
elif video_type == 'cat_list':
cat_list = re.compile(r'<a\s*class=\"category__link link\"\s*href=\"([^\"]+)\"\s*>\s*<img\s*class=\"category__image\"\s*src=\"([^\"]+)\"\s*alt=(?:[^\>]+)>\s*<strong class=\"category__title\">([^\<]+)</strong>', re.DOTALL|re.IGNORECASE).findall(data)
if cat_list:
amount = len(cat_list)
for link, img, title in cat_list:
cat = 'channel_video'
images = { 'thumb': str(img), 'fanart': str(img) }
#open get url and open player
add_dir( clean_text( title ), BASE_URL + link.strip() + '/videos', 3, images, {}, cat )
elif video_type == 'following':
videos_regex = r'<ol\s*class=\"followed-channels__list\">(.*)</ol>'
videos = re.compile(videos_regex, re.DOTALL|re.IGNORECASE).findall(data)
if videos:
videos = videos[0].split('"followed-channel flex items-')
videos.pop(0)
amount = len(videos)
for video in videos:
video_title = ''
images = {}
title = re.compile(r'<span\s*class=\"clamp-2\">([^<]+)<\/span>', re.DOTALL|re.IGNORECASE).findall(video)
followers = re.compile(r'<div\s*class=\"followed-channel__followers(?:[^\"]+)\">([^<]+)</div>', re.DOTALL|re.IGNORECASE).findall(video)
link = re.compile(r'<a\s*class=\"(?:[^\"]+)\"\s*href=\"([^\"]+)\">', re.DOTALL|re.IGNORECASE).findall(video)
img = re.compile(r'<(?:img|span)\s*class=\"channel__avatar([^\"]+)\"\s*(?:src=\"([^\"]+)\")?', re.DOTALL|re.IGNORECASE).findall(video)
if title:
video_title = '[B]' + clean_text( title[0] ) + '[/B]'
if '<use href="#channel_verified" />' in video:
video_title += ' [COLOR gold](Verified)[/COLOR]'
link = link[0] if link else ""
if img:
if 'channel__letter' in img[0][0]:
if title:
image_url = MEDIA_DIR + 'letters/' + title[0][0].lower() + '.png'
else:
image_url = ''
else:
image_url = img[0][1]
images = { 'thumb': str(image_url), 'fanart': str(image_url) }
if 'channel__live' in img[0][0]:
video_title += ' [COLOR red](Live)[/COLOR]'
if followers:
video_title += '\n[COLOR green]' + followers[0].strip() + '[/COLOR]'
cat = 'user'
if '/user/' not in link:
cat = 'channel_video'
#open get url and open player
add_dir( video_title, BASE_URL + link, 3, images, {}, cat, True, True, play, { 'name' : link, 'subscribe': False } )
else:
4 months ago
channels = re.compile(r'a href=(.+?)>\s*<div class=\"channel-item--img\">\s*<i class=\'user-image (?:user-image--img user-image--img--id-([^\']+)\')?(?:user-image--letter\' data-letter=([a-zA-Z]))? data-js=user-image>\s*</i>\s*</div>\s*<h3 class=channel-item--title>(.+?)</h3>\s*<span class=channel-item--subscribers>(.+?) Followers</span>',re.DOTALL).findall(data)
if channels:
amount = len(channels)
for link, img_id, img_letter, channel_name, subscribers in channels:
# split channel and user
if search:
if cat == 'channel':
if '/c/' not in link:
continue
else:
if '/user/' not in link:
continue
if '<svg' in channel_name:
channel_name = channel_name.split('<svg')[0] + " (Verified)"
if img_id:
img = str( get_image( data, img_id ) )
else:
img = MEDIA_DIR + 'letters/' + img_letter + '.png'
images = { 'thumb': str(img), 'fanart': str(img) }
video_title = '[B]' + channel_name + '[/B]\n[COLOR palegreen]' + subscribers + '[/COLOR] [COLOR yellow]' + get_string(30156) + '[/COLOR]'
#open get url and open player
add_dir( video_title, BASE_URL + link, 3, images, {}, cat, True, True, play, { 'name' : link, 'subscribe': True } )
return amount
1 year ago
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
1 year ago
def get_playlist_video_id( url ):
"""
gets a playlist video id from a URL
helps in adding video to playlist
"""
data = request_get(url)
# gets embed id from embed url
video_id = re.compile(
'data-id=\"([0-9]+)\"',
re.MULTILINE|re.DOTALL|re.IGNORECASE
).findall(data)
if video_id:
return video_id[0]
return False
def resolver( url ):
""" Resolves a URL for rumble & returns resolved link to video """
1 year ago
2 months ago
# playback options - 0: high auto, 1: low auto, 2: quality select
playback_method = int( ADDON.getSetting('playbackMethod') )
1 year ago
media_url = False
1 year ago
2 months ago
if playback_method > 0:
urls = []
1 year ago
video_id = get_video_id( url )
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=' + video_id)
sizes = [ '1080', '720', '480', '360', 'hls' ]
1 year ago
for quality in sizes:
# get urls for quality
matches = re.compile(
'"' + quality + '".+?url.+?:"(.*?)"',
re.MULTILINE|re.DOTALL|re.IGNORECASE
).findall(data)
1 year ago
if matches:
2 months ago
if playback_method > 0:
1 year ago
urls.append(( quality, matches[0] ))
else:
media_url = matches[0]
1 year ago
break
2 months ago
# if not automatically selecting highest quality
if int( playback_method ) > 0:
2 months ago
# m3u8 check
if len( urls ) == 1 and '.m3u8' in urls[0][1]:
from lib.m3u8 import m3u8
m3u8_handler = m3u8()
urls = m3u8_handler.process( request_get( urls[0][1] ) )
# reverses array - small to large
if playback_method == 1:
urls = urls[::-1]
media_url = urls[0][1]
# quality select
elif playback_method == 2:
if len(urls) > 0:
selected_index = xbmcgui.Dialog().select(
'Select Quality', [(sourceItem[0] or '?') for sourceItem in urls]
)
2 months ago
if selected_index != -1:
media_url = urls[selected_index][1]
1 year ago
if media_url:
media_url = media_url.replace('\/', '/')
return media_url
1 year ago
def play_video( name, url, thumb, play=2 ):
""" method to play video """
# get video link
1 year ago
url = resolver(url)
if url:
# Use HTTP
if ADDON.getSetting('useHTTP') == 'true':
url = url.replace('https://', 'http://', 1)
list_item = xbmcgui.ListItem(name, path=url)
list_item.setArt({'icon': thumb, 'thumb': thumb})
info_labels={ 'Title': name, 'plot': '' }
item_set_info( list_item, info_labels )
if play == 1:
xbmc.Player().play(item=url, listitem=list_item)
elif play == 2:
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, list_item)
else:
xbmcgui.Dialog().ok( 'Error', 'Video not found' )
1 year ago
def search_items( url, cat ):
""" Searches rumble """
search_str = get_search_string(heading="Search")
if not search_str:
return False, 0
title = urllib.parse.quote_plus(search_str)
pagination( url, 1, cat, title )
1 year ago
def favorites_show():
""" Displays favorites """
data = favorites_load()
1 year ago
try:
amount = len(data)
if amount > 0:
for i in data:
1 year ago
name = i[0]
url = i[1]
mode = i[2]
images = { 'thumb': str(i[3]), 'fanart': str(i[4]) }
info_labels = { 'plot': str(i[5]) }
1 year ago
cat = i[6]
folder = ( i[7] == 'True' )
1 year ago
play = i[8]
add_dir( name, url, mode, images, info_labels, cat, folder, True, int(play) )
1 year ago
xbmcplugin.endOfDirectory(PLUGIN_ID)
else:
xbmcgui.Dialog().ok( get_string(14117), get_string(30155) )
except Exception:
1 year ago
xbmcplugin.endOfDirectory(PLUGIN_ID)
def favorite_add(name, url, fav_mode, thumb, fanart, plot, cat, folder, play):
""" add favorite from name """
data = favorites_load()
data.append((name, url, fav_mode, thumb, fanart, plot, cat, folder, play))
fav_file = open( favorites, 'w' )
fav_file.write(json.dumps(data))
fav_file.close()
notify( get_string(30152), name, thumb )
1 year ago
def favorite_remove( name ):
""" remove favorite from name """
# TODO: remove via something more unique instead
# TODO: remove via a method that doesn't require to loop through all favorites
data = favorites_load()
if data:
for index in range(len(data)):
if data[index][0] == name:
del data[index]
fav_file = open( favorites, 'w' )
fav_file.write(json.dumps(data))
fav_file.close()
break
notify( get_string(30154), name )
1 year ago
def favorites_import():
""" Due to plugin name change from original fork, the favorites will need to be imported """
if not xbmcgui.Dialog().yesno(
'Import Favorites',
'This will replace the favorites with the plugin.video.rumble.matrix version.\nProceed?',
nolabel = 'Cancel',
yeslabel = 'Ok'
):
return
# no point trying to run this as it didn't exist for python 2
if six.PY2:
notify( 'Favorites Not Found' )
return
# make sure path exists
favorites_create()
#load matrix favourites
rumble_matrix_dir = xbmcvfs.translatePath(os.path.join('special://home/userdata/addon_data/plugin.video.rumble.matrix', 'favorites.dat'))
if os.path.exists(rumble_matrix_dir):
rumble_matrix = open( rumble_matrix_dir ).read()
if rumble_matrix:
fav_file = open( favorites, 'w' )
fav_file.write(rumble_matrix)
fav_file.close()
notify( 'Imported Favorites' )
return
notify( 'Favorites Not Found' )
def login_session_reset():
""" Forces a rumble session reset """
RUMBLE_USER.reset_session_details()
# Session Reset
notify( get_string(30200) )
5 months ago
def login_test():
""" Method that resets session, then tests the login """
RUMBLE_USER.reset_session_details()
if RUMBLE_USER.has_login_details():
if RUMBLE_USER.login():
# Login Success
notify( get_string(30201) )
5 months ago
else:
# Login Failed
notify( get_string(30202) )
5 months ago
else:
# No details detected
notify( get_string(30203) )
def subscribe( name, action ):
""" Attempts to (un)subscribe to rumble channel """
# make sure we have a session
if RUMBLE_USER.has_session():
action_type = False
if '/user/' in name:
name = name.replace( '/user/', '' )
action_type = 'user'
elif '/c/' in name:
name = name.replace( '/c/', '' )
action_type = 'channel'
if action_type:
# subscribe to action
data = RUMBLE_USER.subscribe( action, action_type, name )
if data:
# Load data from JSON
data = json.loads(data)
# make sure everything looks fine
if data.get( 'user', False ) and data.get( 'data', False ) \
and data[ 'user' ][ 'logged_in' ] and data[ 'data' ][ 'thumb' ]:
if action == 'subscribe':
notify( 'Subscribed to ' + name, None, data[ 'data' ][ 'thumb' ] )
else:
notify( 'Unubscribed to ' + name, None, data[ 'data' ][ 'thumb' ] )
return True
notify( 'Unable to to perform action' )
return False
def add_dir( name, url, mode, images = {}, info_labels = {}, cat = '', folder=True, fav_context=False, play=0, subscribe_context=False ):
1 year ago
""" Adds directory items """
art_dict = {
'thumb': images.get( 'thumb', HOME_DIR + 'icon.png' ),
'fanart': images.get( 'fanart', HOME_DIR + 'fanart.jpg' ),
}
# set default image location to MEDIA_DIR
for art_type, art_loc in art_dict.items():
if art_loc:
if not art_loc.startswith( HOME_DIR ) and \
not art_loc.startswith( 'http' ) and \
not art_loc.startswith( '\\' ):
art_dict[ art_type ] = MEDIA_DIR + art_dict[ art_type ]
link_params = {
'url': url,
'mode': str( mode ),
'name': name,
'thumb': art_dict[ 'thumb' ],
'fanart': art_dict[ 'fanart' ],
'plot': info_labels.get( 'plot', '' ),
'cat': cat,
}
context_menu = []
1 year ago
if play:
link_params['play'] = str( play )
link = build_url( link_params )
list_item = xbmcgui.ListItem( name )
1 year ago
if folder:
list_item.setArt({'icon': 'DefaultFolder.png', 'thumb': art_dict[ 'thumb' ]})
1 year ago
else:
list_item.setArt({'icon': 'DefaultVideo.png', 'thumb': art_dict[ 'thumb' ]})
6 months ago
xbmcplugin.setContent(PLUGIN_ID, 'videos')
1 year ago
if play == 2 and mode == 4:
list_item.setProperty('IsPlayable', 'true')
context_menu.append((get_string(30158), 'Action(Queue)'))
if RUMBLE_USER.has_login_details():
# need to get current
params=get_params()
current_url = params.get( 'url', None )
if '/playlists/watch-later' in current_url:
# delete watch later context
context_menu.append(('Delete from Watch Later','RunPlugin(%s)' % build_url( {'mode': '12','url': url, 'cat':'delete'} )))
else:
# add watch later context
context_menu.append(('Add to Watch Later','RunPlugin(%s)' % build_url( {'mode': '12','url': url, 'cat':'add'} )))
info_labels['title'] = name
if play:
# adds information context menu
info_labels['mediatype'] = 'tvshow'
item_set_info( list_item, info_labels )
list_item.setProperty( 'fanart_image', art_dict[ 'fanart' ] )
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': '13','url': url} )))
if fav_context:
favorite_str = favorites_load( True )
1 year ago
try:
name_fav = json.dumps(name)
except Exception:
name_fav = name
1 year ago
try:
# 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} )))
1 year ago
else:
fav_params = {
'url': url,
'mode': '5',
'name': name,
'thumb': art_dict[ 'thumb' ],
'fanart': art_dict[ 'fanart' ],
'plot': info_labels.get( 'plot', '' ),
'cat': cat,
'folder': str(folder),
'fav_mode': str(mode),
'play': str(play),
}
context_menu.append((get_string(30151),'RunPlugin(%s)' %build_url( fav_params )))
except Exception:
1 year ago
pass
if context_menu:
list_item.addContextMenuItems(context_menu)
xbmcplugin.addDirectoryItem(handle=PLUGIN_ID, url=link, listitem=list_item, isFolder=folder)
1 year ago
def playlist_manage( url, action="add" ):
""" Adds to Rumble's Playlist """
video_id = get_playlist_video_id( url )
if video_id:
if action == "add":
RUMBLE_USER.playlist_add_video( video_id )
message = "Added to playlist"
else:
RUMBLE_USER.playlist_delete_video( video_id )
message = "Deleted from playlist"
else:
if action == "add":
message = "Cannot add to playlist"
else:
message = "Cannot delete from playlist"
notify( message, "Playlist" )
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" )
1 year ago
def main():
1 year ago
""" main method to start plugin """
1 year ago
params=get_params()
mode=int(params.get( 'mode', 0 ))
page=int(params.get( 'page', 1 ))
play=int(params.get( 'play', 0 ))
fav_mode=int(params.get( 'fav_mode', 0 ))
url = params.get( 'url', None )
if url:
url=urllib.parse.unquote_plus(url)
name = params.get( 'name', None )
if name:
name = urllib.parse.unquote_plus(name)
thumb=params.get( 'thumb', None )
if thumb:
thumb=urllib.parse.unquote_plus(thumb)
fanart=params.get( 'fanart', None )
if fanart:
fanart=urllib.parse.unquote_plus(fanart)
plot=params.get( 'plot', None )
if plot:
plot=urllib.parse.unquote_plus(plot)
subtitle=params.get( 'subtitle', None )
if subtitle:
subtitle=urllib.parse.unquote_plus(subtitle)
cat=params.get( 'cat', None )
if cat:
cat=urllib.parse.unquote_plus(cat)
search=params.get( 'search', None )
if search:
search=urllib.parse.unquote_plus(search)
folder=params.get( 'folder', None )
if folder:
folder=urllib.parse.unquote_plus(folder)
folder=params.get( 'folder', None )
if folder:
folder=urllib.parse.unquote_plus(folder)
if mode==0:
1 year ago
home_menu()
elif mode==1:
search_menu()
elif mode==2:
search_items(url,cat)
elif mode==3:
if search and search is not None:
pagination(url, page, cat, search)
1 year ago
else:
pagination(url, page, cat)
1 year ago
elif mode==4:
play_video(name, url, thumb, play)
elif mode in [5,6]:
if '\\ ' in name:
1 year ago
name = name.split('\\ ')[1]
if ' - ' in name:
1 year ago
name = name.split(' - ')[0]
if mode == 5:
favorite_add( name, url, fav_mode, thumb, fanart, plot, cat, str(folder), str(play) )
else:
favorite_remove( name )
1 year ago
elif mode==7:
favorites_show()
1 year ago
elif mode==8:
ADDON.openSettings()
elif mode==9:
favorites_import()
elif mode==10:
login_session_reset()
elif mode==11:
subscribe(name, cat)
elif mode==12:
playlist_manage(url, cat)
5 months ago
elif mode==13:
comments_show(url)
elif mode==14:
5 months ago
login_test()
1 year ago
if __name__ == "__main__":
main()