196 lines
8.1 KiB
Python
196 lines
8.1 KiB
Python
# coding=utf-8
|
|
import os, sys
|
|
import xbmc, xbmcaddon, xbmcplugin, xbmcgui, xbmcvfs
|
|
import xml.etree.ElementTree as xmltree
|
|
from traceback import print_exc
|
|
from urllib.parse import unquote
|
|
|
|
from resources.lib.common import *
|
|
|
|
class OrderByFunctions():
|
|
def __init__(self, ltype):
|
|
self.ltype = ltype
|
|
|
|
def _load_rules( self ):
|
|
if self.ltype.startswith('video'):
|
|
overridepath = os.path.join( DEFAULTPATH , "videorules.xml" )
|
|
else:
|
|
overridepath = os.path.join( DEFAULTPATH , "musicrules.xml" )
|
|
try:
|
|
tree = xmltree.parse( overridepath )
|
|
return tree
|
|
except:
|
|
return None
|
|
|
|
def translateOrderBy( self, rule ):
|
|
# Load the rules
|
|
tree = self._load_rules()
|
|
hasValue = True
|
|
if rule[ 0 ] == "sorttitle":
|
|
rule[ 0 ] = "title"
|
|
if rule[ 0 ] != "random":
|
|
# Get the field we're ordering by
|
|
elems = tree.getroot().find( "matches" ).findall( "match" )
|
|
for elem in elems:
|
|
if elem.attrib.get( "name" ) == rule[ 0 ]:
|
|
match = xbmc.getLocalizedString( int( elem.find( "label" ).text ) )
|
|
else:
|
|
# We'll manually set for random
|
|
match = xbmc.getLocalizedString( 590 )
|
|
# Get localization of direction
|
|
direction = None
|
|
elems = tree.getroot().find( "orderby" ).findall( "type" )
|
|
for elem in elems:
|
|
if elem.text == rule[ 1 ]:
|
|
direction = xbmc.getLocalizedString( int( elem.attrib.get( "label" ) ) )
|
|
directionVal = rule[ 1 ]
|
|
if direction is None:
|
|
direction = xbmc.getLocalizedString( int( tree.getroot().find( "orderby" ).find( "type" ).attrib.get( "label" ) ) )
|
|
directionVal = tree.getroot().find( "orderby" ).find( "type" ).text
|
|
return [ [ match, rule[ 0 ] ], [ direction, directionVal ] ]
|
|
|
|
def displayOrderBy( self, actionPath):
|
|
try:
|
|
# Load the xml file
|
|
tree = xmltree.parse( unquote(actionPath) )
|
|
root = tree.getroot()
|
|
# Get the content type
|
|
content = root.find( "content" ).text
|
|
# Get the order node
|
|
orderby = root.find( "order" )
|
|
if orderby is None:
|
|
# There is no orderby element, so add one
|
|
self.newOrderBy( tree, actionPath )
|
|
orderby = root.find( "order" )
|
|
match = orderby.text
|
|
if "direction" in orderby.attrib:
|
|
direction = orderby.attrib.get( "direction" )
|
|
else:
|
|
direction = ""
|
|
translated = self.translateOrderBy( [match, direction ] )
|
|
listitem = xbmcgui.ListItem( label="%s" % ( translated[ 0 ][ 0 ] ) )
|
|
action = "plugin://plugin.library.node.editor?ltype=%s&type=editOrderBy&actionPath=" % self.ltype + actionPath + "&content=" + content + "&default=" + translated[0][1]
|
|
xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
|
|
listitem = xbmcgui.ListItem( label="%s" % ( translated[ 1 ][ 0 ] ) )
|
|
action = "plugin://plugin.library.node.editor?ltype=%s&type=editOrderByDirection&actionPath=" % self.ltype + actionPath + "&default=" + translated[1][1]
|
|
xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
|
|
xbmcplugin.setContent(int(sys.argv[1]), 'files')
|
|
xbmcplugin.endOfDirectory(int(sys.argv[1]))
|
|
except:
|
|
print_exc()
|
|
|
|
def editOrderBy( self, actionPath, content, default ):
|
|
# Load all operator groups
|
|
tree = self._load_rules().getroot()
|
|
elems = tree.find( "matches" ).findall( "match" )
|
|
selectName = []
|
|
selectValue = []
|
|
# Find the matches for the content we've been passed
|
|
for elem in elems:
|
|
contentMatch = elem.find( content )
|
|
if contentMatch is not None:
|
|
selectName.append( xbmc.getLocalizedString( int( elem.find( "label" ).text ) ) )
|
|
selectValue.append( elem.attrib.get( "name" ) )
|
|
# Add a random element
|
|
selectName.append( xbmc.getLocalizedString( 590 ) )
|
|
selectValue.append( "random" )
|
|
# Let the user select an operator
|
|
selectedOperator = xbmcgui.Dialog().select( LANGUAGE( 30314 ), selectName )
|
|
# If the user selected no operator...
|
|
if selectedOperator == -1:
|
|
return
|
|
returnVal = selectValue[ selectedOperator ]
|
|
if returnVal == "title":
|
|
returnVal = "sorttitle"
|
|
self.writeUpdatedOrderBy( actionPath, field = returnVal )
|
|
|
|
def editDirection( self, actionPath, direction ):
|
|
# Load all directions
|
|
tree = self._load_rules().getroot()
|
|
elems = tree.find( "orderby" ).findall( "type" )
|
|
selectName = []
|
|
selectValue = []
|
|
# Find the group we've been passed and load its operators
|
|
for elem in elems:
|
|
selectName.append( xbmc.getLocalizedString( int( elem.attrib.get( "label" ) ) ) )
|
|
selectValue.append( elem.text )
|
|
# Let the user select an operator
|
|
selectedOperator = xbmcgui.Dialog().select( LANGUAGE( 30315 ), selectName )
|
|
# If the user selected no operator...
|
|
if selectedOperator == -1:
|
|
return
|
|
self.writeUpdatedOrderBy( actionPath, direction = selectValue[ selectedOperator ] )
|
|
|
|
def writeUpdatedOrderBy( self, actionPath, field = None, direction = None ):
|
|
# This function writes an updated orderby rule
|
|
try:
|
|
# Load the xml file
|
|
tree = xmltree.parse( unquote(unquote(actionPath)) )
|
|
root = tree.getroot()
|
|
# Get all the rules
|
|
orderby = root.find( "order" )
|
|
if field is not None:
|
|
orderby.text = field
|
|
if direction is not None:
|
|
orderby.set( "direction", direction )
|
|
# Save the file
|
|
self.indent( root )
|
|
tree.write( unquote(actionPath), encoding="UTF-8" )
|
|
except:
|
|
print_exc()
|
|
|
|
def newOrderBy( self, tree, actionPath ):
|
|
# This function adds a new OrderBy, with default match and direction
|
|
try:
|
|
# Load the xml file
|
|
#tree = xmltree.parse( actionPath )
|
|
root = tree.getroot()
|
|
# Get the content type
|
|
content = root.find( "content" )
|
|
if content is None:
|
|
xbmcgui.Dialog().ok( ADDONNAME, LANGUAGE( 30406 ) )
|
|
return
|
|
else:
|
|
content = content.text
|
|
# Find the default match for this content type
|
|
ruleTree = self._load_rules().getroot()
|
|
elems = ruleTree.find( "matches" ).findall( "match" )
|
|
match = "title"
|
|
for elem in elems:
|
|
contentCheck = elem.find( content )
|
|
if contentCheck is not None:
|
|
# We've found the first match for this type
|
|
match = elem.attrib.get( "name" )
|
|
break
|
|
if match == "title":
|
|
match = "sorttitle"
|
|
# Find the default direction
|
|
elem = ruleTree.find( "orderby" ).find( "type" )
|
|
direction = elem.text
|
|
# Write the new rule
|
|
newRule = xmltree.SubElement( root, "order" )
|
|
newRule.text = match
|
|
newRule.set( "direction", direction )
|
|
# Save the file
|
|
self.indent( root )
|
|
tree.write( unquote( actionPath ), encoding="UTF-8" )
|
|
except:
|
|
print_exc()
|
|
|
|
# in-place prettyprint formatter
|
|
def indent( self, elem, level=0 ):
|
|
i = "\n" + level*"\t"
|
|
if len(elem):
|
|
if not elem.text or not elem.text.strip():
|
|
elem.text = i + "\t"
|
|
if not elem.tail or not elem.tail.strip():
|
|
elem.tail = i
|
|
for elem in elem:
|
|
self.indent(elem, level+1)
|
|
if not elem.tail or not elem.tail.strip():
|
|
elem.tail = i
|
|
else:
|
|
if level and (not elem.tail or not elem.tail.strip()):
|
|
elem.tail = i
|
|
|