Commit 7ebd78a4 authored by Dupin's avatar Dupin
Browse files

Initial commit

parents
# Kodi PeerTube
PeerTube plugin for Kodi
Work with direct download, need help to use torrent player instead.
from xbmcswift2 import Plugin
from math import ceil
import resources.lib.api as peertube
STRINGS = {
'previous': 10001,
'next': 10002,
'browse_instances': 30001,
'my_instances': 30002,
'my_channels': 30003,
'add_to_my_instances': 30011,
'del_from_my_instances': 30012,
'add_to_my_channels': 30021,
'del_from_my_channels': 30022,
'lastest_videos': 30031,
'list_of_channels': 30032,
'list_of_accounts': 30033
}
ITEMS_PER_PAGES = 50
plugin = Plugin()
my_instances = plugin.get_storage('my_instances.json', file_format='json')
my_channels = plugin.get_storage('my_channels.json', file_format='json')
@plugin.route('/')
def show_root_menu():
items = (
{'label': _('browse_instances'),
'path': plugin.url_for('show_list_of_instances')},
{'label': _('my_instances'),
'path': plugin.url_for('show_my_instances')},
{'label': _('my_channels'),
'path': plugin.url_for('show_my_channels')}
)
return plugin.finish(items)
@plugin.route('/instances/')
def show_list_of_instances():
__init_request_args()
__init_pagine()
instances = peertube.load_list_of_instances(params=plugin.request.args)
items = __instance_item_list(instances['data'])
return __pagine(show_list_of_instances, items, instances['total'])
@plugin.route('/instances/<host>/')
def show_instance(host):
items = [
{ 'label': _('lastest_videos'),
'path': plugin.url_for(endpoint='show_list_of_videos', host=host, sort='-publishedAt') },
{ 'label': _('list_of_channels'),
'path': plugin.url_for(endpoint='show_list_of_channels', host=host) },
{ 'label': _('list_of_accounts'),
'path': plugin.url_for(endpoint='show_list_of_accounts', host=host) }
]
return plugin.finish(items)
@plugin.route('/videos/<host>/')
def show_list_of_videos(host):
__init_request_args()
__init_pagine()
videos = peertube.load_list_of_videos(host, params=plugin.request.args)
items = __video_item_list(host, videos['data'])
return __pagine(show_list_of_videos, items, videos['total'], host=host)
@plugin.route('/videos/<host>/<uuid>/')
def show_video(host, uuid):
video = peertube.load_video(host , uuid)
stream_url = video['files'][0]['fileDownloadUrl']
plugin.set_resolved_url(stream_url)
@plugin.route('/accounts/<host>')
def show_list_of_accounts(host):
__init_request_args()
__init_pagine()
accounts = peertube.load_list_of_accounts(host, params=plugin.request.args)
items = __account_item_list(host, accounts['data'])
return __pagine(show_list_of_accounts, items, accounts['total'], host=host)
@plugin.route('/accounts/<host>/<name>')
def show_account_videos(host, name):
videos = peertube.load_account_videos(host, name)
return __video_item_list(host, videos)
@plugin.route('/channels/<host>/')
def show_list_of_channels(host):
__init_request_args()
__init_pagine()
channels = peertube.load_list_of_channels(host, params=plugin.request.args)
items = __channel_item_list(channels['data'])
return __pagine(show_list_of_channels, items, channels['total'], host=host)
@plugin.route('/channels/<host>/<uuid>/')
def show_channel_videos(host, uuid):
__init_request_args()
__init_pagine()
videos = peertube.load_channel_list_of_videos(host, uuid, params=plugin.request.args)
items = __video_item_list(host, videos['data'])
return __pagine(show_channel_videos, items, videos['total'], host=host, uuid=uuid)
@plugin.route('/my/instances/add/<host>/')
def add_to_my_instances(host):
instance = peertube.load_instance_config(host)['instance']
if host not in my_instances:
my_instances[host] = {
'name': instance['name'],
'host': host,
'shortDescription': instance['shortDescription']
}
my_instances.sync()
@plugin.route('/my/instances/del/<host>/')
def del_from_my_instances(host):
if host in my_instances:
del my_instances[host]
my_instances.sync()
@plugin.route('/my/instances/')
def show_my_instances():
return __instance_item_list(my_instances.values())
@plugin.route('/my/channels/add/<host>/<name>/')
def add_to_my_channels(host, name):
channel = peertube.load_channel(host, name)
key = name + '@' + host
if key not in my_channels:
my_channels[key] = channel
my_channels.sync()
@plugin.route('/my/channels/del/<host>/<name>/')
def del_from_my_channels(host, name):
key = name + '@' + host
if key in my_channels:
del my_channes[key]
my_channels.sync()
@plugin.route('/my/channels/')
def show_my_channels():
return __channel_item_list(my_channels.values())
def __video_item(host, video):
thumb = 'https://{}{}'.format(host, video['thumbnailPath'])
context_menu = [__channel_context_item(video['channel'])]
return {
'label': video['name'],
'thumbnail': thumb,
'info' : {
'title': video['name'],
'plot': video['description'],
'duration': int(video['duration']),
'date': video['createdAt'].partition("T")[0].replace("-", "."),
'dateadded': video['publishedAt'].replace("T", " ").partition(".")[0]
},
'context_menu': context_menu,
'is_playable': True,
'path': plugin.url_for(endpoint='show_video', host=host, uuid=video['uuid'])
}
def __video_item_list(host, videos):
return [__video_item(host, video) for video in videos]
def __account_item(host, account):
name = account['name'] + '@' + account['host']
thumb = None
if account['avatar']:
thumb = 'https://{}{}'.format(host, account['avatar']['path'])
return {
'label': name,
'thumbnail': thumb,
'info': { 'plot': account['description']},
'path': plugin.url_for(endpoint='show_account_videos', host=host, name=name)
}
def __account_item_list(host, accounts):
return [__account_item(host, account) for account in accounts]
def __channel_context_item(channel):
key = channel['name'] + '@' + channel['host']
context = 'del_from_my_channels' if key in my_channels else 'add_to_my_channels'
return (_(context),
'XBMC.RunPlugin({})'.format(
plugin.url_for(
endpoint=context,
name=channel['name'],
host=channel['host']
)
)
)
def __channel_item(channel):
thumb = 'https://{}{}'.format(channel['host'], channel['avatar'])
context_menu = [__channel_context_item(channel)]
return {
'label': channel['displayName'],
'thumbnail': thumb,
'info': {
'plot': channel['description']
},
'context_menu': context_menu,
'path': plugin.url_for(endpoint='show_channel_videos', host=channel['host'], uuid=channel['name'])
}
def __channel_item_list(channels):
return [__channel_item(channel) for channel in channels]
def __instance_item(instance):
host=instance['host'].encode('utf-8')
context_my = 'del_from_my_instances' if instance['host'] in my_instances else 'add_to_my_instances'
context_menu = [
(_(context_my),
'XBMC.RunPlugin({})'.format(
plugin.url_for(
endpoint=context_my,
host=host
)
))
]
return {
'label': host,
'info': {
'plot': instance['shortDescription']
},
'context_menu': context_menu,
'path': plugin.url_for(endpoint='show_instance', host=host)
}
def __instance_item_list(instances):
return [__instance_item(instance) for instance in instances]
def __init_request_args():
# Items in args request are in list, but i want the item itself
for key, value in plugin.request.args.items():
plugin.request.args[key] = value[0]
def __init_pagine():
if 'start' not in plugin.request.args:
plugin.request.args['start'] = str(0)
if 'count' not in plugin.request.args:
plugin.request.args['count'] = str(ITEMS_PER_PAGES)
def __pagine(caller, items, total, **kwargs):
start = int(plugin.request.args['start'])
count = int(plugin.request.args['count'])
if start > 0:
items.insert(0, {
'label': '<< ' +_('previous'),
'path': plugin.url_for(caller.__name__, start=str(max(0, start-count)), count=str(count), **kwargs)
})
if (start + count) < total:
items.append({
'label': _('next') + ' >>',
'path': plugin.url_for(caller.__name__, start=str(start+count), count=str(count), **kwargs)
})
return plugin.finish(items, update_listing=True)
def _(string_id):
if string_id in STRINGS:
return plugin.get_string(STRINGS[string_id])
else:
plugin.log.warning('String is missing: %s' % string_id)
return string_id
if __name__ == '__main__':
plugin.run()
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.peertube" name="PeerTube" version="0.0.2" provider-name="dupin">
<requires>
<import addon="xmc.python" version="2.1.0"/>
<import addon="script.module.xbmcswift2" version="2.4.0"/>
</requires>
<extension point="xbmc.python.pluginsource" library="addon.py">
<provides>video</provides>
</extension>
<extension point="xbmc.addon.metadata">
<language></language>
<summary lang="fr">Plugin PeerTube</summary>
<description lang="fr">PeerTube est un logiciel libre d'hébergement de vidéos décentralisé.</description>
<summary lang="en">Plugin for PeerTube</summary>
<description lang="en">PeerTube is a free, decentralized, federated video platform that uses peer-to-peer technology to reduce load on individual servers.</description>
<platform>all</platform>
<license></license>
<forum></forum>
<website></website>
<email></email>
<source></source>
<news></news>
</extension>
</addon>
fanart.jpg

20.9 KB

icon.png

3.16 KB

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<strings>
<!-- Misc -->
<string id="10001">Précédent</string>
<string id="10002">Suivant</string>
<!-- Root Menu -->
<string id="30001">Parcourir les instances</string>
<string id="30002">Mes instances</string>
<string id="30003">Mes chaines</string>
<!-- Instance Context Menu -->
<string id="30011">Ajouter à mes instances</string>
<string id="30012">Retirer de mes instances</string>
<!-- Channel Context Menu -->
<string id="30021">Ajouter à mes chaines</string>
<string id="30022">Retirer de mes chaines</string>
<!-- Instance Menu -->
<string id="30031">Dernières vidéos</string>
<string id="30032">Liste des chaines</string>
<string id="30033">Liste des utilisateurs</string>
</strings>
import urllib
import json
API_V1 = 'https://{host}/api/v1/{path}'
INSTANCES_PROVIDER = 'instances.joinpeertube.org'
def __load_datas(url):
response = urllib.urlopen(url)
charset = response.headers.getparam('charset')
if charset is None:
charset = 'utf-8'
return json.loads(response.read().decode(charset))
def __peertube_query(host, path, params={}):
url = API_V1.format(host=host, path=path)
if params:
url = url + '?' + __build_query_string(params)
return __load_datas(url)
def __build_query_string(args):
args = {k: v for k, v in args.items() if v} # Remove None items
return urllib.urlencode(args)
def load_list_of_instances(params={}):
query_string = __build_query_string(params)
url = 'https://{host}/api/v1/instances?{query}'.format(host=INSTANCES_PROVIDER, query=query_string)
return __load_datas(url)
def load_instance_config(host):
return __peertube_query(host, 'config')
# params are: category, count, sort, start
def load_list_of_videos(host, params={}):
return __peertube_query(host, 'videos', params)
# params are: count, sort, start
def load_list_of_channels(host, params={}):
return __peertube_query(host, 'video-channels', params)
def load_channel(host, name):
return __peertube_query(host, 'video-channels/' + name)
def load_channel_list_of_videos(host, channel_uid, params):
path = 'video-channels/' + channel_uid + '/videos'
return __peertube_query(host, path, params)
def load_video(host, uuid):
path='videos/' + uuid
return __peertube_query(host, path)
def load_list_of_accounts(host, params):
datas = __peertube_query(host, 'accounts', params)
return datas
def load_account_videos(host, name):
path = 'accounts/' + name + '/videos'
datas = __peertube_query(host, path)
return datas['data']
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment