def test_err(self, mock_popen, mock_logger): self.stderr_mock.write( dedent(""" Failed to create client object: Daemon not running """).encode("utf-8")) self.stdout_mock.seek(0) mock_popen.return_value.stdout = self.stdout_mock self.stderr_mock.seek(0) mock_popen.return_value.stderr = self.stderr_mock get_avahi_address("octopi.local") self.assertTrue(mock_logger.call_count, 1) mock_logger.called_with( "avahi-resolve-host-name error: Failed to create client object: Daemon not running" )
def test_pass_hostname(self, mock_popen): self.stdout_mock.write( dedent(""" octopi.local\t10.192.202.23 """).encode("utf-8")) self.stdout_mock.seek(0) mock_popen.return_value.stdout = self.stdout_mock self.stderr_mock.seek(0) mock_popen.return_value.stderr = self.stderr_mock get_avahi_address("octopi.local") mock_popen.assert_called_with( ["avahi-resolve-host-name", "-4", "octopi.local"], stdout=-1, stderr=-1)
def check_printers(): app.logger.debug("Checking known printers...") for raw_printer in printers.get_printers(): printer = clients.get_printer_instance(raw_printer) if printer.hostname is not None: current_ip = network.get_avahi_address(printer.hostname) if current_ip is not None and current_ip != printer.ip: printer.ip = current_ip printer.update_network_host() else: hostname = network.get_avahi_hostname(printer.ip) if hostname is not None: printer.hostname = hostname printer.update_network_host() printer.is_alive() printers.update_printer( uuid=printer.uuid, name=printer.name, hostname=printer.hostname, ip=printer.ip, port=printer.port, protocol=printer.protocol, client=printer.client_name(), client_props={ "version": printer.client_info.version, "connected": printer.client_info.connected, "access_level": printer.client_info.access_level, "api_key": printer.client_info.api_key, "webcam": printer.webcam(), }, printer_props=printer.get_printer_props(), )
def test_mac_addr_on_first_try(self, mock_popen): self.stdout_mock.write( dedent(""" octopi.local fe80::1015:d815:253e:f8e5 """).encode("utf-8")) self.stdout_mock.seek(0) mock_popen.return_value.stdout = self.stdout_mock self.stderr_mock.seek(0) mock_popen.return_value.stderr = self.stderr_mock self.assertEqual(get_avahi_address("octopi.local"), None)
def test_drop_error_message(self, mock_popen): self.stdout_mock.write( dedent(""" Failed to resolve host name 'octopi.local': Timeout reached """).encode("utf-8")) self.stdout_mock.seek(0) mock_popen.return_value.stdout = self.stdout_mock self.stderr_mock.seek(0) mock_popen.return_value.stderr = self.stderr_mock self.assertEqual(get_avahi_address("octopi.local"), None)
def test_regex(self, mock_popen): self.stdout_mock.write( dedent(""" octopi.local\t10.192.202.23 """).encode("utf-8")) self.stdout_mock.seek(0) mock_popen.return_value.stdout = self.stdout_mock self.stderr_mock.seek(0) mock_popen.return_value.stderr = self.stderr_mock result = get_avahi_address("octopi.local") self.assertEqual(result, "10.192.202.23")
def check_printer(printer_uuid): app.logger.debug("Checking printer %s" % printer_uuid) raw_printer = printers.get_printer(printer_uuid) # todo: The `get_printer` method should raise an exception instead of returning None if raw_printer is None: app.logger.info( "Printer was deleted after it was scheduled for update.") return raw_client = network_clients.get_network_client( raw_printer["network_client_uuid"]) printer_data = dict(raw_client) printer_data.update(raw_printer) printer = clients.get_printer_instance(printer_data) # websocket printers are not expected to change if printer.protocol in ["http", "https"]: if printer.hostname is not None: current_ip = network.get_avahi_address(printer.hostname) if current_ip is not None and current_ip != printer.ip: printer.ip = current_ip printer.update_network_base() hostname = network.get_avahi_hostname(printer.ip) if hostname is not None and hostname != printer.hostname: printer.hostname = hostname printer.update_network_base() now = datetime.now() if now.minute % 15 == 0 and printer.client_info.connected: printer.sniff() printer.karmen_sniff() else: printer.is_alive() if (printer.client_info.pill_info and printer.client_info.pill_info.get( "update_status", None) is not None): printer.karmen_sniff() if printer.hostname != raw_client.get( "hostname") or printer.ip != raw_client.get("ip"): network_clients.update_network_client( uuid=raw_client["uuid"], hostname=printer.hostname, ip=printer.ip, ) printers.update_printer( uuid=printer.uuid, client_props={ "version": printer.client_info.version, "connected": printer.client_info.connected, "access_level": printer.client_info.access_level, "api_key": printer.client_info.api_key, "webcam": printer.client_info.webcam, "plugins": printer.client_info.plugins, "pill_info": printer.client_info.pill_info, }, )
def check_printer(printer_uuid): app.logger.debug("Checking printer %s" % printer_uuid) raw_printer = printers.get_printer(printer_uuid) raw_client = network_clients.get_network_client( raw_printer["network_client_uuid"]) printer_data = dict(raw_client) printer_data.update(raw_printer) printer = clients.get_printer_instance(printer_data) # websocket printers are not expected to change if printer.protocol in ["http", "https"]: if printer.hostname is not None: current_ip = network.get_avahi_address(printer.hostname) if current_ip is not None and current_ip != printer.ip: printer.ip = current_ip printer.update_network_base() hostname = network.get_avahi_hostname(printer.ip) if hostname is not None and hostname != printer.hostname: printer.hostname = hostname printer.update_network_base() now = datetime.now() if now.minute % 15 == 0 and printer.client_info.connected: printer.sniff() else: printer.is_alive() if printer.hostname != raw_client.get( "hostname") or printer.ip != raw_client.get("ip"): network_clients.update_network_client( uuid=raw_client["uuid"], hostname=printer.hostname, ip=printer.ip, ) printers.update_printer( uuid=printer.uuid, client_props={ "version": printer.client_info.version, "connected": printer.client_info.connected, "access_level": printer.client_info.access_level, "api_key": printer.client_info.api_key, "webcam": printer.client_info.webcam, "plugins": printer.client_info.plugins, }, )
def printer_create(org_uuid): data = request.json if not data: return abort(make_response(jsonify(message="Missing payload"), 400)) uuid = guid.uuid4() ip = data.get("ip", None) port = data.get("port", None) hostname = data.get("hostname", None) name = data.get("name", None) api_key = data.get("api_key", None) protocol = data.get("protocol", "http") path = data.get("path", "") token = data.get("token", None) if token is not None and token != "": if not app.config.get("CLOUD_MODE"): return abort(make_response(jsonify(message="Missing token"), 400)) existing_network_client = network_clients.get_network_client_by_socket_token( token) if existing_network_client: existing_printer = printers.get_printer_by_network_client_uuid( org_uuid, existing_network_client.get("uuid")) if existing_printer is not None: return abort( make_response(jsonify(message="Printer exists"), 409)) path = "" hostname = "" ip = "" protocol = "" port = 0 else: if app.config.get("CLOUD_MODE"): return abort( make_response( jsonify( message= "Cannot add printer without a token in CLOUD_MODE"), 500, )) if ((not ip and not hostname) or not name or protocol not in ["http", "https"] or (hostname and re.match(r"^[0-9a-zA-Z.-]+\.local$", hostname) is None) or (ip and re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", ip) is None) or (port and re.match(r"^\d{0,5}$", str(port)) is None)): return abort( make_response( jsonify( message="Missing some network data about the printer"), 400)) if hostname and not ip: ip = network.get_avahi_address(hostname) if not ip: return abort( make_response( jsonify(message="Cannot resolve %s with mDNS" % hostname), 500)) if ip and not hostname: hostname = network.get_avahi_hostname(ip) existing_network_client = network_clients.get_network_client_by_props( hostname, ip, port, path) if existing_network_client: existing_printer = printers.get_printer_by_network_client_uuid( org_uuid, existing_network_client.get("uuid")) if existing_printer is not None: return abort( make_response(jsonify(message="Printer exists"), 409)) if not existing_network_client: existing_network_client = { "uuid": guid.uuid4(), "hostname": hostname, "client": "octoprint", # TODO make this more generic "protocol": protocol, "ip": ip, "port": port, "path": path, "token": token, } network_clients.add_network_client(**existing_network_client) printer = clients.get_printer_instance({ "uuid": uuid, "network_client_uuid": existing_network_client["uuid"], "organization_uuid": org_uuid, "name": name, "client": existing_network_client["client"], "protocol": existing_network_client["protocol"], "hostname": existing_network_client["hostname"], "ip": existing_network_client["ip"], "port": existing_network_client["port"], "path": existing_network_client["path"], "token": existing_network_client["token"], }) printer.add_api_key(api_key) printer.update_network_base() printer.sniff() printers.add_printer( uuid=uuid, network_client_uuid=existing_network_client["uuid"], organization_uuid=org_uuid, name=name, client=printer.client_name(), client_props={ "version": printer.client_info.version, "connected": printer.client_info.connected, "access_level": printer.client_info.access_level, "api_key": printer.client_info.api_key, "webcam": printer.client_info.webcam, "plugins": printer.client_info.plugins, }, ) # TODO cache webcam, job, status for a small amount of time in this client return jsonify(make_printer_response(printer, ["status", "webcam", "job"])), 201
def printer_create(): data = request.json if not data: return abort(make_response("", 400)) uuid = uuidmodule.uuid4() ip = data.get("ip", None) port = data.get("port", None) hostname = data.get("hostname", None) name = data.get("name", None) api_key = data.get("api_key", None) protocol = data.get("protocol", "http") if ((not ip and not hostname) or not name or protocol not in ["http", "https"] or (hostname and re.match(r"^[0-9a-zA-Z.-]+\.local$", hostname) is None) or (ip and re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", ip) is None) or (port and re.match(r"^\d{0,5}$", str(port)) is None)): return abort(make_response("", 400)) if hostname and not ip: ip = network.get_avahi_address(hostname) if not ip: return abort( make_response("Cannot resolve %s with mDNS" % hostname, 500)) if ip and not hostname: hostname = network.get_avahi_hostname(ip) if printers.get_printer_by_network_props(hostname, ip, port) is not None: return abort(make_response("", 409)) printer = clients.get_printer_instance({ "uuid": uuid, "hostname": hostname, "ip": ip, "port": port, "name": name, "protocol": protocol, "client": "octoprint", # TODO make this more generic }) printer.add_api_key(api_key) printer.sniff() printers.add_printer( uuid=uuid, name=name, hostname=hostname, ip=ip, port=port, protocol=printer.protocol, client=printer.client_name(), client_props={ "version": printer.client_info.version, "connected": printer.client_info.connected, "access_level": printer.client_info.access_level, "api_key": printer.client_info.api_key, "webcam": printer.webcam(), }, ) # TODO cache webcam, job, status for a small amount of time in client return jsonify(make_printer_response(printer, ["status", "webcam", "job"])), 201