def __init__( self, parent, url, location, service, control_url, node=None, dump='' ): self.__parent = parent self.state_variables = {} self.__actions = {} self.__node = node self.url = url self.__icons = {} if node is not None: icons = node.find('iconList') if icons is None: icons = [] for icon in icons: icon = Icon(self, url, icon) self.__icons[icon.__name__] = icon self.service = service location = location.replace(url, '') location = location.replace('//', '/') if not location.startswith('/'): location = '/' + location response = requests.get(url + location) if dump: path = location if path.startswith('/'): path = path[1:] if '/' in path: path, file_name = path.rsplit('/', 1) path = os.path.join(dump, path) else: file_name = path path = dump if not os.path.exists(path): os.makedirs(path) if not file_name.endswith('.xml'): file_name += '.xml' if isinstance(response.content, bytes): content = response.content.decode('utf-8') else: content = response.content with open(os.path.join(path, file_name), 'w') as f: f.write(content) try: root = etree.fromstring(response.content) except: import traceback print(repr(response.content)) traceback.print_exc() return root = strip_xmlns(root) actions = root.find('actionList') if actions is None: actions = [] state_variables = root.find('serviceStateTable') if state_variables is None: state_variables = [] for state_variable in state_variables: state_variable = StateVariable(state_variable) self.state_variables[state_variable.name] = state_variable for action in actions: action = Action( self, action, self.state_variables, service, url + control_url ) self.__actions[action.__name__] = action
def build(self, ip_address, locations, dump=''): self._devices.clear() self._services.clear() self.ip_address = ip_address for location in locations: parsed = urlparse(location) url = '{0}://{1}:{2}/'.format(parsed.scheme, parsed.hostname, parsed.port) logger.debug(self.ip_address + ' <-- (' + location + ') ""') response = requests.get(location) logger.debug(self.ip_address + ' --> (' + location + ') ' + response.content.decode('utf-8')) path = parsed.path if path.startswith('/'): path = path[1:] if '/' in path: path, file_name = path.rsplit('/', 1) else: file_name = path path = '' if not file_name.endswith('.xml'): file_name += '.xml' if dump: content = response.content.decode('utf-8') if path: output = os.path.join(dump, path) if not os.path.exists(output): os.makedirs(output) else: output = dump indent_count = 0 for line in content.split('\n'): for char in list(line): if not line: continue if char != ' ' and not indent_count: break if char == ' ': indent_count += 1 else: if indent_count != 2: indent_count = 0 break if indent_count: break with open(os.path.join(output, file_name), 'w') as f: for line in content.split('\n'): if not line.strip(): continue line = line.replace('\t', ' ') if indent_count: count = 0 for char in list(line): if char != ' ': break count += 1 line = ' ' * (count / 2) + line.strip() f.write(line + '\n') try: root = etree.fromstring(response.content.decode('utf-8')) except etree.XMLSyntaxError: return except ValueError: try: root = etree.fromstring(response.content) except etree.XMLSyntaxError: return root = strip_xmlns(root) node = root.find('device') if node is None: services = [] devices = [] else: services = node.find('serviceList') if services is None: services = [] devices = node.find('deviceList') if devices is None: devices = [] for service in services: scpdurl = service.find('SCPDURL').text.replace(url, '') if '/' not in scpdurl and path and path not in scpdurl: scpdurl = path + '/' + scpdurl control_url = service.find('controlURL').text if control_url is None: if scpdurl.endswith('.xml'): control_url = scpdurl.rsplit('/', 1)[0] if control_url == scpdurl: control_url = '' else: control_url = scpdurl else: control_url = control_url.replace(url, '') if control_url.startswith('/'): control_url = control_url[1:] if scpdurl.startswith('/'): scpdurl = scpdurl[1:] service_id = service.find('serviceId').text service_type = service.find('serviceType').text service = Service(self, url, scpdurl, service_type, control_url, node, dump=dump) name = service_id.split(':')[-1] service.__name__ = name self._services[name] = service for device in devices: device = EmbeddedDevice(url, node=device, parent=self, dump=dump) self._devices[device.__name__] = device
def __init__(self, ip, locations, dump=''): self.ip_address = ip cls_name = None self._devices = {} self._services = {} for location in locations: parsed_url = urlparse(location) url = parsed_url.scheme + '://' + parsed_url.netloc response = requests.get(location) if dump: path = location if path.startswith('/'): path = path[1:] if '/' in path: path, file_name = path.rsplit('/', 1) path = os.path.join(dump, path) else: file_name = path path = dump if not os.path.exists(path): os.makedirs(path) if not file_name.endswith('.xml'): file_name += '.xml' if isinstance(response.content, bytes): content = response.content.decode('utf-8') else: content = response.content with open(os.path.join(path, file_name), 'w') as f: f.write(content) root = etree.fromstring(response.content) root = strip_xmlns(root) node = root.find('device') services = node.find('serviceList') if services is None: services = [] devices = node.find('deviceList') if devices is None: devices = [] for service in services: scpdurl = service.find('SCPDURL').text.replace(url, '') control_url = service.find('controlURL').text if control_url is None: if scpdurl.endswith('.xml'): control_url = scpdurl.rsplit('/', 1)[0] if control_url == scpdurl: control_url = '' else: control_url = scpdurl else: control_url = control_url.replace(url, '') service_id = service.find('serviceId').text service_type = service.find('serviceType').text service = Service( self, url, scpdurl, service_type, control_url, node, dump=dump ) name = service_id.split(':')[-1] service.__name__ = name self._services[name] = service for device in devices: device = EmbeddedDevice( url, node=device, parent=self, dump=dump ) self._devices[device.__name__] = device if cls_name is None: cls_name = node.find('modelName') if cls_name is not None and cls_name.text: cls_name = cls_name.text.replace(' ', '_').replace('-', '') self.__name__ = cls_name
def __call__(self, *args, **kwargs): for i, arg in enumerate(args): try: kwargs[self.params[i].__name__] = arg except IndexError: for param in self.params: print(param.__name__) raise doc = Document() envelope = doc.createElementNS('', 's:Envelope') envelope.setAttribute('xmlns:s', ENVELOPE_XMLNS) envelope.setAttribute('s:encodingStyle', 'http://schemas.xmlsoap.org/soap/encoding/') body = doc.createElementNS('', 's:Body') fn = doc.createElementNS('', self.__name__) fn.setAttribute('xmlns:u', self.service) for param in self.params: if param.__name__ not in kwargs: value = param(None) else: value = param(kwargs[param.__name__]) tmp_node = doc.createElement(param.__name__) tmp_text_node = doc.createTextNode(str(value)) tmp_node.appendChild(tmp_text_node) fn.appendChild(tmp_node) body.appendChild(fn) envelope.appendChild(body) doc.appendChild(envelope) pure_xml = doc.toxml() header = { 'SOAPAction': '"{service}#{method}"'.format(service=self.service, method=self.__name__), 'Content-Type': 'text/xml' } response = requests.post(self.control_url, data=pure_xml, headers=header) envelope = etree.fromstring(response.content) envelope = strip_xmlns(envelope) body = envelope.find('Body') return_value = [] if body is not None: response = body.find(self.__name__ + 'Response') if response is not None: for ret_val in self.ret_vals: value = response.find(ret_val.__name__) if value is None: value = ret_val(None) else: value = ret_val(value.text) return_value += [value] if not return_value and self.ret_vals: for val in self.ret_vals: return_value += [val(None)] return return_value