# -*- coding: utf-8 -*- # h-client, a client for an h-source server (such as http://www.h-node.com) # Copyright (C) 2011 Antonio Gallo # # # h-client is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # h-client is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with h-client. If not, see . import os import string import re import sys import pycurl import urllib import htmlentitydefs from xml.dom import minidom from odict import * class Device(object): #from codename to h-source distro code _distrosTable = { 'deltah' : 'gnewsense_2_3', 'metad' : 'gnewsense_3_0', 'awen' : 'trisquel_3_5', 'taranis' : 'trisquel_4_0', 'slaine' : 'trisquel_4_5' } #list of options for the howItWorks entry _howItWorksOptions = ['yes','no'] #list of subtypes _subtypes = [] #allowed years of commercialization _years = [ 'not-specified', '2011', '2010', '2009', '2008', '2007', '2006', '2005', '2004', '2003', '2002', '2001', '2000', '1999', '1998', '1997', '1996', '1995', '1994', '1993', '1992' ] #list of interfaces _interfaces = [] _status = True errors = [] def __init__(self): self._post = {} self._type = '' self._vendor = '' self._model = '' self._otherNames = '' self._kernel = '' self._distributions = [self.userDistribution()] self._interface = 'not-specified' self._year = 'not-specified' self._vendorId = '' self._productId = '' self._howItWorks = '' self._driver = '' self._description = '' self._subtype = 'not-specified' self._icon = 'unknown.png' def setPost(self): self._post['model'] = self._model self._post['other_names'] = self._otherNames.replace("\n","\r\n") self._post['kernel'] = self._kernel self._post['distribution'] = self.createDistroEntry() self._post['comm_year'] = self._year self._post['pci_id'] = self._vendorId + ':' + self._productId self._post['interface'] = self._interface self._post['description'] = self._description.replace("\n","\r\n") self._post['driver'] = self._driver #replace the HTML entitites with utf-8 characters def htmlentitiesDecode(self,string): for entity,code in htmlentitydefs.name2codepoint.iteritems(): string = string.replace("&"+entity+";",unichr(code)) string = string.replace("'","'") return string.encode('utf-8') #get the h-source distro code from the codename def getDistroCode(self,codenameString): codenames = self._distrosTable.keys() for codename in codenames: if codenameString.find(codename) != -1: return self._distrosTable[codename] return '' #create the distribution entry def createDistroEntry(self): cleanDistros = [] for distro in self._distributions: cleanDistros.append(distro.lstrip().rstrip()) #remove duplicates cleanDistros = list(set(cleanDistros)) #sort the elements cleanDistros = sorted(cleanDistros) dis = ' , '.join(cleanDistros) #correct a strange python behaviour if dis != '': if dis[0] == ' , ': dis = dis[3:] return dis #add a distribution def addDistribution(self,distroName): self._distributions.append(distroName) #add many distributions #distroList: comma separated list of distros (type: string) def addDistributions(self,distroList): distros = distroList.split(',') for distro in distros: self.addDistribution(distro) #get the h-source distro code of the user def userDistribution(self): if not os.system('cat /etc/*-release | grep CODENAME > tmp/distro'): f = open('tmp/distro','r') row = f.readline().rstrip("\n").lower() f.close(); os.system('rm -f tmp/distro') return self.getDistroCode(row) else: self._status = False self.errors.append('tmp folder not writable') def getSubtype(self): return self._subtype def getSubtypes(self): return self._subtypes def getHowItWorksOptions(self): return self._howItWorksOptions def getInterfaces(self): return self._interfaces def getYears(self): return self._years def getType(self): return self._type def getVendor(self): return self._vendor def getModel(self): return self._model def getOtherNames(self): return self._otherNames def getKernel(self): return self._kernel def getDistributions(self): return self._distributions def getInterface(self): return self._interface def getYear(self): return self._year def getVendorId(self): return self._vendorId def getProductId(self): return self._productId def getHowItWorks(self): return self._howItWorks def getDriver(self): return self._driver def getDescription(self): return self._description def getIcon(self): return self._icon def setType(self,ttype): self._type = ttype def setVendor(self,vendor): self._vendor = vendor def setModel(self,model): self._model = model def setOtherNames(self,otherNames): self._otherNames = otherNames def setKernel(self,kernel): self._kernel = kernel def setDistributions(self,distributions): self._distributions = distributions def setInterface(self,interface): self._interface = interface def setYear(self,year): self._year = year def setVendorId(self,vendorId): self._vendorId = vendorId def setProductId(self,productId): self._productId = productId def setHowItWorks(self,howItWorks): self._howItWorks = howItWorks def setDriver(self,driver): self._driver = driver def setDescription(self,description): self._description = description def setSubtype(self,subtype): self._subtype = subtype def setIcon(self,icon): self._icon = icon def getStatus(self): return self._status def getPost(self): return self._post class Videocard(Device): def __init__(self): super(Videocard, self).__init__() self._type = 'videocard' self._howItWorks = 'does_not_work' self._interfaces = ['not-specified','PCI','AGP','PCI-E','ISA','MCA','VLB'] self._howItWorksOptions = ['works_with_3D','works_without_3D','does_not_work'] self._icon = 'videocard.png' def setPost(self): super(Videocard, self).setPost() self._post['video_card_works'] = self._howItWorks class Wifi(Device): def __init__(self): super(Wifi, self).__init__() self._type = 'wifi' self._howItWorks = 'no' self._interfaces = ['not-specified','USB','PCI','PCI-E','mini-PCI','mini-PCI-E','ExpressCard','PC-Card'] self._icon = 'wifi.png' def setPost(self): super(Wifi, self).setPost() self._post['wifi_works'] = self._howItWorks class Soundcard(Device): def __init__(self): super(Soundcard, self).__init__() self._type = 'soundcard' self._howItWorks = 'no' self._interfaces = ['not-specified','PCI','ISA','USB','Firewire','Parallel','PCI-E','PCMCIA'] self._icon = 'soundcard.png' def setPost(self): super(Soundcard, self).setPost() self._post['sound_card_works'] = self._howItWorks class Printer(Device): def __init__(self): super(Printer, self).__init__() self._type = 'printer' self._howItWorks = 'C-None' self._interfaces = ['not-specified','USB','Serial','Parallel','Firewire','SCSI','Ethernet'] self._howItWorksOptions = ['A-Full','B-Partial','C-None'] self._subtypes = ['not-specified','laser','inkjet','other'] self._icon = 'printer.png' def setPost(self): super(Printer, self).setPost() self._post['compatibility'] = self._howItWorks self._post['subtype'] = self._subtype class Scanner(Device): def __init__(self): super(Scanner, self).__init__() self._type = 'scanner' self._howItWorks = 'C-None' self._interfaces = ['not-specified','USB','Serial','Parallel','Firewire','SCSI','Ethernet'] self._howItWorksOptions = ['A-Full','B-Partial','C-None'] self._icon = 'scanner.png' def setPost(self): super(Scanner, self).setPost() self._post['compatibility'] = self._howItWorks class Threegcard(Device): def __init__(self): super(Threegcard, self).__init__() self._type = '3G-card' self._howItWorks = 'no' self._interfaces = ['not-specified','USB','PCI','PCI-E','mini-PCI','mini-PCI-E','ExpressCard','PC-Card'] self._icon = '3G-card.png' def setPost(self): super(Threegcard, self).setPost() self._post['wifi_works'] = self._howItWorks class Webcam(Device): def __init__(self): super(Webcam, self).__init__() self._type = 'webcam' self._howItWorks = 'no' self._interfaces = ['not-specified','USB','Firewire','Parallel','Wifi','Serial'] self._icon = 'webcam.png' def setPost(self): super(Webcam, self).setPost() self._post['webcam_works'] = self._howItWorks class Bluetooth(Device): def __init__(self): super(Bluetooth, self).__init__() self._type = 'bluetooth' self._howItWorks = 'no' self._interfaces = ['not-specified','USB','PCI','PCI-E','mini-PCI','mini-PCI-E','ExpressCard','PC-Card'] self._icon = 'bluetooth.png' def setPost(self): super(Bluetooth, self).setPost() self._post['bluetooth_works'] = self._howItWorks class Acquisitioncard(Device): def __init__(self): super(Acquisitioncard, self).__init__() self._type = 'acquisition-card' self._howItWorks = 'no' self._interfaces = ['not-specified','USB','PCI','PCI-E','mini-PCI','mini-PCI-E','ExpressCard','PC-Card','Firewire','Parallel','Serial'] self._icon = 'acquisition-card.png' def setPost(self): super(Acquisitioncard, self).setPost() self._post['compatibility'] = self._howItWorks class Fingerprintreader(Device): def __init__(self): super(Fingerprintreader, self).__init__() self._type = 'fingerprint-reader' self._howItWorks = 'no' self._interfaces = ['not-specified','USB','PCI','PCI-E','mini-PCI','mini-PCI-E','ExpressCard','PC-Card','Firewire','Parallel','Serial'] self._icon = 'fingerprint-reader.png' def setPost(self): super(Fingerprintreader, self).setPost() self._post['fingerprint_works'] = self._howItWorks class Unknown(Device): def __init__(self): super(Unknown, self).__init__() self._type = 'unknown' self._howItWorks = 'no' self._interfaces = ['not-specified','USB'] self._icon = 'unknown.png' def setPost(self): super(Unknown, self).setPost() #class to carry out http requests by means of pycurl class Mycurl: _post = None #set the domain def __init__(self,domain): self.contents = '' self.setDomain(domain) def getStatus(self): return self._status def setDomain(self,domain): self.domain = domain #check if the trailing slash is present if len(self.domain) > 1: if self.domain[len(self.domain)-1] != '/': self.domain += '/' def getDomain(self): return self.domain def setPost(self,post): self._post = post def body_callback(self, buf): self.contents = self.contents + buf #perform the HTTP request def perform(self,requestUri = ''): self.url = self.domain + requestUri; #print self.url self.contents = '' c = pycurl.Curl() c.setopt(c.URL, self.url) c.setopt(pycurl.COOKIEFILE, 'tmp/cookies.txt') c.setopt(pycurl.COOKIEJAR, 'tmp/cookies.txt') if self._post != None: c.setopt(c.POSTFIELDS, urllib.urlencode(self._post)) c.setopt(c.WRITEFUNCTION, self.body_callback) try: c.perform() result = True except: result = False #print c.getinfo(c.HTTP_CODE) #result = False #if c.getinfo(c.HTTP_CODE) == 200: #result = True c.close() return result class Client: devices = {} _status = True errors = [] _types = { '0403' : { 'type' : 'soundcard', 'controller': 'soundcards' }, '0280' : { 'type' : 'wifi', 'controller': 'wifi' }, '0300' : { 'type' : 'videocard', 'controller': 'videocards' }, '070100' : { 'type' : 'printer', 'controller': 'printers' }, '070101' : { 'type' : 'printer', 'controller': 'printers' }, '070102' : { 'type' : 'printer', 'controller': 'printers' }, '070103' : { 'type' : 'printer', 'controller': 'printers' }, '0701ff' : { 'type' : 'printer', 'controller': 'printers' }, 'e00101' : { 'type' : 'bluetooth', 'controller': 'bluetooth' }, '020205' : { 'type' : '3G-card', 'controller': 'threegcards' }, '0e0100' : { 'type' : 'webcam', 'controller': 'webcams' }, 'ff0100' : { 'type' : 'webcam', 'controller': 'webcams' }, '060101' : { 'type' : 'scanner', 'controller': 'scanners' }, '0d0000' : { 'type' : 'fingerprint-reader', 'controller': 'fingerprintreaders' }, 'ffffff' : { 'type' : 'unknown', 'controller': 'unknown' } } def __init__(self,url = ''): self.request = Mycurl(url) #create the allowedDistros ordered dictionary self.allowedDistros = OrderedDict([ ('blag_90001','BLAG 90001'), ('blag_120000','BLAG 120000'), ('dragora_1_1','Dragora 1.1'), ('dragora_2_0','Dragora 2.0 Ardi'), ('dynebolic_2_5_2','Dynebolic 2.5.2 DHORUBA'), ('gnewsense_2_3','gNewSense 2.3 Deltah'), ('gnewsense_3_0','gNewSense 3.0 Metad'), ('musix_2_0','Musix GNU+Linux 2.0 R0'), ('parabola','Parabola GNU/Linux'), ('trisquel_3_5','Trisquel 3.5 Awen'), ('trisquel_4_0','Trisquel 4.0 Taranis'), ('trisquel_4_5','Trisquel 4.5 Slaine'), ('ututo_xs_2009','UTUTO XS 2009'), ('ututo_xs_2010','UTUTO XS 2010'), ('venenux_0_8','VENENUX 0.8'), ('venenux_0_8_2','VENENUX-EC 0.8.2')] ) #get the list of types def getTypes(self): types = [] for Class,struct in self._types.iteritems(): if struct['type'] not in types: types.append(struct['type']) return types #check if a distro code is allowed or not def distroIsAllowed(self,distroCode): allowedDistroCodes = self.allowedDistros.keys() if distroCode in allowedDistroCodes: return True return False def getNode(self): return self.request.getDomain() def setNode(self,domain): self.request.setDomain(domain) #get the type from the Class id def getType(self, Class): Classes = self._types.keys() if Class in Classes: return self._types[Class]['type'] return None #get the controller from the Class id def getController(self, Class): Classes = self._types.keys() if Class in Classes: return self._types[Class]['controller'] return None #return a device object def getObject(self,Class): if Class == '0403': return Soundcard() elif Class == '0280': return Wifi() elif Class == '0300': return Videocard() elif Class == '070100' or Class == '070101' or Class == '070102' or Class == '070103' or Class == '0701ff': return Printer() elif Class == '0e0100' or Class == 'ff0100': return Webcam() elif Class == 'e00101': return Bluetooth() elif Class == '060101': return Scanner() elif Class == '0d0000': return Fingerprintreader() elif Class == '020205': return Threegcard() elif Class == 'ffffff': return Unknown() else: return None def getObjectFromType(self,Type): if Type == 'soundcard': return Soundcard() elif Type == 'wifi': return Wifi() elif Type == 'videocard': return Videocard() elif Type == 'printer': return Printer() elif Type == 'webcam': return Webcam() elif Type == 'bluetooth': return Bluetooth() elif Type == 'scanner': return Scanner() elif Type == 'fingerprint-reader': return Fingerprintreader() elif Type == '3G-card': return Threegcard() else: return None #get the class from the type def getClassFromType(self,Type): for Class,struct in self._types.iteritems(): if struct['type'] == Type: return Class #get the kernel version def getKernel(self): if not os.system('uname -r > tmp/kernel'): f = open('tmp/kernel','r') row = f.readline().replace("\n","") f.close(); os.system('rm -f tmp/kernel') return row else: self._status = False self.errors.append('tmp folder not writable') #log in def login(self, username, password): self.request.setPost({'username' : username, 'password' : password}) result = self.request.perform('users/login/en') self.request.setPost(None) if result: if self.isLogged(): return True else: self.errors.append("wrong username or password") else: self.errors.append("unable to connect to server") return False #log out def logout(self): result = self.request.perform('users/logout/en') if result: return True else: self.errors.append("unable to connect to server") return False #get info about the user logged def getUserInfo(self): result = self.request.perform('client/userinfo/en') if result: try: xmldoc = minidom.parseString(self.request.contents) status = xmldoc.getElementsByTagName("status")[0].childNodes[0].data username = '' token = '' groups = '' if status == 'logged': username = xmldoc.getElementsByTagName("username")[0].childNodes[0].data token = xmldoc.getElementsByTagName("token")[0].childNodes[0].data groups = xmldoc.getElementsByTagName("groups")[0].childNodes[0].data return {'status':status,'username':username,'token':token,'groups':groups} except: self.errors.append("the server is not up-to-date: unable to parse the xml database") return False else: self.errors.append("unable to connect to server") return False #return True if the user is logged, else return False def isLogged(self): info = self.getUserInfo() if info != False: if info['status'] == 'logged': return True return False #return the license info def getLicenseNotice(self): result = self.request.perform("client/licenseinfo/en"); if result: xmldoc = minidom.parseString(self.request.contents) notice = xmldoc.getElementsByTagName("license_info")[0].childNodes[0].data.encode('utf-8') return notice else: self.errors.append("unable to connect to server") return False def addLeadingZero(self,string): if len(string) == 1: return '0'+string else: return string def createDevices(self): #parse the poutput of the lspci command if not os.system('lspci -vmmnn > tmp/temp'): f = open('tmp/temp','r') while 1: row = f.readline() if not row: break #get the slot if row.find('Slot') != -1: #get the class row = f.readline().rstrip("\n") if row: cl = re.match('Class\:(.*)\[(.*)\]',row,re.I) if cl: #get the object dev = self.getObject(cl.group(2)) if dev: #set the type attribute of the device object dev.setType(self.getType(cl.group(2))) #get the vendorid row = f.readline().rstrip("\n") if row: vn = re.match('Vendor\:(.*)\[(.*)\]',row,re.I) if vn: dev.setVendorId(vn.group(2).lstrip("\t")) #get the productid row = f.readline().rstrip("\n") if row: pr = re.match('Device\:(.*)\[(.*)\]',row,re.I) if pr: dev.setProductId(pr.group(2).lstrip("\t")) dev.setModel(pr.group(1).lstrip("\t")) dev.setKernel(self.getKernel()) self.devices['p_' + dev.getVendorId() + ':' + dev.getProductId()] = [dev,cl.group(2),'insert','0'] else: self.errors.append('the lspci -vmmnn output is not a standard output, some products row not found') else: self.errors.append('the lspci -vmmnn output is not a standard output, some vendors row not found') else: self.errors.append('the lspci -vmmnn output is not a standard output, some class row not found') f.close(); else: self.errors.append('tmp folder not writable') #parse the output of the lsusb command if not os.system('lsusb -v > tmp/temp'): f = open('tmp/temp','r') deviceDict = {} keyNumber = 0 usbDeviceIsFound = 'N' while 1: row = f.readline() crow = row.replace("\n","").lstrip().rstrip() if not row: break #clear pid and vid if a new device has been found if row.find('Device Descriptor:') != -1 and row.find('HID Device Descriptor:') == -1: usbDeviceIsFound = 'N' keyNumber = keyNumber + 1 keyString = str(keyNumber) deviceDict[keyString] = {} #find the vendor if crow.find('idVendor') != -1: #print crow res = re.match('idVendor(.*)0x([a-zA-Z0-9]{4})(.*)',crow,re.I) if res: deviceDict[keyString]['vendorId'] = res.group(2).lstrip().rstrip() deviceDict[keyString]['vendorName'] = res.group(3).lstrip().rstrip() #find the product if crow.find('idProduct') != -1: #print crow res = re.match('idProduct(.*)0x([a-zA-Z0-9]{4})(.*)',crow,re.I) if res: deviceDict[keyString]['productId'] = res.group(2).lstrip().rstrip() deviceDict[keyString]['productName'] = res.group(3).lstrip().rstrip() if usbDeviceIsFound == 'N': #find the class if crow.find('bInterfaceClass') != -1: #print crow res = re.match('bInterfaceClass([\s]*)([0-9]*)(.*)',crow,re.I) if res: cl = hex(int(res.group(2).lstrip().rstrip())) deviceDict[keyString]['classId'] = self.addLeadingZero(cl[2:]) deviceDict[keyString]['className'] = res.group(3).lstrip().rstrip() #find the subclass if crow.find('bInterfaceSubClass') != -1: #print crow res = re.match('bInterfaceSubClass([\s]*)([0-9]*)(.*)',crow,re.I) if res: cl = hex(int(res.group(2).lstrip().rstrip())) deviceDict[keyString]['subclassId'] = self.addLeadingZero(cl[2:]) deviceDict[keyString]['subclassName'] = res.group(3).lstrip().rstrip() #find the protocol if crow.find('bInterfaceProtocol') != -1: #print crow res = re.match('bInterfaceProtocol([\s]*)([0-9]*)(.*)',crow,re.I) if res: cl = hex(int(res.group(2).lstrip().rstrip())) deviceDict[keyString]['protocolId'] = self.addLeadingZero(cl[2:]) deviceDict[keyString]['protocolName'] = res.group(3).lstrip().rstrip() currentClassCode = str(deviceDict[keyString]['classId'])+str(deviceDict[keyString]['subclassId'])+str(deviceDict[keyString]['protocolId']) if self.getObject(currentClassCode) and currentClassCode != 'ffffff': usbDeviceIsFound = 'Y' f.close(); #create the USB devices for key,value in deviceDict.iteritems(): Class = str(value['classId']) + str(value['subclassId']) + str(value['protocolId']) #get the USB object dev = self.getObject(Class) if dev: dev.setType(self.getType(Class)) dev.setVendorId(value['vendorId']) dev.setInterface('USB') dev.setProductId(value['productId']) dev.setModel(value['productName']) dev.setKernel(self.getKernel()) self.devices['u_' + dev.getVendorId() + ':' + dev.getProductId()] = [dev,Class,'insert','0'] else: self.errors.append('tmp folder not writable') #change the type of a device #deviceCode: the code of the device #nType: the new type of the device def changeType(self,deviceCode,nType): dev = self.getObjectFromType(nType) if dev != None: dev.setModel(self.devices[deviceCode][0].getModel()) dev.setOtherNames(self.devices[deviceCode][0].getOtherNames()) dev.setKernel(self.devices[deviceCode][0].getKernel()) dev.setDistributions(self.devices[deviceCode][0].getDistributions()) dev.setInterface(self.devices[deviceCode][0].getInterface()) dev.setYear(self.devices[deviceCode][0].getYear()) dev.setVendorId(self.devices[deviceCode][0].getVendorId()) dev.setProductId(self.devices[deviceCode][0].getProductId()) dev.setHowItWorks(self.devices[deviceCode][0].getHowItWorks()) dev.setDriver(self.devices[deviceCode][0].getDriver()) dev.setDescription(self.devices[deviceCode][0].getDescription()) dev.setSubtype(self.devices[deviceCode][0].getSubtype()) dev.setIcon(nType+".png") Class = self.getClassFromType(nType) self.devices[deviceCode][0] = dev self.devices[deviceCode][1] = Class #syncronize with the xml database def sync(self): #perform an http request self.request.contents = '' result = self.request.perform('download/all/en') #print result if result: #loop the found devices for key,dev in self.devices.iteritems(): #find the class #Class = dev[1] vendorid_productid = key[2:] #reset the device params dev[2] = 'insert' dev[3] = '0' #parse the xml database try: xmldoc = minidom.parseString(self.request.contents) devices = xmldoc.getElementsByTagName("device") for device in devices: #check it is not a notebook deviceType = device.getElementsByTagName("type")[0].childNodes[0].data.encode('utf-8') if deviceType != 'notebook': code = device.getElementsByTagName("vendorid_productid")[0] if code.hasChildNodes(): if code.childNodes[0].data == vendorid_productid: if deviceType != dev[0].getType(): self.changeType(key,deviceType) modelName = device.getElementsByTagName("model_name")[0].childNodes[0].data.encode('utf-8') interface = device.getElementsByTagName("interface")[0].childNodes[0].data.encode('utf-8') distribution = device.getElementsByTagName("distribution")[0].childNodes[0].data.encode('utf-8') idDevice = device.getElementsByTagName("id")[0].childNodes[0].data.encode('utf-8') if deviceType == 'printer' or deviceType == 'scanner': works = device.getElementsByTagName("compatibility")[0].childNodes[0].data.encode('utf-8') if deviceType == 'printer': #set the subtype subtype = device.getElementsByTagName("subtype")[0].childNodes[0].data.encode('utf-8') dev[0].setSubtype(subtype) else: works = device.getElementsByTagName("it_works")[0].childNodes[0].data.encode('utf-8') year = device.getElementsByTagName("year")[0].childNodes[0].data.encode('utf-8') if device.getElementsByTagName("other_names")[0].hasChildNodes(): other_names = device.getElementsByTagName("other_names")[0].childNodes[0].data.encode('utf-8') dev[0].setOtherNames(other_names) else: dev[0].setOtherNames('') if device.getElementsByTagName("description")[0].hasChildNodes(): description = device.getElementsByTagName("description")[0].childNodes[0].data.encode('utf-8') dev[0].setDescription(dev[0].htmlentitiesDecode(description)) else: dev[0].setDescription('') if device.getElementsByTagName("kernel_libre")[0].hasChildNodes(): kernel_libre = device.getElementsByTagName("kernel_libre")[0].childNodes[0].data.encode('utf-8') dev[0].setKernel(kernel_libre) if device.getElementsByTagName("driver")[0].hasChildNodes(): driver = device.getElementsByTagName("driver")[0].childNodes[0].data.encode('utf-8') dev[0].setDriver(driver) else: dev[0].setDriver('') #print modelName dev[0].setModel(modelName) dev[0].setInterface(interface) dev[0].setDistributions([]) dev[0].addDistributions(distribution) dev[0].setHowItWorks(works) dev[0].setYear(year) dev[2] = 'update' dev[3] = idDevice except: self.errors.append("the server is not up-to-date: unable to parse the xml database") else: self.errors.append("unable to connect to server") def submit(self,deviceCode = None): for key,dev in self.devices.iteritems(): if key == deviceCode or deviceCode == None: dev[0].setPost() post = dev[0].getPost() #get the node controller controller = self.getController(dev[1]) #get the user info info = self.getUserInfo() token = info['token'] post['from_client'] = 'yes' if dev[2] == 'update': post['id_hard'] = dev[3] post['updateAction'] = 'update' url = controller + '/update/en/' + token elif dev[2] == 'insert': post['insertAction'] = 'insert' url = controller + '/insert/en/' + token self.request.setPost(post) self.request.perform(url.encode('utf-8')) #parse the response xmldoc = minidom.parseString(self.request.contents) response = xmldoc.getElementsByTagName("status")[0].childNodes[0].data.encode('utf-8') notice = xmldoc.getElementsByTagName("notice")[0].childNodes[1].data.encode('utf-8') self.errors.append(notice.lstrip().rstrip()) if response == 'executed': return True else: return False