From d72ddb0f0211ea854292d445ac184a7b4bbe07b8 Mon Sep 17 00:00:00 2001 From: Antonio Gallo Date: Sun, 13 Mar 2011 01:22:03 +0000 Subject: starded h-cliend coding --- h-client/hlibrary.py | 474 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 474 insertions(+) create mode 100644 h-client/hlibrary.py (limited to 'h-client/hlibrary.py') diff --git a/h-client/hlibrary.py b/h-client/hlibrary.py new file mode 100644 index 0000000..6e8f66f --- /dev/null +++ b/h-client/hlibrary.py @@ -0,0 +1,474 @@ +# -*- coding: utf-8 -*- +# hlibrary, a python library to manage the database of an h-source node +# Copyright (C) 2011 Antonio Gallo +# +# +# hlibrary 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. +# +# hlibrary 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 hlibrary. If not, see . + +import os +import string +import re +import sys +import pycurl +import urllib +from xml.dom import minidom + + + +class Device(object): + + _allowedDistros = { + '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', + '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' + } + + _status = True + + errors = [] + + def __init__(self): + self._post = {} + self._type = None + self._vendor = None + self._model = None + self._kernel = None + self._distributions = None + self._interface = 'not-specified' + self._year = 'not-specified' + self._vendorId = None + self._productId = None + self._howItWorks = None + self._driver = '' + self._description = None + + def setPost(self): + self._post['model'] = self._model; + self._post['kernel'] = self._kernel; + self._post['distribution'] = self._distributions; + self._post['comm_year'] = self._year; + self._post['pci_id'] = self._vendorId + ':' + self._productId; + self._post['interface'] = self._interface; + self._post['description'] = self._description; + self._post['driver'] = self._driver; + + + def getType(self): + return self._type + + def getVendor(self): + return self._vendor + + def getModel(self): + return self._model + + 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 setType(self,ttype): + self._type = ttype + + def setVendor(self,vendor): + self._vendor = vendor + + def setModel(self,model): + self._model = model + + def setKernel(self,kernel): + self._kernel = kernel + + def setDistributions(self,distributions): + distArray = distributions.split(','); + + allowedDistKeys = self._allowedDistros.keys() + + for dist in distArray: + if dist not in allowedDistKeys: + self._status = False + self.errors.append('distribution ' + dist + ' not allowed') + + 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 getStatus(self): + return self._status + + def getPost(self): + return self._post + +class Videocard(Device): + + def __init__(self): + super(Videocard, self).__init__() + self._type = 'videocard'; + + 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'; + + 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'; + + def setPost(self): + super(Soundcard, self).setPost() + self._post['sound_card_works'] = self._howItWorks + + +#class to carry out http requests by means of pycurl +class Mycurl: + + _post = None + + #set the domain + def __init__(self,domain): + self.contents = '' + self.domain = domain + #check if the trailing slash is present + if self.domain[len(self.domain)-1] != '/': + self.domain += '/' + + def setPost(self,post): + self._post = post + + def body_callback(self, buf): + self.contents = self.contents + buf + + 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) + c.perform() + c.close() + +class Client: + + devices = {} + + _status = True + errors = [] + + _types = { + '0403' : { + 'type' : 'soundcard', + 'controller': 'soundcards' + }, + '0280' : { + 'type' : 'wifi', + 'controller': 'wifi' + }, + '0300' : { + 'type' : 'videocard', + 'controller': 'videocards' + } + } + + def __init__(self,url): + self.request = Mycurl(url) + + #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() + else: + return None + + #get the system kernel + def getKernel(self): + if not os.system('uname -r > tmp/temp'): + f = open('tmp/temp','r') + row = f.readline().replace("\n","") + f.close(); + 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}) + self.request.perform('users/login/en') + self.request.setPost(None) + + #log out + def logout(self): + self.request.perform('users/logout/en') + + #get info about the user logged + def getUserInfo(self): + self.request.perform('users/info/en') + xmldoc = minidom.parseString(self.request.contents) + status = modelName = xmldoc.getElementsByTagName("status")[0].childNodes[0].data + + username = '' + token = '' + groups = '' + + if status == 'logged': + username = modelName = xmldoc.getElementsByTagName("username")[0].childNodes[0].data + token = modelName = xmldoc.getElementsByTagName("token")[0].childNodes[0].data + groups = modelName = xmldoc.getElementsByTagName("groups")[0].childNodes[0].data + + return {'status':status,'username':username,'token':token,'groups':groups} + + #return True if the user is logged, else return False + def isLogged(self): + info = self.getUserInfo() + + if info['status'] == 'logged': + return True + + return False + + def createDevices(self): + 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().replace("\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().replace("\n","") + if row: + vn = re.match('Vendor\:(.*)\[(.*)\]',row,re.I) + if vn: + dev.setVendorId(vn.group(2).replace("\t","")) + #get the productid + row = f.readline().replace("\n","") + if row: + pr = re.match('Device\:(.*)\[(.*)\]',row,re.I) + if pr: + dev.setProductId(pr.group(2).replace("\t","")) + dev.setModel(pr.group(1).replace("\t","")) + + dev.setInterface('not-specified') + dev.setKernel(self.getKernel()) + + self.devices['p_' + dev.getVendorId() + ':' + dev.getProductId()] = [dev,cl.group(2),'insert','0'] + + else: + self._status = False + self.errors.append('the lspci -vmmnn output is not a standard output, some products row not found') + else: + self._status = False + self.errors.append('the lspci -vmmnn output is not a standard output, some vendors row not found') + else: + self._status = False + self.errors.append('the lspci -vmmnn output is not a standard output, some class row not found') + + f.close(); + else: + self._status = False + self.errors.append('tmp folder not writable') + + #syncronize with the xml database + def sync(self): + #loop the found devices + for key,dev in self.devices.iteritems(): + #find the class + Class = dev[1] + vendorid_productid = key[2:] + #find the controller + controller = self.getController(Class) + + #perform an http request + self.request.contents = '' + self.request.perform('download/' + controller + '/en') + + #parse the xml database + xmldoc = minidom.parseString(self.request.contents) + devices = xmldoc.getElementsByTagName("device") + for device in devices: + + code = device.getElementsByTagName("vendorid_productid")[0] + if code.hasChildNodes(): + if (code.childNodes[0].data == vendorid_productid): + + modelName = device.getElementsByTagName("model_name")[0].childNodes[0].data + interface = device.getElementsByTagName("interface")[0].childNodes[0].data + distribution = device.getElementsByTagName("distribution")[0].childNodes[0].data + idDevice = device.getElementsByTagName("id")[0].childNodes[0].data + works = device.getElementsByTagName("it_works")[0].childNodes[0].data + year = device.getElementsByTagName("year")[0].childNodes[0].data + description = device.getElementsByTagName("description")[0].childNodes[0].data + + #print modelName + dev[0].setModel(modelName) + dev[0].setInterface(interface) + dev[0].setDistributions(distribution) + dev[0].setHowItWorks(works) + dev[0].setYear(year) + dev[0].setDescription(description) + dev[2] = 'update' + dev[3] = idDevice + + def submit(self): + for key,dev in self.devices.iteritems(): + dev[0].setPost() + post = dev[0].getPost() + if dev[2] == 'update': + #get the node controller + controller = self.getController(dev[1]) + #get the device id (inside the node database) + post['id_hard'] = dev[3] + post['updateAction'] = 'update' + #get the user info + info = self.getUserInfo() + token = info['token'] + url = controller + '/update/en/' + token + + self.request.setPost(post) + self.request.perform(url.encode('utf-8')) + #print self.request.contents + + +#d = Videocard() + +#d.setVendor('Acer') +#print d.getType() +#d.setDistributions('trisquel_4_0,gnewsense'); +#print d.getStatus() + +client = Client('http://h-source/') +client.createDevices() +#client.request.perform('download/all/it') +#print client.request.url +client.sync() + +#for key,dev in client.devices.iteritems(): + #print key + #print dev[0].getModel() + #print dev[0].getDistributions() + #print dev[0].getYear() + #print dev[3] + #print dev[0].getHowItWorks() + #print dev[0].getDescription()+"\n"+"\n" + + +client.login('','') +#print client.isLogged() +client.submit() +client.logout() +#client.devices['p_14e4:4311'][0].setPost() +#print client.devices['p_14e4:4311'][0].getPost() \ No newline at end of file -- cgit v1.2.3