2015-12-25 07:07:00 +11:00
|
|
|
# -*- coding: utf-8 -*-
|
2016-03-03 04:56:42 +11:00
|
|
|
###############################################################################
|
2017-12-10 00:35:08 +11:00
|
|
|
from logging import getLogger
|
2017-05-04 04:30:33 +10:00
|
|
|
from shutil import copytree
|
2015-12-25 07:07:00 +11:00
|
|
|
import xml.etree.ElementTree as etree
|
2017-05-21 04:24:47 +10:00
|
|
|
from os import makedirs
|
2015-12-25 07:07:00 +11:00
|
|
|
|
|
|
|
import xbmc
|
2017-05-12 03:44:08 +10:00
|
|
|
from xbmcvfs import exists
|
2015-12-25 07:07:00 +11:00
|
|
|
|
2018-02-11 22:59:04 +11:00
|
|
|
from utils import window, settings, language as lang, try_encode, indent, \
|
|
|
|
normalize_nodes, exists_dir, try_decode
|
2017-01-25 02:56:07 +11:00
|
|
|
import variables as v
|
2018-02-13 17:24:39 +11:00
|
|
|
import state
|
2015-12-25 07:07:00 +11:00
|
|
|
|
2016-09-05 00:34:25 +10:00
|
|
|
###############################################################################
|
2016-08-30 02:44:27 +10:00
|
|
|
|
2017-12-10 00:35:08 +11:00
|
|
|
log = getLogger("PLEX."+__name__)
|
2016-08-30 02:44:27 +10:00
|
|
|
|
2016-09-05 00:34:25 +10:00
|
|
|
###############################################################################
|
2017-05-04 04:30:33 +10:00
|
|
|
# Paths are strings, NOT unicode!
|
2015-12-25 07:07:00 +11:00
|
|
|
|
|
|
|
|
|
|
|
class VideoNodes(object):
|
|
|
|
|
|
|
|
def commonRoot(self, order, label, tagname, roottype=1):
|
|
|
|
|
|
|
|
if roottype == 0:
|
|
|
|
# Index
|
|
|
|
root = etree.Element('node', attrib={'order': "%s" % order})
|
|
|
|
elif roottype == 1:
|
|
|
|
# Filter
|
|
|
|
root = etree.Element('node', attrib={'order': "%s" % order, 'type': "filter"})
|
|
|
|
etree.SubElement(root, 'match').text = "all"
|
|
|
|
# Add tag rule
|
|
|
|
rule = etree.SubElement(root, 'rule', attrib={'field': "tag", 'operator': "is"})
|
|
|
|
etree.SubElement(rule, 'value').text = tagname
|
|
|
|
else:
|
|
|
|
# Folder
|
|
|
|
root = etree.Element('node', attrib={'order': "%s" % order, 'type': "folder"})
|
|
|
|
|
|
|
|
etree.SubElement(root, 'label').text = label
|
2016-03-03 04:56:42 +11:00
|
|
|
etree.SubElement(root, 'icon').text = "special://home/addons/plugin.video.plexkodiconnect/icon.png"
|
2015-12-25 07:07:00 +11:00
|
|
|
|
|
|
|
return root
|
|
|
|
|
2016-02-23 17:00:24 +11:00
|
|
|
def viewNode(self, indexnumber, tagname, mediatype, viewtype, viewid, delete=False):
|
2016-03-03 19:04:15 +11:00
|
|
|
# Plex: reassign mediatype due to Kodi inner workings
|
2016-03-15 23:09:51 +11:00
|
|
|
# How many items do we get at most?
|
2018-02-13 17:24:39 +11:00
|
|
|
limit = state.FETCH_PMS_ITEM_NUMBER
|
2016-03-03 19:04:15 +11:00
|
|
|
mediatypes = {
|
|
|
|
'movie': 'movies',
|
|
|
|
'show': 'tvshows',
|
|
|
|
'photo': 'photos',
|
|
|
|
'homevideo': 'homevideos',
|
|
|
|
'musicvideos': 'musicvideos'
|
|
|
|
}
|
|
|
|
mediatype = mediatypes[mediatype]
|
|
|
|
|
2015-12-25 07:07:00 +11:00
|
|
|
if viewtype == "mixed":
|
2016-03-03 04:56:42 +11:00
|
|
|
dirname = "%s-%s" % (viewid, mediatype)
|
2015-12-25 07:07:00 +11:00
|
|
|
else:
|
2016-02-23 17:00:24 +11:00
|
|
|
dirname = viewid
|
2017-01-21 01:46:34 +11:00
|
|
|
|
2017-05-04 04:30:33 +10:00
|
|
|
# Returns strings
|
2018-02-11 22:59:04 +11:00
|
|
|
path = try_decode(xbmc.translatePath(
|
2017-05-21 04:24:47 +10:00
|
|
|
"special://profile/library/video/"))
|
2018-02-11 22:59:04 +11:00
|
|
|
nodepath = try_decode(xbmc.translatePath(
|
2017-05-21 04:24:47 +10:00
|
|
|
"special://profile/library/video/Plex-%s/" % dirname))
|
2015-12-25 07:07:00 +11:00
|
|
|
|
2017-01-21 01:46:34 +11:00
|
|
|
if delete:
|
2017-05-17 22:42:28 +10:00
|
|
|
if exists_dir(nodepath):
|
|
|
|
from shutil import rmtree
|
|
|
|
rmtree(nodepath)
|
|
|
|
log.info("Sucessfully removed videonode: %s." % tagname)
|
2017-01-21 01:46:34 +11:00
|
|
|
return
|
|
|
|
|
2015-12-25 07:07:00 +11:00
|
|
|
# Verify the video directory
|
2017-05-12 03:29:57 +10:00
|
|
|
if not exists_dir(path):
|
2017-05-04 04:30:33 +10:00
|
|
|
copytree(
|
2018-02-11 22:59:04 +11:00
|
|
|
src=try_decode(xbmc.translatePath(
|
2017-05-21 04:24:47 +10:00
|
|
|
"special://xbmc/system/library/video")),
|
2018-02-11 22:59:04 +11:00
|
|
|
dst=try_decode(xbmc.translatePath(
|
2017-05-21 04:24:47 +10:00
|
|
|
"special://profile/library/video")))
|
2015-12-25 07:07:00 +11:00
|
|
|
|
2016-03-08 02:16:57 +11:00
|
|
|
# Create the node directory
|
2016-06-05 02:48:22 +10:00
|
|
|
if mediatype != "photos":
|
2017-05-12 03:29:57 +10:00
|
|
|
if not exists_dir(nodepath):
|
2016-03-08 02:16:57 +11:00
|
|
|
# folder does not exist yet
|
2016-09-05 00:34:25 +10:00
|
|
|
log.debug('Creating folder %s' % nodepath)
|
2017-05-12 03:44:08 +10:00
|
|
|
makedirs(nodepath)
|
2015-12-25 07:07:00 +11:00
|
|
|
|
|
|
|
# Create index entry
|
|
|
|
nodeXML = "%sindex.xml" % nodepath
|
|
|
|
# Set windows property
|
2016-03-03 04:56:42 +11:00
|
|
|
path = "library://video/Plex-%s/" % dirname
|
2015-12-25 07:07:00 +11:00
|
|
|
for i in range(1, indexnumber):
|
|
|
|
# Verify to make sure we don't create duplicates
|
2016-05-31 16:06:42 +10:00
|
|
|
if window('Plex.nodes.%s.index' % i) == path:
|
2015-12-25 07:07:00 +11:00
|
|
|
return
|
|
|
|
|
2016-06-05 02:48:22 +10:00
|
|
|
if mediatype == "photos":
|
2017-03-09 03:53:43 +11:00
|
|
|
path = "plugin://plugin.video.plexkodiconnect?mode=browseplex&key=/library/sections/%s&id=%s" % (viewid, viewid)
|
2017-05-04 04:30:33 +10:00
|
|
|
|
2016-05-31 16:06:42 +10:00
|
|
|
window('Plex.nodes.%s.index' % indexnumber, value=path)
|
2017-05-04 04:30:33 +10:00
|
|
|
|
2015-12-25 07:07:00 +11:00
|
|
|
# Root
|
2016-06-05 02:48:22 +10:00
|
|
|
if not mediatype == "photos":
|
2016-02-23 10:56:08 +11:00
|
|
|
if viewtype == "mixed":
|
2016-03-03 04:56:42 +11:00
|
|
|
specialtag = "%s-%s" % (tagname, mediatype)
|
2017-05-04 04:30:33 +10:00
|
|
|
root = self.commonRoot(order=0,
|
|
|
|
label=specialtag,
|
|
|
|
tagname=tagname,
|
|
|
|
roottype=0)
|
2016-02-23 10:56:08 +11:00
|
|
|
else:
|
2017-05-04 04:30:33 +10:00
|
|
|
root = self.commonRoot(order=0,
|
|
|
|
label=tagname,
|
|
|
|
tagname=tagname,
|
|
|
|
roottype=0)
|
2016-01-12 08:20:34 +11:00
|
|
|
try:
|
2016-09-05 00:34:25 +10:00
|
|
|
indent(root)
|
2017-05-04 04:30:33 +10:00
|
|
|
except:
|
|
|
|
pass
|
2017-05-29 23:39:11 +10:00
|
|
|
etree.ElementTree(root).write(nodeXML, encoding="UTF-8")
|
2015-12-25 07:07:00 +11:00
|
|
|
|
|
|
|
nodetypes = {
|
|
|
|
'1': "all",
|
|
|
|
'2': "recent",
|
|
|
|
'3': "recentepisodes",
|
|
|
|
'4': "inprogress",
|
|
|
|
'5': "inprogressepisodes",
|
|
|
|
'6': "unwatched",
|
2016-01-06 18:59:41 +11:00
|
|
|
'7': "nextepisodes",
|
2015-12-25 07:07:00 +11:00
|
|
|
'8': "sets",
|
|
|
|
'9': "genres",
|
|
|
|
'10': "random",
|
2016-01-13 11:03:35 +11:00
|
|
|
'11': "recommended",
|
2017-03-09 02:41:49 +11:00
|
|
|
'12': "ondeck",
|
|
|
|
'13': 'browsefiles'
|
2015-12-25 07:07:00 +11:00
|
|
|
}
|
|
|
|
mediatypes = {
|
|
|
|
# label according to nodetype per mediatype
|
2017-03-09 02:41:49 +11:00
|
|
|
'movies':
|
2016-01-13 11:03:35 +11:00
|
|
|
{
|
2017-03-09 02:41:49 +11:00
|
|
|
'1': tagname,
|
|
|
|
'2': 30174,
|
|
|
|
# '4': 30177,
|
|
|
|
# '6': 30189,
|
|
|
|
'8': 39501,
|
|
|
|
'9': 135,
|
|
|
|
'10': 30227,
|
|
|
|
'11': 30230,
|
|
|
|
'12': 39500,
|
|
|
|
'13': 39702
|
2016-01-13 11:03:35 +11:00
|
|
|
},
|
2015-12-25 07:07:00 +11:00
|
|
|
|
2017-03-09 02:41:49 +11:00
|
|
|
'tvshows':
|
2016-01-13 11:03:35 +11:00
|
|
|
{
|
2017-03-09 02:41:49 +11:00
|
|
|
'1': tagname,
|
|
|
|
# '2': 30170,
|
|
|
|
'3': 30174,
|
|
|
|
# '4': 30171,
|
|
|
|
# '5': 30178,
|
|
|
|
# '7': 30179,
|
|
|
|
'9': 135,
|
|
|
|
'10': 30227,
|
|
|
|
# '11': 30230,
|
|
|
|
'12': 39500,
|
|
|
|
'13': 39702
|
2016-01-13 11:03:35 +11:00
|
|
|
},
|
2017-03-09 02:41:49 +11:00
|
|
|
|
|
|
|
'homevideos':
|
2016-01-13 11:03:35 +11:00
|
|
|
{
|
2017-03-09 02:41:49 +11:00
|
|
|
'1': tagname,
|
|
|
|
'2': 30251,
|
|
|
|
'11': 30253,
|
|
|
|
'13': 39702
|
2016-01-13 11:03:35 +11:00
|
|
|
},
|
2017-03-09 02:41:49 +11:00
|
|
|
|
|
|
|
'photos':
|
2016-01-13 11:03:35 +11:00
|
|
|
{
|
2017-03-09 02:41:49 +11:00
|
|
|
'1': tagname,
|
|
|
|
'2': 30252,
|
|
|
|
'8': 30255,
|
|
|
|
'11': 30254,
|
|
|
|
'13': 39702
|
2016-01-13 11:03:35 +11:00
|
|
|
},
|
2016-02-04 23:22:33 +11:00
|
|
|
|
2017-03-09 02:41:49 +11:00
|
|
|
'musicvideos':
|
2016-01-19 06:17:14 +11:00
|
|
|
{
|
2017-03-09 02:41:49 +11:00
|
|
|
'1': tagname,
|
|
|
|
'2': 30256,
|
|
|
|
'4': 30257,
|
|
|
|
'6': 30258,
|
|
|
|
'13': 39702
|
2016-02-04 23:22:33 +11:00
|
|
|
}
|
2015-12-25 07:07:00 +11:00
|
|
|
}
|
|
|
|
|
2016-03-15 23:09:51 +11:00
|
|
|
# Key: nodetypes, value: sort order in Kodi
|
|
|
|
sortorder = {
|
|
|
|
'1': '3', # "all",
|
|
|
|
'2': '2', # "recent",
|
|
|
|
'3': '2', # "recentepisodes",
|
|
|
|
# '4': # "inprogress",
|
|
|
|
# '5': # "inprogressepisodes",
|
|
|
|
# '6': # "unwatched",
|
|
|
|
# '7': # "nextepisodes",
|
|
|
|
'8': '7', # "sets",
|
|
|
|
'9': '6', # "genres",
|
|
|
|
'10': '8', # "random",
|
|
|
|
'11': '5', # "recommended",
|
|
|
|
'12': '1', # "ondeck"
|
2017-03-09 02:41:49 +11:00
|
|
|
'13': '9' # browse by folder
|
2016-03-15 23:09:51 +11:00
|
|
|
}
|
|
|
|
|
2015-12-25 07:07:00 +11:00
|
|
|
nodes = mediatypes[mediatype]
|
|
|
|
for node in nodes:
|
|
|
|
|
|
|
|
nodetype = nodetypes[node]
|
2016-02-23 17:00:24 +11:00
|
|
|
nodeXML = "%s%s_%s.xml" % (nodepath, viewid, nodetype)
|
2015-12-25 07:07:00 +11:00
|
|
|
# Get label
|
|
|
|
stringid = nodes[node]
|
2016-02-17 19:13:37 +11:00
|
|
|
if node != "1":
|
2016-08-30 02:44:27 +10:00
|
|
|
label = lang(stringid)
|
2015-12-25 07:07:00 +11:00
|
|
|
if not label:
|
|
|
|
label = xbmc.getLocalizedString(stringid)
|
|
|
|
else:
|
|
|
|
label = stringid
|
|
|
|
|
|
|
|
# Set window properties
|
2016-06-05 02:48:22 +10:00
|
|
|
if (mediatype == "homevideos" or mediatype == "photos") and nodetype == "all":
|
2016-01-12 08:20:34 +11:00
|
|
|
# Custom query
|
2016-06-05 02:48:22 +10:00
|
|
|
path = ("plugin://plugin.video.plexkodiconnect/?id=%s&mode=browseplex&type=%s"
|
|
|
|
% (viewid, mediatype))
|
|
|
|
elif (mediatype == "homevideos" or mediatype == "photos"):
|
2016-01-12 08:20:34 +11:00
|
|
|
# Custom query
|
2016-06-05 02:48:22 +10:00
|
|
|
path = ("plugin://plugin.video.plexkodiconnect/?id=%s&mode=browseplex&type=%s&folderid=%s"
|
|
|
|
% (viewid, mediatype, nodetype))
|
2016-01-12 08:20:34 +11:00
|
|
|
elif nodetype == "nextepisodes":
|
2015-12-25 07:07:00 +11:00
|
|
|
# Custom query
|
2016-03-15 23:09:51 +11:00
|
|
|
path = "plugin://plugin.video.plexkodiconnect/?id=%s&mode=nextup&limit=%s" % (tagname, limit)
|
2017-01-25 02:56:07 +11:00
|
|
|
# elif v.KODIVERSION == 14 and nodetype == "recentepisodes":
|
2016-03-16 00:19:56 +11:00
|
|
|
elif nodetype == "recentepisodes":
|
2015-12-25 07:07:00 +11:00
|
|
|
# Custom query
|
2016-03-16 00:19:56 +11:00
|
|
|
path = ("plugin://plugin.video.plexkodiconnect/?id=%s&mode=recentepisodes&type=%s&tagname=%s&limit=%s"
|
|
|
|
% (viewid, mediatype, tagname, limit))
|
2017-01-25 02:56:07 +11:00
|
|
|
elif v.KODIVERSION == 14 and nodetype == "inprogressepisodes":
|
2015-12-25 07:07:00 +11:00
|
|
|
# Custom query
|
2016-03-15 23:09:51 +11:00
|
|
|
path = "plugin://plugin.video.plexkodiconnect/?id=%s&mode=inprogressepisodes&limit=%s" % (tagname, limit)
|
2016-03-15 03:47:05 +11:00
|
|
|
elif nodetype == 'ondeck':
|
|
|
|
# PLEX custom query
|
2016-03-15 23:09:51 +11:00
|
|
|
if mediatype == "tvshows":
|
|
|
|
path = ("plugin://plugin.video.plexkodiconnect/?id=%s&mode=ondeck&type=%s&tagname=%s&limit=%s"
|
|
|
|
% (viewid, mediatype, tagname, limit))
|
|
|
|
elif mediatype =="movies":
|
|
|
|
# Reset nodetype; we got the label
|
|
|
|
nodetype = 'inprogress'
|
2017-03-09 02:41:49 +11:00
|
|
|
elif nodetype == 'browsefiles':
|
|
|
|
path = 'plugin://plugin.video.plexkodiconnect?mode=browseplex&key=/library/sections/%s/folder' % viewid
|
2015-12-25 07:07:00 +11:00
|
|
|
else:
|
2016-03-03 04:56:42 +11:00
|
|
|
path = "library://video/Plex-%s/%s_%s.xml" % (dirname, viewid, nodetype)
|
2017-05-04 04:30:33 +10:00
|
|
|
|
2016-06-05 02:48:22 +10:00
|
|
|
if mediatype == "photos":
|
2016-01-12 08:20:34 +11:00
|
|
|
windowpath = "ActivateWindow(Pictures,%s,return)" % path
|
|
|
|
else:
|
2017-01-25 02:56:07 +11:00
|
|
|
if v.KODIVERSION >= 17:
|
2016-08-13 02:35:03 +10:00
|
|
|
# Krypton
|
|
|
|
windowpath = "ActivateWindow(Videos,%s,return)" % path
|
|
|
|
else:
|
|
|
|
windowpath = "ActivateWindow(Video,%s,return)" % path
|
2017-05-04 04:30:33 +10:00
|
|
|
|
2015-12-25 07:07:00 +11:00
|
|
|
if nodetype == "all":
|
|
|
|
|
|
|
|
if viewtype == "mixed":
|
2016-03-03 04:56:42 +11:00
|
|
|
templabel = "%s-%s" % (tagname, mediatype)
|
2015-12-25 07:07:00 +11:00
|
|
|
else:
|
|
|
|
templabel = label
|
|
|
|
|
2016-05-31 16:06:42 +10:00
|
|
|
embynode = "Plex.nodes.%s" % indexnumber
|
2016-02-04 23:22:33 +11:00
|
|
|
window('%s.title' % embynode, value=templabel)
|
|
|
|
window('%s.path' % embynode, value=windowpath)
|
|
|
|
window('%s.content' % embynode, value=path)
|
|
|
|
window('%s.type' % embynode, value=mediatype)
|
2015-12-25 07:07:00 +11:00
|
|
|
else:
|
2016-05-31 16:06:42 +10:00
|
|
|
embynode = "Plex.nodes.%s.%s" % (indexnumber, nodetype)
|
2016-02-04 23:22:33 +11:00
|
|
|
window('%s.title' % embynode, value=label)
|
|
|
|
window('%s.path' % embynode, value=windowpath)
|
|
|
|
window('%s.content' % embynode, value=path)
|
2015-12-25 07:07:00 +11:00
|
|
|
|
2016-06-05 02:48:22 +10:00
|
|
|
if mediatype == "photos":
|
2016-02-04 23:22:33 +11:00
|
|
|
# For photos, we do not create a node in videos but we do want the window props
|
|
|
|
# to be created.
|
|
|
|
# To do: add our photos nodes to kodi picture sources somehow
|
2016-01-12 08:20:34 +11:00
|
|
|
continue
|
2017-05-04 04:30:33 +10:00
|
|
|
|
2018-02-11 22:59:04 +11:00
|
|
|
if exists(try_encode(nodeXML)):
|
2015-12-25 07:07:00 +11:00
|
|
|
# Don't recreate xml if already exists
|
|
|
|
continue
|
|
|
|
|
|
|
|
# Create the root
|
2017-03-09 02:41:49 +11:00
|
|
|
if (nodetype in ("nextepisodes", "ondeck", 'recentepisodes', 'browsefiles') or mediatype == "homevideos"):
|
2015-12-25 07:07:00 +11:00
|
|
|
# Folder type with plugin path
|
2016-03-15 23:09:51 +11:00
|
|
|
root = self.commonRoot(order=sortorder[node], label=label, tagname=tagname, roottype=2)
|
2015-12-25 07:07:00 +11:00
|
|
|
etree.SubElement(root, 'path').text = path
|
|
|
|
etree.SubElement(root, 'content').text = "episodes"
|
|
|
|
else:
|
2016-03-15 23:09:51 +11:00
|
|
|
root = self.commonRoot(order=sortorder[node], label=label, tagname=tagname)
|
2015-12-25 07:07:00 +11:00
|
|
|
if nodetype in ('recentepisodes', 'inprogressepisodes'):
|
|
|
|
etree.SubElement(root, 'content').text = "episodes"
|
|
|
|
else:
|
|
|
|
etree.SubElement(root, 'content').text = mediatype
|
|
|
|
|
|
|
|
# Elements per nodetype
|
|
|
|
if nodetype == "all":
|
|
|
|
etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
|
|
|
|
|
|
|
|
elif nodetype == "recent":
|
|
|
|
etree.SubElement(root, 'order', {'direction': "descending"}).text = "dateadded"
|
|
|
|
etree.SubElement(root, 'limit').text = limit
|
2016-09-05 00:34:25 +10:00
|
|
|
if settings('MovieShowWatched') == 'false':
|
2016-05-16 02:26:07 +10:00
|
|
|
rule = etree.SubElement(root,
|
|
|
|
'rule',
|
|
|
|
{'field': "playcount",
|
|
|
|
'operator': "is"})
|
|
|
|
etree.SubElement(rule, 'value').text = "0"
|
2015-12-25 07:07:00 +11:00
|
|
|
|
|
|
|
elif nodetype == "inprogress":
|
|
|
|
etree.SubElement(root, 'rule', {'field': "inprogress", 'operator': "true"})
|
|
|
|
etree.SubElement(root, 'limit').text = limit
|
2016-04-08 21:06:20 +10:00
|
|
|
etree.SubElement(
|
|
|
|
root,
|
|
|
|
'order',
|
|
|
|
{'direction': 'descending'}
|
|
|
|
).text = 'lastplayed'
|
2015-12-25 07:07:00 +11:00
|
|
|
|
|
|
|
elif nodetype == "genres":
|
|
|
|
etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
|
|
|
|
etree.SubElement(root, 'group').text = "genres"
|
|
|
|
|
|
|
|
elif nodetype == "unwatched":
|
|
|
|
etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
|
|
|
|
rule = etree.SubElement(root, "rule", {'field': "playcount", 'operator': "is"})
|
|
|
|
etree.SubElement(rule, 'value').text = "0"
|
|
|
|
|
|
|
|
elif nodetype == "sets":
|
|
|
|
etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
|
2016-04-11 17:49:02 +10:00
|
|
|
etree.SubElement(root, 'group').text = "tags"
|
2015-12-25 07:07:00 +11:00
|
|
|
|
|
|
|
elif nodetype == "random":
|
|
|
|
etree.SubElement(root, 'order', {'direction': "ascending"}).text = "random"
|
|
|
|
etree.SubElement(root, 'limit').text = limit
|
|
|
|
|
|
|
|
elif nodetype == "recommended":
|
|
|
|
etree.SubElement(root, 'order', {'direction': "descending"}).text = "rating"
|
|
|
|
etree.SubElement(root, 'limit').text = limit
|
|
|
|
rule = etree.SubElement(root, 'rule', {'field': "playcount", 'operator': "is"})
|
|
|
|
etree.SubElement(rule, 'value').text = "0"
|
|
|
|
rule2 = etree.SubElement(root, 'rule',
|
|
|
|
attrib={'field': "rating", 'operator': "greaterthan"})
|
|
|
|
etree.SubElement(rule2, 'value').text = "7"
|
|
|
|
|
|
|
|
elif nodetype == "recentepisodes":
|
|
|
|
# Kodi Isengard, Jarvis
|
|
|
|
etree.SubElement(root, 'order', {'direction': "descending"}).text = "dateadded"
|
|
|
|
etree.SubElement(root, 'limit').text = limit
|
|
|
|
rule = etree.SubElement(root, 'rule', {'field': "playcount", 'operator': "is"})
|
|
|
|
etree.SubElement(rule, 'value').text = "0"
|
|
|
|
|
|
|
|
elif nodetype == "inprogressepisodes":
|
|
|
|
# Kodi Isengard, Jarvis
|
2016-03-15 23:09:51 +11:00
|
|
|
etree.SubElement(root, 'limit').text = limit
|
2015-12-25 07:07:00 +11:00
|
|
|
rule = etree.SubElement(root, 'rule',
|
|
|
|
attrib={'field': "inprogress", 'operator':"true"})
|
|
|
|
|
|
|
|
try:
|
2016-09-05 00:34:25 +10:00
|
|
|
indent(root)
|
2017-05-04 04:30:33 +10:00
|
|
|
except:
|
|
|
|
pass
|
2017-05-29 23:39:11 +10:00
|
|
|
etree.ElementTree(root).write(nodeXML, encoding="UTF-8")
|
2015-12-25 07:07:00 +11:00
|
|
|
|
|
|
|
def singleNode(self, indexnumber, tagname, mediatype, itemtype):
|
2018-02-11 22:59:04 +11:00
|
|
|
tagname = try_encode(tagname)
|
|
|
|
cleantagname = try_decode(normalize_nodes(tagname))
|
|
|
|
nodepath = try_decode(xbmc.translatePath(
|
2017-05-21 04:24:47 +10:00
|
|
|
"special://profile/library/video/"))
|
2016-03-03 04:56:42 +11:00
|
|
|
nodeXML = "%splex_%s.xml" % (nodepath, cleantagname)
|
|
|
|
path = "library://video/plex_%s.xml" % cleantagname
|
2017-01-25 02:56:07 +11:00
|
|
|
if v.KODIVERSION >= 17:
|
2016-08-13 02:35:03 +10:00
|
|
|
# Krypton
|
|
|
|
windowpath = "ActivateWindow(Videos,%s,return)" % path
|
|
|
|
else:
|
|
|
|
windowpath = "ActivateWindow(Video,%s,return)" % path
|
2016-05-07 21:15:02 +10:00
|
|
|
|
2015-12-25 07:07:00 +11:00
|
|
|
# Create the video node directory
|
2017-05-12 03:26:13 +10:00
|
|
|
if not exists_dir(nodepath):
|
2015-12-25 07:07:00 +11:00
|
|
|
# We need to copy over the default items
|
2017-05-04 04:30:33 +10:00
|
|
|
copytree(
|
2018-02-11 22:59:04 +11:00
|
|
|
src=try_decode(xbmc.translatePath(
|
2017-05-21 04:24:47 +10:00
|
|
|
"special://xbmc/system/library/video")),
|
2018-02-11 22:59:04 +11:00
|
|
|
dst=try_decode(xbmc.translatePath(
|
2017-05-21 04:24:47 +10:00
|
|
|
"special://profile/library/video")))
|
2015-12-25 07:07:00 +11:00
|
|
|
|
|
|
|
labels = {
|
|
|
|
'Favorite movies': 30180,
|
|
|
|
'Favorite tvshows': 30181,
|
|
|
|
'channels': 30173
|
|
|
|
}
|
2016-08-30 02:44:27 +10:00
|
|
|
label = lang(labels[tagname])
|
2016-05-31 16:06:42 +10:00
|
|
|
embynode = "Plex.nodes.%s" % indexnumber
|
2016-02-04 23:22:33 +11:00
|
|
|
window('%s.title' % embynode, value=label)
|
|
|
|
window('%s.path' % embynode, value=windowpath)
|
|
|
|
window('%s.content' % embynode, value=path)
|
|
|
|
window('%s.type' % embynode, value=itemtype)
|
2015-12-25 07:07:00 +11:00
|
|
|
|
2018-02-11 22:59:04 +11:00
|
|
|
if exists(try_encode(nodeXML)):
|
2015-12-25 07:07:00 +11:00
|
|
|
# Don't recreate xml if already exists
|
|
|
|
return
|
|
|
|
|
|
|
|
if itemtype == "channels":
|
2017-05-04 04:30:33 +10:00
|
|
|
root = self.commonRoot(order=1,
|
|
|
|
label=label,
|
|
|
|
tagname=tagname,
|
|
|
|
roottype=2)
|
2016-03-03 04:56:42 +11:00
|
|
|
etree.SubElement(root, 'path').text = "plugin://plugin.video.plexkodiconnect/?id=0&mode=channels"
|
2015-12-25 07:07:00 +11:00
|
|
|
else:
|
|
|
|
root = self.commonRoot(order=1, label=label, tagname=tagname)
|
|
|
|
etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
|
|
|
|
|
|
|
|
etree.SubElement(root, 'content').text = mediatype
|
|
|
|
|
|
|
|
try:
|
2016-09-05 00:34:25 +10:00
|
|
|
indent(root)
|
2017-05-04 04:30:33 +10:00
|
|
|
except:
|
|
|
|
pass
|
2017-05-29 23:39:11 +10:00
|
|
|
etree.ElementTree(root).write(nodeXML, encoding="UTF-8")
|
2015-12-25 07:07:00 +11:00
|
|
|
|
|
|
|
def clearProperties(self):
|
|
|
|
|
2016-08-30 02:44:27 +10:00
|
|
|
log.info("Clearing nodes properties.")
|
2016-05-31 16:06:42 +10:00
|
|
|
plexprops = window('Plex.nodes.total')
|
2015-12-25 07:07:00 +11:00
|
|
|
propnames = [
|
|
|
|
"index","path","title","content",
|
|
|
|
"inprogress.content","inprogress.title",
|
|
|
|
"inprogress.content","inprogress.path",
|
|
|
|
"nextepisodes.title","nextepisodes.content",
|
|
|
|
"nextepisodes.path","unwatched.title",
|
|
|
|
"unwatched.content","unwatched.path",
|
|
|
|
"recent.title","recent.content","recent.path",
|
|
|
|
"recentepisodes.title","recentepisodes.content",
|
|
|
|
"recentepisodes.path","inprogressepisodes.title",
|
|
|
|
"inprogressepisodes.content","inprogressepisodes.path"
|
|
|
|
]
|
|
|
|
|
2016-05-31 16:06:42 +10:00
|
|
|
if plexprops:
|
|
|
|
totalnodes = int(plexprops)
|
2015-12-25 07:07:00 +11:00
|
|
|
for i in range(totalnodes):
|
|
|
|
for prop in propnames:
|
2016-09-05 00:34:25 +10:00
|
|
|
window('Plex.nodes.%s.%s' % (str(i), prop), clear=True)
|