Browse only local videos by default
Use "local" instead of "all-local" by default because "all-local" requires admin privileges Other improvements: * Replace urllib with requests to make the management of the HTTP requests simpler (better error handling and easier implementation of complex requests in the future) * Refactor the functions used to build the HTTP request to improve maintainability (don't know if it makes sense to keep a single function for the "search" and the "list videos" request). * Use "urlencode" to generate the Kodi URL using a dict to make it more generic. * Create a function to log messages easily in Kodi's debug log. It will decrease the amount of duplicate code. * Fix some errors reported by pylint with regards to PEP 8
This commit is contained in:
parent
3677924a60
commit
d657480eab
|
@ -3,6 +3,7 @@
|
||||||
<requires>
|
<requires>
|
||||||
<import addon="xbmc.python" version="2.25.0"/>
|
<import addon="xbmc.python" version="2.25.0"/>
|
||||||
<import addon="script.module.addon.signals" version="0.0.3"/>
|
<import addon="script.module.addon.signals" version="0.0.3"/>
|
||||||
|
<import addon="script.module.requests" version="2.22.0"/>
|
||||||
</requires>
|
</requires>
|
||||||
<extension point="xbmc.python.pluginsource" library="peertube.py">
|
<extension point="xbmc.python.pluginsource" library="peertube.py">
|
||||||
<provides>video</provides>
|
<provides>video</provides>
|
||||||
|
@ -21,7 +22,7 @@
|
||||||
<source>https://github.com/StCyr/plugin.video.peertube</source>
|
<source>https://github.com/StCyr/plugin.video.peertube</source>
|
||||||
<news>
|
<news>
|
||||||
0.3.1.1
|
0.3.1.1
|
||||||
Add local videos only browsing
|
Add local videos only browsing
|
||||||
0.3.1
|
0.3.1
|
||||||
Fixed some bugs
|
Fixed some bugs
|
||||||
The 'change current instance" functionality currently doesn't work because
|
The 'change current instance" functionality currently doesn't work because
|
||||||
|
@ -32,13 +33,13 @@ Implemented the 'Browse instances' functionality
|
||||||
0.2.2
|
0.2.2
|
||||||
Implemented the 'video sort method' functionality
|
Implemented the 'video sort method' functionality
|
||||||
0.2.1
|
0.2.1
|
||||||
Fixed some bugs
|
Fixed some bugs
|
||||||
Added a 'video sort method' setting (functionality not implemented yet though)
|
Added a 'video sort method' setting (functionality not implemented yet though)
|
||||||
0.2.0
|
0.2.0
|
||||||
Implemented 'browse selected instance' functionality
|
Implemented 'browse selected instance' functionality
|
||||||
Implemented 'search videos on selected instance' functionality
|
Implemented 'search videos on selected instance' functionality
|
||||||
0.1.1
|
0.1.1
|
||||||
4th PoC.
|
4th PoC.
|
||||||
First functional PoC with background download
|
First functional PoC with background download
|
||||||
0.1.0
|
0.1.0
|
||||||
Third PoC (download in background should work. Needs testing though)
|
Third PoC (download in background should work. Needs testing though)
|
||||||
|
|
285
peertube.py
285
peertube.py
|
@ -5,13 +5,25 @@
|
||||||
# - Do sanity checks on received data
|
# - Do sanity checks on received data
|
||||||
# - Handle languages better (with .po files)
|
# - Handle languages better (with .po files)
|
||||||
# - Get the best quality torrent given settings and/or available bandwidth
|
# - Get the best quality torrent given settings and/or available bandwidth
|
||||||
# See how they do that in the peerTube client's code
|
# See how they do that in the peerTube client's code
|
||||||
|
import sys
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Python 3.x
|
||||||
|
from urllib.parse import parse_qsl
|
||||||
|
except ImportError:
|
||||||
|
# Python 2.x
|
||||||
|
from urlparse import parse_qsl
|
||||||
|
|
||||||
import time, sys
|
|
||||||
import urllib2, json
|
|
||||||
from urlparse import parse_qsl
|
|
||||||
import xbmc, xbmcgui, xbmcaddon, xbmcplugin, xbmcvfs
|
|
||||||
import AddonSignals
|
import AddonSignals
|
||||||
|
import requests
|
||||||
|
from requests.compat import urljoin, urlencode
|
||||||
|
import xbmc
|
||||||
|
import xbmcaddon
|
||||||
|
import xbmcgui
|
||||||
|
import xbmcplugin
|
||||||
|
import xbmcvfs
|
||||||
|
|
||||||
|
|
||||||
class PeertubeAddon():
|
class PeertubeAddon():
|
||||||
"""
|
"""
|
||||||
|
@ -25,19 +37,23 @@ class PeertubeAddon():
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
xbmc.log('PeertubeAddon: Initialising', xbmc.LOGDEBUG)
|
# These 2 steps must be done first since the logging function requires
|
||||||
|
# the add-on name
|
||||||
|
# Get an Addon instance
|
||||||
|
addon = xbmcaddon.Addon()
|
||||||
|
# Get the add-on name
|
||||||
|
self.addon_name = addon.getAddonInfo('name')
|
||||||
|
|
||||||
|
self.debug('Initialising')
|
||||||
|
|
||||||
# Save addon URL and ID
|
# Save addon URL and ID
|
||||||
self.plugin_url = plugin
|
self.plugin_url = plugin
|
||||||
self.plugin_id = plugin_id
|
self.plugin_id = plugin_id
|
||||||
|
|
||||||
# Get an Addon instance
|
|
||||||
addon = xbmcaddon.Addon()
|
|
||||||
|
|
||||||
# Select preferred instance by default
|
# Select preferred instance by default
|
||||||
self.selected_inst = addon.getSetting('preferred_instance')
|
self.selected_inst = addon.getSetting('preferred_instance')
|
||||||
|
|
||||||
# Get the number of videos to show per page
|
# Get the number of videos to show per page
|
||||||
self.items_per_page = int(addon.getSetting('items_per_page'))
|
self.items_per_page = int(addon.getSetting('items_per_page'))
|
||||||
|
|
||||||
# Get the video sort method
|
# Get the video sort method
|
||||||
|
@ -50,12 +66,24 @@ class PeertubeAddon():
|
||||||
self.play = 0
|
self.play = 0
|
||||||
self.torrent_name = ''
|
self.torrent_name = ''
|
||||||
|
|
||||||
# filter= 'local' or 'all-local' in verb search rest api
|
# Get the video filter from the settings that will be used when
|
||||||
# applied for browsing only
|
# browsing the videos. The value from the settings is converted into
|
||||||
self.video_filter = addon.getSetting('video_filter')
|
# one of the expected values by the REST APIs ("local" or "all-local")
|
||||||
|
if 'all-local' in addon.getSetting('video_filter'):
|
||||||
|
self.video_filter = 'all-local'
|
||||||
|
else:
|
||||||
|
self.video_filter = 'local'
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def debug(self, message):
|
||||||
|
"""Log a message in Kodi's log with the level xbmc.LOGDEBUG
|
||||||
|
|
||||||
|
:param message: Message to log
|
||||||
|
:type message: str
|
||||||
|
"""
|
||||||
|
xbmc.log('{0}: {1}'.format(self.addon_name, message), xbmc.LOGDEBUG)
|
||||||
|
|
||||||
def query_peertube(self, req):
|
def query_peertube(self, req):
|
||||||
"""
|
"""
|
||||||
Issue a PeerTube API request and return the results
|
Issue a PeerTube API request and return the results
|
||||||
|
@ -64,20 +92,30 @@ class PeertubeAddon():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Send the PeerTube REST API request
|
# Send the PeerTube REST API request
|
||||||
|
self.debug('Issuing request {0}'.format(req))
|
||||||
|
response = requests.get(url=req)
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
# Use Request.raise_for_status() to raise an exception if the HTTP
|
||||||
|
# request returned an unsuccessful status code.
|
||||||
try:
|
try:
|
||||||
xbmc.log('PeertubeAddon: Issuing request {0}'.format(req), xbmc.LOGDEBUG)
|
response.raise_for_status()
|
||||||
resp = urllib2.urlopen(req)
|
except requests.HTTPError as e:
|
||||||
data = json.load(resp)
|
xbmcgui.Dialog().notification('Communication error',
|
||||||
except:
|
'Error during request on {0}'
|
||||||
xbmcgui.Dialog().notification('Communication error', 'Error during my request on {0}'.format(self.selected_inst), xbmcgui.NOTIFICATION_ERROR)
|
.format(self.selected_inst),
|
||||||
return None
|
xbmcgui.NOTIFICATION_ERROR)
|
||||||
|
# Print the JSON as it may contain an 'error' key with the details
|
||||||
|
# of the error
|
||||||
|
self.debug('Error => "{}"'.format(data['error']))
|
||||||
|
raise e
|
||||||
|
|
||||||
# Return when no results are found
|
# Return when no results are found
|
||||||
if data['total'] == 0:
|
if data['total'] == 0:
|
||||||
xbmc.log('PeertubeAddon: No result found', xbmc.LOGDEBUG)
|
self.debug('No result found')
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
xbmc.log('PeertubeAddon: Found {0} results'.format(data['total']), xbmc.LOGDEBUG)
|
self.debug('Found {0} results'.format(data['total']))
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@ -93,16 +131,16 @@ class PeertubeAddon():
|
||||||
|
|
||||||
# Create a list item with a text label
|
# Create a list item with a text label
|
||||||
list_item = xbmcgui.ListItem(label=data['name'])
|
list_item = xbmcgui.ListItem(label=data['name'])
|
||||||
|
|
||||||
if data_type == 'videos':
|
if data_type == 'videos':
|
||||||
# Add thumbnail
|
# Add thumbnail
|
||||||
list_item.setArt({'thumb': self.selected_inst + '/' + data['thumbnailPath']})
|
list_item.setArt({'thumb': self.selected_inst + '/' + data['thumbnailPath']})
|
||||||
|
|
||||||
# Set a fanart image for the list item.
|
# Set a fanart image for the list item.
|
||||||
#list_item.setProperty('fanart_image', data['thumb'])
|
# list_item.setProperty('fanart_image', data['thumb'])
|
||||||
|
|
||||||
# Compute media info from item's metadata
|
# Compute media info from item's metadata
|
||||||
info = {'title':data['name'],
|
info = {'title': data['name'],
|
||||||
'playcount': data['views'],
|
'playcount': data['views'],
|
||||||
'plotoutline': data['description'],
|
'plotoutline': data['description'],
|
||||||
'duration': data['duration']
|
'duration': data['duration']
|
||||||
|
@ -113,54 +151,64 @@ class PeertubeAddon():
|
||||||
info['rating'] = data['likes']/(data['likes'] + data['dislikes'])
|
info['rating'] = data['likes']/(data['likes'] + data['dislikes'])
|
||||||
|
|
||||||
# Set additional info for the list item.
|
# Set additional info for the list item.
|
||||||
list_item.setInfo('video', info)
|
list_item.setInfo('video', info)
|
||||||
|
|
||||||
# Videos are playable
|
# Videos are playable
|
||||||
list_item.setProperty('IsPlayable', 'true')
|
list_item.setProperty('IsPlayable', 'true')
|
||||||
|
|
||||||
# Find the URL of the best possible video matching user's preferrence
|
# Find the URL of the best possible video matching user's preferences
|
||||||
# TODO: Error handling
|
# TODO: Error handling
|
||||||
current_res = 0
|
current_res = 0
|
||||||
higher_res = -1
|
higher_res = -1
|
||||||
torrent_url = ''
|
torrent_url = ''
|
||||||
resp = urllib2.urlopen(self.selected_inst + '/api/v1/videos/' + data['uuid'])
|
response = requests.get(self.selected_inst + '/api/v1/videos/'
|
||||||
metadata = json.load(resp)
|
+ data['uuid'])
|
||||||
xbmc.log('PeertubeAddon: Looking for the best possible video matching user preferrences', xbmc.LOGDEBUG)
|
metadata = response.json()
|
||||||
|
self.debug('Looking for the best possible video quality matching user preferences')
|
||||||
for f in metadata['files']:
|
for f in metadata['files']:
|
||||||
# Get file resolution
|
# Get file resolution
|
||||||
res = f['resolution']['id']
|
res = f['resolution']['id']
|
||||||
if res == self.preferred_resolution:
|
if res == self.preferred_resolution:
|
||||||
# Stop directly, when we find the exact same resolution as the user's preferred one
|
# Stop directly, when we find the exact same resolution as the user's preferred one
|
||||||
xbmc.log('PeertubeAddon: Found video with preferred resolution', xbmc.LOGDEBUG)
|
self.debug('Found video with preferred resolution')
|
||||||
torrent_url = f['torrentUrl']
|
torrent_url = f['torrentUrl']
|
||||||
break
|
break
|
||||||
elif res < self.preferred_resolution and res > current_res:
|
elif res < self.preferred_resolution and res > current_res:
|
||||||
# Else, try to find the best one just below the user's preferred one
|
# Else, try to find the best one just below the user's preferred one
|
||||||
xbmc.log('PeertubeAddon: Found video with good lower resolution ({0})'.format(f['resolution']['label']), xbmc.LOGDEBUG)
|
self.debug('Found video with good lower resolution'
|
||||||
torrent_url = f['torrentUrl']
|
'({0})'.format(f['resolution']['label']))
|
||||||
current_res = res
|
torrent_url = f['torrentUrl']
|
||||||
elif res > self.preferred_resolution and ( res < higher_res or higher_res == -1 ):
|
current_res = res
|
||||||
# In the worth case, we'll take the one just above the user's preferred one
|
elif res > self.preferred_resolution and (res < higher_res or higher_res == -1):
|
||||||
xbmc.log('PeertubeAddon: Saving video with higher resolution ({0}) as a possible alternative'.format(f['resolution']['label']), xbmc.LOGDEBUG)
|
# In the worst case, we'll take the one just above the user's preferred one
|
||||||
backup_url = f['torrentUrl']
|
self.debug('Saving video with higher resolution ({0})'
|
||||||
higher_res = res
|
'as a possible alternative'
|
||||||
|
.format(f['resolution']['label']))
|
||||||
|
backup_url = f['torrentUrl']
|
||||||
|
higher_res = res
|
||||||
|
|
||||||
# Use smallest file with an higher resolution, when we didn't find a resolution equal or
|
# Use smallest file with an higher resolution, when we didn't find a resolution equal or
|
||||||
# slower than the user's preferred one
|
# lower than the user's preferred one
|
||||||
if not torrent_url:
|
if not torrent_url:
|
||||||
xbmc.log('PeertubeAddon: Using video with higher resolution as alternative', xbmc.LOGDEBUG)
|
self.debug('Using video with higher resolution as alternative')
|
||||||
torrent_url = backup_url
|
torrent_url = backup_url
|
||||||
|
|
||||||
# Compose the correct URL for Kodi
|
# Compose the correct URL for Kodi
|
||||||
url = self.build_kodi_url_action_url('play_video', torrent_url)
|
url = self.build_kodi_url({
|
||||||
|
'action': 'play_video',
|
||||||
|
'url': torrent_url
|
||||||
|
})
|
||||||
|
|
||||||
elif data_type == 'instances':
|
elif data_type == 'instances':
|
||||||
# TODO: Add a context menu to select instance as preferred instance
|
# TODO: Add a context menu to select instance as preferred instance
|
||||||
# Instances are not playable
|
# Instances are not playable
|
||||||
list_item.setProperty('IsPlayable', 'false')
|
list_item.setProperty('IsPlayable', 'false')
|
||||||
|
|
||||||
# Set URL to select this instance
|
# Set URL to select this instance
|
||||||
url = self.build_kodi_url_action_url('select_instance',data['host'])
|
url = self.build_kodi_url({
|
||||||
|
'action': 'select_instance',
|
||||||
|
'url': data['host']
|
||||||
|
})
|
||||||
|
|
||||||
# Add our item to the listing as a 3-element tuple.
|
# Add our item to the listing as a 3-element tuple.
|
||||||
listing.append((url, list_item, False))
|
listing.append((url, list_item, False))
|
||||||
|
@ -168,21 +216,77 @@ class PeertubeAddon():
|
||||||
# Add a 'Next page' button when there are more data to show
|
# Add a 'Next page' button when there are more data to show
|
||||||
start = int(start) + self.items_per_page
|
start = int(start) + self.items_per_page
|
||||||
if lst['total'] > start:
|
if lst['total'] > start:
|
||||||
list_item = xbmcgui.ListItem( label='Next page ({0})'.format(start/self.items_per_page) )
|
list_item = xbmcgui.ListItem(label='Next page ({0})'
|
||||||
url = '{0}?action=browse_{1}&start={2}'.format(self.plugin_url, data_type, start)
|
.format(start/self.items_per_page))
|
||||||
|
url = self.build_kodi_url({
|
||||||
|
'action': 'browse_{0}'.format(data_type),
|
||||||
|
'start': start})
|
||||||
listing.append((url, list_item, True))
|
listing.append((url, list_item, True))
|
||||||
|
|
||||||
return listing
|
return listing
|
||||||
|
|
||||||
def build_peertube_rest_api_search_request(self,search,start):
|
def build_video_rest_api_request(self, search, start):
|
||||||
# Didn't yet find a correct way to do a search with a filter set to local.
|
"""Build the URL of an HTTP request using the PeerTube videos REST API.
|
||||||
# then if a search value is given it won't filter on local
|
|
||||||
|
The same function is used for browsing and searching videos.
|
||||||
|
|
||||||
|
:param search: keywords to search
|
||||||
|
:type search: string
|
||||||
|
:param start: offset
|
||||||
|
:type start: int
|
||||||
|
:return: the URL of the request
|
||||||
|
:rtype: str
|
||||||
|
|
||||||
|
Didn't yet find a correct way to do a search with a filter set to
|
||||||
|
local. Then if a search value is given it won't filter on local
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Common parameters of the request
|
||||||
|
params = {
|
||||||
|
'count': self.items_per_page,
|
||||||
|
'start': start,
|
||||||
|
'sort': self.sort_method
|
||||||
|
}
|
||||||
|
|
||||||
|
# Depending on the type of request (search or list videos), add
|
||||||
|
# specific parameters and define the API to use
|
||||||
if search is None:
|
if search is None:
|
||||||
# video api does not provide search=
|
# Video API does not provide "search" but provides "filter" so add
|
||||||
req = '{0}/api/v1/videos?count={1}&start={2}&sort={3}&filter={4}'.format(self.selected_inst, self.items_per_page, start, self.sort_method,self.video_filter)
|
# it to the parameters
|
||||||
|
params.update({'filter': self.video_filter})
|
||||||
|
api_url = '/api/v1/videos'
|
||||||
else:
|
else:
|
||||||
# search api does not provide filter=
|
# Search API does not provide "filter" but provides "search" so add
|
||||||
req = '{0}/api/v1/search/videos?count={1}&start={2}&sort={3}&search={4}'.format(self.selected_inst, self.items_per_page, start, self.sort_method,search)
|
# it to the parameters
|
||||||
|
params.update({'search': search})
|
||||||
|
api_url = '/api/v1/search/videos'
|
||||||
|
|
||||||
|
# Build the full URL of the request (instance + API + parameters)
|
||||||
|
req = '{0}?{1}'.format(urljoin(self.selected_inst, api_url),
|
||||||
|
urlencode(params))
|
||||||
|
|
||||||
|
return req
|
||||||
|
|
||||||
|
def build_browse_instances_rest_api_request(self, start):
|
||||||
|
"""Build the URL of an HTTP request using the PeerTube REST API to
|
||||||
|
browse the PeerTube instances.
|
||||||
|
|
||||||
|
:param start: offset
|
||||||
|
:type start: int
|
||||||
|
:return: the URL of the request
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Create the parameters of the request
|
||||||
|
params = {
|
||||||
|
'count': self.items_per_page,
|
||||||
|
'start': start
|
||||||
|
}
|
||||||
|
|
||||||
|
# Join the base URL with the REST API and the parameters
|
||||||
|
req = '{0}?{1}'.format('https://instances.joinpeertube.org/api/v1/instances',
|
||||||
|
urlencode(params))
|
||||||
|
|
||||||
return req
|
return req
|
||||||
|
|
||||||
def search_videos(self, start):
|
def search_videos(self, start):
|
||||||
|
@ -198,9 +302,9 @@ class PeertubeAddon():
|
||||||
# Go back to main menu when user cancels
|
# Go back to main menu when user cancels
|
||||||
if not search:
|
if not search:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Create the PeerTube REST API request for searching videos
|
# Create the PeerTube REST API request for searching videos
|
||||||
req = self.build_peertube_rest_api_search_request(search,start)
|
req = self.build_video_rest_api_request(search, start)
|
||||||
|
|
||||||
# Send the query
|
# Send the query
|
||||||
results = self.query_peertube(req)
|
results = self.query_peertube(req)
|
||||||
|
@ -218,7 +322,7 @@ class PeertubeAddon():
|
||||||
xbmcplugin.endOfDirectory(self.plugin_id)
|
xbmcplugin.endOfDirectory(self.plugin_id)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def browse_videos(self, start):
|
def browse_videos(self, start):
|
||||||
"""
|
"""
|
||||||
Function to navigate through all the video published by a PeerTube instance
|
Function to navigate through all the video published by a PeerTube instance
|
||||||
|
@ -227,7 +331,7 @@ class PeertubeAddon():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Create the PeerTube REST API request for listing videos
|
# Create the PeerTube REST API request for listing videos
|
||||||
req = self.build_peertube_rest_api_search_request(None,start)
|
req = self.build_video_rest_api_request(None, start)
|
||||||
|
|
||||||
# Send the query
|
# Send the query
|
||||||
results = self.query_peertube(req)
|
results = self.query_peertube(req)
|
||||||
|
@ -242,14 +346,14 @@ class PeertubeAddon():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def browse_instances(self, start):
|
def browse_instances(self, start):
|
||||||
"""
|
"""
|
||||||
Function to navigate through all PeerTube instances
|
Function to navigate through all PeerTube instances
|
||||||
:param start: str
|
:param start: str
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Create the PeerTube REST API request for browsing PeerTube instances
|
# Create the PeerTube REST API request for browsing PeerTube instances
|
||||||
req = '{0}/api/v1/instances?count={1}&start={2}'.format('https://instances.joinpeertube.org', self.items_per_page, start)
|
req = self.build_browse_instances_rest_api_request(start)
|
||||||
|
|
||||||
# Send the query
|
# Send the query
|
||||||
results = self.query_peertube(req)
|
results = self.query_peertube(req)
|
||||||
|
@ -260,7 +364,7 @@ class PeertubeAddon():
|
||||||
# Add our listing to Kodi.
|
# Add our listing to Kodi.
|
||||||
xbmcplugin.addDirectoryItems(self.plugin_id, listing, len(listing))
|
xbmcplugin.addDirectoryItems(self.plugin_id, listing, len(listing))
|
||||||
xbmcplugin.endOfDirectory(self.plugin_id)
|
xbmcplugin.endOfDirectory(self.plugin_id)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def play_video_continue(self, data):
|
def play_video_continue(self, data):
|
||||||
|
@ -271,8 +375,8 @@ class PeertubeAddon():
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
xbmc.log('PeertubeAddon: Received metadata_downloaded signal, will start playing media', xbmc.LOGDEBUG)
|
self.debug('Received metadata_downloaded signal, will start playing media')
|
||||||
self.play = 1
|
self.play = 1
|
||||||
self.torrent_f = data['file']
|
self.torrent_f = data['file']
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -284,12 +388,12 @@ class PeertubeAddon():
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
xbmc.log('PeertubeAddon: Starting torrent download ({0})'.format(torrent_url), xbmc.LOGDEBUG)
|
self.debug('Starting torrent download ({0})'.format(torrent_url))
|
||||||
|
|
||||||
# Start a downloader thread
|
# Start a downloader thread
|
||||||
AddonSignals.sendSignal('start_download', {'url': torrent_url})
|
AddonSignals.sendSignal('start_download', {'url': torrent_url})
|
||||||
|
|
||||||
# Wait until the PeerTubeDownloader has downloaded all the torrent's metadata
|
# Wait until the PeerTubeDownloader has downloaded all the torrent's metadata
|
||||||
AddonSignals.registerSlot('plugin.video.peertube', 'metadata_downloaded', self.play_video_continue)
|
AddonSignals.registerSlot('plugin.video.peertube', 'metadata_downloaded', self.play_video_continue)
|
||||||
timeout = 0
|
timeout = 0
|
||||||
while self.play == 0 and timeout < 10:
|
while self.play == 0 and timeout < 10:
|
||||||
|
@ -305,32 +409,34 @@ class PeertubeAddon():
|
||||||
xbmc.sleep(3000)
|
xbmc.sleep(3000)
|
||||||
|
|
||||||
# Pass the item to the Kodi player for actual playback.
|
# Pass the item to the Kodi player for actual playback.
|
||||||
xbmc.log('PeertubeAddon: Starting video playback ({0})'.format(torrent_url), xbmc.LOGDEBUG)
|
self.debug('Starting video playback ({0})'.format(torrent_url))
|
||||||
play_item = xbmcgui.ListItem(path=self.torrent_f)
|
play_item = xbmcgui.ListItem(path=self.torrent_f)
|
||||||
xbmcplugin.setResolvedUrl(self.plugin_id, True, listitem=play_item)
|
xbmcplugin.setResolvedUrl(self.plugin_id, True, listitem=play_item)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def select_instance(self, instance):
|
def select_instance(self, instance):
|
||||||
"""
|
"""
|
||||||
Change currently selected instance to 'instance' parameter
|
Change currently selected instance to 'instance' parameter
|
||||||
:param instance: str
|
:param instance: str
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.selected_inst = 'https://' + instance
|
self.selected_inst = 'https://' + instance
|
||||||
xbmcgui.Dialog().notification('Current instance changed', 'Changed current instance to {0}'.format(self.selected_inst), xbmcgui.NOTIFICATION_INFO)
|
xbmcgui.Dialog().notification('Current instance changed', 'Changed current instance to {0}'.format(self.selected_inst), xbmcgui.NOTIFICATION_INFO)
|
||||||
xbmc.log('PeertubeAddon: Changing currently selected instance to {0}'.format(self.selected_inst), xbmc.LOGDEBUG)
|
self.debug('Changing currently selected instance to {0}'
|
||||||
|
.format(self.selected_inst))
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def build_kodi_url_action_url(self,action,url):
|
def build_kodi_url(self, parameters):
|
||||||
url = '{0}?action={1}&url={2}'.format(self.plugin_url,action,url)
|
"""Build a Kodi URL based on the parameters.
|
||||||
return url
|
|
||||||
|
|
||||||
def build_kodi_url_action(self,action):
|
:param parameters: dict containing all the parameters that will be
|
||||||
url = '{0}?action={1}&start=0'.format(self.plugin_url,action)
|
encoded in the URL
|
||||||
return url
|
"""
|
||||||
|
|
||||||
|
return '{0}?{1}'.format(self.plugin_url, urlencode(parameters))
|
||||||
|
|
||||||
def main_menu(self):
|
def main_menu(self):
|
||||||
"""
|
"""
|
||||||
|
@ -344,17 +450,17 @@ class PeertubeAddon():
|
||||||
|
|
||||||
# 1st menu entry
|
# 1st menu entry
|
||||||
list_item = xbmcgui.ListItem(label='Browse selected instance')
|
list_item = xbmcgui.ListItem(label='Browse selected instance')
|
||||||
url = self.build_kodi_url_action('browse_videos')
|
url = self.build_kodi_url({'action': 'browse_videos', 'start': 0})
|
||||||
listing.append((url, list_item, True))
|
listing.append((url, list_item, True))
|
||||||
|
|
||||||
# 2nd menu entry
|
# 2nd menu entry
|
||||||
list_item = xbmcgui.ListItem(label='Search on selected instance')
|
list_item = xbmcgui.ListItem(label='Search on selected instance')
|
||||||
url = self.build_kodi_url_action('search_videos')
|
url = self.build_kodi_url({'action': 'search_videos', 'start': 0})
|
||||||
listing.append((url, list_item, True))
|
listing.append((url, list_item, True))
|
||||||
|
|
||||||
# 3rd menu entry
|
# 3rd menu entry
|
||||||
list_item = xbmcgui.ListItem(label='Select other instance')
|
list_item = xbmcgui.ListItem(label='Select other instance')
|
||||||
url = self.build_kodi_url_action('browse_instances')
|
url = self.build_kodi_url({'action': 'browse_instances', 'start': 0})
|
||||||
listing.append((url, list_item, True))
|
listing.append((url, list_item, True))
|
||||||
|
|
||||||
# Add our listing to Kodi.
|
# Add our listing to Kodi.
|
||||||
|
@ -362,7 +468,7 @@ class PeertubeAddon():
|
||||||
|
|
||||||
# Finish creating a virtual folder.
|
# Finish creating a virtual folder.
|
||||||
xbmcplugin.endOfDirectory(self.plugin_id)
|
xbmcplugin.endOfDirectory(self.plugin_id)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def router(self, paramstring):
|
def router(self, paramstring):
|
||||||
|
@ -400,6 +506,7 @@ class PeertubeAddon():
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
# Initialise addon
|
# Initialise addon
|
||||||
|
|
|
@ -39,5 +39,5 @@ msgid "Delete downloaded videos when Kodi exits"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#30005"
|
msgctxt "#30005"
|
||||||
msgid "Filter local or all videos ( for browsing only )"
|
msgid "Filter local or all videos (for browsing only)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -7,5 +7,5 @@
|
||||||
<setting id="preferred_resolution" type="select" values="1080|720|480|360|240" default='480' label="30003"/>
|
<setting id="preferred_resolution" type="select" values="1080|720|480|360|240" default='480' label="30003"/>
|
||||||
<setting type="sep"/>
|
<setting type="sep"/>
|
||||||
<setting id="delete_files" type="bool" default="true" label="30004"/>
|
<setting id="delete_files" type="bool" default="true" label="30004"/>
|
||||||
<setting id="video_filter" type="select" values="local|all-local" default="all-local" label="30005"/>
|
<setting id="video_filter" type="select" values="local|all-local (requires admin privileges)" default="local" label="30005"/>
|
||||||
</settings>
|
</settings>
|
||||||
|
|
Loading…
Reference in New Issue