From 5f7c8ffaee20db69df952e36127902af31d246bb Mon Sep 17 00:00:00 2001 From: Roee Date: Wed, 22 Jul 2015 22:29:09 +0300 Subject: [PATCH 1/5] Allow custom background path w/ unicode characters --- resources/lib/xmlfunctions.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/lib/xmlfunctions.py b/resources/lib/xmlfunctions.py index 32ea5849..7bdb19c8 100644 --- a/resources/lib/xmlfunctions.py +++ b/resources/lib/xmlfunctions.py @@ -709,7 +709,10 @@ def buildElement( self, item, Tree, groupName, visibilityCondition, profileVisib xbmc.executebuiltin( "Skin.SetString(skinshortcuts-widget-" + str( self.widgetCount ) + "," + property[ 1 ] + ")" ) self.widgetCount += 1 elif property[0] == "background": - xbmc.executebuiltin( "Skin.SetBool(skinshortcuts-background-" + property[1] + ")" ) + try: + xbmc.executebuiltin( "Skin.SetBool(skinshortcuts-background-" + property[1] + ")" ) + except UnicodeEncodeError: + xbmc.executebuiltin( "Skin.SetBool(skinshortcuts-background-" + property[1].encode('utf-8') + ")" ) # If this is the main menu, and we're cloning widgets or backgrounds... if groupName == "mainmenu": From 0d0160f55cd400ff39e8cb9d702e25848328eac2 Mon Sep 17 00:00:00 2001 From: Roee Date: Fri, 24 Jul 2015 00:24:35 +0300 Subject: [PATCH 2/5] Allow non-english path for custom thumbnail/icon --- resources/lib/gui.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/resources/lib/gui.py b/resources/lib/gui.py index 38355447..9799a206 100644 --- a/resources/lib/gui.py +++ b/resources/lib/gui.py @@ -473,6 +473,12 @@ def _save_shortcuts( self, weEnabledSystemDebug = False, weEnabledScriptDebug = # Inform user menu couldn't be saved xbmcgui.Dialog().ok( __addon__.getAddonInfo( "name" ), __language__( 32097 ), __language__( 32094 ) ) + def _try_decode(self, text, encoding="utf-8"): + try: + return text.decode(encoding) + except: + return text + def _save_shortcuts_function( self ): # Save shortcuts if self.changeMade == True: @@ -522,21 +528,18 @@ def _save_shortcuts_function( self ): # Icon and thumbnail if listitem.getProperty( "untranslatedIcon" ): - xmltree.SubElement( shortcut, "icon" ).text = listitem.getProperty( "untranslatedIcon" ) + icon = listitem.getProperty( "untranslatedIcon" ) else: if listitem.getProperty( "original-icon" ): - xmltree.SubElement( shortcut, "icon" ).text = listitem.getProperty( "original-icon" ) + icon = listitem.getProperty( "original-icon" ) else: - xmltree.SubElement( shortcut, "icon" ).text = listitem.getProperty( "icon" ) - - xmltree.SubElement( shortcut, "thumb" ).text = listitem.getProperty( "thumbnail" ) + icon = listitem.getProperty( "icon" ) + + xmltree.SubElement( shortcut, "icon" ).text = self._try_decode(icon) + xmltree.SubElement( shortcut, "thumb" ).text = self._try_decode(listitem.getProperty( "thumbnail" )) # Action - try: - action = listitem.getProperty( "path" ).decode( "utf-8" ) - except: - action = listitem.getProperty( "path" ) - xmltree.SubElement( shortcut, "action" ).text = action + xmltree.SubElement( shortcut, "action" ).text = self._try_decode(listitem.getProperty( "path" )) # Visible if listitem.getProperty( "visible-condition" ): From 0050611fe9503107ee6e7ef634f7e95005f150d3 Mon Sep 17 00:00:00 2001 From: Roee Date: Tue, 28 Jul 2015 15:46:23 +0300 Subject: [PATCH 3/5] Another unicode warning fix --- resources/lib/gui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/gui.py b/resources/lib/gui.py index 9799a206..5a7bf93f 100644 --- a/resources/lib/gui.py +++ b/resources/lib/gui.py @@ -985,7 +985,7 @@ def onClick(self, controlID): oldlabelID = listitem.getProperty( "labelID" ) # If the item is blank, set the current label to empty - if label == __language__(32013): + if label.decode('utf-8') == __language__(32013): label = "" # Get new label from keyboard dialog From 2de3a8b658f1db3912d907c73e649a65f42c0d8a Mon Sep 17 00:00:00 2001 From: Roee Date: Tue, 28 Jul 2015 15:47:22 +0300 Subject: [PATCH 4/5] Removed redundant unicode decoding attempt --- resources/lib/xmlfunctions.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/resources/lib/xmlfunctions.py b/resources/lib/xmlfunctions.py index 7bdb19c8..fcbfe4ac 100644 --- a/resources/lib/xmlfunctions.py +++ b/resources/lib/xmlfunctions.py @@ -696,10 +696,7 @@ def buildElement( self, item, Tree, groupName, visibilityCondition, profileVisib else: additionalproperty = xmltree.SubElement( newelement, "property" ) additionalproperty.set( "name", property[0].decode( "utf-8" ) ) - try: - additionalproperty.text = DATA.local( property[1].decode( "utf-8" ) )[1] - except: - additionalproperty.text = DATA.local( property[1] )[1] + additionalproperty.text = DATA.local( property[1] )[1] # If this is a widget or background, set a skin setting to say it's enabled if property[0] == "widget": From eae500f6f849303ee9d56db1782c87f863911f16 Mon Sep 17 00:00:00 2001 From: Roee Date: Tue, 28 Jul 2015 19:38:37 +0300 Subject: [PATCH 5/5] Moved try_decode to external module Moved try_decode to external module. Use it across script code. --- resources/lib/datafunctions.py | 28 +++++------------- resources/lib/gui.py | 53 ++++++++++------------------------ resources/lib/unicodeutils.py | 10 +++++++ resources/lib/xmlfunctions.py | 21 ++++---------- 4 files changed, 37 insertions(+), 75 deletions(-) create mode 100644 resources/lib/unicodeutils.py diff --git a/resources/lib/datafunctions.py b/resources/lib/datafunctions.py index feabf88f..d51fba97 100644 --- a/resources/lib/datafunctions.py +++ b/resources/lib/datafunctions.py @@ -8,6 +8,7 @@ from traceback import print_exc from htmlentitydefs import name2codepoint from unidecode import unidecode +from unicodeutils import try_decode import nodefunctions NODE = nodefunctions.NodeFunctions() @@ -137,10 +138,7 @@ def _get_shortcuts( self, group, defaultGroup = None, isXML = False, profileDir paths = [userShortcuts, skinShortcuts, defaultShortcuts ] for path in paths: - try: - path = path.decode( "utf-8" ) - except: - pass + path = try_decode( path ) tree = None altPath = path.replace( ".DATA.xml", ".shortcuts" ) @@ -809,10 +807,7 @@ def local( self, data ): if data is None: return ["","","",""] - try: - data = data.decode( "utf-8" ) - except: - pass + data = try_decode( data ) skinid = None lasttranslation = None @@ -1107,10 +1102,8 @@ def upgrade_xmlfile( self, path, mixedVersion = False, saveFile = True ): actionTree = xmltree.SubElement( root, "shortcut" ) # Action - try: - action = urllib.unquote( shortcut[4] ).decode( "utf-8" ) - except: - action = urllib.unquote( shortcut[4] ) + action = try_decode( urllib.unquote( shortcut[4] ) ) + xmltree.SubElement( actionTree, "action" ).text = action # Label and label2, defaultID @@ -1119,15 +1112,8 @@ def upgrade_xmlfile( self, path, mixedVersion = False, saveFile = True ): xmltree.SubElement( actionTree, "defaultID" ).text = DataFunctions()._get_labelID( DataFunctions().local( shortcut[0] )[3], action, True ) # Icon and thumbnail - try: - xmltree.SubElement( actionTree, "icon" ).text = shortcut[2].decode( "utf-8" ) - except: - xmltree.SubElement( actionTree, "icon" ).text = shortcut[2] - - try: - xmltree.SubElement( actionTree, "thumb" ).text = shortcut[3].decode( "utf-8" ) - except: - xmltree.SubElement( actionTree, "thumb" ).text = shortcut[3] + xmltree.SubElement( actionTree, "icon" ).text = try_decode( shortcut[2] ) + xmltree.SubElement( actionTree, "thumb" ).text = try_decode( shortcut[3] ) # mixedVersion will be True if we're upgrading a skin's defaults if mixedVersion == True: diff --git a/resources/lib/gui.py b/resources/lib/gui.py index 5a7bf93f..7a145268 100644 --- a/resources/lib/gui.py +++ b/resources/lib/gui.py @@ -6,7 +6,7 @@ from xml.sax.saxutils import escape as escapeXML import thread from traceback import print_exc -from unidecode import unidecode +from unicodeutils import try_decode import random import datafunctions @@ -472,12 +472,6 @@ def _save_shortcuts( self, weEnabledSystemDebug = False, weEnabledScriptDebug = else: # Inform user menu couldn't be saved xbmcgui.Dialog().ok( __addon__.getAddonInfo( "name" ), __language__( 32097 ), __language__( 32094 ) ) - - def _try_decode(self, text, encoding="utf-8"): - try: - return text.decode(encoding) - except: - return text def _save_shortcuts_function( self ): # Save shortcuts @@ -498,15 +492,13 @@ def _save_shortcuts_function( self ): for listitem in self.allListItems: # If the item has a label... - if listitem.getLabel().decode('utf-8') != __language__(32013): + if try_decode( listitem.getLabel() ) != __language__(32013): # Generate labelID, and mark if it has changed labelID = listitem.getProperty( "labelID" ) newlabelID = labelID + # defaultID - try: - defaultID = listitem.getProperty( "defaultID" ).decode( "utf-8" ) - except: - defaultID = listitem.getProperty( "defaultID" ) + defaultID = try_decode( listitem.getProperty( "defaultID" ) ) localizedString = listitem.getProperty( "localizedString" ) if localizedString is None or localizedString == "": @@ -535,11 +527,11 @@ def _save_shortcuts_function( self ): else: icon = listitem.getProperty( "icon" ) - xmltree.SubElement( shortcut, "icon" ).text = self._try_decode(icon) - xmltree.SubElement( shortcut, "thumb" ).text = self._try_decode(listitem.getProperty( "thumbnail" )) + xmltree.SubElement( shortcut, "icon" ).text = try_decode( icon ) + xmltree.SubElement( shortcut, "thumb" ).text = try_decode( listitem.getProperty( "thumbnail" ) ) # Action - xmltree.SubElement( shortcut, "action" ).text = self._try_decode(listitem.getProperty( "path" )) + xmltree.SubElement( shortcut, "action" ).text = try_decode( listitem.getProperty( "path" ) ) # Visible if listitem.getProperty( "visible-condition" ): @@ -556,11 +548,7 @@ def _save_shortcuts_function( self ): # Save the shortcuts DATA.indent( root ) path = os.path.join( __datapath__ , DATA.slugify( self.group ) + ".DATA.xml" ) - - try: - path = path.decode( "utf-8" ) - except: - pass + path = try_decode( path ) tree.write( path.replace( ".shortcuts", ".DATA.xml" ), encoding="UTF-8" ) @@ -597,20 +585,11 @@ def _save_shortcuts_function( self ): paths = [[os.path.join( __datapath__, DATA.slugify( labelIDFrom ) + "." + str( i ) + ".DATA,xml" ).encode( "utf-8" ), "Move"], [os.path.join( __skinpath__, DATA.slugify( defaultIDFrom ) + "." + str( i ) + ".DATA.xml" ).encode( "utf-8" ), "Copy"], [os.path.join( __defaultpath__, DATA.slugify( defaultIDFrom ) + "." + str( i ) + ".DATA.xml" ).encode( "utf-8" ), "Copy"]] target = os.path.join( __datapath__, DATA.slugify( labelIDTo ) + "." + str( i ) + ".DATA.xml" ).encode( "utf-8" ) - try: - target = target.decode( "utf-8" ) - except: - pass + target = try_decode( target ) for path in paths: - try: - path[ 0 ] = path[ 0 ].decode( "utf-8" ) - except: - pass - try: - path[ 1 ] = path[ 1 ].decode( "utf-8" ) - except: - pass + path[0] = try_decode( path[0] ) + path[1] = try_decode( path[1] ) if path[1] == "New": tree = xmltree.ElementTree( xmltree.Element( "shortcuts" ) ) @@ -985,7 +964,7 @@ def onClick(self, controlID): oldlabelID = listitem.getProperty( "labelID" ) # If the item is blank, set the current label to empty - if label.decode('utf-8') == __language__(32013): + if try_decode( label ) == __language__(32013): label = "" # Get new label from keyboard dialog @@ -1036,15 +1015,13 @@ def onClick(self, controlID): keyboard.doModal() if ( keyboard.isConfirmed() ): - try: - action = keyboard.getText().decode( "utf-8" ) - except: - action = keyboard.getText() + action = try_decode( keyboard.getText() ) + if action == "": action = "noop" # Check that a change was really made - if action == listitem.getProperty( "path" ): + if action == try_decode( listitem.getProperty( "path" ) ): return else: return diff --git a/resources/lib/unicodeutils.py b/resources/lib/unicodeutils.py new file mode 100644 index 00000000..51876a9d --- /dev/null +++ b/resources/lib/unicodeutils.py @@ -0,0 +1,10 @@ +# coding=utf-8 + + +def try_decode(text, encoding="utf-8"): + if isinstance(text, str): + try: + return text.decode(encoding) + except: + pass + return text diff --git a/resources/lib/xmlfunctions.py b/resources/lib/xmlfunctions.py index fcbfe4ac..f66c6341 100644 --- a/resources/lib/xmlfunctions.py +++ b/resources/lib/xmlfunctions.py @@ -4,6 +4,7 @@ import xml.etree.ElementTree as xmltree from xml.sax.saxutils import escape as escapeXML from traceback import print_exc +from unicodeutils import try_decode if sys.version_info < (2, 7): import simplejson @@ -673,10 +674,7 @@ def buildElement( self, item, Tree, groupName, visibilityCondition, profileVisib # Group name group = xmltree.SubElement( newelement, "property" ) group.set( "name", "group" ) - try: - group.text = groupName.decode( "utf-8" ) - except: - group.text = groupName + group.text = try_decode( groupName ) if groupName == "mainmenu": self.MAINWIDGET = {} @@ -689,10 +687,7 @@ def buildElement( self, item, Tree, groupName, visibilityCondition, profileVisib for property in properties: if property[0] == "node.visible": visibleProperty = xmltree.SubElement( newelement, "visible" ) - try: - visibleProperty.text = property[1].decode( "utf-8" ) - except: - visibleProperty.text = property[1] + visibleProperty.text = try_decode( property[1] ) else: additionalproperty = xmltree.SubElement( newelement, "property" ) additionalproperty.set( "name", property[0].decode( "utf-8" ) ) @@ -726,18 +721,12 @@ def buildElement( self, item, Tree, groupName, visibilityCondition, profileVisib for key in self.MAINWIDGET: additionalproperty = xmltree.SubElement( newelement, "property" ) additionalproperty.set( "name", key ) - try: - additionalproperty.text = self.MAINWIDGET[ key ].decode( "utf-8" ) - except: - additionalproperty.text = self.MAINWIDGET[ key ] + additionalproperty.text = try_decode( self.MAINWIDGET[ key ] ) if "clonebackgrounds" in options and len( self.MAINBACKGROUND ) is not 0: for key in self.MAINBACKGROUND: additionalproperty = xmltree.SubElement( newelement, "property" ) additionalproperty.set( "name", key ) - try: - additionalproperty.text = DATA.local( self.MAINBACKGROUND[ key ].decode( "utf-8" ) )[1] - except: - additionalproperty.text = DATA.local( self.MAINBACKGROUND[ key ] )[1] + additionalproperty.text = DATA.local( self.MAINBACKGROUND[ key ] )[1] propertyPatterns = self.getPropertyPatterns(labelID.text, groupName) if len(propertyPatterns) > 0: