Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented UPGRADE high lvl Connect command #814

Merged
merged 1 commit into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ repos:
# hooks:
# - id: pylint
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.0.269'
rev: 'v0.0.280'
hooks:
- id: ruff
args: [--fix]
Expand Down
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
- Add support to be running behind the proxy
* Hold the STOPPED and FINISHED state for at least 11s
* Fix MK2(.5)S SN being broken on multi-instance images
* Implemented UPGRADE high lvl Connect command

0.7.0 (2023-05-19)
* Fixed printer sends info about api key change to Connect after change
Expand Down
39 changes: 39 additions & 0 deletions prusa/link/printer_adapter/command_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import logging
from pathlib import Path
from re import Match
from subprocess import STDOUT, CalledProcessError, check_call, check_output
from sys import executable
from threading import Event
from time import time
from typing import Dict, Optional, Set
Expand Down Expand Up @@ -36,6 +38,21 @@
log = logging.getLogger(__name__)


def check_update_prusalink():
"""Run the bash script to check for PrusaLink updates and return output"""
return check_output(
[executable, '-m', 'pip', 'install', '--no-deps', '--dry-run',
'-U', 'prusalink'], stderr=STDOUT).decode()


def update_prusalink():
"""Run the bash script to update PrusaLink and return output"""
return check_output(
[executable, '-m', 'pip', 'install', '-U',
'--upgrade-strategy', 'only-if-needed', 'prusalink'],
stderr=STDOUT).decode()


class TryUntilState(Command):
"""A base for commands stop, pause and resume print"""
command_name = "pause/stop/resume print"
Expand Down Expand Up @@ -447,6 +464,28 @@ def waiter(sender, match):
"or our serial reading component broke..")


class UpgradeLink(Command):
"""Class for upgrading PrusaLink"""
command_name = "upgrade_link"

def _run_command(self):
try:
output = update_prusalink()

# No update available
if "Installing collected packages" not in output:
raise CommandFailed("No update available")

# New version was installed correctly - restart PrusaLink
check_call([executable, '-m', 'prusalink', 'restart'])
log.info("PrusaLink upgraded successfully")

# There's a problem with package installation, or it does not exist
except CalledProcessError as exception:
raise CommandFailed("There's a problem with package installation, "
"or it does not exist") from exception


class JobInfo(Command):
"""Class for sending/getting the job info"""
command_name = "job_info"
Expand Down
9 changes: 9 additions & 0 deletions prusa/link/printer_adapter/prusa_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
StartPrint,
StopPrint,
UnloadFilament,
UpgradeLink,
)
from .command_queue import CommandQueue, CommandResult
from .file_printer import FilePrinter
Expand Down Expand Up @@ -160,6 +161,7 @@ def __init__(self, cfg: Config, settings: Settings) -> None:
self.printer.set_handler(CommandType.GCODE, self.execute_gcode)
self.printer.set_handler(CommandType.PAUSE_PRINT, self.pause_print)
self.printer.set_handler(CommandType.RESET_PRINTER, self.reset_printer)
self.printer.set_handler(CommandType.UPGRADE, self.upgrade_link)
self.printer.set_handler(CommandType.RESUME_PRINT, self.resume_print)
self.printer.set_handler(CommandType.START_PRINT, self.start_print)
self.printer.set_handler(CommandType.STOP_PRINT, self.stop_print)
Expand Down Expand Up @@ -504,6 +506,13 @@ def reset_printer(self, caller: SDKCommand) -> CommandResult:
command = ResetPrinter(command_id=caller.command_id)
return self.command_queue.force_command(command)

def upgrade_link(self, caller: SDKCommand) -> CommandResult:
"""
Connects the command to upgrade link from CONNECT with its handler
"""
command = UpgradeLink(command_id=caller.command_id)
return self.command_queue.do_command(command)

def job_info(self, caller: SDKCommand) -> CommandResult:
"""
Connects the command to send job info from CONNECT with its handler
Expand Down
18 changes: 7 additions & 11 deletions prusa/link/web/main.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
"""Main pages and core API"""
import logging
import subprocess
from os import listdir
from os.path import basename, getmtime, getsize, join
from socket import gethostname
from subprocess import CalledProcessError, check_output
from sys import executable, version
from subprocess import CalledProcessError
from sys import version

from gcode_metadata import get_metadata
from pkg_resources import working_set # type: ignore
Expand All @@ -31,6 +30,8 @@
SetReady,
StartPrint,
StopPrint,
check_update_prusalink,
update_prusalink,
)
from ..printer_adapter.job import Job, JobState
from .lib.auth import REALM, check_api_digest, check_config
Expand Down Expand Up @@ -633,9 +634,8 @@ def api_update(req, env):

if env == "prusalink":
try:
output = check_output(
[executable, '-m', 'pip', 'install', '--no-deps', '--dry-run',
'-U', 'prusalink'], stderr=subprocess.STDOUT).decode()
output = check_update_prusalink()

# There's a problem with package installation, or it does not exist
except CalledProcessError as exception:
raise conditions.UnavailableUpdate(exception.output.decode()) \
Expand Down Expand Up @@ -666,11 +666,7 @@ def api_update_post(req, env):
# pylint: disable=unused-argument
if env == "prusalink":
try:
output = \
check_output(
[executable, '-m', 'pip', 'install', '-U',
'--upgrade-strategy', 'only-if-needed', 'prusalink'],
stderr=subprocess.STDOUT).decode()
output = update_prusalink()

# No update available
if "Installing collected packages" not in output:
Expand Down