plugin.video.vidfltr/default.py
2018-11-14 16:52:19 +01:00

1039 lines
43 KiB
Python

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from kodi_six import xbmc, xbmcaddon, xbmcgui, xbmcplugin
import sys
import os
import urllib
import json
import io
import re
import time
from datetime import date, datetime, timedelta
import random
from unidecode import unidecode
addonID = 'plugin.video.vidfltr'
addon = xbmcaddon.Addon(id=addonID)
pluginhandle = int(sys.argv[1])
translation = addon.getLocalizedString
addonDir = xbmc.translatePath(addon.getAddonInfo('path'))
defaultFanart = os.path.join(addonDir, 'resources/images/noicon.png')
fanart = os.path.join(addonDir, 'noicon.png')
icon = os.path.join(addonDir, 'noicon.png')
addon_work_folder = xbmc.translatePath("special://profile/addon_data/" + addonID)
jsonVideos = xbmc.translatePath("special://profile/addon_data/" + addonID + "/videos.json")
jsonArtists = xbmc.translatePath("special://profile/addon_data/" + addonID + "/artists.json")
jsonStyles = xbmc.translatePath("special://profile/addon_data/" + addonID + "/styles.json")
maxFileAge = int(addon.getSetting("maxFileAge"))
maxFileAge = maxFileAge * 60
mediatype = addon.getSetting("mediatype")
# show only official, fanmade or all videos?
videoselection = str(addon.getSetting("videoselection")).lower()
# despite this selection show all in similar playlists and more from?
relatedselection = str(addon.getSetting("relatedselection")).lower()
playLocalFile = str(addon.getSetting("playLocalFile")).lower()
filesinlists = int(addon.getSetting("filesinlists"))
useYTDL = addon.getSetting("useytdl")
# show if video is unofficial in title
showunoffintitle = addon.getSetting("showunoffintitle")
# summed up provider playcount considered to be played often
pcounthigh = int(addon.getSetting("pcounthigh"))
# local playcount considered to be played often
lcounthigh = int(addon.getSetting("lcounthigh"))
# addon developer playcount considered to be often played
acounthigh = int(addon.getSetting("acounthigh"))
# summed up provider comment count considered to be high
ccounthigh = int(addon.getSetting("ccounthigh"))
# like count considered to be high
likecounthigh = int(addon.getSetting("likecounthigh"))
# dislike count considered to be high
dislikecounthigh = int(addon.getSetting("dislikecounthigh"))
# play from here. Does work in general but refreshes the container which is bit contra-productive in random lists ;)
# XBMC.PlayMedia(plugin://plugin.video.vidfltr/?mode=sortTitlesBy&url=year%7crandom%7c-1,isdir)
if not os.path.isdir(addon_work_folder):
os.mkdir(addon_work_folder)
def getVideos():
if not os.path.isfile(jsonVideos):
updateData()
else:
fileTime = os.path.getmtime(jsonVideos)
now = time.time()
if now - fileTime > maxFileAge:
updateData()
with io.open(jsonVideos, 'r', encoding='utf-8') as f:
data = json.load(f)
return data
def getArtists():
if not os.path.isfile(jsonArtists):
updateData()
else:
fileTime = os.path.getmtime(jsonArtists)
now = time.time()
if now - fileTime > maxFileAge:
updateData()
with io.open(jsonArtists, 'r', encoding='utf-8') as f:
data = json.load(f)
return data
def getStyles():
if not os.path.isfile(jsonStyles):
updateData()
else:
fileTime = os.path.getmtime(jsonStyles)
now = time.time()
if now - fileTime > maxFileAge:
updateData()
with io.open(jsonStyles, 'r', encoding='utf-8') as f:
data = json.load(f)
return data
def updateData():
try:
target = urllib.URLopener()
target.retrieve("https://vidfltr.slashproc.org/api/videos.json", jsonVideos)
target = urllib.URLopener()
target.retrieve("https://vidfltr.slashproc.org/api/artists.json", jsonArtists)
target = urllib.URLopener()
target.retrieve("https://vidfltr.slashproc.org/api/styles.json", jsonStyles)
except:
# return to getVideos/getArtists on network error or 404 or...
# ...to make it not fatal if the json can't be updated
return
def alphabet():
alphabet = ['#']
for letter in range(65, 91):
alphabet.append(chr(letter))
return alphabet
def main():
addDir(translation(30029), '', 'mainrandom', fanart)
addDir(translation(30012), '', 'mainsorted', fanart)
addDir(translation(30022), '&sort=all', 'styles', fanart)
addDir(translation(30005), '', 'artists', fanart)
addDir(translation(30118), '', 'countrycodes', fanart)
addDir(translation(30001), '', 'search', fanart)
addDir(translation(30006), '', 'updateData', fanart)
endOfDirectory()
def artists():
for alpha in alphabet():
addDir(alpha, '&style=artists&limit=' + alpha, 'showArtist', fanart)
endOfDirectory()
def countrycodes():
data = getArtists()
result = []
for entry in data:
countrycode = entry['countrycode']
if countrycode != "" and countrycode not in result:
result.append(countrycode)
elif countrycode == "" and "unknown" not in result:
result.append('unknown')
result.sort()
for entry in result:
addDir(entry, '&style=country&limit=' + entry, 'showArtist', fanart, len(result))
endOfDirectory()
def mainrandom():
addDir(translation(30034), '&limit=year&sort=random&start=0', 'sortTitlesBy', fanart)
addDir(translation(30035), '&limit=year&sort=random&start=0&hit=true', 'sortTitlesBy', fanart)
addDir(translation(30017), '&limit=all&sort=random&start=0', 'sortTitlesBy', fanart)
addDir(translation(30031), '&limit=all&sort=random&start=0&hit=true', 'sortTitlesBy', fanart)
addDir(translation(30117), '&sort=random', 'numbers', fanart)
addDir(translation(30022), '&sort=random', 'styles', fanart)
endOfDirectory()
def mainsorted():
addDir(translation(30032), '&limit=all&sort=date&start=0', 'sortTitlesBy', fanart)
addDir(translation(30033), '&limit=all&sort=date&start=0&hit=true', 'sortTitlesBy', fanart)
addDir(translation(30117), '&sort=sorted', 'numbers', fanart)
addDir(translation(30022), '&sort=sorted', 'styles', fanart)
endOfDirectory()
def numbers():
if sort == "random":
addDir(translation(30111), '&limit=all&sort=random&start=0&count=pcount', 'sortTitlesBy', fanart)
addDir(translation(30113), '&limit=all&sort=random&start=0&count=acount', 'sortTitlesBy', fanart)
addDir(translation(30114), '&limit=all&sort=random&start=0&count=comments', 'sortTitlesBy', fanart)
addDir(translation(30115), '&limit=all&sort=random&start=0&count=likes', 'sortTitlesBy', fanart)
addDir(translation(30116), '&limit=all&sort=random&start=0&count=dislikes', 'sortTitlesBy', fanart)
addDir(translation(30119), '&limit=all&sort=random&start=0&count=controversial', 'sortTitlesBy', fanart)
endOfDirectory()
if sort == "sorted":
addDir(translation(30111), '&limit=all&sort=count&start=0&count=pcount', 'sortTitlesBy', fanart)
addDir(translation(30113), '&limit=all&sort=count&start=0&count=acount', 'sortTitlesBy', fanart)
addDir(translation(30114), '&limit=all&sort=count&start=0&count=comments', 'sortTitlesBy', fanart)
addDir(translation(30115), '&limit=all&sort=count&start=0&count=likes', 'sortTitlesBy', fanart)
addDir(translation(30116), '&limit=all&sort=count&start=0&count=dislikes', 'sortTitlesBy', fanart)
addDir(translation(30119), '&limit=all&sort=count&start=0&count=controversial', 'sortTitlesBy', fanart)
endOfDirectory()
def play(url):
data = getVideos()
result = []
slug = url
if slug != "":
for entry in data:
if entry['slug'] == slug:
# play from local file.
# does only work on addon developer pc -- atleast for now
if playLocalFile == "true":
musicvideoid = "-1"
try:
# try to find music video in library with utc time from slug
dateadded = datetime.utcfromtimestamp(float(entry['slug']))
dateadded = str(dateadded)
jsonRespond = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "params": {"sort": {"order": "ascending", "method": "title"}, "filter": {"operator": "contains", "field": "dateadded", "value": "%s"}, "properties": ["file", "playcount", "genre", "artist", "title"]}, "limits":{"end":0,"start":0}, "method": "VideoLibrary.GetMusicvideos", "id": "libMusicVideos"}' % dateadded)
local = json.loads(jsonRespond)
for vid in local["result"]["musicvideos"]:
playback_url = vid["file"]
musicvideoid = int(vid["musicvideoid"])
playcount = int(vid['playcount'])
genre = vid['genre']
artist = vid['artist']
artist = ''.join(artist)
title = vid['title']
title = (artist + ' - ' + title )
xbmc.log(msg="date from slug", level=xbmc.LOGDEBUG)
except:
try:
# if not found because of inconsistencies based on MEZ vs. MESZ try to find music video in library with time from dateadded
dateadded = entry['dateadded']
jsonRespond = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "params": {"sort": {"order": "ascending", "method": "title"}, "filter": {"operator": "contains", "field": "dateadded", "value": "%s"}, "properties": ["file", "playcount", "genre", "artist", "title"]}, "limits":{"end":0,"start":0}, "method": "VideoLibrary.GetMusicvideos", "id": "libMusicVideos"}' % dateadded)
local = json.loads(jsonRespond)
for vid in local["result"]["musicvideos"]:
playback_url = vid["file"]
musicvideoid = int(vid["musicvideoid"])
playcount = int(vid['playcount'])
genre = vid['genre']
artist = vid['artist']
artist = ''.join(artist)
title = vid['title']
title = (artist + ' - ' + title )
xbmc.log(msg="date from dateadded", level=xbmc.LOGDEBUG)
except:
if useYTDL == "true":
# if play from local file is set but nonetheless not found use Provider-URL
xbmc.log(msg="not found, play from provider", level=xbmc.LOGDEBUG)
import YDStreamExtractor
idVideo = entry['purl']
ytdl = YDStreamExtractor.getVideoInfo(idVideo)
playback_url = ytdl.streamURL()
musicvideoid = "-1"
else:
# without youtube_dl
xbmc.log(msg="without ytdl", level=xbmc.LOGDEBUG)
playback_url = entry['url']
# default mode: play from provider -- either with ytdl or vimeo/youtube/dailymotion addon
else:
xbmc.log(msg="play from provider", level=xbmc.LOGDEBUG)
if useYTDL == "true":
xbmc.log(msg="with ytdl", level=xbmc.LOGDEBUG)
import YDStreamExtractor
idVideo = entry['purl']
ytdl = YDStreamExtractor.getVideoInfo(idVideo)
playback_url = ytdl.streamURL()
else:
# without youtube_dl
xbmc.log(msg="without ytdl", level=xbmc.LOGDEBUG)
playback_url = entry['url']
item = xbmcgui.ListItem(path=playback_url)
# avoids CCurlFile::Stat - Failed: Unsupported protocol(1) for plugin://
# disabled, unclear if this is the way to
#item.setContentLookup(False)
# add some Listitem info for local files
# should already be set in addVideo() but it isn't, doh!
if playLocalFile == "true" and not musicvideoid == "-1":
item.setInfo(type="video", infoLabels={"mediatype": mediatype, "dbid": musicvideoid, "title": title, "genre": genre })
# doesn't work
# item.setProperty('StartOffset', '56.4')
# item.setProperty("VolumeAmplification", "7")
# xbmc.log(msg=item.getProperty('VolumeAmplification'), level=xbmc.LOGNOTICE)
xbmc.log(msg=playback_url, level=xbmc.LOGNOTICE)
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, item)
def styles():
data = getVideos()
channels = []
xbmc.log(msg=sort, level=xbmc.LOGDEBUG)
for entry in data:
if entry['style'] not in channels:
channels.append(entry['style'])
length = len(channels)
channels.sort()
for channel in channels:
addDir(channel, '&style=' + channel + '&sort=' + sort, 'showChannel', getFanart(channel), length)
endOfDirectory()
def showChannel(style, sort):
channel = style
if channel != "":
fanart = getFanart(channel)
xbmc.log(msg=channel, level=xbmc.LOGDEBUG)
if sort == "sorted" or sort == "all":
addDir(translation(30032), '&limit=' + channel + '&sort=date&start=0', 'sortTitlesBy', fanart, 6)
addDir(translation(30033), '&limit=' + channel + '&sort=date&start=0&hit=true', 'sortTitlesBy', fanart, 6)
# genre splitted artists, only menu entry which uses the old initials mode and
# therefore entries where the artist isn't at the beginning of the title are excluded :-(
addDir(translation(30005), channel, 'sortTitleInitials', fanart, 6)
if sort == "random" or sort == "all":
addDir(translation(30029), '&limit=' + channel + '&sort=random&start=0', 'sortTitlesBy', fanart, 6)
addDir(translation(30031), '&limit=' + channel + '&sort=random&start=0&hit=true', 'sortTitlesBy', fanart, 6)
endOfDirectory()
def sortTitleInitials(channel=""):
data = getVideos()
result = []
fanart = getFanart(channel)
if channel != "":
for entry in data:
if entry['style'] == channel:
if len(entry['title']) > 0:
l = entry['title'][0].upper()
if not re.match('^([a-z|A-Z])', l):
l = '#'
if l not in result:
if videoselection == "0":
if "true" in entry['official'].lower():
result.append(l)
elif videoselection == "1":
if "false" in entry['official'].lower():
result.append(l)
else:
result.append(l)
result.sort()
for entry in result:
addDir(entry, channel + '|' + entry, 'sortTitles', fanart, len(result))
endOfDirectory()
def sortArtistInitials(channel=""):
data = getVideos()
result = []
fanart = getFanart(channel)
if channel != "":
for entry in data:
for artist in entry['artists']:
# xbmc.log(msg=channel.encode('utf-8'), level=xbmc.LOGNOTICE)
# xbmc.log(msg=artist.encode('utf-8'), level=xbmc.LOGNOTICE)
if artist not in channel:
if len(artist) > 0:
l = artist[0].upper()
if not re.match('^([a-z|A-Z])', l):
l = '#'
if l not in result:
if videoselection == "0":
if "true" in entry['official'].lower():
result.append(l)
elif videoselection == "1":
if "false" in entry['official'].lower():
result.append(l)
else:
result.append(l)
result.sort()
for entry in result:
addDir(entry, channel + '|' + entry,
'sortArtists', fanart, len(result))
endOfDirectory()
def sortTitles(channelInitial=""):
xbmcplugin.setContent(pluginhandle, 'musicvideos')
data = getVideos()
result = []
params = channelInitial.split("|")
channel = ""
initial = ""
if len(params) > 1:
channel = params[0]
initial = params[1]
# else:
# channel = params[0]
fanart = getFanart(channel)
# xbmc.log(msg=initial.encode('utf-8'), level=xbmc.LOGNOTICE)
if channel != "":
xbmc.log(msg=channel.encode('utf-8'), level=xbmc.LOGDEBUG)
for entry in data:
if entry['style'] == channel:
i = entry['title'][0].upper()
if initial == '#':
if not re.match('^([a-z|A-Z])', i):
if videoselection == "0":
if "true" in entry['official'].lower():
result.append(entry)
elif videoselection == "1":
if "false" in entry['official'].lower():
result.append(entry)
else:
result.append(entry)
else:
if initial == i:
if videoselection == "0":
if "true" in entry['official'].lower():
result.append(entry)
elif videoselection == "1":
if "false" in entry['official'].lower():
result.append(entry)
else:
result.append(entry)
# sloooow
#elif channel in entry['artists']:
# result.append(entry)
result.sort(key=lambda entry: entry['title'].upper())
for entry in result:
addVideo(entry)
endOfDirectory()
def showArtist(url):
# limit artists by first letter or country
data = getArtists()
result = []
# xbmc.log(msg=url, level=xbmc.LOGNOTICE)
# xbmc.log(msg=style, level=xbmc.LOGNOTICE)
# xbmc.log(msg=limit, level=xbmc.LOGNOTICE)
if style == 'artists':
for entry in data:
i = unidecode(entry['artist'])[0].upper()
if limit == '#':
if not re.match('^([a-z|A-Z])', i):
result.append(entry)
else:
if limit == i:
result.append(entry)
elif style == 'country':
for entry in data:
i = entry['countrycode']
if limit == i:
result.append(entry)
elif limit == 'unknown':
result.append(entry)
for entry in result:
artist = entry['artist']
fanart = entry['thumbnail']
if videoselection == "0":
if entry['official'] >= "1":
addDir(artist, unidecode(artist.upper()), 'sortArtists', fanart, len(result))
elif videoselection == "1":
if entry['unofficial'] >= "1":
addDir(artist, unidecode(artist.upper()), 'sortArtists', fanart, len(result))
elif videoselection == "2":
addDir(artist, unidecode(artist.upper()), 'sortArtists', fanart, len(result))
endOfDirectory()
def sortArtists(channel=""):
# get videos for individual artist
xbmcplugin.setContent(pluginhandle, 'musicvideos')
data = getVideos()
result = []
# using param=string parameters does not work here because some obscure chars
# are lost in translation so the old implementation from Mediathek Direkt with
# splitting on | will be used. Have to take a deeper look to fix this...
params = channel.split("|")
# xbmc.log(msg=url, level=xbmc.LOGNOTICE)
channel = params[0]
if len(params) > 1:
start = params[1]
if channel != "" and channel != "relaartists":
fanart = getFanart(channel)
for entry in data:
artists_upper = [unidecode(artist.upper()) for artist in entry['artists']]
if channel in artists_upper:
if videoselection == "0":
if "true" in entry['official'].lower():
result.append(entry)
elif videoselection == "1":
if "false" in entry['official'].lower():
result.append(entry)
else:
result.append(entry)
#show "more from..." artists
if channel != "" and channel == "relartists":
fanart = getFanart(channel)
for entry in data:
if entry['slug'] == start:
artists_upper = [unidecode(artist.upper()) for artist in entry['artists']]
channels = []
for channel in artists_upper:
channels.append(channel)
xbmc.log(msg=str(channels), level=xbmc.LOGNOTICE)
# nested loops don't look like an optimal solution and are a bit slow
for entry in data:
for artist in channels:
if artist in [unidecode(name.upper()) for name in entry['artists']]:
if entry not in result:
if videoselection == "0":
if "true" in entry['official'].lower():
result.append(entry)
elif videoselection == "1":
if "false" in entry['official'].lower():
result.append(entry)
else:
result.append(entry)
result.sort(key=lambda entry: entry['title'].upper())
for entry in result:
# xbmc.log(msg=url, level=xbmc.LOGNOTICE)
addVideo(entry)
endOfDirectory()
def sortTitlesBy(limit, sort, start):
xbmcplugin.setContent(pluginhandle, 'musicvideos')
data = getVideos()
result = []
channel = limit
start = int(start)
end = start + filesinlists
nextstart = end + 1
# xbmc.log(msg=channel, level=xbmc.LOGNOTICE)
fanart = getFanart(channel)
# limit to hits
if hit != "" and hit == "true":
for entry in data:
if entry['hit'] == "true":
if videoselection == "0":
if "true" in entry['official']:
result.append(entry)
elif videoselection == "1":
if "false" in entry['official']:
result.append(entry)
elif videoselection == "2":
result.append(entry)
data = result
result = []
# played often at provider
if mycount != "" and mycount == "pcount" and sort != "count":
for entry in data:
# played often at provider
if int(entry['pcount']) >= pcounthigh:
if videoselection == "0":
if "true" in entry['official']:
result.append(entry)
elif videoselection == "1":
if "false" in entry['official']:
result.append(entry)
elif videoselection == "2":
result.append(entry)
# xbmc.log(msg=str(entry['pcount']), level=xbmc.LOGNOTICE)
data = result
result = []
# played often by addon developer
if mycount != "" and mycount == "acount" and sort != "count":
for entry in data:
if int(entry['acount']) >= acounthigh:
if videoselection == "0":
if "true" in entry['official']:
result.append(entry)
elif videoselection == "1":
if "false" in entry['official']:
result.append(entry)
elif videoselection == "2":
result.append(entry)
# xbmc.log(msg=str(entry['pcount']), level=xbmc.LOGNOTICE)
data = result
result = []
# often commented
if mycount != "" and mycount == "comments" and sort != "count":
for entry in data:
if int(entry['comments']) >= ccounthigh:
if videoselection == "0":
if "true" in entry['official']:
result.append(entry)
elif videoselection == "1":
if "false" in entry['official']:
result.append(entry)
elif videoselection == "2":
result.append(entry)
# xbmc.log(msg=str(entry['pcount']), level=xbmc.LOGNOTICE)
data = result
result = []
# often liked
if mycount != "" and mycount == "likes" and sort != "count":
for entry in data:
if int(entry['likes']) >= likecounthigh:
if videoselection == "0":
if "true" in entry['official']:
result.append(entry)
elif videoselection == "1":
if "false" in entry['official']:
result.append(entry)
elif videoselection == "2":
result.append(entry)
# xbmc.log(msg=str(entry['pcount']), level=xbmc.LOGNOTICE)
data = result
result = []
# often disliked
if mycount != "" and mycount == "dislikes" and sort != "count":
for entry in data:
if int(entry['dislikes']) >= dislikecounthigh:
if videoselection == "0":
if "true" in entry['official']:
result.append(entry)
elif videoselection == "1":
if "false" in entry['official']:
result.append(entry)
elif videoselection == "2":
result.append(entry)
# xbmc.log(msg=str(entry['pcount']), level=xbmc.LOGNOTICE)
data = result
result = []
# controversial based on nearly the same number of likes and dislikes
if mycount != "" and mycount == "controversial":
for entry in data:
if int(entry['controversial']) == int(1):
if videoselection == "0":
if "true" in entry['official']:
result.append(entry)
elif videoselection == "1":
if "false" in entry['official']:
result.append(entry)
elif videoselection == "2":
result.append(entry)
# xbmc.log(msg=str(entry['pcount']), level=xbmc.LOGNOTICE)
data = result
result = []
# limit by style
if channel != "" and channel != "all" and channel != "year" and channel != "related":
for entry in data:
if entry['style'] == channel:
if videoselection == "0":
if "true" in entry['official']:
result.append(entry)
elif videoselection == "1":
if "false" in entry['official']:
result.append(entry)
elif videoselection == "2":
result.append(entry)
# or limit to last year
# hm, either style or year, not both?
elif channel != "" and channel == "year":
lastyear = datetime.now() - timedelta(days=365)
for entry in data:
# dateadded = entry['dateadded']
# ehrm, first version worked for many days but now fails?
# related to https://bugs.python.org/issue27400 ?
try:
dateadded = datetime.strptime(entry['dateadded'], '%Y-%m-%d %H:%M:%S')
except TypeError:
import time
dateadded = datetime.fromtimestamp(time.mktime(time.strptime(entry['dateadded'], '%Y-%m-%d %H:%M:%S')))
if dateadded >= lastyear:
if videoselection == "0":
if "true" in entry['official']:
result.append(entry)
elif videoselection == "1":
if "false" in entry['official']:
result.append(entry)
elif videoselection == "2":
result.append(entry)
# related tracks (generated with musly)
elif channel != "" and channel == "related":
start = str(start)
# xbmc.log(msg=str(start), level=xbmc.LOGNOTICE)
for entry in data:
if entry['slug'] == start:
# add slug for which the playlist should be shown
result.append(entry)
slugs = ""
slugs = entry['related']
# xbmc.log(msg=slugs, level=xbmc.LOGNOTICE)
for entry in data:
# add all related slugs
if entry['slug'] in slugs:
# xbmc.log(msg=str(entry), level=xbmc.LOGNOTICE)
# hm, doesn't work
if entry['artist'] not in result:
if videoselection != "2" and relatedselection != "true":
if videoselection == "0":
if "true" in entry['official']:
result.append(entry)
elif videoselection == "1":
if "false" in entry['official']:
result.append(entry)
else:
result.append(entry)
maximum = len(result)
start = 0
# "more from..." artists
elif channel != "" and channel == "relartists":
start = str(start)
for entry in data:
if entry['slug'] == start:
# add slug for which the artists should be shown
artists = ""
artists = entry['artists']
for entry in data:
xbmc.log(msg=str(artists), level=xbmc.LOGNOTICE)
# add all entries with artist in artists
if entry['artists'] in artists:
# xbmc.log(msg=str(entry), level=xbmc.LOGNOTICE)
if videoselection != "2" and relatedselection != "true":
if videoselection == "0":
if "true" in entry['official']:
result.append(entry)
elif videoselection == "1":
if "false" in entry['official']:
result.append(entry)
else:
result.append(entry)
maximum = len(result)
start = 0
# not used anywhere?
else:
for entry in data:
if videoselection == "0":
if "true" in entry['official']:
result.append(entry)
elif videoselection == "1":
if "false" in entry['official']:
result.append(entry)
elif videoselection == "2":
result.append(entry)
if sort != "" and sort == "random":
random.shuffle(result)
result = result[:filesinlists]
start = 0
end = filesinlists
maximum = filesinlists - 1
if sort != "" and sort == "date":
if channel != "":
modus = channel
else:
modus = 'all'
result = result
maximum = len(result)
if sort != "" and sort == "count":
if channel != "":
modus = channel
else:
modus = 'all'
# sort by negated count first and then by title in lexical order.
# If count would'nt be negated one had to use reverse=true
# But then the second sorting, by title would be reversed also
result = sorted(result, key = lambda i: (-1*float(i[mycount]), i['title']))
# itemgetter, should be faster (hm, but does'nt work: ValueError: could not convert string to float: pcount)
# importing "operator" for implementing itemgetter
#from operator import itemgetter
#result = sorted(result, key=itemgetter((float(mycount), 'title'),reverse = True))
maximum = len(result)
else:
maximum = len(result)
# play all (TODO)
addDir(translation(30109), '', '', fanart)
# back to VIDFLTR (only useful if the back history would be cleared)
# if start > 0:
# addDir(translation(30108), '', 'main', fanart)
for entry in result[start:end]:
addVideo(entry, mycount)
if maximum > end and sort != "random" and channel != "year":
# next page link
if sort != "" and sort == "count":
addDir(translation(30036), '&limit=' + modus + '&sort=count&start=' + str(nextstart) + '&count=' + mycount, 'sortTitlesBy', fanart)
else:
addDir(translation(30036), '&limit=' + modus + '&sort=date&start=' + str(nextstart), 'sortTitlesBy', fanart)
endOfDirectory()
def endOfDirectory():
# xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_UNSORTED)
# xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_LABEL)
# xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_DATEADDED)
# xbmcplugin.addSortMethod(
# pluginhandle, xbmcplugin.SORT_METHOD_PROGRAM_COUNT)
# xbmcplugin.addSortMethod(
# pluginhandle, xbmcplugin.SORT_METHOD_VIDEO_RUNTIME)
# xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_GENRE)
xbmcplugin.endOfDirectory(pluginhandle)
def search(channel=""):
xbmcplugin.setContent(pluginhandle, 'musicvideos')
result = []
keyboard = xbmc.Keyboard('', translation(30002))
keyboard.doModal()
if keyboard.isConfirmed() and keyboard.getText():
# search_string = keyboard.getText().encode('utf8').lower()
search_string = keyboard.getText().lower()
if len(search_string) > 1:
data = getVideos()
for entry in data:
cEntry = entry
if search_string in cEntry['title'].lower():
if channel != "":
if cEntry['style'] == channel:
# cEntry['title'] = cEntry['style']+':
# '+cEntry['title']
if videoselection == "0":
if "true" in entry['official'].lower():
result.append(cEntry)
else:
result.append(cEntry)
else:
# cEntry['title'] = cEntry['style']+':
# '+cEntry['title']
if videoselection == "0":
if "true" in entry['official'].lower():
result.append(cEntry)
else:
result.append(cEntry)
elif search_string in cEntry['artist'].lower():
if channel != "":
if cEntry['style'] == channel:
# cEntry['title'] = cEntry['style']+':
# '+cEntry['title']
if videoselection == "0":
if "true" in entry['official'].lower():
result.append(cEntry)
else:
result.append(cEntry)
else:
# cEntry['title'] = cEntry['style']+':
# '+cEntry['title']
if videoselection == "0":
if "true" in entry['official'].lower():
result.append(cEntry)
else:
result.append(cEntry)
result.sort(key=lambda entry: entry['style'].lower())
for entry in result:
addVideo(entry)
endOfDirectory()
# not used (TODO?)
def searchDate(channelDate=""):
xbmcplugin.setContent(pluginhandle, 'musicvideos')
channel = ""
date = ""
params = channelDate.split('|')
channel = params[0]
if len(params) > 1:
date = params[1]
result = []
if date == "":
dialog = xbmcgui.Dialog()
date = dialog.numeric(1, translation(30007))
date = re.sub('[^0-9|^\/]', '0', date)
date = date.replace('/', '.')
if (channel != "") and (len(date) == 10):
data = getVideos()
for entry in data:
cEntry = entry
if (entry['style'] == channel) and (entry['date'] == date):
cEntry[1] = cEntry[2] + ': ' + cEntry[1]
if videoselection == "0":
if "true" in entry['official'].lower():
result.append(cEntry)
else:
result.append(cEntry)
result.sort(key=lambda entry: entry['title'].lower())
for entry in result:
addVideo(entry)
endOfDirectory()
# not used (TODO?)
def downloadFile(video_url):
# get best qualiy url
bq_url = getBestQuality(video_url)
# get filname from video_url
filename = video_url.split('/')[-1]
filetype = filename.split('.')[-1]
# open browser dialog to choose destination
dialog = xbmcgui.Dialog()
download_dir = dialog.browse(3, translation(30102), "files")
target = urllib.URLopener()
fullPath = xbmc.translatePath(download_dir + filename)
target.retrieve(video_url, fullPath)
dialog.ok(addonID, translation(30101), str(fullPath))
# only used in style directories
def getFanart(channel):
fanart = os.path.join(
addonDir, 'resources/images/fanart_' + channel + '.jpg')
if not os.path.isfile(fanart.encode('utf-8')):
fanart = icon
return fanart
def addDir(name, url, mode, iconimage, total=0):
u = sys.argv[0] + "?url=" + urllib.quote_plus(url.encode('utf-8')) + "&mode=" + str(mode)
# xbmc.log(msg=u, level=xbmc.LOGNOTICE)
ok = True
liz = xbmcgui.ListItem(name, iconImage=icon, thumbnailImage=iconimage, offscreen=True)
description = ""
if mode == "showChannel":
data = getStyles()
for style in data:
if style['style'] == name:
description = style['description']
liz.setInfo(type="Video", infoLabels={"Title": name, "PlotOutline": description, "Plot": description, "Tagline": description})
if iconimage:
liz.setProperty("fanart_image", iconimage)
else:
liz.setProperty("fanart_image", defaultFanart)
ok = xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=u, listitem=liz, totalItems=total, isFolder=True)
return ok
def addVideo(entry, mycount="playcount"):
ok = True
# Altlast. Sinn dahinter?
if len(entry) > 7:
dateadded = datetime.utcfromtimestamp(float(entry['slug']))
dateadded = str(dateadded)
slug = entry['slug']
url = '%s?mode=play&url=%s' % (sys.argv[0], slug)
channel = entry['artist']
artist = entry['artist']
artists = entry['artists']
director = entry['director']
title = entry['title']
if "false" in entry['official'].lower() and "true" in showunoffintitle:
title = (title + ' (vid by ' + director + ')')
tracktitle = entry['tracktitle']
style = entry['style']
if mycount == "pcount":
playcount = entry['pcount']
elif mycount == "lcount":
playcount = entry['lcount']
else:
playcount = entry['acount']
#slug = entry['slug']
if playLocalFile == "true":
description = "Provider: " + entry['provider'] + "\nprovider playcount: " + entry['pcount'] + "\nlikes: " + entry['likes'] + "\ndislikes: " + entry['dislikes'] + "\ncomments: " + entry['comments']
else:
description = ""
if "false" in entry['official'].lower():
description = (
"Unofficial Video by " + director + "\n" + description)
#link = entry['slug']
fanart = entry['thumbnail']
duration = entry['duration']
# Soll man das nun nutzen oder nicht?
# Mit offscreen=true werden Listen zigmal schneller dargestellt (klappt erst ab krypton)
li = xbmcgui.ListItem(title, offscreen=True)
li.setInfo(type="video", infoLabels={ "mediatype": mediatype, "Title": title, "Originaltitle": tracktitle, "Genre": style, "Director": director, "PlotOutline": description, "Plot": description, "Tagline": style, "Artist": entry['artists'], "dateadded": dateadded, "playcount": playcount, "Duration": duration})
li.setArt({'thumb': fanart})
li.setProperty("fanart_image", fanart)
li.setProperty('IsPlayable', 'true')
li.addContextMenuItems([
(translation(30121),'XBMC.Container.Update(plugin://'+addonID+'/?mode=sortTitlesBy&url=%26start%3d'+slug+'%26limit%3drelated%26sort%3dnone)',),
(translation(30122),'XBMC.Container.Update(plugin://'+addonID+'/?mode=sortArtists&url=relartists%7C'+slug+')',)
],replaceItems=True)
ok = xbmcplugin.addDirectoryItem(handle=pluginhandle, url=url, listitem=li)
return ok
def parameters_string_to_dict(parameters):
paramDict = {}
if parameters:
paramPairs = parameters[1:].split("&")
for paramsPair in paramPairs:
paramSplits = paramsPair.split('=')
if (len(paramSplits)) == 2:
paramDict[paramSplits[0]] = paramSplits[1]
return paramDict
params = parameters_string_to_dict(sys.argv[2])
mode = urllib.unquote_plus(params.get('mode', '')).decode('utf-8')
url = urllib.unquote_plus(params.get('url', '')).decode('utf-8')
extraparams = parameters_string_to_dict(url)
limit = urllib.unquote_plus(extraparams.get('limit', '')).decode('utf-8')
sort = urllib.unquote_plus(extraparams.get('sort', '')).decode('utf-8')
start = urllib.unquote_plus(extraparams.get('start', '')).decode('utf-8')
start = str(start)
style = urllib.unquote_plus(extraparams.get('style', '')).decode('utf-8')
hit = urllib.unquote_plus(extraparams.get('hit', '')).decode('utf-8')
mycount = urllib.unquote_plus(extraparams.get('count', '')).decode('utf-8')
slug = urllib.unquote_plus(extraparams.get('slug', '')).decode('utf-8')
#xbmc.log(msg=str(sys.argv), level=xbmc.LOGNOTICE)
#xbmc.log(msg=str(mode), level=xbmc.LOGNOTICE)
#xbmc.log(msg=str(url), level=xbmc.LOGNOTICE)
#xbmc.log(msg=str(limit), level=xbmc.LOGDEBUG)
#xbmc.log(msg=str(sort), level=xbmc.LOGDEBUG)
#xbmc.log(msg=str(start), level=xbmc.LOGDEBUG)
#xbmc.log(msg=str(style), level=xbmc.LOGNOTICE)
if mode == 'updateData':
updateData()
elif mode == 'alphabet':
alphabet()
elif mode == 'showChannel':
showChannel(style, sort)
elif mode == 'search':
search(url)
elif mode == 'sortTitleInitials':
sortTitleInitials(url)
elif mode == 'sortTitles':
sortTitles(url)
elif mode == 'sortArtists':
sortArtists(url)
elif mode == 'showArtist':
showArtist(url)
elif mode == 'sortTitlesBy':
sortTitlesBy(limit, sort, start)
elif mode == 'searchDate':
searchDate(url)
elif mode == 'mainsorted':
mainsorted()
elif mode == 'mainrandom':
mainrandom()
elif mode == 'numbers':
numbers()
elif mode == 'countrycodes':
countrycodes()
elif mode == 'artists':
artists()
elif mode == 'styles':
styles()
elif mode == 'stylesrandom':
stylesrandom()
elif mode == 'channelsrandom':
channelsrandom(url)
elif mode == 'related':
related(limit)
elif mode == 'play':
play(url)
else:
main()