Esempio n. 1
0
 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"
     )
Esempio n. 2
0
 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)
Esempio n. 3
0
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(),
        )
Esempio n. 4
0
 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)
Esempio n. 5
0
 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)
Esempio n. 6
0
 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")
Esempio n. 7
0
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,
        },
    )
Esempio n. 8
0
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,
        },
    )
Esempio n. 9
0
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
Esempio n. 10
0
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