Compare commits
22 commits
Author | SHA1 | Date | |
---|---|---|---|
bassdart | f0628a967a | ||
bassdart | 4ba6096b9b | ||
bassdart | 664517d2d3 | ||
bassdart | a65c1889e5 | ||
bassdart | d413338612 | ||
bassdart | 5c1f348d36 | ||
bassdart | 195bde9327 | ||
bassdart | f140d15032 | ||
bassdart | 64e9016dca | ||
bassdart | 822f4faff2 | ||
bassdart | 75f286828e | ||
bassdart | 76753e2fee | ||
bassdart | 8e4ff16741 | ||
bassdart | 4e0aee9c0c | ||
bassdart | 46538086c4 | ||
bassdart | c1783e3631 | ||
bassdart | 6efa5beb33 | ||
bassdart | 32a8310491 | ||
bassdart | 71190b08a3 | ||
bassdart | b572f564c9 | ||
bassdart | 4222f04793 | ||
bassdart | 304f63907f |
26
addon.xml
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<addon id="plugin.video.vidfltr" name="VIDFLTR Music Videos" version="0.9.5" provider-name="bassdart">
|
||||
<addon id="plugin.video.vidfltr" name="VIDFLTR Music Videos" version="0.9.9" provider-name="bassdart">
|
||||
<requires>
|
||||
<import addon="xbmc.python" version="2.1.0"/>
|
||||
<import addon="script.module.kodi-six" />
|
||||
|
@ -23,7 +23,29 @@
|
|||
<website>https://vidfltr.slashproc.org/</website>
|
||||
<email></email>
|
||||
<source>https://kodi.slashproc.org/repo/plugin.video.vidfltr/</source>
|
||||
<news>0.9.5
|
||||
<assets>
|
||||
<icon>resources/img/kodi/icon.png</icon>
|
||||
<fanart>resources/img/kodi/fanart.jpg</fanart>
|
||||
<banner>resources/img/kodi/banner.jpg</banner>
|
||||
<clearlogo>resources/img/kodi/clearlogo.png</clearlogo>
|
||||
<screenshot></screenshot>
|
||||
</assets>
|
||||
<news>0.9.9
|
||||
- play with new Vimeo Add-on from jaylinski if it's available and otherwise fallback to youtube-dl
|
||||
0.9.8
|
||||
- add folder display settings
|
||||
- add random musly list folder
|
||||
- add incoming / incoming hits folder
|
||||
- small (mostly whitespace) fixes
|
||||
0.9.7
|
||||
- Vimeo Add-on is broken, play with Youtube-DL until it's fixed
|
||||
0.9.6
|
||||
- add display of official/unofficial count in main artist and country folders
|
||||
- fix pager enumeration in main artist and country if Video Selection isn't set to show all videos
|
||||
- don't list artists with known country also in Unknown
|
||||
- add page counter for main artists, countries and sorted folders
|
||||
- various other fixes and cleanups
|
||||
0.9.5
|
||||
- fix display of quotation marks in video lists
|
||||
- add pagination for artists on main page and countries
|
||||
- fix Musly (similar music) sort order and filter out dupes
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
0.9.9
|
||||
- play with new Vimeo Add-on from jaylinski if it's available and otherwise fallback to youtube-dl
|
||||
0.9.8
|
||||
- add folder display settings
|
||||
- add random musly list folder
|
||||
- add incoming / incoming hits folder
|
||||
- small (mostly whitespace) fixes
|
||||
0.9.7
|
||||
- Vimeo Add-on is broken, play with Youtube-DL until it's fixed
|
||||
0.9.6
|
||||
- add display of official/unofficial count in main artist and country folders
|
||||
- fix pager enumeration in main artist and country if Video Selection isn't set to show all videos
|
||||
- don't list artists with known country also in Unknown
|
||||
- add page counter for main artists, countries and sorted folders
|
||||
- various other fixes and cleanups
|
||||
0.9.5
|
||||
- fix display of quotation marks in video lists
|
||||
- add pagination for artists on main page and countries
|
||||
|
|
396
default.py
|
@ -10,6 +10,7 @@ import re
|
|||
import time
|
||||
from datetime import date, datetime, timedelta
|
||||
import random
|
||||
import math
|
||||
from unidecode import unidecode
|
||||
|
||||
addonID = 'plugin.video.vidfltr'
|
||||
|
@ -17,11 +18,12 @@ 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')
|
||||
# don't use special folder icons as long as there is'nt a nice icon for every style
|
||||
fanart = 'DefaultFolder.png'
|
||||
icon = os.path.join(addonDir, 'noicon.png')
|
||||
defaultFanart = os.path.join(addonDir, 'resources/img/kodi/noicon.png')
|
||||
icon = os.path.join(addonDir, 'resources/img/kodi/icon.png')
|
||||
clearlogo = os.path.join(addonDir, 'resources/img/kodi/clearlogo.png')
|
||||
fanart = os.path.join(addonDir, 'resources/img/kodi/fanart.png')
|
||||
banner = os.path.join(addonDir, 'resources/img/kodi/banner.png')
|
||||
poster = os.path.join(addonDir, 'resources/img/kodi/poster.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")
|
||||
|
@ -31,8 +33,14 @@ 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()
|
||||
if videoselection != "2":
|
||||
# videoselection is set to official or fanmade
|
||||
# despite this selection show all in similar playlists and more from?
|
||||
relatedselection = str(addon.getSetting("relatedselection")).lower()
|
||||
else:
|
||||
# if videoselection is set to show all videos relatedselection should
|
||||
# also be true if the setting was set to false beforehand
|
||||
relatedselection = "true"
|
||||
playLocalFile = str(addon.getSetting("playLocalFile")).lower()
|
||||
filesinlists = int(addon.getSetting("filesinlists"))
|
||||
useYTDL = addon.getSetting("useytdl")
|
||||
|
@ -52,9 +60,21 @@ likecounthigh = int(addon.getSetting("likecounthigh"))
|
|||
dislikecounthigh = int(addon.getSetting("dislikecounthigh"))
|
||||
# needed for comapatibilty mode used with KODI <= 17 aka Krypton
|
||||
xbmcversion = int(xbmc.getInfoLabel('System.BuildVersion')[:2])
|
||||
# get folder settings
|
||||
showincoming = addon.getSetting("show-incoming")
|
||||
showincominghits = addon.getSetting("show-incoming-hits")
|
||||
showrandom = addon.getSetting("show-random")
|
||||
showsorted = addon.getSetting("show-sorted")
|
||||
showstyles = addon.getSetting("show-styles")
|
||||
showartists = addon.getSetting("show-artists")
|
||||
showcountries = addon.getSetting("show-countries")
|
||||
showsearch = addon.getSetting("show-search")
|
||||
showmuslyrandom = addon.getSetting("show-musly-random")
|
||||
showupdate = addon.getSetting("show-update")
|
||||
|
||||
# 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)
|
||||
# But it's ok in a musly-list?:
|
||||
# XBMC.PlayMedia(plugin://plugin.video.vidfltr/?mode=sortTitlesBy&url=%26start%3d1555257469%26limit%3drelated%26sort%3dnone,isdir
|
||||
|
||||
if not os.path.isdir(addon_work_folder):
|
||||
os.mkdir(addon_work_folder)
|
||||
|
@ -115,13 +135,24 @@ def alphabet():
|
|||
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)
|
||||
if showincoming == "true":
|
||||
addDir(translation(30007), '&limit=all&sort=date&start=0', 'sortTitlesBy', fanart)
|
||||
if showincominghits == "true":
|
||||
addDir(translation(30008), '&limit=all&sort=date&start=0&hit=true', 'sortTitlesBy', fanart)
|
||||
if showrandom == "true":
|
||||
addDir(translation(30029), '', 'mainrandom', fanart)
|
||||
if showsorted == "true":
|
||||
addDir(translation(30012), '', 'mainsorted', fanart)
|
||||
if showstyles == "true":
|
||||
addDir(translation(30022), '&sort=all', 'styles', fanart)
|
||||
if showartists == "true":
|
||||
addDir(translation(30005), '', 'artists', fanart)
|
||||
if showcountries == "true":
|
||||
addDir(translation(30118), '', 'countrycodes', fanart)
|
||||
if showsearch == "true":
|
||||
addDir(translation(30001), '', 'search', fanart)
|
||||
if showupdate == "true":
|
||||
addDir(translation(30006), '', 'updateData', fanart)
|
||||
endOfDirectory()
|
||||
|
||||
|
||||
|
@ -137,8 +168,8 @@ def countrycodes():
|
|||
countrycode = entry['countrycode']
|
||||
if countrycode != "" and countrycode not in result:
|
||||
result.append(countrycode)
|
||||
elif countrycode == "" and "unknown" not in result:
|
||||
result.append('unknown')
|
||||
elif countrycode == "" and translation(30124) not in result:
|
||||
result.append(translation(30124))
|
||||
result.sort()
|
||||
for entry in result:
|
||||
addDir(entry, '&style=country&limit=' + entry + '&start=0', 'showArtist', fanart, len(result))
|
||||
|
@ -151,6 +182,8 @@ def mainrandom():
|
|||
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)
|
||||
if showmuslyrandom == "true":
|
||||
addDir(translation(30024), '&limit=related&start=0&sort=none', 'sortTitlesBy', fanart)
|
||||
endOfDirectory()
|
||||
|
||||
def mainsorted():
|
||||
|
@ -236,7 +269,7 @@ def play(url):
|
|||
# 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)
|
||||
|
@ -247,9 +280,21 @@ def play(url):
|
|||
ytdl = YDStreamExtractor.getVideoInfo(idVideo)
|
||||
playback_url = ytdl.streamURL()
|
||||
else:
|
||||
# without youtube_dl
|
||||
xbmc.log(msg="without ytdl", level=xbmc.LOGDEBUG)
|
||||
playback_url = entry['url']
|
||||
if "vimeo" in entry['provider']:
|
||||
if xbmc.getCondVisibility("System.HasAddon(plugin.video.vimeo)") and int((xbmcaddon.Addon("plugin.video.vimeo").getAddonInfo("version").strip().replace(".",""))) >= 500:
|
||||
xbmc.log(msg="using the new Vimeo addon from jaylinski", level=xbmc.LOGNOTICE)
|
||||
playback_url = entry['url']
|
||||
else:
|
||||
# quick hard coded workaround
|
||||
xbmc.log(msg="old vimeo addon is broken, playing with ytdl. Please install the new jaylinski Vimeo Addon from the official KODI Repo", level=xbmc.LOGNOTICE)
|
||||
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)
|
||||
|
||||
|
@ -264,12 +309,14 @@ def play(url):
|
|||
|
||||
# doesn't work
|
||||
# item.setProperty('StartOffset', '56.4')
|
||||
# Bug? It maybe works with StartPercent, see https://forum.kodi.tv/showthread.php?tid=129188&pid=2443114#pid2443114
|
||||
# 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 = []
|
||||
|
@ -410,6 +457,7 @@ def sortTitles(channelInitial=""):
|
|||
def showArtist(style, limit, start):
|
||||
# limit artists by first letter or country
|
||||
data = getArtists()
|
||||
preresult = []
|
||||
result = []
|
||||
# xbmc.log(msg=url, level=xbmc.LOGNOTICE)
|
||||
# xbmc.log(msg=style, level=xbmc.LOGNOTICE)
|
||||
|
@ -422,21 +470,35 @@ def showArtist(style, limit, start):
|
|||
i = unidecode(entry['artist'])[0].upper()
|
||||
if limit == '#':
|
||||
if not re.match('^([a-z|A-Z])', i):
|
||||
result.append(entry)
|
||||
preresult.append(entry)
|
||||
else:
|
||||
if limit == i:
|
||||
result.append(entry)
|
||||
preresult.append(entry)
|
||||
elif style == 'country':
|
||||
|
||||
for entry in data:
|
||||
i = entry['countrycode']
|
||||
if limit == i:
|
||||
preresult.append(entry)
|
||||
elif limit == translation(30124) and i == "":
|
||||
preresult.append(entry)
|
||||
|
||||
# limit the result list according to the "Video Selection" Setting
|
||||
for entry in preresult:
|
||||
if videoselection == "0":
|
||||
if entry['official'] >= "1":
|
||||
result.append(entry)
|
||||
elif limit == 'unknown':
|
||||
elif videoselection == "1":
|
||||
if entry['unofficial'] >= "1":
|
||||
result.append(entry)
|
||||
elif videoselection == "2":
|
||||
result.append(entry)
|
||||
|
||||
maximum = len(result)
|
||||
for entry in result[start:end]:
|
||||
artist = entry['artist']
|
||||
official = int(entry['official'])
|
||||
unofficial = int(entry['unofficial'])
|
||||
|
||||
if entry['fanart'] != "":
|
||||
fanart = entry['fanart']
|
||||
elif entry['thumbnail'] != "":
|
||||
|
@ -445,16 +507,16 @@ def showArtist(style, limit, start):
|
|||
fanart = ""
|
||||
|
||||
if videoselection == "0":
|
||||
if entry['official'] >= "1":
|
||||
addDir(artist, unidecode(artist.upper()), 'sortArtists', fanart, len(result))
|
||||
addDir("%s (%s)" % (artist, official), unidecode(artist.upper()), 'sortArtists', fanart, official)
|
||||
elif videoselection == "1":
|
||||
if entry['unofficial'] >= "1":
|
||||
addDir(artist, unidecode(artist.upper()), 'sortArtists', fanart, len(result))
|
||||
addDir("%s (%s)" % (artist, unofficial), unidecode(artist.upper()), 'sortArtists', fanart, unofficial)
|
||||
elif videoselection == "2":
|
||||
addDir(artist, unidecode(artist.upper()), 'sortArtists', fanart, len(result))
|
||||
addDir("%s (%s/%s)" % (artist, official, unofficial), unidecode(artist.upper()), 'sortArtists', fanart, (official + unofficial))
|
||||
if maximum > end:
|
||||
pagemax = (float(maximum) / float(filesinlists))
|
||||
pagenext = (float(nextstart) / float(filesinlists))
|
||||
fanart = 'DefaultFolder.png'
|
||||
addDir(translation(30036), '&style=' + style + '&limit=' + limit + '&start=' + str(nextstart), 'showArtist', fanart)
|
||||
addDir("%s: %s/%s" % (translation(30036), str(int(math.ceil(pagenext))), str(int(math.ceil(pagemax)))), '&style=' + style + '&limit=' + limit + '&start=' + str(nextstart), 'showArtist', fanart)
|
||||
endOfDirectory()
|
||||
|
||||
|
||||
|
@ -471,7 +533,33 @@ def sortArtists(channel=""):
|
|||
channel = params[0]
|
||||
if len(params) > 1:
|
||||
start = params[1]
|
||||
if channel != "" and channel != "relaartists":
|
||||
#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)
|
||||
|
||||
# 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:
|
||||
# limit selection based on videoselection setting if show all isn't activated
|
||||
if relatedselection != "true" and videoselection != "2":
|
||||
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 artist
|
||||
elif channel != "":
|
||||
fanart = getFanart(channel)
|
||||
for entry in data:
|
||||
artists_upper = [unidecode(artist.upper()) for artist in entry['artists']]
|
||||
|
@ -485,35 +573,9 @@ def sortArtists(channel=""):
|
|||
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()
|
||||
|
||||
|
@ -525,52 +587,35 @@ def sortTitlesBy(limit, sort, start):
|
|||
start = int(start)
|
||||
end = start + filesinlists
|
||||
nextstart = end + 1
|
||||
# xbmc.log(msg=channel, level=xbmc.LOGNOTICE)
|
||||
|
||||
fanart = getFanart(channel)
|
||||
|
||||
# limit selection if "all" isn't activated in videoselection
|
||||
#if videoselection != "2" and channel != "related" and channel != "relartists":
|
||||
if videoselection != "2":
|
||||
data = limitselection(data)
|
||||
|
||||
# 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)
|
||||
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)
|
||||
result.append(entry)
|
||||
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)
|
||||
result.append(entry)
|
||||
data = result
|
||||
result = []
|
||||
|
||||
|
@ -578,15 +623,7 @@ def sortTitlesBy(limit, sort, start):
|
|||
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)
|
||||
result.append(entry)
|
||||
data = result
|
||||
result = []
|
||||
|
||||
|
@ -594,15 +631,7 @@ def sortTitlesBy(limit, sort, start):
|
|||
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)
|
||||
result.append(entry)
|
||||
data = result
|
||||
result = []
|
||||
|
||||
|
@ -610,15 +639,7 @@ def sortTitlesBy(limit, sort, start):
|
|||
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)
|
||||
result.append(entry)
|
||||
data = result
|
||||
result = []
|
||||
|
||||
|
@ -626,15 +647,7 @@ def sortTitlesBy(limit, sort, start):
|
|||
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)
|
||||
result.append(entry)
|
||||
data = result
|
||||
result = []
|
||||
|
||||
|
@ -642,20 +655,12 @@ def sortTitlesBy(limit, sort, start):
|
|||
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)
|
||||
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:
|
||||
|
@ -664,18 +669,20 @@ def sortTitlesBy(limit, sort, start):
|
|||
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)
|
||||
result.append(entry)
|
||||
# related tracks (generated with musly)
|
||||
elif channel != "" and channel == "related":
|
||||
start = str(start)
|
||||
# xbmc.log(msg=str(start), level=xbmc.LOGNOTICE)
|
||||
# random musly list
|
||||
if start == 0:
|
||||
# pick a random item from the already limited list (based on videoselection setting)
|
||||
entry = random.choice(data)
|
||||
start = str(entry['slug'])
|
||||
else:
|
||||
start = str(start)
|
||||
# now we have to add the unlimited video list
|
||||
# It will be limited later, again, if the videoselection
|
||||
# setting should also be honoured in related lists
|
||||
data = getVideos()
|
||||
for entry in data:
|
||||
if entry['slug'] == start:
|
||||
slugs = []
|
||||
|
@ -683,25 +690,15 @@ def sortTitlesBy(limit, sort, start):
|
|||
slugs.extend(entry['slug'].split(", "))
|
||||
# and add all related slugs
|
||||
slugs.extend(entry['related'].split(", "))
|
||||
#xbmc.log(msg=str(slugs), level=xbmc.LOGNOTICE)
|
||||
for entry in data:
|
||||
# add all related slugs
|
||||
if entry['slug'] in slugs:
|
||||
#xbmc.log(msg=str(result['artists']), level=xbmc.LOGNOTICE)
|
||||
# filter out tracks with the same title, where only the video differs.
|
||||
# if a related slug is listed earlier in data (= newer video) the
|
||||
# main slug will be filtered out.
|
||||
# In this case we add it again later, after sorting the result
|
||||
if not filter(lambda result: result['title'] == entry['title'], 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)
|
||||
result.append(entry)
|
||||
# slugs are sorted newest first because that's how they occur in the json
|
||||
# so we have to sort the result to the order in related aka the musly order (with prepended main slug)
|
||||
order_dict = {slug: index for index, slug in enumerate(slugs)}
|
||||
|
@ -714,6 +711,10 @@ def sortTitlesBy(limit, sort, start):
|
|||
for entry in data:
|
||||
if entry['slug'] == start:
|
||||
result.insert(0, entry)
|
||||
# limit selection?
|
||||
if videoselection != "2" and relatedselection != "true":
|
||||
result = limitselection(result)
|
||||
|
||||
maximum = len(result)
|
||||
# related is a list with max 21 entries, so we have to set start always to 0
|
||||
start = 0
|
||||
|
@ -730,61 +731,50 @@ def sortTitlesBy(limit, sort, start):
|
|||
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)
|
||||
result.append(entry)
|
||||
xbmc.log(msg=str(results), level=xbmc.LOGNOTICE)
|
||||
# limit selection?
|
||||
if videoselection != "2" and relatedselection != "true":
|
||||
result = limitselection(result)
|
||||
start = 0
|
||||
|
||||
# not used anywhere?
|
||||
# sorted lists (by date and by numbers. But NOT controversial, which is a fixed list)
|
||||
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)
|
||||
|
||||
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']))
|
||||
|
||||
if mycount != "" and mycount == "controversial":
|
||||
# controversial is either 0 or 1 so it does not makes sense to sort upon it
|
||||
# instead sort videos considered controversial by dislikes
|
||||
# change controversial in videos.json to a float?
|
||||
result = sorted(result, key = lambda i: (-1*float(i['dislikes']), i['title']))
|
||||
else:
|
||||
# If count would'nt be negated one had to use reverse=true
|
||||
# but then the second sorting, by title would be reversed also
|
||||
# sort by negated count first and then by title in lexical order.
|
||||
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)
|
||||
|
@ -795,12 +785,17 @@ def sortTitlesBy(limit, sort, start):
|
|||
# playlist.clear()
|
||||
for entry in result[start:end]:
|
||||
addVideo(entry, mycount)
|
||||
maximum = len(result)
|
||||
if maximum > end and sort != "random" and channel != "year":
|
||||
pagemax = (float(maximum) / float(filesinlists))
|
||||
pagenext = (float(nextstart) / float(filesinlists))
|
||||
# next page link
|
||||
if sort != "" and sort == "count":
|
||||
addDir(translation(30036), '&limit=' + modus + '&sort=count&start=' + str(nextstart) + '&count=' + mycount, 'sortTitlesBy', fanart)
|
||||
addDir("%s: %s/%s" % (translation(30036), str(int(math.ceil(pagenext))), str(int(math.ceil(pagemax)))), '&limit=' + modus + '&sort=count&start=' + str(nextstart) + '&count=' + mycount, 'sortTitlesBy', fanart)
|
||||
elif hit != "" and hit == "true":
|
||||
addDir("%s: %s/%s" % (translation(30036), str(int(math.ceil(pagenext))), str(int(math.ceil(pagemax)))), '&limit=' + modus + '&sort=date&start=' + str(nextstart) + '&hit=true', 'sortTitlesBy', fanart)
|
||||
else:
|
||||
addDir(translation(30036), '&limit=' + modus + '&sort=date&start=' + str(nextstart), 'sortTitlesBy', fanart)
|
||||
addDir("%s: %s/%s" % (translation(30036), str(int(math.ceil(pagenext))), str(int(math.ceil(pagemax)))), '&limit=' + modus + '&sort=date&start=' + str(nextstart), 'sortTitlesBy', fanart)
|
||||
endOfDirectory()
|
||||
|
||||
|
||||
|
@ -924,13 +919,26 @@ def getFanart(channel):
|
|||
fanart = icon
|
||||
return fanart
|
||||
|
||||
def limitselection(data):
|
||||
xbmc.log(msg="limit by videoselection", level=xbmc.LOGDEBUG)
|
||||
result = []
|
||||
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)
|
||||
return result
|
||||
|
||||
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
|
||||
# if (xbmcversion < 17):
|
||||
liz = xbmcgui.ListItem(name, iconImage=icon, thumbnailImage=iconimage)
|
||||
liz = xbmcgui.ListItem(name, thumbnailImage=iconimage)
|
||||
# else:
|
||||
# With offscreen=true large lists (=folder) load much faster (needs >= krypton)
|
||||
# But at the end, the differences are minimal in VIDFLTR, so just drop it :-)
|
||||
|
@ -946,7 +954,12 @@ def addDir(name, url, mode, iconimage, total=0):
|
|||
if iconimage:
|
||||
liz.setProperty("fanart_image", iconimage)
|
||||
else:
|
||||
liz.setProperty("fanart_image", defaultFanart)
|
||||
liz.setProperty("fanart_image", fanart)
|
||||
|
||||
if iconimage:
|
||||
liz.setArt({ 'fanart' : iconimage })
|
||||
else:
|
||||
liz.setArt({ 'fanart' : fanart })
|
||||
ok = xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=u, listitem=liz, totalItems=total, isFolder=True)
|
||||
return ok
|
||||
|
||||
|
@ -954,8 +967,8 @@ def addDir(name, url, mode, iconimage, total=0):
|
|||
def addVideo(entry, mycount="playcount"):
|
||||
ok = True
|
||||
|
||||
# initiaize the global video playlist. The item will be added later
|
||||
# playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
|
||||
# initialize the global video playlist. The item will be added later
|
||||
# playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
|
||||
|
||||
# Altlast. Sinn dahinter?
|
||||
if len(entry) > 7:
|
||||
|
@ -984,7 +997,7 @@ def addVideo(entry, mycount="playcount"):
|
|||
if playLocalFile == "true":
|
||||
description = "Provider: " + entry['provider'] + "\nprovider playcount: " + entry['pcount'] + "\nlikes: " + entry['likes'] + "\ndislikes: " + entry['dislikes'] + "\ncomments: " + entry['comments']
|
||||
else:
|
||||
description = ""
|
||||
description = "Provider: " + entry['provider'] + ""
|
||||
if "false" in entry['official'].lower():
|
||||
description = (
|
||||
"Unofficial Video by " + director + "\n" + description)
|
||||
|
@ -1037,6 +1050,7 @@ 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)
|
||||
|
@ -1077,10 +1091,6 @@ 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':
|
||||
|
|
BIN
icon.png
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
resources/img/kodi/banner.jpg
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
resources/img/kodi/clearlogo.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
resources/img/kodi/fanart.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
resources/img/kodi/icon.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/img/kodi/poster.jpg
Normal file
After Width: | Height: | Size: 35 KiB |
|
@ -36,6 +36,14 @@ msgctxt "#30006"
|
|||
msgid "Refresh Data"
|
||||
msgstr "Daten aktualisieren"
|
||||
|
||||
msgctxt "#30007"
|
||||
msgid "Incoming"
|
||||
msgstr "Neueste"
|
||||
|
||||
msgctxt "#30008"
|
||||
msgid "Incoming Hits"
|
||||
msgstr "Neueste Hits"
|
||||
|
||||
msgctxt "#30011"
|
||||
msgid "Random"
|
||||
msgstr "Zufällig"
|
||||
|
@ -81,8 +89,12 @@ msgid "Hits, grouped by style"
|
|||
msgstr "Hits, gruppiert nach Musikstil"
|
||||
|
||||
msgctxt "#30022"
|
||||
msgid "Style (not genre)"
|
||||
msgstr "Stil (nicht Genre)"
|
||||
msgid "Genre"
|
||||
msgstr "Genre"
|
||||
|
||||
msgctxt "#30024"
|
||||
msgid "Random Musly Playlist"
|
||||
msgstr "Zufällige Musly Liste"
|
||||
|
||||
msgctxt "#30025"
|
||||
msgid "Artists"
|
||||
|
@ -217,7 +229,7 @@ msgid "By numbers"
|
|||
msgstr "Nach Zahlen"
|
||||
|
||||
msgctxt "#30118"
|
||||
msgid "Countrys"
|
||||
msgid "Countries"
|
||||
msgstr "Länder"
|
||||
|
||||
msgctxt "#30119"
|
||||
|
@ -229,8 +241,8 @@ msgid "Show in title that video is unofficial"
|
|||
msgstr "Im Titel anzeigen das Video inoffiziell ist"
|
||||
|
||||
msgctxt "#30121"
|
||||
msgid "Similar music"
|
||||
msgstr "Ähnliche Musik"
|
||||
msgid "Similar music (Musly)"
|
||||
msgstr "Ähnliche Musik (Musly)"
|
||||
|
||||
msgctxt "#30122"
|
||||
msgid "More from..."
|
||||
|
@ -239,3 +251,11 @@ msgstr "Mehr von..."
|
|||
msgctxt "#30123"
|
||||
msgid "Show all videos in similiar and more from... playlists"
|
||||
msgstr "Zeige alle Videos in Similar- und "Mehr von"-Playlisten"
|
||||
|
||||
msgctxt "#30124"
|
||||
msgid "unknown"
|
||||
msgstr "unbekannt"
|
||||
|
||||
msgctxt "#30125"
|
||||
msgid "Folder"
|
||||
msgstr "Verzeichnisse"
|
||||
|
|
|
@ -36,6 +36,14 @@ msgctxt "#30006"
|
|||
msgid "Refresh Data"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#30007"
|
||||
msgid "Incoming"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#30008"
|
||||
msgid "Incoming Hits"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#30011"
|
||||
msgid "Random"
|
||||
msgstr ""
|
||||
|
@ -81,7 +89,11 @@ msgid "Hits, grouped by style"
|
|||
msgstr ""
|
||||
|
||||
msgctxt "#30022"
|
||||
msgid "Style (not genre)"
|
||||
msgid "Genre"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#30024"
|
||||
msgid "Random Musly Playlist"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#30025"
|
||||
|
@ -217,7 +229,7 @@ msgid "By numbers"
|
|||
msgstr ""
|
||||
|
||||
msgctxt "#30118"
|
||||
msgid "Countrys"
|
||||
msgid "Countries"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#30119"
|
||||
|
@ -229,7 +241,7 @@ msgid "Show in title that video is unofficial"
|
|||
msgstr ""
|
||||
|
||||
msgctxt "#30121"
|
||||
msgid "Similar music"
|
||||
msgid "Similar music (Musly)"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#30122"
|
||||
|
@ -239,3 +251,11 @@ msgstr ""
|
|||
msgctxt "#30123"
|
||||
msgid "Show all videos in similiar and more from... playlists"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#30124"
|
||||
msgid "unknown"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#30125"
|
||||
msgid "Folder"
|
||||
msgstr ""
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<settings>
|
||||
<!-- standard -->
|
||||
<category label="30097">
|
||||
<setting label="30098" type="slider" id="maxFileAge" default="1440" range="720,720,4320" option="int" />
|
||||
<setting label="30030" type="slider" id="filesinlists" default="50" range="25,25,500" option="int" />
|
||||
|
@ -10,6 +11,7 @@
|
|||
<setting label="30106" type="select" id="mediatype" default="musicvideo" values="musicvideo|movie|video"/>
|
||||
<setting label="30104" type="bool" id="playLocalFile" default="false" visible="System.HasAddon(service.nfo.watchedstate.updater_bassdart)"/>
|
||||
</category>
|
||||
<!-- advanced -->
|
||||
<category label="30110">
|
||||
<setting label="30111" type="slider" id="pcounthigh" default="10000000" range="100000,100000,50000000" option="int" />
|
||||
<setting label="30112" type="slider" id="lcounthigh" default="5" range="1,1,50" option="int" visible="System.HasAddon(service.nfo.watchedstate.updater_bassdart)"/>
|
||||
|
@ -18,4 +20,17 @@
|
|||
<setting label="30115" type="slider" id="likecounthigh" default="5000" range="1000,500,100000" option="int" />
|
||||
<setting label="30116" type="slider" id="dislikecounthigh" default="1500" range="500,500,100000" option="int" />
|
||||
</category>
|
||||
<!-- folder -->
|
||||
<category label="30125">
|
||||
<setting label="30007" type="bool" id="show-incoming" default="true"/>
|
||||
<setting label="30008" type="bool" id="show-incoming-hits" default="false"/>
|
||||
<setting label="30029" type="bool" id="show-random" default="true"/>
|
||||
<setting label="30012" type="bool" id="show-sorted" default="true"/>
|
||||
<setting label="30022" type="bool" id="show-styles" default="true"/>
|
||||
<setting label="30025" type="bool" id="show-artists" default="true"/>
|
||||
<setting label="30118" type="bool" id="show-countries" default="true"/>
|
||||
<setting label="30001" type="bool" id="show-search" default="true"/>
|
||||
<setting label="30024" type="bool" id="show-musly-random" default="false"/>
|
||||
<setting label="30006" type="bool" id="show-update" default="false"/>
|
||||
</category>
|
||||
</settings>
|
||||
|
|