def is_json_ok(self, json_file = None, data = None): """ Check if the json file is OK @param json_file : path to the json file @param data : json data """ try: if json_file != None: pkg_json = PackageJson(path = json_file) elif data != None: pkg_json = PackageJson(data = data) except: self.log.error(u"Error while reading the json file '{0}' : {1}".format(json_file, traceback.format_exc())) return False try: pkg_json.validate() except PackageException as e: self.log.error(u"Invalid json file. Reason : {0}".format(e.value)) return False self.json = pkg_json.get_json() if self.is_compliant_with_domogik() == False: return False return True
def __init__(self, type, name): """ Init a plugin @param type : package type @param name : package name """ self.type = type self.name = name self.json = None ### init logger log = logger.Logger('manager') self.log = log.get_logger('manager') self.valid = False self.log.debug(u"Package {0}-{1} : read the json file and validate it".format(self.type, self.name)) try: pkg_json = PackageJson(pkg_type = self.type, name = self.name) pkg_json.validate() self.json = pkg_json.get_json() self.valid = True self.log.debug(u"Package {0}-{1} : the json file is valid".format(self.type, self.name)) except PackageException as e: self.log.error(u"Package {0}-{1} : error while trying to read the json file".format(self.type, self.name)) self.log.error(u"Package {0}-{1} : invalid json file".format(self.type, self.name)) self.log.error(u"Package {0}-{1} : {2}".format(self.type, self.name, e.value))
def fill_data(self): """ Fill the client data by reading the json file """ try: self.log.info(u"Plugin {0} : read the json file".format(self.name)) pkg_json = PackageJson(pkg_type = "plugin", name = self.name) #we don't need to validate the json file as it has already be done in the check_avaiable_packages function self.data = pkg_json.get_json() self.add_configuration_values_to_data() except PackageException as e: self.log.error(u"Plugin {0} : error while trying to read the json file".format(self.name)) self.log.error(u"Plugin {0} : invalid json file".format(self.name)) self.log.error(u"Plugin {0} : {1}".format(self.name, e.value)) self.set_status(STATUS_INVALID) pass
def __init__(self, json_path): """ Init tool @param plugin_name : plugin name """ self._db = DbHelper() try: self.pkg = PackageJson(path = json_path).json except PackageException as exp: print("Error in json file:") print( exp.value ) exit() except: print(str(traceback.format_exc())) return print("Json file OK") # check type == plugin if self.pkg["identity"]["type"] not in ["plugin", "external"]: print("Error : this package type is not recognized") exit() # check if json version is at least 2 if self.pkg['json_version'] < 2: print("Error : this package is to old for this version of domogik") exit()
def __init__(self): """ Init """ parser = ArgumentParser() parser.add_argument("path", help="Path to the json file") self.options = parser.parse_args() if self.options.path != '': try: pkg = PackageJson(path=self.options.path) pkg.validate() print "JSON OK" except PackageException as e: print "JSON NOT OK" print e.value else: parser.print_help()
def is_json_ok(self, json_file=None, data=None): """ Check if the json file is OK @param json_file : path to the json file @param data : json data """ try: if json_file != None: pkg_json = PackageJson(path=json_file) elif data != None: pkg_json = PackageJson(data=data) except PackageException as e: self.log.error(u"Invalid json file. Reason : {0}".format(e.value)) return False except: self.log.error( u"Error while reading the json file '{0}' : {1}".format( json_file, traceback.format_exc())) return False try: pkg_json.validate() except PackageException as e: self.log.error(u"Invalid json file. Reason : {0}".format(e.value)) return False self.json = pkg_json.get_json() if self.is_compliant_with_domogik() == False: return False return True
def _load_json(self): """ Load the plugin json file """ try: self.log.info(u"Read the json file and validate id".format(self._name)) pkg_json = PackageJson(pkg_type = "plugin", name = self._name) # check if json is valid if pkg_json.validate() == False: # TODO : how to get the reason ? self.log.error(u"Invalid json file") self.force_leave(status = STATUS_INVALID) else: # if valid, store the data so that it can be used later self.log.info(u"The json file is valid") self.json_data = pkg_json.get_json() except: self.log.error(u"Error while trying to read the json file : {1}".format(self._name, traceback.format_exc())) self.force_leave(status = STATUS_INVALID)
def _load_json(self): """ Load the client json file """ try: self.log.info(u"Read the json file and validate id".format(self._name)) pkg_json = PackageJson(pkg_type = self._type, name = self._name) # check if json is valid if pkg_json.validate() == False: # TODO : how to get the reason ? self.log.error(u"Invalid json file") self.force_leave(status = STATUS_INVALID) else: # if valid, store the data so that it can be used later self.log.info(u"The json file is valid") self.json_data = pkg_json.get_json() except: self.log.error(u"Error while trying to read the json file : {1}".format(self._name, traceback.format_exc())) self.force_leave(status = STATUS_INVALID)
def get_installed_packages_list(self): """ List all packages in install folder and return a detailed list """ if PACKAGE_MODE != True: raise PackageException("Package mode not activated") pkg_list = [] for rep in [PLUGIN_JSON_PATH, EXTERNAL_JSON_PATH]: for root, dirs, files in os.walk(rep): for fic in files: if fic[-5:] == ".json": pkg_json = PackageJson(path="%s/%s" % (root, fic)).json # TODO : replace by identity and repo informations # from the json ??? pkg_list.append(pkg_json["identity"]) return sorted(pkg_list, key=lambda k: (k['fullname'], k['version']))
def url2xpl_stat_to_json(techno): # loda the json file pjson = PackageJson(techno) jsn = pjson.json jsn["xpl_commands"] = [] jsn["xpl_stats"] = [] cfg = Loader('domogik') config = cfg.load() conf = dict(config[1]) if not conf.has_key('package_path'): print "This script should only be launched in DEV mode, exiting" return if not conf.has_key('src_prefix'): print "src_prefix is not defined, exiting" return # find all *.xml files for fname in jsn["files"]: if fname.endswith('.xml'): print "handling file %s" % (fname) # parse the files xml_data = minidom.parse(conf['src_prefix'] + '/' + fname) if xml_data.getElementsByTagName("command") == []: # We have a stats file for schema in xml_data.getElementsByTagName("schema"): # values for value in schema.getElementsByTagName("value"): stat = {} stat["parameters"] = {} stat["parameters"]["static"] = [] stat["parameters"]["device"] = [] stat["parameters"]["dynamic"] = [] stat["schema"] = schema.attributes.get("name").value stat["reference"] = fname # device inside mapping = device stat["parameters"]["device"].append({ 'key': schema.getElementsByTagName("device") [0].attributes.get("field").value }) #<value field="current" new_name="gust" # filter_key="type" filter_value="gust" /> # filter_key + filter_value => static if value.attributes.get("filter_key") is not None and \ value.attributes.get("filter_value") is not None: item = {} item["key"] = \ value.attributes.get("filter_key").value item["value"] = \ value.attributes.get("filter_value").value stat["parameters"]["static"].append(item) # new_name => # field = dynamic item = {} item["key"] = value.attributes.get("field").value if value.attributes.get("new_name") is not None: item["new_name"] = value.attributes.get( "new_name").value stat["parameters"]["dynamic"].append(item) # each value field jsn["xpl_stats"].append(stat) else: cmd = {} cmd["parameters"] = {} cmd["parameters"]["static"] = [] cmd["parameters"]["device"] = [] cmd["parameters"]["dynamic"] = [] stat = {} stat["parameters"] = {} stat["parameters"]["static"] = [] stat["parameters"]["device"] = [] stat["parameters"]["dynamic"] = [] #=== Do the command part xml_command = xml_data.getElementsByTagName("command")[0] xml_parameters = xml_command.getElementsByTagName( "parameters")[0] # command name => reference cmd["reference"] = str( xml_data.getElementsByTagName("command")[0].attributes.get( "name").value) # schema => schema cmd["schema"] = str( xml_command.getElementsByTagName("schema") [0].firstChild.nodeValue) # not all files have a command if xml_command.getElementsByTagName("command-xpl-value") != []: static = {} #command-key => parameters static static["key"] = str( xml_command.getElementsByTagName("command-key") [0].firstChild.nodeValue) #command-xpl-value => parameter static value static["value"] = str( xml_command.getElementsByTagName("command-xpl-value") [0].firstChild.nodeValue) cmd["parameters"]["static"].append(static) # address-key => parameters device cmd["parameters"]["device"].append({'key': \ xml_command.getElementsByTagName("address-key")[0].firstChild.nodeValue}) # parameters => dynamic for param in xml_parameters.getElementsByTagName("parameter"): # loc = param.attributes.get("location") value = param.attributes.get("value") item = {} item["key"] = param.attributes.get("key").value if value is not None: item["value"] = value.value cmd["parameters"]["static"].append(item) else: cmd["parameters"]["dynamic"].append(item) #=== Do the stat part xml_listener = xml_data.getElementsByTagName("listener")[0] xml_filter = xml_listener.getElementsByTagName("filter")[0] # command name => reference stat["reference"] = xml_data.getElementsByTagName( "command")[0].attributes.get("name").value # schema => schema stat["schema"] = xml_listener.getElementsByTagName( "schema")[0].firstChild.nodeValue # keys for key in xml_filter.getElementsByTagName("key"): item = {} item["key"] = key.attributes.get("name").value value = key.attributes.get("value").value if value.startswith('@') and value.endswith('@'): stat["parameters"]["device"].append(item) else: item["value"] = value stat["parameters"]["static"].append(item) # link the stat with the cmd cmd["stat_reference"] = stat["reference"] # insert into json jsn["xpl_commands"].append(cmd) jsn["xpl_stats"].append(stat) # rewrite the json file print json.dumps(jsn, sort_keys=True, indent=4)
#!/usr/bin/python #-*- coding: utf-8 -*- ### configuration ########################################### plugin = "notify" ######################################################## from domogik.common.packagejson import PackageJson print(u"Package validation ...") p = PackageJson(name=plugin, pkg_type = "plugin") print(p.json) print(u"****************************************************") if p.validate() == False : print(u"*** Error json validation for plugin : {0}".format(plugin)) else : print(u"Json is validate for plugin : {0}".format(plugin))
#!/usr/bin/python #-*- coding: utf-8 -*- ### configuration ########################################### plugin = "ozwave" ######################################################## import json import sys import os from domogik.common.packagejson import PackageJson json_file = "/var/lib/domogik/domogik_packages/plugin_{0}/info.json".format(plugin) if os.path.exists(json_file) : json_file = os.path.realpath(json_file) data = json.load(open(json_file)) print data print "Package validation ..." p = PackageJson(path=json_file) if p.validate() == False : print "*** Error json validation :{0}".format(json_file) else : print "Json is validate :{0}".format(json_file) else : print "*** Error *** Don't find file :{0}".format(json_file)
def _create_package_for_external(self, id, output_dir, force): """ Create package for a external 1. read json file to get informations and list of files 2. generate package @param id : name of external @param output_dir : target directory for package @param force : False : ask for confirmation """ self.log("Hardware id : %s" % id) if PACKAGE_MODE == True: msg = "Domogik in 'production' mode (packages management activated) : creating a package is not possible" self.log(msg) return try: pkg_obj = PackageJson(id, pkg_type="external") pkg_json = pkg_obj.json except: self.log(str(traceback.format_exc())) return # check version format try: NormalizedVersion(pkg_json["identity"]["version"]) except: self.log("Plugin version '%s' is not valid. Exiting." % pkg_json["identity"]["version"]) return try: NormalizedVersion(pkg_json["identity"]["domogik_min_version"]) except: self.log("Domogik min version '%s' is not valid. Exiting." % pkg_json["identity"]["domogik_min_version"]) return self.log("Json file OK") if pkg_json["identity"]["type"] != "external": self.log("Error : this package is not an external member") return # display external informations pkg_obj.display() # check file existence if pkg_json["files"] == []: self.log("There is no file defined : the package won't be created") return # check doc files exist doc_path = DOC_PATH + "/external/%s/" % id doc_fullpath = SRC_PATH + doc_path if not os.path.isdir(doc_fullpath): self.log( "There is no documentation files in '%s' : the package won't be created" % doc_fullpath) return if force == False: self.log("\nAre these informations OK ?") resp = raw_input("[o/N]") if resp.lower() != "o": self.log("Exiting...") return # Copy Json file in a temporary location in order to complete it json_tmp_file = "%s/external-%s-%s.json" % (tempfile.gettempdir( ), pkg_json["identity"]["id"], pkg_json["identity"]["version"]) shutil.copyfile(pkg_json["identity"]["info_file"], json_tmp_file) # Update info.json with generation date pkg_obj.set_generated(json_tmp_file) # Create .tgz self._create_tar_gz( "external-%s-%s" % (pkg_json["identity"]["id"], pkg_json["identity"]["version"]), output_dir, pkg_json["all_files"], json_tmp_file, pkg_json["identity"]["icon_file"], doc_fullpath)
#!/usr/bin/python #-*- coding: utf-8 -*- ### configuration ########################################### plugin = "irtrans" ######################################################## import json import sys import os from domogik.common.packagejson import PackageJson json_file = "/var/lib/domogik/domogik_packages/plugin_{0}/info.json".format( plugin) if os.path.exists(json_file): json_file = os.path.realpath(json_file) data = json.load(open(json_file)) print data print "Package validation ..." p = PackageJson(path=json_file) if p.validate() == False: print "*** Error json validation :{0}".format(json_file) else: print "Json is validate :{0}".format(json_file) else: print "*** Error *** Don't find file :{0}".format(json_file)
def install_package(self, path, version=None, package_part=PKG_PART_XPL): """ Install a package 0. Eventually download package 1. Extract tar.gz 2. Install package 3. Insert data in database @param path : path for tar.gz @param version : version to install (default : highest) @param package_part : PKG_PART_XPL (for manager), PKG_PART_RINOR (for RINOR) """ if PACKAGE_MODE != True: raise PackageException("Package mode not activated") self.log("Start install for part '%s' of '%s'" % (package_part, path)) if path[0:6] == "cache:": path = "%s/package/download/%s" % (REST_URL, path[6:]) if path[0:5] == "repo:": pkg, status = self._find_package(path[5:], version) if status != True: return status path = pkg.archive_url # get package name if path[0:4] == "http": # special process for a http path id = full_name = '-'.join(path.split("/")[-3:]) print("id=%s" % full_name) else: full_name = os.path.basename(path) # twice to remove first .gz and then .tar id = os.path.splitext(full_name)[0] id = os.path.splitext(id)[0] self.log("Ask for installing package id : %s" % id) # get temp dir to extract data my_tmp_dir_dl = TMP_EXTRACT_DIR my_tmp_dir = "%s/%s" % (my_tmp_dir_dl, id) self._create_folder(my_tmp_dir) # Check if we need to download package if path[0:4] == "http": dl_path = "%s/%s.tgz" % (my_tmp_dir_dl, full_name) self.log("Downloading package : '%s' to '%s'" % (path, dl_path)) urllib.urlretrieve(path, dl_path) path = dl_path self.log("Package downloaded : %s" % path) # extract in tmp directory self.log("Extracting package...") try: self._extract_package(path, my_tmp_dir) except: msg = "Error while extracting package '%s' : %s" % ( path, traceback.format_exc()) self.log(msg) raise PackageException(msg) self.log("Package successfully extracted.") # get Json informations pkg_json = PackageJson(path="%s/info.json" % my_tmp_dir).json # check compatibility with domogik installed version __import__("domogik") dmg = sys.modules["domogik"] self.log("Domogik version = %s" % dmg.__version__) self.log("Minimum Domogik version required for package = %s" % pkg_json["identity"]["domogik_min_version"]) print("%s < %s" % (pkg_json["identity"]["domogik_min_version"], dmg.__version__)) if pkg_json["identity"]["domogik_min_version"] > dmg.__version__: msg = "This package needs a Domogik version >= %s. Actual is %s. Installation ABORTED!" % ( pkg_json["identity"]["domogik_min_version"], dmg.__version__) self.log(msg) raise PackageException(msg) # check the json_version file self.log("Required json version = %s" % MIN_JSON_VERSION) self.log("Package json version = %s" % pkg_json["json_version"]) if pkg_json["json_version"] < MIN_JSON_VERSION: msg = "This package has json_version set to %s, but Domogik needs at least %s" % ( pkg_json["json_version"], MIN_JSON_VERSION) self.log(msg) raise PackageException(msg) # create install directory self._create_folder(INSTALL_PATH) # install plugin in $HOME self.log("Installing package (%s)..." % pkg_json["identity"]["type"]) try: if pkg_json["identity"]["type"] in ('plugin', 'external'): self._install_plugin_or_external(my_tmp_dir, INSTALL_PATH, pkg_json["identity"]["type"], package_part) else: raise "Package type '%s' not installable" % pkg_json[ "identity"]["type"] except: msg = "Error while installing package : %s" % ( traceback.format_exc()) self.log(msg) raise PackageException(msg) self.log("Package successfully extracted.") # insert data in database if pkg_json["identity"]["type"] in ('plugin', 'external'): if package_part == PKG_PART_RINOR: self.log("Insert data in database...") pkg_data = PackageData("%s/info.json" % my_tmp_dir) pkg_data.insert() self.log("Package installation finished") return True
def _create_package_for_external(self, id, output_dir, force): """ Create package for a external 1. read json file to get informations and list of files 2. generate package @param id : name of external @param output_dir : target directory for package @param force : False : ask for confirmation """ self.log("Hardware id : %s" % id) if PACKAGE_MODE == True: msg = "Domogik in 'production' mode (packages management activated) : creating a package is not possible" self.log(msg) return try: pkg_obj = PackageJson(id, pkg_type="external") pkg_json = pkg_obj.json except: self.log(str(traceback.format_exc())) return # check version format try: NormalizedVersion(pkg_json["identity"]["version"]) except: self.log("Plugin version '%s' is not valid. Exiting." % pkg_json["identity"]["version"]) return try: NormalizedVersion(pkg_json["identity"]["domogik_min_version"]) except: self.log("Domogik min version '%s' is not valid. Exiting." % pkg_json["identity"]["domogik_min_version"]) return self.log("Json file OK") if pkg_json["identity"]["type"] != "external": self.log("Error : this package is not an external member") return # display external informations pkg_obj.display() # check file existence if pkg_json["files"] == []: self.log("There is no file defined : the package won't be created") return # check doc files exist doc_path = DOC_PATH + "/external/%s/" % id doc_fullpath = SRC_PATH + doc_path if not os.path.isdir(doc_fullpath): self.log("There is no documentation files in '%s' : the package won't be created" % doc_fullpath) return if force == False: self.log("\nAre these informations OK ?") resp = raw_input("[o/N]") if resp.lower() != "o": self.log("Exiting...") return # Copy Json file in a temporary location in order to complete it json_tmp_file = "%s/external-%s-%s.json" % ( tempfile.gettempdir(), pkg_json["identity"]["id"], pkg_json["identity"]["version"], ) shutil.copyfile(pkg_json["identity"]["info_file"], json_tmp_file) # Update info.json with generation date pkg_obj.set_generated(json_tmp_file) # Create .tgz self._create_tar_gz( "external-%s-%s" % (pkg_json["identity"]["id"], pkg_json["identity"]["version"]), output_dir, pkg_json["all_files"], json_tmp_file, pkg_json["identity"]["icon_file"], doc_fullpath, )