def set_day_night_theme(self, dayornight, themename, themefile): ''' Sets a new daynight theme''' currenttimevalue = xbmc.getInfoLabel( "Skin.String(SkinHelper.ColorTheme.%s.time)" % dayornight) if not currenttimevalue: currenttimevalue = "20:00" if dayornight == "night" else "07:00" timevalue = xbmcgui.Dialog().input( self.addon.getLocalizedString(32017), currenttimevalue).decode("utf-8") try: # check if the time is valid check_date = datetime(*(time.strptime(timevalue, "%H:%M")[0:6])) del check_date base_setting = "SkinHelper.ColorTheme.%s" % dayornight xbmc.executebuiltin("Skin.SetString(%s.theme,%s)" % (base_setting, try_encode(themename))) xbmc.executebuiltin("Skin.SetString(%s.time,%s)" % (base_setting, timevalue)) label = "%s (%s %s)" % (try_encode(themename), self.addon.getLocalizedString(32019), timevalue) xbmc.executebuiltin("Skin.SetString(%s.label,%s)" % (base_setting, label)) xbmc.executebuiltin("Skin.SetString(%s.file,%s)" % (base_setting, try_encode(themefile))) except Exception as exc: log_exception(__name__, exc) xbmcgui.Dialog().ok(xbmc.getLocalizedString(329), self.addon.getLocalizedString(32018))
def get_skin_constants(): '''gets a list of all skin constants as set in the special xml file''' all_constants = {} all_variables = {} if sys.version_info.major == 3: addonpath = try_decode( xbmcvfs.translatePath( try_encode(os.path.join("special://skin/", 'addon.xml')))) else: addonpath = try_decode( xbmc.translatePath( try_encode(os.path.join("special://skin/", 'addon.xml')))) addon = xmltree.parse(addonpath) extensionpoints = addon.findall("extension") for extensionpoint in extensionpoints: if extensionpoint.attrib.get("point") == "xbmc.gui.skin": resolutions = extensionpoint.findall("res") for resolution in resolutions: if sys.version_info.major == 3: includes_file = try_decode( xbmcvfs.translatePath( try_encode( os.path.join( "special://skin/", try_decode( resolution.attrib.get("folder")), "script-skin_helper_service-includes.xml" )))) else: includes_file = try_decode( xbmc.translatePath( try_encode( os.path.join( "special://skin/", try_decode( resolution.attrib.get("folder")), "script-skin_helper_service-includes.xml" )))) if xbmcvfs.exists(includes_file): doc = parse(includes_file) listing = doc.documentElement.getElementsByTagName( 'constant') # constants for item in listing: name = try_decode( item.attributes['name'].nodeValue) value = try_decode(item.firstChild.nodeValue) all_constants[name] = value # variables listing = doc.documentElement.getElementsByTagName( 'variable') for item in listing: name = try_decode( item.attributes['name'].nodeValue) value_item = item.getElementsByTagName('value')[0] value = try_decode(value_item.firstChild.nodeValue) all_variables[name] = value return all_constants, all_variables
def restore_colortheme(self): '''restore zipbackup of colortheme to colorthemes folder''' zip_path = xbmcgui.Dialog().browse( 1, self.addon.getLocalizedString(32030), "files", ".zip") if zip_path and zip_path.endswith(".zip"): # create temp path temp_path = try_encode('special://temp/skinbackup/') temp_zip = try_encode("special://temp/colortheme.zip") if xbmcvfs.exists(temp_path): recursive_delete_dir(temp_path) xbmcvfs.mkdir(temp_path) # unzip to temp xbmcvfs.copy(zip_path, temp_zip) unzip_fromfile(temp_zip, temp_path) for filename in xbmcvfs.listdir(temp_path)[1]: filename = filename.decode("utf-8") sourcefile = os.path.join(temp_path, filename) destfile = os.path.join(self.userthemes_path, filename) xbmcvfs.copy(sourcefile, destfile) # cleanup temp xbmcvfs.delete(temp_zip) recursive_delete_dir(temp_path) xbmcgui.Dialog().ok(self.addon.getLocalizedString(32026), self.addon.getLocalizedString(32027))
def __init__(self): self.userthemes_path = try_encode("special://profile/addon_data/%s/themes/" % xbmc.getSkinDir()) if not xbmcvfs.exists(self.userthemes_path): xbmcvfs.mkdir(self.userthemes_path) self.skinthemes_path = try_encode("special://skin/extras/skinthemes/") if xbmcvfs.exists("special://home/addons/resource.skinthemes.%s/resources/" % get_skin_name()): self.skinthemes_path = try_encode("special://home/addons/resource.skinthemes.%s/resources/" % get_skin_name()) self.addon = xbmcaddon.Addon(ADDON_ID)
def restore(self, filename="", silent=False): '''restore skin settings from file''' if not filename: filename = self.get_restorefilename() #skip if filename is not a zip file if not filename.endswith("zip"): return progressdialog = None if not silent: progressdialog = xbmcgui.DialogProgress( self.addon.getLocalizedString(32006)) progressdialog.create(self.addon.getLocalizedString(32007)) if filename and xbmcvfs.exists(filename): # create temp path temp_path = self.create_temp() if not filename.endswith("zip"): # assume that passed filename is actually a skinsettings file skinsettingsfile = filename else: # copy zip to temp directory and unzip skinsettingsfile = temp_path + "guisettings.txt" if progressdialog: progressdialog.update(0, "unpacking backup...") zip_temp = try_encode( '%sskinbackup-%s.zip' % (ADDON_DATA, datetime.now().strftime('%Y-%m-%d-%H-%M'))) copy_file(filename, zip_temp, True) unzip_fromfile(zip_temp, temp_path) delete_file(zip_temp) # copy skinshortcuts preferences self.restore_skinshortcuts(temp_path) # restore any custom skin images or themes for directory in ["custom_images/", "themes/"]: custom_images_folder = try_encode( "special://profile/addon_data/%s/%s" % (xbmc.getSkinDir(), directory)) custom_images_folder_temp = temp_path + directory if xbmcvfs.exists(custom_images_folder_temp): for file in xbmcvfs.listdir( custom_images_folder_temp)[1]: xbmcvfs.copy(custom_images_folder_temp + file, custom_images_folder + file) # restore guisettings if xbmcvfs.exists(skinsettingsfile): self.restore_guisettings(skinsettingsfile, progressdialog) # cleanup temp recursive_delete_dir(temp_path) progressdialog.close() if not silent: xbmcgui.Dialog().ok(self.addon.getLocalizedString(32006), self.addon.getLocalizedString(32009))
def backup(self, filters=None, backup_file="", silent=False): '''create skin backup''' if not filters: filters = [] if not backup_file: return # create temp path temp_path = self.create_temp() zip_temp = try_encode( '%sskinbackup-%s.zip' % (temp_path, datetime.now().strftime('%Y-%m-%d %H.%M'))) temp_path = temp_path + "skinbackup/" # backup skinshortcuts preferences if not filters or (filters and "skinshortcuts" in filters): self.backup_skinshortcuts(temp_path + "skinshortcuts/") # backup skin settings if "skinshortcutsonly" not in filters: skinsettings_path = os.path.join(temp_path, try_encode("guisettings.txt")) self.backup_skinsettings(skinsettings_path, filters, temp_path) # zip the backup if sys.version_info.major == 3: zip_temp = try_decode(xbmcvfs.translatePath(zip_temp)) else: zip_temp = try_decode(xbmc.translatePath(zip_temp)) zip_tofile(temp_path, zip_temp) # copy file to destination - wait until it's really copied xbmc.log("Skin Helper Backup --> Saving Backup to %s" % backup_file, level=xbmc.LOGINFO) copy_file(zip_temp, backup_file, True) if not xbmcvfs.exists(backup_file): if not silent: raise IOError('Failed to copy ' + zip_temp + " to " + backup_file) # cleanup temp recursive_delete_dir(temp_path) xbmcvfs.delete(zip_temp) # clean old backups self.clean_oldbackups() self.create_temp() # show success message if not silent: xbmcgui.Dialog().ok(self.addon.getLocalizedString(32004), self.addon.getLocalizedString(32005))
def restore_skinshortcuts(temp_path): '''restore skinshortcuts files''' source_path = temp_path + try_encode("skinshortcuts/") if xbmcvfs.exists(source_path): dest_path = try_encode('special://profile/addon_data/script.skinshortcuts/') for filename in xbmcvfs.listdir(source_path)[1]: filename = try_decode(filename) sourcefile = source_path + filename destfile = dest_path + filename if filename == "SKINPROPERTIES.properties": destfile = dest_path + filename.replace("SKINPROPERTIES", xbmc.getSkinDir()) elif xbmc.getCondVisibility("SubString(Skin.String(skinshortcuts-sharedmenu),false)"): destfile = "%s-" % (xbmc.getSkinDir()) copy_file(sourcefile, destfile)
def reset(self, filters=None, silent=False): '''reset skin settings''' log_msg("filters: %s" % filters) if silent or (not silent and xbmcgui.Dialog().yesno( heading=self.addon.getLocalizedString(32010), message=self.addon.getLocalizedString(32011))): if filters: # only restore specific settings skinsettings = self.get_skinsettings(filters) for setting in skinsettings: xbmc.executebuiltin( try_encode("Skin.Reset(%s)" % setting[1])) else: # restore all skin settings xbmc.executebuiltin( "RunScript(script.skinshortcuts,type=resetall&warning=false)" ) xbmc.sleep(250) xbmc.executebuiltin("Skin.ResetSettings") xbmc.sleep(250) xbmc.executebuiltin("ReloadSkin") # fix default settings and labels xbmc.sleep(1500) xbmc.executebuiltin( "RunScript(script.skin.helper.service,action=checkskinsettings)" )
def backup_skinshortcuts(self, dest_path): '''backup skinshortcuts including images''' source_path = try_encode( 'special://profile/addon_data/script.skinshortcuts/') if not xbmcvfs.exists(dest_path): xbmcvfs.mkdir(dest_path) for file in xbmcvfs.listdir(source_path)[1]: file = file sourcefile = source_path + file destfile = dest_path + file if xbmc.getCondVisibility( "SubString(Skin.String(skinshortcuts-sharedmenu),false)"): # User is not sharing menu, so strip the skin name out of the destination file destfile = destfile.replace("%s." % (xbmc.getSkinDir()), "") if (file.endswith(".DATA.xml") and (not xbmc.getCondVisibility( "SubString(Skin.String(skinshortcuts-sharedmenu),false)") or file.startswith(xbmc.getSkinDir()))): xbmcvfs.copy(sourcefile, destfile) # parse shortcuts file and look for any images - if found copy them to addon folder self.backup_skinshortcuts_images(destfile, dest_path) elif file.endswith(".properties") and xbmc.getSkinDir() in file: if xbmc.getSkinDir() in file: destfile = dest_path + file.replace( xbmc.getSkinDir(), "SKINPROPERTIES") copy_file(sourcefile, destfile) self.backup_skinshortcuts_properties(destfile, dest_path) else: # just copy the remaining files copy_file(sourcefile, destfile)
def __init__(self, e): if isinstance(e, str): try: e = xml.fromstring(e) except Exception: LOGGER.exception("Skipping malformed line") return if isinstance(e, xml.Element): e = etree_to_dict(e) if isinstance(e, dict): e = DictObject.objectify(e) assert isinstance(e, DictObject) assert hasattr(e.item, "type") self.type = ascii_integers_to_string(e.item.type) self.code = ascii_integers_to_string(e.item.code) self.length = int(e.item.length) if "data" in e.item: assert self.length > 0 # length is zero if data is undefined. self.data = encoded_to_str(e.item.data["#text"], e.item.data["@encoding"], as_bytes=True) if e.item.data["@encoding"] == "base64": self._data_base64 = try_decode(e.item.data["#text"]) else: self._data_base64 = None else: assert self.length == 0 # length is zero if data is undefined. self.data = try_encode("") self._data_base64 = None
def save_skin_image(self, skinstring="", multi_image=False, header=""): '''let the user select an image and save it to addon_data for easy backup''' cur_value = try_decode(xbmc.getInfoLabel("Skin.String(%s)" % skinstring)) cur_value_org = try_decode(xbmc.getInfoLabel("Skin.String(%s.org)" % skinstring)) if not multi_image: # single image (allow copy to addon_data) value = try_decode(xbmcgui.Dialog().browse(2, header, 'files', '', True, True, cur_value_org)) if value: ext = value.split(".")[-1] newfile = ("special://profile/addon_data/%s/custom_images/%s.%s" % (xbmc.getSkinDir(), skinstring + time.strftime("%Y%m%d%H%M%S", time.gmtime()), ext)) if "special://profile/addon_data/%s/custom_images/" % xbmc.getSkinDir() in cur_value: xbmcvfs.delete(cur_value) xbmcvfs.copy(value, newfile) xbmc.executebuiltin("Skin.SetString(%s.org,%s)" % (try_encode(skinstring), try_encode(value))) value = newfile else: # multi image if not cur_value_org.startswith("$"): delim = "\\" if "\\" in cur_value_org else "/" curdir = cur_value_org.rsplit(delim, 1)[0] + delim else: curdir = "" value = try_decode(xbmcgui.Dialog().browse(0, self.addon.getLocalizedString(32005), 'files', '', True, True, curdir)) return value
def write_skin_constants(self, constants=None, variables=None): '''writes the list of all skin constants''' if sys.version_info.major == 3: addonpath = try_decode( xbmcvfs.translatePath( try_encode(os.path.join("special://skin/", 'addon.xml')))) else: addonpath = try_decode( xbmc.translatePath( try_encode(os.path.join("special://skin/", 'addon.xml')))) addon = xmltree.parse(addonpath) extensionpoints = addon.findall("extension") for extensionpoint in extensionpoints: if extensionpoint.attrib.get("point") == "xbmc.gui.skin": resolutions = extensionpoint.findall("res") for resolution in resolutions: includes_file = xbmcvfs.translatePath( os.path.join( "special://skin/", try_decode(resolution.attrib.get("folder")), "script-skin_helper_service-includes.xml").encode( "utf-8")) tree = xmltree.ElementTree(xmltree.Element("includes")) root = tree.getroot() if constants: for key, value in list(constants.items()): if value: child = xmltree.SubElement(root, "constant") child.text = value child.attrib["name"] = key # also write to skin strings xbmc.executebuiltin("Skin.SetString(%s,%s)" % (key, value)) if variables: for key, value in list(variables.items()): if value: child = xmltree.SubElement(root, "variable") child.attrib["name"] = key child2 = xmltree.SubElement(child, "value") child2.text = value self.indent_xml(tree.getroot()) xmlstring = xmltree.tostring(tree.getroot()) fileobj = xbmcvfs.File(includes_file, 'w') fileobj.write(xmlstring) fileobj.close() xbmc.executebuiltin("ReloadSkin()")
def base64(self): if self._base64: return self._base64 if self._binary: self._base64 = encodebytes(try_encode(self._binary)) return self._base64 else: return None
def get_backuppath(self): '''get the file location where backups should be stored''' backuppath = self.addon.getSetting("backup_path") if not backuppath: backuppath = xbmcgui.Dialog().browse( 3, self.addon.getLocalizedString(32002), 'files') self.addon.setSetting("backup_path", try_encode(backuppath)) return backuppath
def get_restorefilename(self): '''browse for backup file''' backuppath = self.addon.getSetting("backup_path") filename = try_decode(xbmcgui.Dialog().browse( 1, self.addon.getLocalizedString(32008), 'files', '.zip', False, False, try_encode(backuppath))) filename = filename.replace( "//", "") # possible fix for strange path issue on atv/ftv ? return filename
def create_temp(): '''create temp folder for skin backup/restore''' temp_path = try_encode('%stemp/' % ADDON_DATA) # workaround weird slashes behaviour on some platforms. temp_path = temp_path.replace("//","/").replace("special:/","special://") if xbmcvfs.exists(temp_path): recursive_delete_dir(temp_path) xbmc.sleep(2000) xbmcvfs.mkdirs(temp_path) xbmcvfs.mkdirs(temp_path + "skinbackup/") return temp_path
def backup_theme(self, themename): '''backup a colortheme to a zipfile''' import zipfile backup_path = xbmcgui.Dialog().browse( 3, self.addon.getLocalizedString(32029), "files").decode("utf-8") if backup_path: xbmc.executebuiltin("ActivateWindow(busydialog)") backup_name = try_encode("%s ColorTheme - %s" % (get_skin_name().capitalize(), themename)) backupfile = os.path.join(backup_path, backup_name + try_encode(".zip")) zip_temp = try_encode('special://temp/%s.zip' % backup_name) xbmcvfs.delete(zip_temp) xbmcvfs.delete(backupfile) if sys.version_info.major == 3: zip_temp = xbmcvfs.translatePath(zip_temp).decode("utf-8") zip_file = zipfile.ZipFile(zip_temp, "w", zipfile.ZIP_DEFLATED) abs_src = os.path.abspath( xbmcvfs.translatePath( self.userthemes_path).decode("utf-8")) else: zip_temp = xbmc.translatePath(zip_temp).decode("utf-8") zip_file = zipfile.ZipFile(zip_temp, "w", zipfile.ZIP_DEFLATED) abs_src = os.path.abspath( xbmc.translatePath(self.userthemes_path).decode("utf-8")) for filename in xbmcvfs.listdir(self.userthemes_path)[1]: if (filename.startswith("%s_" % themename) or filename.replace( ".theme", "").replace(".jpg", "") == themename): filename = filename.decode("utf-8") if sys.version_info.major == 3: filepath = xbmcvfs.translatePath( self.userthemes_path + filename).decode("utf-8") else: filepath = xbmc.translatePath(self.userthemes_path + filename).decode("utf-8") absname = os.path.abspath(filepath) arcname = absname[len(abs_src) + 1:] zip_file.write(absname, arcname) zip_file.close() xbmcvfs.copy(zip_temp, backupfile) xbmc.executebuiltin("Dialog.Close(busydialog)")
def correct_skin_settings(self): '''correct any special skin settings''' skinconstants = {} for settingid, settingvalues in list(self.skinsettings.items()): curvalue = try_decode(xbmc.getInfoLabel("Skin.String(%s)" % settingid)) curlabel = try_decode(xbmc.getInfoLabel("Skin.String(%s.label)" % settingid)) # first check if we have a sublevel if settingvalues and settingvalues[0]["value"].startswith("||SUBLEVEL||"): sublevel = settingvalues[0]["value"].replace("||SUBLEVEL||", "") settingvalues = self.skinsettings.get(sublevel) for settingvalue in settingvalues: value = settingvalue["value"] label = settingvalue["label"] if "%" in label: label = label % value # only correct the label if value already set if value and value == curvalue: xbmc.executebuiltin( "Skin.SetString(%s.label,%s)" % (try_encode(settingid), try_encode(label))) # set the default value if current value is empty if not (curvalue or curlabel): if settingvalue["default"] and getCondVisibility(settingvalue["default"]): xbmc.executebuiltin( "Skin.SetString(%s.label,%s)" % (try_encode(settingid), try_encode(label))) xbmc.executebuiltin( "Skin.SetString(%s,%s)" % (try_encode(settingid), try_encode(value))) # additional onselect actions for action in settingvalue["onselectactions"]: if action["condition"] and getCondVisibility(action["condition"]): command = action["command"] if "$" in command: command = xbmc.getInfoLabel(command) xbmc.executebuiltin(try_encode(command)) # process any multiselects for option in settingvalue["settingoptions"]: settingid = option["id"] if (not xbmc.getInfoLabel("Skin.String(defaultset_%s)" % settingid) and option["default"] and getCondVisibility(option["default"])): xbmc.executebuiltin("Skin.SetBool(%s)" % settingid) xbmc.executebuiltin("Skin.SetString(defaultset_%s,defaultset)" % settingid) # set the default constant value if current value is empty if (not curvalue and settingvalue["constantdefault"] and getCondVisibility(settingvalue["constantdefault"])): skinconstants[settingid] = value # update skin constants if needed only if skinconstants: self.update_skin_constants(skinconstants)
def do(self, command): """ Send a request to the api. :param action: :param data: :param query: :return: """ headers = {"Active-Remote": self.token, "Host": "starlight.local"} url = base_url.format(command=try_encode(command), host=self.host, port=self.port) r = requests.get(url, headers=headers, verify=False) # Allow unsigned certificates. return r
def backup_skinsettings(self, dest_file, filters, temp_path): '''backup the skinsettings (guisettings)''' # save guisettings skinfile = xbmcvfs.File(dest_file, "w") skinsettings = self.get_skinsettings(filters) skinfile.write(repr(skinsettings)) skinfile.close() # copy any custom skin images or themes for item in ["custom_images/", "themes/"]: custom_images_folder = try_encode("special://profile/addon_data/%s/%s" % (xbmc.getSkinDir(), item)) if xbmcvfs.exists(custom_images_folder): custom_images_folder_temp = os.path.join(temp_path, item) for file in xbmcvfs.listdir(custom_images_folder)[1]: source = os.path.join(custom_images_folder, file) dest = os.path.join(custom_images_folder_temp, file) copy_file(source, dest)
def playlists_widgets(): '''skin provided playlists''' widgets = [] import xml.etree.ElementTree as xmltree for playlist_path in [ "special://skin/playlists/", "special://skin/extras/widgetplaylists/", "special://skin/extras/playlists/" ]: if xbmcvfs.exists(playlist_path): log_msg("skinshortcuts widgets processing: %s" % playlist_path) media_array = kodi_json('Files.GetDirectory', { "directory": playlist_path, "media": "files" }) for item in media_array: if item["file"].endswith(".xsp"): playlist = item["file"] contents = xbmcvfs.File(item["file"], 'r') contents_data = try_decode(contents.read()) contents.close() xmldata = xmltree.fromstring(try_encode(contents_data)) media_type = "" label = item["label"] for line in xmldata.getiterator(): if line.tag == "smartplaylist": media_type = line.attrib['type'] if line.tag == "name": label = line.text try: languageid = int(label) label = xbmc.getLocalizedString(languageid) except Exception: pass if not media_type: mutils = MetadataUtils() media_type = mutils.detect_plugin_content(playlist) del mutils widgets.append([label, playlist, media_type]) return widgets
def set_skinshortcuts_property(property_name="", value="", label=""): '''set custom property in skinshortcuts menu editor''' if value or label: wait_for_skinshortcuts_window() xbmc.sleep(250) xbmc.executebuiltin("SetProperty(customProperty,%s)" % try_encode(property_name)) xbmc.executebuiltin("SetProperty(customValue,%s)" % try_encode(value)) xbmc.executebuiltin("SendClick(404)") xbmc.sleep(250) xbmc.executebuiltin("SetProperty(customProperty,%s.name)" % try_encode(property_name)) xbmc.executebuiltin("SetProperty(customValue,%s)" % try_encode(label)) xbmc.executebuiltin("SendClick(404)") xbmc.sleep(250) xbmc.executebuiltin("SetProperty(customProperty,%sName)" % try_encode(property_name)) xbmc.executebuiltin("SetProperty(customValue,%s)" % try_encode(label)) xbmc.executebuiltin("SendClick(404)")
def data_base64(self): if self._data_base64: return self._data_base64 else: return encodebytes(try_encode(self.data))
def create_colortheme(self): '''create a colortheme from current skin color settings''' try: current_skinfont = None json_response = kodi_json("Settings.GetSettingValue", {"setting": "lookandfeel.font"}) if json_response: current_skinfont = json_response current_skincolors = None json_response = kodi_json("Settings.GetSettingValue", {"setting": "lookandfeel.skincolors"}) if json_response: current_skincolors = json_response # user has to enter name for the theme themename = xbmcgui.Dialog().input( self.addon.getLocalizedString(32023), type=xbmcgui.INPUT_ALPHANUM).decode("utf-8") if not themename: return xbmc.executebuiltin("ActivateWindow(busydialog)") xbmc.executebuiltin( "Skin.SetString(SkinHelper.LastColorTheme,%s)" % try_encode(themename)) # add screenshot custom_thumbnail = xbmcgui.Dialog().browse( 2, self.addon.getLocalizedString(32024), 'files') if custom_thumbnail: xbmcvfs.copy(custom_thumbnail, self.userthemes_path + themename + ".jpg") # read the guisettings file to get all skin settings from resources.lib.backuprestore import BackupRestore skinsettingslist = BackupRestore().get_skinsettings([ "color", "opacity", "texture", "panel", "colour", "background", "image" ]) newlist = [] if skinsettingslist: newlist.append(("THEMENAME", themename)) newlist.append( ("DESCRIPTION", self.addon.getLocalizedString(32025))) newlist.append( ("SKINTHEME", xbmc.getInfoLabel("Skin.CurrentTheme"))) newlist.append(("SKINFONT", current_skinfont)) newlist.append(("SKINCOLORS", current_skincolors)) # look for any images in the skin settings and translate them so they can # be included in the theme backup for skinsetting in skinsettingslist: setting_type = skinsetting[0] setting_name = skinsetting[1] setting_value = skinsetting[2] if setting_type == "string" and setting_value: if (setting_value and (setting_value.endswith(".png") or setting_value.endswith(".gif") or setting_value.endswith(".jpg")) and "resource://" not in setting_value): image = get_clean_image(setting_value) extension = image.split(".")[-1] newimage = "%s_%s.%s" % ( themename, normalize_string(setting_name), extension) newimage_path = self.userthemes_path + newimage if xbmcvfs.exists(image): xbmcvfs.copy(image, newimage_path) skinsetting = (setting_type, setting_name, newimage_path) newlist.append(skinsetting) # save guisettings text_file_path = self.userthemes_path + themename + ".theme" text_file = xbmcvfs.File(text_file_path, "w") text_file.write(repr(newlist)) text_file.close() xbmc.executebuiltin("Dialog.Close(busydialog)") xbmcgui.Dialog().ok(self.addon.getLocalizedString(32026), self.addon.getLocalizedString(32027)) except Exception as exc: xbmc.executebuiltin("Dialog.Close(busydialog)") log_exception(__name__, exc) xbmcgui.Dialog().ok(self.addon.getLocalizedString(32028), self.addon.getLocalizedString(32030), str(exc))
def set_skin_setting(self, setting="", window_header="", sublevel="", cur_value_label="", skip_skin_string=False, original_id="", cur_value=""): '''allows the skinner to use a select dialog to set all kind of skin settings''' if not cur_value_label: cur_value_label = try_decode(xbmc.getInfoLabel("Skin.String(%s.label)" % setting)) if not cur_value: cur_value = try_decode(xbmc.getInfoLabel("Skin.String(%s)" % setting)) rich_layout = False listitems = [] if sublevel: listitem = xbmcgui.ListItem(label="..") listitem.setProperty("icon", "DefaultFolderBack.png") listitem.setProperty("value", "||BACK||") listitems.append(listitem) all_values = self.skinsettings.get(sublevel, []) elif original_id: all_values = self.skinsettings.get(original_id, []) else: all_values = self.skinsettings.get(setting, []) for item in all_values: if not item["condition"] or getCondVisibility(item["condition"]): value = item["value"] icon = item["icon"] if icon: rich_layout = True label = item["label"] if "%" in label: label = label % value if value == "||MULTISELECT||" or item["settingoptions"]: return self.multi_select(item["settingoptions"], window_header) listitem = xbmcgui.ListItem(label, label2=item["description"]) listitem.setArt({'icon': icon}) listitem.setProperty("value", value) listitem.setProperty("icon", icon) listitem.setProperty("description", item["description"]) listitem.setProperty("onselectactions", repr(item["onselectactions"])) listitems.append(listitem) # show select dialog dialog = DialogSelect("DialogSelect.xml", "", listing=listitems, windowtitle=window_header, richlayout=rich_layout, autofocuslabel=cur_value_label) dialog.doModal() selected_item = dialog.result del dialog # process the results if selected_item: value = try_decode(selected_item.getProperty("value")) label = try_decode(selected_item.getLabel()) if value.startswith("||SUBLEVEL||"): sublevel = value.replace("||SUBLEVEL||", "") self.set_skin_setting(setting, window_header, sublevel) elif value == "||BACK||": self.set_skin_setting(setting, window_header) else: if value == "||BROWSEIMAGE||": value = self.save_skin_image(setting, True, label) if value == "||BROWSESINGLEIMAGE||": value = self.save_skin_image(setting, False, label) if value == "||BROWSEMULTIIMAGE||": value = self.save_skin_image(setting, True, label) if value == "||PROMPTNUMERIC||": value = try_decode(xbmcgui.Dialog().input(label, cur_value, 1)) if value == "||PROMPTSTRING||": value = try_decode(xbmcgui.Dialog().input(label, cur_value, 0)) if value == "||PROMPTSTRINGASNUMERIC||": validinput = False while not validinput: try: value = try_decode(xbmcgui.Dialog().input(label, cur_value, 0)) valueint = int(value) validinput = True del valueint except Exception: value = xbmcgui.Dialog().notification("Invalid input", "Please enter a number...") # write skin strings if not skip_skin_string and value != "||SKIPSTRING||": xbmc.executebuiltin("Skin.SetString(%s,%s)" % (try_encode(setting), try_encode(value))) xbmc.executebuiltin("Skin.SetString(%s.label,%s)" % (try_encode(setting), try_encode(label))) # process additional actions onselectactions = selected_item.getProperty("onselectactions") if onselectactions: for action in eval(onselectactions): if not action["condition"] or getCondVisibility(action["condition"]): xbmc.executebuiltin(action["command"]) return (value, label) else: return (None, None)