Updated kodi settings on Lenovo
This commit is contained in:
@@ -0,0 +1,836 @@
|
||||
# coding=utf-8
|
||||
import os, sys, shutil, unicodedata, re, types
|
||||
|
||||
from resources.lib.common import *
|
||||
|
||||
from html.entities import name2codepoint
|
||||
from urllib.parse import parse_qs
|
||||
from urllib.parse import quote, unquote
|
||||
|
||||
import xbmc, xbmcplugin, xbmcgui, xbmcvfs
|
||||
import xml.etree.ElementTree as xmltree
|
||||
import urllib
|
||||
from unidecode import unidecode
|
||||
|
||||
from traceback import print_exc
|
||||
import json
|
||||
|
||||
from resources.lib import rules, pathrules, viewattrib, orderby, moveNodes
|
||||
|
||||
# character entity reference
|
||||
CHAR_ENTITY_REXP = re.compile('&(%s);' % '|'.join(name2codepoint))
|
||||
|
||||
# decimal character reference
|
||||
DECIMAL_REXP = re.compile('&#(\d+);')
|
||||
|
||||
# hexadecimal character reference
|
||||
HEX_REXP = re.compile('&#x([\da-fA-F]+);')
|
||||
|
||||
REPLACE1_REXP = re.compile(r'[\']+')
|
||||
REPLACE2_REXP = re.compile(r'[^-a-z0-9]+')
|
||||
REMOVE_REXP = re.compile('-{2,}')
|
||||
|
||||
|
||||
|
||||
class Main:
|
||||
# MAIN ENTRY POINT
|
||||
def __init__(self, params, ltype, rule, attrib, pathrule, orderby):
|
||||
|
||||
self._parse_argv()
|
||||
self.ltype = ltype
|
||||
self.PARAMS = params
|
||||
self.RULE = rule
|
||||
self.ATTRIB = attrib
|
||||
self.PATHRULE = pathrule
|
||||
self.ORDERBY = orderby
|
||||
# If there are no custom library nodes in the profile directory, copy them from the Kodi install
|
||||
targetDir = os.path.join( xbmcvfs.translatePath( "special://profile" ), "library", ltype )
|
||||
if True:
|
||||
if not os.path.exists( targetDir ):
|
||||
xbmcvfs.mkdirs( targetDir )
|
||||
originDir = os.path.join( xbmcvfs.translatePath( "special://xbmc" ), "system", "library", ltype )
|
||||
dirs, files = xbmcvfs.listdir( originDir )
|
||||
self.copyNode( dirs, files, targetDir, originDir )
|
||||
else:
|
||||
xbmcgui.Dialog().ok(ADDONNAME, LANGUAGE( 30400 ) )
|
||||
print_exc
|
||||
xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
|
||||
return
|
||||
# Create data if not exists
|
||||
if not os.path.exists(DATAPATH):
|
||||
xbmcvfs.mkdir(DATAPATH)
|
||||
if "type" in self.PARAMS:
|
||||
# We're performing a specific action
|
||||
if self.PARAMS[ "type" ] == "delete":
|
||||
message = LANGUAGE( 30401 )
|
||||
actionpath = unquote(self.PARAMS["actionPath"])
|
||||
if self.PARAMS[ "actionPath" ] == targetDir:
|
||||
# Ask the user is they want to reset all nodes
|
||||
message = LANGUAGE( 30402 )
|
||||
result = xbmcgui.Dialog().yesno(ADDONNAME, message )
|
||||
if result:
|
||||
if actionpath.endswith( ".xml" ):
|
||||
# Delete single file
|
||||
xbmcvfs.delete(actionpath)
|
||||
else:
|
||||
# Delete folder
|
||||
self.RULE.deleteAllNodeRules(actionpath)
|
||||
shutil.rmtree(actionpath)
|
||||
else:
|
||||
return
|
||||
elif self.PARAMS[ "type" ] == "deletenode":
|
||||
result = xbmcgui.Dialog().yesno(ADDONNAME, LANGUAGE( 30403 ) )
|
||||
if result:
|
||||
self.changeViewElement( self.PARAMS[ "actionPath" ], self.PARAMS[ "node" ], "" )
|
||||
elif self.PARAMS[ "type" ] == "editlabel":
|
||||
if self.PARAMS[ "label" ].isdigit():
|
||||
label = xbmc.getLocalizedString( int( self.PARAMS[ "label" ] ) )
|
||||
else:
|
||||
label = self.PARAMS[ "label" ]
|
||||
# Get new label from keyboard dialog
|
||||
keyboard = xbmc.Keyboard( label, LANGUAGE( 30300 ), False )
|
||||
keyboard.doModal()
|
||||
if ( keyboard.isConfirmed() ):
|
||||
newlabel = keyboard.getText()
|
||||
if newlabel != "" and newlabel != label:
|
||||
# We've got a new label, update the xml file
|
||||
self.changeViewElement( self.PARAMS[ "actionPath" ], "label", newlabel )
|
||||
else:
|
||||
return
|
||||
elif self.PARAMS[ "type" ] == "editvisibility":
|
||||
currentVisibility = self.getRootAttrib( self.PARAMS[ "actionPath" ], "visible" )
|
||||
# Get new visibility from keyboard dialog
|
||||
keyboard = xbmc.Keyboard( currentVisibility, LANGUAGE( 30301 ), False )
|
||||
keyboard.doModal()
|
||||
if ( keyboard.isConfirmed() ):
|
||||
newVisibility = keyboard.getText()
|
||||
if newVisibility != currentVisibility:
|
||||
# We've got a new label, update the xml file
|
||||
self.changeRootAttrib( self.PARAMS[ "actionPath" ], "visible", newVisibility )
|
||||
else:
|
||||
return
|
||||
elif self.PARAMS[ "type" ] == "moveNode":
|
||||
self.indexCounter = -1
|
||||
|
||||
# Get existing nodes
|
||||
nodes = {}
|
||||
self.listNodes( self.PARAMS[ "actionPath" ], nodes )
|
||||
|
||||
# Get updated order
|
||||
newOrder = moveNodes.getNewOrder( nodes, int( self.PARAMS[ "actionItem" ] ) )
|
||||
|
||||
if newOrder is not None:
|
||||
# Update the orders
|
||||
for i, node in enumerate( newOrder, 1 ):
|
||||
path = unquote( node[ 2 ] )
|
||||
if node[ 3 ] == "folder":
|
||||
path = os.path.join( unquote( node[ 2 ] ), "index.xml" )
|
||||
self.changeRootAttrib( path, "order", str( i * 10 ) )
|
||||
|
||||
elif self.PARAMS[ "type" ] == "newView":
|
||||
# Get new view name from keyboard dialog
|
||||
keyboard = xbmc.Keyboard( "", LANGUAGE( 30316 ), False )
|
||||
keyboard.doModal()
|
||||
if ( keyboard.isConfirmed() ):
|
||||
newView = keyboard.getText()
|
||||
if newView != "":
|
||||
# Ensure filename is unique
|
||||
filename = self.slugify( newView.lower().replace( " ", "" ) )
|
||||
if os.path.exists( os.path.join( self.PARAMS[ "actionPath" ], filename + ".xml" ) ):
|
||||
count = 0
|
||||
while os.path.exists( os.path.join( self.PARAMS[ "actionPath" ], filename + "-" + str( count ) + ".xml" ) ):
|
||||
count += 1
|
||||
filename = filename + "-" + str( count )
|
||||
# Create a new xml file
|
||||
tree = xmltree.ElementTree( xmltree.Element( "node" ) )
|
||||
root = tree.getroot()
|
||||
subtree = xmltree.SubElement( root, "label" ).text = newView
|
||||
# Add any node rules
|
||||
self.RULE.addAllNodeRules( self.PARAMS[ "actionPath" ], root )
|
||||
# Write the xml file
|
||||
self.indent( root )
|
||||
xmlfile = unquote(os.path.join( self.PARAMS[ "actionPath" ], filename + ".xml" ))
|
||||
if not os.path.exists(xmlfile):
|
||||
with open(xmlfile, 'a'):
|
||||
os.utime(xmlfile, None)
|
||||
tree.write( xmlfile, encoding="UTF-8" )
|
||||
else:
|
||||
return
|
||||
elif self.PARAMS[ "type" ] == "newNode":
|
||||
# Get new node name from the keyboard dialog
|
||||
keyboard = xbmc.Keyboard( "", LANGUAGE( 30303 ), False )
|
||||
keyboard.doModal()
|
||||
if ( keyboard.isConfirmed() ):
|
||||
newNode = keyboard.getText()
|
||||
if newNode == "":
|
||||
return
|
||||
# Ensure foldername is unique
|
||||
foldername = self.slugify( newNode.lower().replace( " ", "" ) )
|
||||
if os.path.exists( os.path.join( self.PARAMS[ "actionPath" ], foldername + os.pathsep ) ):
|
||||
count = 0
|
||||
while os.path.exists( os.path.join( self.PARAMS[ "actionPath" ], foldername + "-" + str( count ) + os.pathsep ) ):
|
||||
count += 1
|
||||
foldername = foldername + "-" + str( count )
|
||||
foldername = unquote(os.path.join( self.PARAMS[ "actionPath" ], foldername ))
|
||||
# Create new node folder
|
||||
xbmcvfs.mkdir( foldername )
|
||||
# Create a new xml file
|
||||
tree = xmltree.ElementTree( xmltree.Element( "node" ) )
|
||||
root = tree.getroot()
|
||||
subtree = xmltree.SubElement( root, "label" ).text = newNode
|
||||
# Ask user if they want to import defaults
|
||||
if self.ltype.startswith( "video" ):
|
||||
defaultNames = [ xbmc.getLocalizedString( 231 ), xbmc.getLocalizedString( 342 ), xbmc.getLocalizedString( 20343 ), xbmc.getLocalizedString( 20389 ) ]
|
||||
defaultValues = [ "", "movies", "tvshows", "musicvideos" ]
|
||||
selected = xbmcgui.Dialog().select( LANGUAGE( 30304 ), defaultNames )
|
||||
else:
|
||||
selected = 0
|
||||
# If the user selected some defaults...
|
||||
if selected != -1 and selected != 0:
|
||||
try:
|
||||
# Copy those defaults across
|
||||
originDir = os.path.join( xbmcvfs.translatePath( "special://xbmc" ), "system", "library", self.ltype, defaultValues[ selected ] )
|
||||
dirs, files = xbmcvfs.listdir( originDir )
|
||||
for file in files:
|
||||
if file != "index.xml":
|
||||
xbmcvfs.copy( os.path.join( originDir, file), os.path.join( foldername, file ) )
|
||||
# Open index.xml and copy values across
|
||||
index = xmltree.parse( os.path.join( originDir, "index.xml" ) ).getroot()
|
||||
if "visible" in index.attrib:
|
||||
root.set( "visible", index.attrib.get( "visible" ) )
|
||||
icon = index.find( "icon" )
|
||||
if icon is not None:
|
||||
xmltree.SubElement( root, "icon" ).text = icon.text
|
||||
except:
|
||||
print_exc()
|
||||
# Write the xml file
|
||||
self.indent( root )
|
||||
tree.write( unquote(os.path.join( foldername, "index.xml" )), encoding="UTF-8" )
|
||||
else:
|
||||
return
|
||||
elif self.PARAMS[ "type" ] == "rule":
|
||||
# Display list of all elements of a rule
|
||||
self.RULE.displayRule( self.PARAMS[ "actionPath" ], self.PATH, self.PARAMS[ "rule" ] )
|
||||
return
|
||||
elif self.PARAMS[ "type" ] == "editMatch":
|
||||
# Editing the field the rule is matched against
|
||||
self.RULE.editMatch( self.PARAMS[ "actionPath" ], self.PARAMS[ "rule" ], self.PARAMS[ "content"], self.PARAMS[ "default" ] )
|
||||
elif self.PARAMS[ "type" ] == "editOperator":
|
||||
# Editing the operator of a rule
|
||||
self.RULE.editOperator( self.PARAMS[ "actionPath" ], self.PARAMS[ "rule" ], self.PARAMS[ "group" ], self.PARAMS[ "default" ] )
|
||||
elif self.PARAMS[ "type" ] == "editValue":
|
||||
# Editing the value of a rule
|
||||
self.RULE.editValue(self.PARAMS["actionPath"], self.PARAMS[ "rule" ] )
|
||||
elif self.PARAMS[ "type" ] == "browseValue":
|
||||
# Browse for the new value of a rule
|
||||
self.RULE.browse( self.PARAMS[ "actionPath" ], self.PARAMS[ "rule" ], self.PARAMS[ "match" ], self.PARAMS[ "content" ] )
|
||||
elif self.PARAMS[ "type" ] == "deleteRule":
|
||||
# Delete a rule
|
||||
self.RULE.deleteRule( self.PARAMS[ "actionPath" ], self.PARAMS[ "rule" ] )
|
||||
elif self.PARAMS[ "type" ] == "editRulesMatch":
|
||||
# Editing whether any or all rules must match
|
||||
self.ATTRIB.editMatch( self.PARAMS[ "actionPath" ] )
|
||||
# --- Edit order-by ---
|
||||
elif self.PARAMS[ "type" ] == "orderby":
|
||||
# Display all elements of order by
|
||||
self.ORDERBY.displayOrderBy( self.PARAMS[ "actionPath" ])
|
||||
return
|
||||
elif self.PARAMS[ "type" ] == "editOrderBy":
|
||||
self.ORDERBY.editOrderBy( self.PARAMS[ "actionPath" ], self.PARAMS[ "content" ], self.PARAMS[ "default" ] )
|
||||
elif self.PARAMS[ "type" ] == "editOrderByDirection":
|
||||
self.ORDERBY.editDirection( self.PARAMS[ "actionPath" ], self.PARAMS[ "default" ] )
|
||||
# --- Edit paths ---
|
||||
elif self.PARAMS[ "type" ] == "addPath":
|
||||
self.ATTRIB.addPath( self.PARAMS[ "actionPath" ] )
|
||||
elif self.PARAMS[ "type" ] == "editPath":
|
||||
self.ATTRIB.editPath( self.PARAMS[ "actionPath" ], self.PARAMS[ "value" ] )
|
||||
elif self.PARAMS[ "type" ] == "pathRule":
|
||||
self.PATHRULE.displayRule( self.PARAMS[ "actionPath" ], int( self.PARAMS[ "rule" ] ) )
|
||||
return
|
||||
elif self.PARAMS[ "type" ] == "deletePathRule":
|
||||
self.ATTRIB.deletePathRule( self.PARAMS[ "actionPath" ], int( self.PARAMS[ "rule" ] ) )
|
||||
elif self.PARAMS[ "type" ] == "editPathMatch":
|
||||
# Editing the field the rule is matched against
|
||||
self.PATHRULE.editMatch( self.PARAMS[ "actionPath" ], int( self.PARAMS[ "rule" ] ) )
|
||||
elif self.PARAMS[ "type" ] == "editPathValue":
|
||||
# Editing the value of a rule
|
||||
self.PATHRULE.editValue( self.PARAMS[ "actionPath" ], int( self.PARAMS[ "rule" ] ) )
|
||||
elif self.PARAMS[ "type" ] == "browsePathValue":
|
||||
# Browse for the new value of a rule
|
||||
self.PATHRULE.browse( self.PARAMS[ "actionPath" ], int( self.PARAMS[ "rule" ] ) )
|
||||
# --- Edit other attribute of view ---
|
||||
# > Content
|
||||
elif self.PARAMS[ "type" ] == "editContent":
|
||||
self.ATTRIB.editContent( self.PARAMS[ "actionPath" ], "" ) # No default to pass, yet!
|
||||
# > Grouping
|
||||
elif self.PARAMS[ "type" ] == "editGroup":
|
||||
self.ATTRIB.editGroup( self.PARAMS[ "actionPath" ], self.PARAMS[ "content" ], "" )
|
||||
# > Limit
|
||||
elif self.PARAMS[ "type" ] == "editLimit":
|
||||
self.ATTRIB.editLimit( self.PARAMS[ "actionPath" ], self.PARAMS[ "value" ] )
|
||||
# > Icon (also for node)
|
||||
elif self.PARAMS[ "type" ] == "editIcon":
|
||||
self.ATTRIB.editIcon( self.PARAMS[ "actionPath" ], self.PARAMS[ "value" ] )
|
||||
elif self.PARAMS[ "type" ] == "browseIcon":
|
||||
self.ATTRIB.browseIcon( self.PARAMS[ "actionPath" ] )
|
||||
# Refresh the listings and exit
|
||||
xbmc.executebuiltin("Container.Refresh")
|
||||
return
|
||||
if self.PATH.endswith( ".xml" ):
|
||||
self.RulesList()
|
||||
else:
|
||||
self.NodesList(targetDir)
|
||||
|
||||
def NodesList( self, targetDir ):
|
||||
# List nodes and views
|
||||
nodes = {}
|
||||
self.indexCounter = -1
|
||||
if self.PATH != "":
|
||||
self.listNodes( self.PATH, nodes )
|
||||
else:
|
||||
self.listNodes( targetDir, nodes )
|
||||
self.PATH = quote( self.PATH )
|
||||
for i, key in enumerate( sorted( nodes ) ):
|
||||
# 0 = Label
|
||||
# 1 = Icon
|
||||
# 2 = Path
|
||||
# 3 = Type
|
||||
# 4 = Order
|
||||
# Localize the label
|
||||
if nodes[ key ][ 0 ].isdigit():
|
||||
label = xbmc.getLocalizedString( int( nodes[ key ][ 0 ] ) )
|
||||
else:
|
||||
label = nodes[ key ][ 0 ]
|
||||
# Create the listitem
|
||||
if nodes[ key ][ 3 ] == "folder":
|
||||
listitem = xbmcgui.ListItem( label="%s >" % ( label ), label2=nodes[ key ][ 4 ] )
|
||||
listitem.setArt({"icon": nodes[ key ][ 1 ]})
|
||||
else:
|
||||
listitem = xbmcgui.ListItem( label=label, label2=nodes[ key ][ 4 ] )
|
||||
listitem.setArt({"icon": nodes[ key ][ 1 ]})
|
||||
# Add context menu items
|
||||
commands = []
|
||||
commandsNode = []
|
||||
commandsView = []
|
||||
commandsNode.append( ( LANGUAGE(30101), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editlabel&actionPath=" % self.ltype + os.path.join( nodes[ key ][ 2 ], "index.xml" ) + "&label=" + nodes[ key ][ 0 ] + ")" ) )
|
||||
commandsNode.append( ( LANGUAGE(30102), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editIcon&actionPath=" % self.ltype + os.path.join( nodes[ key ][ 2 ], "index.xml" ) + "&value=" + nodes[ key ][ 1 ] + ")" ) )
|
||||
commandsNode.append( ( LANGUAGE(30103), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=browseIcon&actionPath=" % self.ltype + os.path.join( nodes [ key ][ 2 ], "index.xml" ) + ")" ) )
|
||||
if self.PATH == "":
|
||||
commandsNode.append( ( LANGUAGE(30104), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=moveNode&actionPath=" % self.ltype + targetDir + "&actionItem=" + str( i ) + ")" ) )
|
||||
else:
|
||||
commandsNode.append( ( LANGUAGE(30104), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=moveNode&actionPath=" % self.ltype + self.PATH + "&actionItem=" + str( i ) + ")" ) )
|
||||
commandsNode.append( ( LANGUAGE(30105), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editvisibility&actionPath=" % self.ltype + os.path.join( nodes[ key ][ 2 ], "index.xml" ) + ")" ) )
|
||||
commandsNode.append( ( LANGUAGE(30100), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=delete&actionPath=" % self.ltype + nodes[ key ][ 2 ] + ")" ) )
|
||||
|
||||
commandsView.append( ( LANGUAGE(30101), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editlabel&actionPath=" % self.ltype + nodes[ key ][ 2 ] + "&label=" + nodes[ key ][ 0 ] + ")" ) )
|
||||
commandsView.append( ( LANGUAGE(30102), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editIcon&actionPath=" % self.ltype + nodes[ key ][ 2 ] + "&value=" + nodes[ key ][ 1 ] + ")" ) )
|
||||
commandsView.append( ( LANGUAGE(30103), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=browseIcon&actionPath=" % self.ltype + nodes[ key ][ 2 ] + ")" ) )
|
||||
if self.PATH == "":
|
||||
commandsView.append( ( LANGUAGE(30104), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=moveNode&actionPath=" % self.ltype + targetDir + "&actionItem=" + str( i ) + ")" ) )
|
||||
else:
|
||||
commandsView.append( ( LANGUAGE(30104), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=moveNode&actionPath=" % self.ltype + self.PATH + "&actionItem=" + str( i ) + ")" ) )
|
||||
commandsView.append( ( LANGUAGE(30105), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editvisibility&actionPath=" % self.ltype + nodes[ key ][ 2 ] + ")" ) )
|
||||
commandsView.append( ( LANGUAGE(30100), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=delete&actionPath=" % self.ltype + nodes[ key ][ 2 ] + ")" ) )
|
||||
if nodes[ key ][ 3 ] == "folder":
|
||||
listitem.addContextMenuItems( commandsNode )
|
||||
xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), "plugin://plugin.library.node.editor?ltype=%s&path=" % self.ltype + nodes[ key ][ 2 ], listitem, isFolder=True )
|
||||
else:
|
||||
listitem.addContextMenuItems( commandsView )
|
||||
xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), "plugin://plugin.library.node.editor?ltype=%s&path=" % self.ltype + nodes[ key ][ 2 ], listitem, isFolder=True )
|
||||
if self.PATH != "":
|
||||
# Get any rules from the index.xml
|
||||
rules, nextRule = self.getRules( os.path.join( unquote( self.PATH ), "index.xml" ), True )
|
||||
rulecount = 0
|
||||
if rules is not None:
|
||||
for rule in rules:
|
||||
commands = []
|
||||
if rule[ 0 ] == "rule":
|
||||
# 1 = field
|
||||
# 2 = operator
|
||||
# 3 = value (optional)
|
||||
if len(rule) == 3:
|
||||
translated = self.RULE.translateRule( [ rule[ 1 ], rule[ 2 ] ] )
|
||||
else:
|
||||
translated = self.RULE.translateRule( [ rule[ 1 ], rule[ 2 ], rule[ 3 ] ] )
|
||||
if len(translated) == 2:
|
||||
listitem = xbmcgui.ListItem( label="%s: %s %s" % ( LANGUAGE(30205), translated[ 0 ][ 0 ], translated[ 1 ][ 0 ] ) )
|
||||
else:
|
||||
listitem = xbmcgui.ListItem( label="%s: %s %s %s" % ( LANGUAGE(30205), translated[ 0 ][ 0 ], translated[ 1 ][ 0 ], translated[ 2 ][ 1 ] ) )
|
||||
commands.append( ( LANGUAGE( 30100 ), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deleteRule&actionPath=" % self.ltype + os.path.join( self.PATH, "index.xml" ) + "&rule=" + str( rulecount ) + ")" ) )
|
||||
action = "plugin://plugin.library.node.editor?ltype=%s&type=rule&actionPath=" % self.ltype + os.path.join( self.PATH, "index.xml" ) + "&rule=" + str( rulecount )
|
||||
rulecount += 1
|
||||
listitem.addContextMenuItems( commands, replaceItems = True )
|
||||
if rule[ 0 ] == "rule" or rule[ 0 ] == "order":
|
||||
xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=True )
|
||||
else:
|
||||
xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
|
||||
# New rule
|
||||
xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=rule&actionPath=" % self.ltype + os.path.join( self.PATH, "index.xml" ) + "&rule=" + str( nextRule), xbmcgui.ListItem( label="* %s" %( LANGUAGE(30005) ) ), isFolder=True )
|
||||
showReset = False
|
||||
if self.PATH == "":
|
||||
self.PATH = quote( targetDir )
|
||||
showReset = True
|
||||
# New view and node
|
||||
xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=newView&actionPath=" % self.ltype + self.PATH, xbmcgui.ListItem( label="* %s" %( LANGUAGE(30006) ) ), isFolder=False )
|
||||
xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=newNode&actionPath=" % self.ltype + self.PATH, xbmcgui.ListItem( label="* %s" %( LANGUAGE(30007) ) ), isFolder=False )
|
||||
if showReset:
|
||||
xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), "plugin://plugin.library.node.editor?ltype=%s&type=delete&actionPath=" % self.ltype + targetDir, xbmcgui.ListItem( label="* %s" %( LANGUAGE(30008) ) ), isFolder=False )
|
||||
xbmcplugin.setContent(int(sys.argv[1]), 'files')
|
||||
xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
|
||||
|
||||
def RulesList( self ):
|
||||
# List rules for specific view
|
||||
rules, nextRule = self.getRules( self.PATH )
|
||||
hasContent = False
|
||||
content = ""
|
||||
hasOrder = False
|
||||
hasGroup = False
|
||||
hasLimit = False
|
||||
hasPath = False
|
||||
splitPath = None
|
||||
rulecount = 0
|
||||
if rules is not None:
|
||||
for rule in rules:
|
||||
commands = []
|
||||
if rule[ 0 ] == "content":
|
||||
# 1 = Content
|
||||
listitem = xbmcgui.ListItem( label="%s: %s" % ( LANGUAGE(30200), self.ATTRIB.translateContent( rule[ 1 ] ) ) )
|
||||
commands.append( ( LANGUAGE(30100), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deletenode&actionPath=" % self.ltype + self.PATH + "&node=content)" ) )
|
||||
action = "plugin://plugin.library.node.editor?ltype=%s&type=editContent&actionPath=" % self.ltype + self.PATH
|
||||
hasContent = True
|
||||
content = rule[ 1 ]
|
||||
elif rule[ 0 ] == "order":
|
||||
# 1 = orderby
|
||||
# 2 = direction (optional?)
|
||||
if len( rule ) == 3:
|
||||
translate = self.ORDERBY.translateOrderBy( [ rule[ 1 ], rule[ 2 ] ] )
|
||||
listitem = xbmcgui.ListItem( label="%s: %s (%s)" % ( LANGUAGE(30201), translate[ 0 ][ 0 ], translate[ 1 ][ 0 ] ) )
|
||||
else:
|
||||
translate = self.ORDERBY.translateOrderBy( [ rule[ 1 ], "" ] )
|
||||
listitem = xbmcgui.ListItem( label="%s: %s" % ( LANGUAGE(30201), translate[ 0 ][ 0 ] ) )
|
||||
commands.append( ( LANGUAGE(30100), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deletenode&actionPath=" % self.ltype + self.PATH + "&node=order)" ) )
|
||||
action = "plugin://plugin.library.node.editor?ltype=%s&type=orderby&actionPath=" % self.ltype + self.PATH
|
||||
hasOrder = True
|
||||
elif rule[ 0 ] == "group":
|
||||
# 1 = group
|
||||
listitem = xbmcgui.ListItem( label="%s: %s" % ( LANGUAGE(30202), self.ATTRIB.translateGroup( rule[ 1 ] ) ) )
|
||||
commands.append( ( LANGUAGE(30100), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deletenode&actionPath=" % self.ltype + self.PATH + "&node=group)" ) )
|
||||
action = "plugin://plugin.library.node.editor?ltype=%s&type=editGroup&actionPath=" % self.ltype + self.PATH + "&value=" + rule[ 1 ] + "&content=" + content
|
||||
hasGroup = True
|
||||
elif rule[ 0 ] == "limit":
|
||||
# 1 = limit
|
||||
listitem = xbmcgui.ListItem( label="%s: %s" % ( LANGUAGE(30203), rule[ 1 ] ) )
|
||||
commands.append( ( LANGUAGE(30100), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deletenode&actionPath=" % self.ltype + self.PATH + "&node=limit)" ) )
|
||||
action = "plugin://plugin.library.node.editor?ltype=%s&type=editLimit&actionPath=" % self.ltype + self.PATH + "&value=" + rule[ 1 ]
|
||||
hasLimit = True
|
||||
elif rule[ 0 ] == "path":
|
||||
# 1 = path
|
||||
# Split the path into components
|
||||
splitPath = self.ATTRIB.splitPath( rule[ 1 ] )
|
||||
|
||||
# Add each element of the path to the list
|
||||
for x, component in enumerate( splitPath ):
|
||||
if x == 0:
|
||||
# library://path/
|
||||
listitem = xbmcgui.ListItem( label="%s: %s" % ( LANGUAGE(30204), self.ATTRIB.translatePath( component ) ) )
|
||||
commands.append( ( LANGUAGE(30100), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deletenode&actionPath=" % self.ltype + self.PATH + "&node=path)" ) )
|
||||
action = "plugin://plugin.library.node.editor?ltype=%s&type=addPath&actionPath=" % self.ltype + self.PATH
|
||||
|
||||
# Get the rules
|
||||
rules = self.PATHRULE.getRulesForPath( splitPath[ 0 ] )
|
||||
if x != 0:
|
||||
# Specific component
|
||||
|
||||
# Add the listitem generated from the last component we processed
|
||||
listitem.addContextMenuItems( commands, replaceItems = True )
|
||||
xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=True )
|
||||
commands = []
|
||||
|
||||
# Get the rule for this component
|
||||
componentRule = self.PATHRULE.getMatchingRule( component, rules )
|
||||
translatedComponent = self.PATHRULE.translateComponent( componentRule, splitPath[ x ] )
|
||||
translatedValue = self.PATHRULE.translateValue( componentRule, splitPath, x )
|
||||
|
||||
listitem = xbmcgui.ListItem( label="%s: %s" % ( translatedComponent, translatedValue ) )
|
||||
commands.append( ( LANGUAGE(30100), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deletePathRule&actionPath=%s&rule=%d)" %( self.ltype, self.PATH, x ) ) )
|
||||
action = "plugin://plugin.library.node.editor?ltype=%s&type=pathRule&actionPath=%s&rule=%d" % ( self.ltype, self.PATH, x )
|
||||
hasPath = True
|
||||
elif rule[ 0 ] == "rule":
|
||||
# 1 = field
|
||||
# 2 = operator
|
||||
# 3 = value (optional)
|
||||
# 4 = ruleNum
|
||||
if len(rule) == 3:
|
||||
translated = self.RULE.translateRule( [ rule[ 1 ], rule[ 2 ] ] )
|
||||
else:
|
||||
translated = self.RULE.translateRule( [ rule[ 1 ], rule[ 2 ], rule[ 3 ] ] )
|
||||
if translated[ 2 ][ 0 ] == "|NONE|":
|
||||
listitem = xbmcgui.ListItem( label="%s: %s %s" % ( LANGUAGE(30205), translated[ 0 ][ 0 ], translated[ 1 ][ 0 ] ) )
|
||||
else:
|
||||
listitem = xbmcgui.ListItem( label="%s: %s %s %s" % ( LANGUAGE(30205), translated[ 0 ][ 0 ], translated[ 1 ][ 0 ], translated[ 2 ][ 1 ] ) )
|
||||
commands.append( ( LANGUAGE(30100), "RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deleteRule&actionPath=" % self.ltype + self.PATH + "&rule=" + str( rule[ 4 ] ) + ")" ) )
|
||||
action = "plugin://plugin.library.node.editor?ltype=%s&type=rule&actionPath=" % self.ltype + self.PATH + "&rule=" + str( rule[ 4 ] )
|
||||
rulecount += 1
|
||||
elif rule[ 0 ] == "match":
|
||||
# 1 = value
|
||||
listitem = xbmcgui.ListItem( label="%s: %s" % ( LANGUAGE(30206), self.ATTRIB.translateMatch( rule[ 1 ] ) ) )
|
||||
action = "plugin://plugin.library.node.editor?ltype=%s&type=editRulesMatch&actionPath=%s" %( self.ltype, self.PATH )
|
||||
hasGroup = True
|
||||
listitem.addContextMenuItems( commands, replaceItems = True )
|
||||
if rule[ 0 ] == "rule" or rule[ 0 ] == "order" or rule[ 0 ] == "path":
|
||||
xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=True )
|
||||
else:
|
||||
xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
|
||||
if not hasContent and not hasPath:
|
||||
# Add content
|
||||
xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=editContent&actionPath=" % self.ltype + self.PATH, xbmcgui.ListItem( label="* %s" %( LANGUAGE(30000) ) ) )
|
||||
if not hasOrder and hasContent:
|
||||
# Add order
|
||||
xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=orderby&actionPath=" % self.ltype + self.PATH, xbmcgui.ListItem( label="* %s" %( LANGUAGE(30002) ) ), isFolder=True )
|
||||
if not hasGroup and hasContent:
|
||||
# Add group
|
||||
xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=editGroup&actionPath=" % self.ltype + self.PATH + "&content=" + content, xbmcgui.ListItem( label="* %s" %( LANGUAGE(30004) ) ) )
|
||||
if not hasLimit and hasContent:
|
||||
# Add limit
|
||||
xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=editLimit&actionPath=" % self.ltype + self.PATH + "&value=25", xbmcgui.ListItem( label="* %s" %( LANGUAGE(30003) ) ) )
|
||||
if not hasPath and not hasContent:
|
||||
# Add path
|
||||
xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=addPath&actionPath=" % self.ltype + self.PATH, xbmcgui.ListItem( label="* %s" %( LANGUAGE(30001) ) ) )
|
||||
if hasContent:
|
||||
# Add rule
|
||||
xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=rule&actionPath=" % self.ltype + self.PATH + "&rule=" + str( nextRule ), xbmcgui.ListItem( label="* %s" %( LANGUAGE(30005) ) ), isFolder = True )
|
||||
if hasPath:
|
||||
if "plugin://" not in splitPath[0][0]:
|
||||
# Add component
|
||||
xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=pathRule&actionPath=%s&rule=%d" % ( self.ltype, self.PATH, x + 1 ), xbmcgui.ListItem( label="* %s" %( LANGUAGE(30009) ) ), isFolder = True )
|
||||
# Manually edit path
|
||||
xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=editPath&actionPath=" % self.ltype + self.PATH + "&value=" + quote( rule[ 1 ] ), xbmcgui.ListItem( label="* %s" %( LANGUAGE(30010) ) ), isFolder = True )
|
||||
xbmcplugin.setContent(int(sys.argv[1]), 'files')
|
||||
xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
|
||||
|
||||
def _parse_argv( self ):
|
||||
try:
|
||||
p = parse_qs(sys.argv[2][1:])
|
||||
for i in p.keys():
|
||||
p[i] = p[i][0]
|
||||
self.PARAMS = p
|
||||
except:
|
||||
p = parse_qs(sys.argv[1])
|
||||
for i in p.keys():
|
||||
p[i] = p[i][0]
|
||||
self.PARAMS = p
|
||||
if "path" in self.PARAMS:
|
||||
self.PATH = self.PARAMS[ "path" ]
|
||||
else:
|
||||
self.PATH = ""
|
||||
|
||||
def getRules( self, actionPath, justRules = False ):
|
||||
returnVal = []
|
||||
try:
|
||||
# Load the xml file
|
||||
tree = xmltree.parse( actionPath )
|
||||
root = tree.getroot()
|
||||
if justRules == False:
|
||||
# Look for a 'content'
|
||||
content = root.find( "content" )
|
||||
if content is not None:
|
||||
returnVal.append( ( "content", content.text ) )
|
||||
# Look for an 'order'
|
||||
order = root.find( "order" )
|
||||
if order is not None:
|
||||
if "direction" in order.attrib:
|
||||
returnVal.append( ( "order", order.text, order.attrib.get( "direction" ) ) )
|
||||
else:
|
||||
returnVal.append( ( "order", order.text ) )
|
||||
# Look for a 'group'
|
||||
group = root.find( "group" )
|
||||
if group is not None:
|
||||
returnVal.append( ( "group", group.text ) )
|
||||
# Look for a 'limit'
|
||||
limit = root.find( "limit" )
|
||||
if limit is not None:
|
||||
returnVal.append( ( "limit", limit.text ) )
|
||||
# Look for a 'path'
|
||||
path = root.find( "path" )
|
||||
if path is not None:
|
||||
returnVal.append( ( "path", path.text ) )
|
||||
# Save the current length of the returnVal - we'll insert Match here if there are two or more rules
|
||||
currentLen = len( returnVal )
|
||||
# Look for any rules
|
||||
ruleNum = 0
|
||||
if actionPath.endswith( "index.xml" ):
|
||||
# Load the rules from RULE module
|
||||
rules = self.RULE.getNodeRules( actionPath )
|
||||
if rules is not None:
|
||||
for rule in rules:
|
||||
returnVal.append( ( "rule", rule[ 0 ], rule[ 1 ], rule[ 2 ], ruleNum ) )
|
||||
ruleNum += 1
|
||||
return returnVal, len( rules )
|
||||
else:
|
||||
return returnVal, 0
|
||||
else:
|
||||
rules = root.findall( "rule" )
|
||||
# Process the rules
|
||||
if rules is not None:
|
||||
for rule in rules:
|
||||
value = rule.find( "value" )
|
||||
if value is not None and value.text is not None:
|
||||
translated = self.RULE.translateRule( [ rule.attrib.get( "field" ), rule.attrib.get( "operator" ), value.text ] )
|
||||
if not self.RULE.isNodeRule( translated, actionPath ):
|
||||
returnVal.append( ( "rule", rule.attrib.get( "field" ), rule.attrib.get( "operator" ), value.text, ruleNum ) )
|
||||
else:
|
||||
translated = self.RULE.translateRule( [ rule.attrib.get( "field" ), rule.attrib.get( "operator" ), "" ] )
|
||||
if not self.RULE.isNodeRule( translated, actionPath ):
|
||||
returnVal.append( ( "rule", rule.attrib.get( "field" ), rule.attrib.get( "operator" ), "", ruleNum ) )
|
||||
ruleNum += 1
|
||||
# Get any current match value if there are more than two rules
|
||||
# (if there's only one, the match value doesn't matter)
|
||||
if ruleNum >= 2:
|
||||
matchRules = "all"
|
||||
match = root.find( "match" )
|
||||
if match is not None:
|
||||
matchRules = match.text
|
||||
returnVal.insert( currentLen, ( "match", matchRules ) )
|
||||
return returnVal, len( rules )
|
||||
return returnVal, 0
|
||||
except:
|
||||
print_exc()
|
||||
|
||||
def listNodes( self, targetDir, nodes ):
|
||||
dirs, files = xbmcvfs.listdir( targetDir )
|
||||
for dir in dirs:
|
||||
self.parseNode( os.path.join( targetDir, dir ), nodes )
|
||||
for file in files:
|
||||
self.parseItem( os.path.join( targetDir, file ), nodes )
|
||||
|
||||
def parseNode( self, node, nodes ):
|
||||
# If the folder we've been passed contains an index.xml, send that file to be processed
|
||||
if os.path.exists( os.path.join( node, "index.xml" ) ):
|
||||
# BETA2 ONLY CODE
|
||||
self.RULE.moveNodeRuleToAppdata( node, os.path.join( node, "index.xml" ) )
|
||||
# /BETA2 ONLY CODE
|
||||
self.parseItem( os.path.join( node, "index.xml" ), nodes, True, node )
|
||||
|
||||
def parseItem( self, file, nodes, isFolder = False, origFolder = None ):
|
||||
if not isFolder and file.endswith( "index.xml" ):
|
||||
return
|
||||
try:
|
||||
# Load the xml file
|
||||
tree = xmltree.parse( file )
|
||||
root = tree.getroot()
|
||||
# Get the item index
|
||||
if "order" in tree.getroot().attrib:
|
||||
index = tree.getroot().attrib.get( "order" )
|
||||
origIndex = index
|
||||
while int( index ) in nodes:
|
||||
index = int( index )
|
||||
index += 1
|
||||
index = str( index )
|
||||
else:
|
||||
self.indexCounter -= 1
|
||||
index = str( self.indexCounter )
|
||||
origIndex = "-"
|
||||
# Get label and icon
|
||||
label = root.find( "label" ).text
|
||||
icon = root.find( "icon" )
|
||||
if icon is not None:
|
||||
icon = icon.text
|
||||
else:
|
||||
icon = ""
|
||||
# Add it to our list of nodes
|
||||
if isFolder:
|
||||
nodes[ int( index ) ] = [ label, icon, quote( origFolder ), "folder", origIndex ]
|
||||
else:
|
||||
nodes[ int( index ) ] = [ label, icon, file, "item", origIndex ]
|
||||
except:
|
||||
print_exc()
|
||||
|
||||
def getViewElement( self, file, element, newvalue ):
|
||||
try:
|
||||
# Load the file
|
||||
tree = xmltree.parse( file )
|
||||
root = tree.getroot()
|
||||
# Change the element
|
||||
node = root.find( element )
|
||||
if node is not None:
|
||||
return node.text
|
||||
else:
|
||||
return ""
|
||||
except:
|
||||
print_exc()
|
||||
|
||||
def changeViewElement( self, file, element, newvalue ):
|
||||
try:
|
||||
# Load the file
|
||||
tree = xmltree.parse( file )
|
||||
root = tree.getroot()
|
||||
# If the element is content, we can only delete this if there are no
|
||||
# rules, limits, orders
|
||||
if element == "content":
|
||||
rule = root.find( "rule" )
|
||||
order = root.find( "order" )
|
||||
limit = root.find( "limit" )
|
||||
if rule is not None or order is not None or limit is not None:
|
||||
xbmcgui.Dialog().ok( ADDONNAME, LANGUAGE( 30404 ) )
|
||||
return
|
||||
# Find the element
|
||||
node = root.find( element )
|
||||
if node is not None:
|
||||
# If we've been passed an empty value, delete the node
|
||||
if newvalue == "":
|
||||
root.remove( node )
|
||||
else:
|
||||
node.text = newvalue
|
||||
else:
|
||||
# Add a new node
|
||||
if newvalue != "":
|
||||
xmltree.SubElement( root, element ).text = newvalue
|
||||
# Pretty print and save
|
||||
self.indent( root )
|
||||
tree.write( file, encoding="UTF-8" )
|
||||
except:
|
||||
print_exc()
|
||||
|
||||
def getRootAttrib( self, file, attrib ):
|
||||
try:
|
||||
# Load the file
|
||||
tree = xmltree.parse( file )
|
||||
root = tree.getroot()
|
||||
# Find the element
|
||||
if attrib in root.attrib:
|
||||
return root.attrib.get( attrib )
|
||||
else:
|
||||
return ""
|
||||
except:
|
||||
print_exc()
|
||||
|
||||
def changeRootAttrib( self, file, attrib, newvalue ):
|
||||
try:
|
||||
# Load the file
|
||||
tree = xmltree.parse( file )
|
||||
root = tree.getroot()
|
||||
# If empty newvalue, delete the attribute
|
||||
if newvalue == "":
|
||||
if attrib in root.attrib:
|
||||
root.attrib.pop( attrib )
|
||||
else:
|
||||
# Change or add the attribute
|
||||
root.set( attrib, newvalue )
|
||||
# Pretty print and save
|
||||
self.indent( root )
|
||||
tree.write( file, encoding="UTF-8" )
|
||||
except:
|
||||
print_exc()
|
||||
|
||||
def copyNode(self, dirs, files, target, origin):
|
||||
for file in files:
|
||||
success = xbmcvfs.copy( os.path.join( origin, file ), os.path.join( target, file ) )
|
||||
for dir in dirs:
|
||||
nextDirs, nextFiles = xbmcvfs.listdir( os.path.join( origin, dir ) )
|
||||
self.copyNode( nextDirs, nextFiles, os.path.join( target, dir ), os.path.join( origin, dir ) )
|
||||
|
||||
# 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
|
||||
|
||||
# Slugify functions
|
||||
def smart_truncate(string, max_length=0, word_boundaries=False, separator=' '):
|
||||
string = string.strip(separator)
|
||||
if not max_length:
|
||||
return string
|
||||
if len(string) < max_length:
|
||||
return string
|
||||
if not word_boundaries:
|
||||
return string[:max_length].strip(separator)
|
||||
if separator not in string:
|
||||
return string[:max_length]
|
||||
truncated = ''
|
||||
for word in string.split(separator):
|
||||
if word:
|
||||
next_len = len(truncated) + len(word) + len(separator)
|
||||
if next_len <= max_length:
|
||||
truncated += '{0}{1}'.format(word, separator)
|
||||
if not truncated:
|
||||
truncated = string[:max_length]
|
||||
return truncated.strip(separator)
|
||||
|
||||
def slugify(self, text, entities=True, decimal=True, hexadecimal=True, max_length=0, word_boundary=False, separator='-', convertInteger=False):
|
||||
# Handle integers
|
||||
if convertInteger and text.isdigit():
|
||||
text = "NUM-" + text
|
||||
# decode unicode ( ??? = Ying Shi Ma)
|
||||
text = unidecode(text)
|
||||
# character entity reference
|
||||
if entities:
|
||||
text = CHAR_ENTITY_REXP.sub(lambda m: unichr(name2codepoint[m.group(1)]), text)
|
||||
# decimal character reference
|
||||
if decimal:
|
||||
try:
|
||||
text = DECIMAL_REXP.sub(lambda m: unichr(int(m.group(1))), text)
|
||||
except:
|
||||
pass
|
||||
# hexadecimal character reference
|
||||
if hexadecimal:
|
||||
try:
|
||||
text = HEX_REXP.sub(lambda m: unichr(int(m.group(1), 16)), text)
|
||||
except:
|
||||
pass
|
||||
# translate
|
||||
text = unicodedata.normalize('NFKD', text)
|
||||
if sys.version_info < (3,):
|
||||
text = text.encode('ascii', 'ignore')
|
||||
# replace unwanted characters
|
||||
text = REPLACE1_REXP.sub('', text.lower()) # replace ' with nothing instead with -
|
||||
text = REPLACE2_REXP.sub('-', text.lower())
|
||||
# remove redundant -
|
||||
text = REMOVE_REXP.sub('-', text).strip('-')
|
||||
# smart truncate if requested
|
||||
if max_length > 0:
|
||||
text = smart_truncate(text, max_length, word_boundary, '-')
|
||||
if separator != '-':
|
||||
text = text.replace('-', separator)
|
||||
return text
|
||||
|
||||
def getVideoLibraryLType():
|
||||
json_query = xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "id": 0, "method": "Settings.GetSettingValue", "params": {"setting": "myvideos.flatten"}}')
|
||||
json_response = json.loads(json_query)
|
||||
|
||||
if json_response.get('result') and json_response['result'].get('value'):
|
||||
if json_response['result']['value']:
|
||||
return "video_flat"
|
||||
|
||||
return "video"
|
||||
|
||||
def run(args):
|
||||
log('script version %s started' % ADDONVERSION)
|
||||
ltype = ''
|
||||
if args[2] == '':
|
||||
videoltype = getVideoLibraryLType()
|
||||
xbmcplugin.addDirectoryItem( int( args[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s" %( videoltype ), xbmcgui.ListItem( label=LANGUAGE(30091) ), isFolder=True )
|
||||
xbmcplugin.addDirectoryItem( int( args[ 1 ] ), "plugin://plugin.library.node.editor?ltype=music", xbmcgui.ListItem( label=LANGUAGE(30092) ), isFolder=True )
|
||||
xbmcplugin.setContent(int(args[1]), 'files')
|
||||
xbmcplugin.endOfDirectory(handle=int(args[1]))
|
||||
else:
|
||||
params = dict( arg.split( "=" ) for arg in args[ 2 ][1:].split( "&" ) )
|
||||
ltype = params['ltype']
|
||||
if ltype != '':
|
||||
RULE = rules.RuleFunctions(ltype)
|
||||
ATTRIB = viewattrib.ViewAttribFunctions(ltype)
|
||||
PATHRULE = pathrules.PathRuleFunctions(ltype)
|
||||
PATHRULE.ATTRIB = ATTRIB
|
||||
ORDERBY = orderby.OrderByFunctions(ltype)
|
||||
Main(params, ltype, RULE, ATTRIB, PATHRULE, ORDERBY)
|
||||
|
||||
log('script stopped')
|
||||
Reference in New Issue
Block a user