diff options
author | David Sommerseth <davids@redhat.com> | 2009-06-10 11:43:56 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2009-06-10 11:43:56 +0200 |
commit | b25b2ca548508cd2beb26f465b7bc5a296592461 (patch) | |
tree | 8c6db01b6ac2bd22baa6b6be1de6382244c471f9 /src | |
parent | b6d42c742d89dda95cc6e371f0fda6bf1d385a45 (diff) | |
download | python-dmidecode-b25b2ca548508cd2beb26f465b7bc5a296592461.tar.gz python-dmidecode-b25b2ca548508cd2beb26f465b7bc5a296592461.tar.xz python-dmidecode-b25b2ca548508cd2beb26f465b7bc5a296592461.zip |
Implemented native libxml2 XML API for dmidecode
To use this API, you need to import dmidecodeXML. This is a wrapper class for
the internal XML API which has been implemented. In addition, you might also
want to import libxml2 as well.
dmidecodeXML::QuerySection(<string>)
Valid section strings can be found in the pymap.xml file, in the <GroupMapping>
tag section.
dmidecodeXML::TypeId(<integer between 0-255>)
Valid values should match the DMI/SMBIOS specification.
dmidecodeXML::SetResultType(resultType)
Result type can be either dmidecodeXML.DMIXML_NODE or dmidecodeXML.DMIXML_DOC
----------------------------------------------------------
import libxml2
import dmidecodeXML
dmixml = dmidecodeXML.dmidecodeXML()
section_nodes = dmixml.QuerySection('processor')
dmixml.SetResultType(dmidecodeXML.DMIXML_DOC)
typeid_doc = dmixml.QueryTypeId(0x10)
dmixml.SetResultType(dmidecodeXML.DMIXML_NODE)
typeid_doc.saveFormatFileEnc("-", "UTF-8", 1)
----------------------------------------------------------
Diffstat (limited to 'src')
-rw-r--r-- | src/dmidecodeXML.py | 62 | ||||
-rw-r--r-- | src/dmidecodemodule.c | 130 | ||||
-rw-r--r-- | src/setup.py | 4 |
3 files changed, 180 insertions, 16 deletions
diff --git a/src/dmidecodeXML.py b/src/dmidecodeXML.py new file mode 100644 index 0000000..93b4598 --- /dev/null +++ b/src/dmidecodeXML.py @@ -0,0 +1,62 @@ +import libxml2 +import dmidecode + +DMIXML_NODE='n' +DMIXML_DOC='d' + +class dmidecodeXML: + "Native Python API for retrieving dmidecode information as XML" + + def __init__(self): + self.restype = DMIXML_NODE; + + def SetResultType(self, type): + """ + Sets the result type of queries. The value can be DMIXML_NODE or DMIXML_DOC, + which will return an libxml2::xmlNode or libxml2::xmlDoc object, respectively + """ + + if type == DMIXML_NODE: + self.restype = DMIXML_NODE + elif type == DMIXML_DOC: + self.restype = DMIXML_DOC + else: + raise TypeError, "Invalid result type value" + return True + + def QuerySection(self, sectname): + """ + Queries the DMI data structure for a given section name. A section + can often contain several DMI type elements + """ + if self.restype == DMIXML_NODE: + ret = libxml2.xmlNode( _obj = dmidecode.xmlapi(query_type='s', + result_type=self.restype, + section=sectname) ) + elif self.restype == DMIXML_DOC: + ret = libxml2.xmlDoc( _obj = dmidecode.xmlapi(query_type='s', + result_type=self.restype, + section=sectname) ) + else: + raise TypeError, "Invalid result type value" + + return ret + + + def QueryTypeId(self, tpid): + """ + Queries the DMI data structure for a specific DMI type. + """ + if self.restype == DMIXML_NODE: + ret = libxml2.xmlNode( _obj = dmidecode.xmlapi(query_type='t', + result_type=self.restype, + typeid=tpid)) + elif self.restype == DMIXML_DOC: + ret = libxml2.xmlDoc( _obj = dmidecode.xmlapi(query_type='t', + result_type=self.restype, + typeid=tpid)) + else: + raise TypeError, "Invalid result type value" + + return ret + diff --git a/src/dmidecodemodule.c b/src/dmidecodemodule.c index e359f10..846d565 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -42,6 +42,7 @@ #include <Python.h> #include <libxml/tree.h> +#include "libxml_wrap.h" #include "xmlpythonizer.h" #include "dmidecodemodule.h" @@ -245,18 +246,9 @@ xmlNode* load_mappingxml(options *opt) { return dmiMAP_GetRootElement(opt->mappingxml); } -static PyObject *dmidecode_get_group(options *opt, const char *section) -{ - PyObject *pydata = NULL; +xmlNode *__dmidecode_xml_getsection(options *opt, const char *section) { xmlNode *dmixml_n = NULL; xmlNode *group_n = NULL; - ptzMAP *mapping = NULL; - - /* Set default option values */ - if( opt->devmem == NULL ) { - opt->devmem = DEFAULT_MEM_DEV; - } - opt->flags = 0; dmixml_n = xmlNewNode(NULL, (xmlChar *) "dmidecode"); assert( dmixml_n != NULL ); @@ -319,6 +311,27 @@ static PyObject *dmidecode_get_group(options *opt, const char *section) xmlSaveFormatFileEnc("-", doc, "UTF-8", 1); xmlFreeDoc(doc); #endif + return dmixml_n; +} + +static PyObject *dmidecode_get_group(options *opt, const char *section) +{ + PyObject *pydata = NULL; + xmlNode *dmixml_n = NULL; + ptzMAP *mapping = NULL; + + /* Set default option values */ + if( opt->devmem == NULL ) { + opt->devmem = DEFAULT_MEM_DEV; + } + opt->flags = 0; + + // Decode the dmidata into an XML node + dmixml_n = __dmidecode_xml_getsection(opt, section); + if( dmixml_n == NULL ) { + // Exception already set + return NULL; + } // Convert the retrieved XML nodes to a Python dictionary mapping = dmiMAP_ParseMappingXML_GroupName(opt->mappingxml, section); @@ -339,11 +352,9 @@ static PyObject *dmidecode_get_group(options *opt, const char *section) } -static PyObject *dmidecode_get_typeid(options *opt, int typeid) +xmlNode *__dmidecode_xml_gettypeid(options *opt, int typeid) { - PyObject *pydata = NULL; xmlNode *dmixml_n = NULL; - ptzMAP *mapping = NULL; /* Set default option values */ if( opt->devmem == NULL ) { @@ -369,6 +380,22 @@ static PyObject *dmidecode_get_typeid(options *opt, int typeid) PyReturnError(PyExc_RuntimeError, "Error decoding DMI data"); } + return dmixml_n; +} + + +static PyObject *dmidecode_get_typeid(options *opt, int typeid) +{ + PyObject *pydata = NULL; + xmlNode *dmixml_n = NULL; + ptzMAP *mapping = NULL; + + dmixml_n = __dmidecode_xml_gettypeid(opt, typeid); + if( dmixml_n == NULL ) { + // Exception already set + return NULL; + } + // Convert the retrieved XML nodes to a Python dictionary mapping = dmiMAP_ParseMappingXML_TypeID(opt->mappingxml, opt->type); if( mapping == NULL ) { @@ -448,6 +475,77 @@ static PyObject *dmidecode_get_type(PyObject * self, PyObject * args) return pydata; } +static PyObject *dmidecode_xmlapi(PyObject *self, PyObject *args, PyObject *keywds) +{ + static char *keywordlist[] = {"query_type", "result_type", "section", "typeid"}; + PyObject *pydata = NULL; + xmlDoc *dmixml_doc = NULL; + xmlNode *dmixml_n = NULL; + char *sect_query = NULL, *qtype = NULL, *rtype = NULL; + int type_query = -1; + + // Parse the keywords - we only support keywords, as this is an internal API + if( !PyArg_ParseTupleAndKeywords(args, keywds, "ss|si", keywordlist, + &qtype, &rtype, §_query, &type_query) ) { + return NULL; + } + + // Check for sensible arguments and retrieve the xmlNode with DMI data + switch( *qtype ) { + case 's': // Section / GroupName + if( sect_query == NULL ) { + PyReturnError(PyExc_TypeError, "section keyword cannot be NULL") + } + dmixml_n = __dmidecode_xml_getsection(global_options, sect_query); + break; + + case 't': // TypeID / direct TypeMap + if( type_query < 0 ) { + PyReturnError(PyExc_TypeError, + "typeid keyword must be set and must be a positive integer"); + } else if( type_query > 255 ) { + PyReturnError(PyExc_ValueError, + "typeid keyword must be an integer between 0 and 255"); + } + dmixml_n = __dmidecode_xml_gettypeid(global_options, type_query); + break; + + default: + PyReturnError(PyExc_TypeError, "Internal error - invalid query type '%c'", *qtype); + } + + // Check if we got any data + if( dmixml_n == NULL ) { + // Exception already set + return NULL; + } + + // Check for sensible return type and wrap the correct type into a Python Object + switch( *rtype ) { + case 'n': + pydata = libxml_xmlNodePtrWrap((xmlNode *) dmixml_n); + break; + + case 'd': + dmixml_doc = xmlNewDoc((xmlChar *) "1.0"); + if( dmixml_doc == NULL ) { + PyReturnError(PyExc_MemoryError, "Could not create new XML document"); + } + xmlDocSetRootElement(dmixml_doc, dmixml_n); + pydata = libxml_xmlDocPtrWrap((xmlDoc *) dmixml_doc); + break; + + default: + PyReturnError(PyExc_TypeError, "Internal error - invalid result type '%c'", *rtype); + } + + // Return XML data + Py_INCREF(pydata); + return pydata; +} + + + static PyObject *dmidecode_dump(PyObject * self, PyObject * null) { const char *f; @@ -544,10 +642,14 @@ static PyMethodDef DMIDataMethods[] = { {(char *)"pythonmap", dmidecode_set_pythonxmlmap, METH_O, (char *) "Use another python dict map definition. The default file is " PYTHON_XML_MAP}, + {(char *)"xmlapi", dmidecode_xmlapi, METH_KEYWORDS, + (char *) "Internal API for retrieving data as raw XML data"}, + {NULL, NULL, 0, NULL} }; -void destruct_options(void *ptr) { +void destruct_options(void *ptr) +{ options *opt = (options *) ptr; if( opt->mappingxml != NULL ) { diff --git a/src/setup.py b/src/setup.py index b02bdf0..54b0357 100644 --- a/src/setup.py +++ b/src/setup.py @@ -22,8 +22,8 @@ setup( "src/xmlpythonizer.c" ], include_dirs = [ "/usr/include/libxml2" ], - library_dirs = [ "/home/nima/dev-room/projects/dmidecode" ], - libraries = [ "util", "xml2" ] + library_dirs = [ "/home/nima/dev-room/projects/dmidecode", "/usr/lib64/python2.5/site-packages"], + libraries = [ "util", "xml2", "xml2mod" ] ) ] ) |