#!/usr/bin/python

"""
ubuntu hwdb xml creator.

(c) 2004 Oliver Grawert (ogra) <hostmaster@grawert.net>

This software is distributed under the terms and conditions of the GNU General
Public License. See http://www.gnu.org/copyleft/gpl.html for details.
"""

import os
import sys
import string

class hwdata2xml:
	def __init__(self):

	 	if sys.argv.__contains__('-h') or len(sys.argv) == 1:
			print "\n\tusage: hwdb-xml [options]\n"
			print "hwdb-xml collects all hardware data needed for "
			print "the hwdb submission, converts it to xml and prints"
			print "to stdout\n"
			print "options:" 
			print " -a	collect all data"
			print " -d	collect device data"
			print " -x	collect xorg.conf and Xorg.0.log"
			print " -b	collect bootlog (dmesg)"
			print " -h	show this help\n"
			return

		if len(sys.argv) > 1:	
			for line in self.xml_header():
				print line
			if sys.argv.__contains__('-d') or sys.argv.__contains__('-a'):
			    for line in self.lshal_xml():
				print line
			if sys.argv.__contains__('-x') or sys.argv.__contains__('-a'):
	    		    for line in self.xorgconf():
	        		print line
	       		    for line in self.xorglog():
	        		print line
			if sys.argv.__contains__('-b') or sys.argv.__contains__('-a'):
			    for line in self.bootlog():
			        print line
		print "</hwinfo>"

	
	def xml_header(self):
	    doc = []

	    doc.append("<?xml version=\"1.0\" standalone=\"no\"?> <!--*- mode: xml -*-->")
	    doc.append("<!DOCTYPE hwinfo SYSTEM \"http://www.ubuntu.com/hwdb\">\n")
	    doc.append("<hwinfo>")

	    return doc

	def lshal_xml(self):
	    doc = []
	    devs = []
	    dev = None
	    devnum = 0

	    doc.append("<devicelist>")

	    proc = open("/proc/cpuinfo")
	    procinfo = proc.readlines()
	    doc.append(' <device id="processor">')
	    for line in procinfo:
		data = line.rstrip().split(":")
		if len(data) > 1:
		    doc.append('  <property class="linux" subclass="cpuinfo" name="'+data[0].rstrip()+'" type="string">'+data[1].lstrip()+'</property>')
	    doc.append(' </device>')

	    proc = open("/proc/meminfo")
	    procinfo = proc.readlines()
	    doc.append(' <device id="memory">')
	    for line in procinfo:
		data = line.rstrip().split(":")
		if len(data) > 1:
		    doc.append('  <property class="linux" subclass="meminfo" name="'+data[0].rstrip()+'" type="string">'+data[1].lstrip()+'</property>')
	    doc.append(' </device>')

	    for line in os.popen('/usr/bin/lshal'):
	        joinline = []
	        fields = string.splitfields(line, '=')
		
	        if len(fields) == 2:
	            if fields[0].strip() == "udi":
	        	devname = string.splitfields(line, '/')
			if devnum != 0:
				doc.append(" </device>\n")
			doc.append(" <device id=\""+devname[len(devname)-1].rstrip("'\n").lower()+"\">")
	    		devnum = devnum+1
		    else:
		        tab = string.maketrans(fields[1],fields[1])
			val = fields[1].translate(tab, '()\'')
			newval = string.splitfields(val)

			propvals = string.splitfields(fields[0].lstrip(), '.')

			classname = propvals[0].rstrip()
			subclass = propvals[1].rstrip()
			type = newval[len(newval)-1]
			newval[len(newval)-1] = ""

			if type == "int" or type == "uint64":
				newval[len(newval)-2] = ""
			name = ""
			if len(propvals) == 2:
				name = subclass.rstrip()
				subclass = ""
			else:
				name = propvals[2].strip()
			if subclass == "procfs":
				subclass = name
				name = propvals[3].strip()

			if not string.join(newval).strip().startswith('<'):
				joinline.append("  <property class=\""+classname+"\"")
				if subclass:
					joinline.append("subclass=\""+subclass+"\"")
				joinline.append("name=\""+name+"\" type=\""+type+"\">"+string.join(newval).strip()+"</property>")
				doc.append(string.join(joinline))
	    doc.append(" </device>\n")
	    doc.append("</devicelist>\n")
	    return doc
    	    
	def bootlog(self):
	    try: file = open("/var/log/dmesg", "r")
            except: return []
	    bootinfo = []
	    bootinfo.append("<bootinfo>")
	    for line in file:
	        newline = string.replace(line, '<', ' ')
	        newline = string.replace(newline, '\010', ' ')
	    	bootinfo.append(" <bootdata>"+newline.strip()+"</bootdata>")
	    bootinfo.append("</bootinfo>\n")
	    return bootinfo
	    
	def xorglog(self):
	    try: file = open("/var/log/Xorg.0.log", "r")
            except: return []
	    xinfo = []
	    xinfo.append("<xloginfo>")
	    for line in file:
	        newline = string.replace(line, '&', ' ')
		if len(newline) > 1:
	    		xinfo.append(" <xlogdata>"+newline.strip()+"</xlogdata>")
	    xinfo.append("</xloginfo>\n")
	    return xinfo

	def xorgconf(self):
	    file = open("/etc/X11/xorg.conf", "r")
	    xconf = []
	    xconf.append("<xconfinfo>")
	    for line in file:
	    	line = line.lstrip()
	    	if not line.startswith('#') and len(line) > 1:
			if line.startswith('Section'):
			    splitted = string.splitfields(line, ' ')
	    		    xconf.append(" <section name="+splitted[1].strip()+">")
			elif line.startswith("EndSection"):
			    xconf.append(" </section>\n") 
			elif line.startswith('SubSection'):
			    splitted = string.splitfields(line, ' ')
	    		    xconf.append("  <subsection name="+splitted[1].strip()+">")
			elif line.startswith("EndSubSection"):
			    xconf.append("  </subsection>\n") 
			else:
			    newline = string.replace(line, '<', ' ')
	        	    newline = string.replace(newline, '\t', ' ')
			    splitted = string.splitfields(newline, ' ')
			    name = splitted[0]
			    splitted[0] = ""
	    		    xconf.append("    <property name=\""+name.lower()+"\">"+string.join(splitted).strip()+"</property>")
	    xconf.append("</xconfinfo>\n")
	    return xconf


if __name__ == "__main__":
    self = hwdata2xml()
