Add & use "octoprint analysis gcode" subcommand
That should solve any weird import issues we have when running gcodeInterpreter.py directly (and hence putting octoprint.util as first entry into the python path, causing potential issues with imported modules such as yaml to catch the octoprint.util.platform module instead of the actual python platform module). See reported problem with that by @CapnBry in #2095
This commit is contained in:
parent
79f7a5a1e7
commit
c84e199e87
5 changed files with 84 additions and 85 deletions
7
src/octoprint/__main__.py
Normal file
7
src/octoprint/__main__.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env python2
|
||||
# coding=utf-8
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
if __name__ == "__main__":
|
||||
import octoprint
|
||||
octoprint.main()
|
||||
|
|
@ -135,9 +135,10 @@ from .plugins import plugin_commands
|
|||
from .dev import dev_commands
|
||||
from .client import client_commands
|
||||
from .config import config_commands
|
||||
from .analysis import analysis_commands
|
||||
|
||||
@click.group(name="octoprint", invoke_without_command=True, cls=click.CommandCollection,
|
||||
sources=[server_commands, plugin_commands, dev_commands, client_commands, config_commands])
|
||||
sources=[server_commands, plugin_commands, dev_commands, client_commands, config_commands, analysis_commands])
|
||||
@standard_options()
|
||||
@legacy_options
|
||||
@click.version_option(version=octoprint.__version__, allow_from_autoenv=False)
|
||||
|
|
|
|||
73
src/octoprint/cli/analysis.py
Normal file
73
src/octoprint/cli/analysis.py
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
# coding=utf-8
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
||||
__copyright__ = "Copyright (C) 2017 The OctoPrint Project - Released under terms of the AGPLv3 License"
|
||||
|
||||
import click
|
||||
|
||||
#~~ "octoprint util" commands
|
||||
|
||||
@click.group()
|
||||
def analysis_commands():
|
||||
pass
|
||||
|
||||
@analysis_commands.group(name="analysis")
|
||||
def util():
|
||||
"""Analysis tools."""
|
||||
pass
|
||||
|
||||
|
||||
@util.command(name="gcode")
|
||||
@click.option("--throttle", "throttle", type=float, default=None)
|
||||
@click.option("--throttle-lines", "throttle_lines", type=int, default=None)
|
||||
@click.option("--speed-x", "speedx", type=float, default=6000)
|
||||
@click.option("--speed-y", "speedy", type=float, default=6000)
|
||||
@click.option("--speed-z", "speedz", type=float, default=300)
|
||||
@click.option("--offset", "offset", type=(float, float), multiple=True)
|
||||
@click.option("--max-t", "maxt", type=int, default=10)
|
||||
@click.option("--g90-extruder", "g90_extruder", is_flag=True)
|
||||
@click.option("--progress", "progress", is_flag=True)
|
||||
@click.argument("path", type=click.Path())
|
||||
def gcode_command(path, speedx, speedy, speedz, offset, maxt, throttle, throttle_lines, g90_extruder, progress):
|
||||
"""Runs a GCODE file analysis."""
|
||||
|
||||
import time
|
||||
import yaml
|
||||
from octoprint.util.gcodeInterpreter import gcode
|
||||
|
||||
throttle_callback = None
|
||||
if throttle:
|
||||
def throttle_callback(filePos, readBytes):
|
||||
if filePos % throttle_lines == 0:
|
||||
# only apply throttle every $throttle_lines lines
|
||||
time.sleep(throttle)
|
||||
|
||||
offsets = offset
|
||||
if offsets is None:
|
||||
offsets = []
|
||||
elif isinstance(offset, tuple):
|
||||
offsets = list(offsets)
|
||||
offsets = [(0, 0)] + offsets
|
||||
if len(offsets) < maxt:
|
||||
offsets += [(0, 0)] * (maxt - len(offsets))
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
progress_callback = None
|
||||
if progress:
|
||||
def progress_callback(percentage):
|
||||
click.echo("PROGRESS:{}".format(percentage))
|
||||
interpreter = gcode(progress_callback=progress_callback)
|
||||
|
||||
interpreter.load(path,
|
||||
speedx=speedx,
|
||||
speedy=speedy,
|
||||
offsets=offsets,
|
||||
throttle=throttle_callback,
|
||||
max_extruders=maxt,
|
||||
g90_extruder=g90_extruder)
|
||||
|
||||
click.echo("DONE:{}s".format(time.time() - start_time))
|
||||
click.echo("RESULTS:")
|
||||
click.echo(yaml.safe_dump(interpreter.get_result(), default_flow_style=False, indent=" ", allow_unicode=True))
|
||||
|
|
@ -324,8 +324,8 @@ class GcodeAnalysisQueue(AbstractAnalysisQueue):
|
|||
speedy = self._current.printer_profile["axes"]["y"]["speed"]
|
||||
offsets = self._current.printer_profile["extruder"]["offsets"]
|
||||
|
||||
interpreter = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "util", "gcodeInterpreter.py"))
|
||||
command = [sys.executable, interpreter, "--speed-x={}".format(speedx), "--speed-y={}".format(speedy),
|
||||
command = [sys.executable, "-m", "octoprint", "analysis", "gcode",
|
||||
"--speed-x={}".format(speedx), "--speed-y={}".format(speedy),
|
||||
"--max-t={}".format(max_extruders), "--throttle={}".format(throttle),
|
||||
"--throttle-lines={}".format(throttle_lines)]
|
||||
for offset in offsets[1:]:
|
||||
|
|
|
|||
|
|
@ -512,85 +512,3 @@ def getCodeFloat(line, code):
|
|||
except:
|
||||
return None
|
||||
|
||||
if __name__ == "__main__":
|
||||
import click
|
||||
import time
|
||||
import yaml
|
||||
import sys
|
||||
|
||||
@click.command()
|
||||
@click.option("--throttle", "throttle", type=float, default=None)
|
||||
@click.option("--throttle-lines", "throttle_lines", type=int, default=None)
|
||||
@click.option("--speed-x", "speedx", type=float, default=6000)
|
||||
@click.option("--speed-y", "speedy", type=float, default=6000)
|
||||
@click.option("--speed-z", "speedz", type=float, default=300)
|
||||
@click.option("--offset", "offset", type=(float, float), multiple=True)
|
||||
@click.option("--max-t", "maxt", type=int, default=10)
|
||||
@click.option("--g90-extruder", "g90_extruder", is_flag=True)
|
||||
@click.option("--progress", "progress", is_flag=True)
|
||||
@click.argument("path", type=click.Path())
|
||||
def main(path, speedx, speedy, speedz, offset, maxt, throttle, throttle_lines, g90_extruder, progress):
|
||||
throttle_callback = None
|
||||
if throttle:
|
||||
def throttle_callback(filePos, readBytes):
|
||||
if filePos % throttle_lines == 0:
|
||||
# only apply throttle every $throttle_lines lines
|
||||
time.sleep(throttle)
|
||||
|
||||
offsets = offset
|
||||
if offsets is None:
|
||||
offsets = []
|
||||
elif isinstance(offset, tuple):
|
||||
offsets = list(offsets)
|
||||
offsets = [(0, 0)] + offsets
|
||||
if len(offsets) < maxt:
|
||||
offsets += [(0, 0)] * (maxt - len(offsets))
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
progress_callback = None
|
||||
if progress:
|
||||
def progress_callback(percentage):
|
||||
print("PROGRESS:{}".format(percentage))
|
||||
interpreter = gcode(progress_callback=progress_callback)
|
||||
|
||||
interpreter.load(path,
|
||||
speedx=speedx,
|
||||
speedy=speedy,
|
||||
offsets=offsets,
|
||||
throttle=throttle_callback,
|
||||
max_extruders=maxt,
|
||||
g90_extruder=g90_extruder)
|
||||
|
||||
print("DONE:{}s".format(time.time() - start_time))
|
||||
print("RESULTS:")
|
||||
print(yaml.safe_dump(interpreter.get_result(), default_flow_style=False, indent=" ", allow_unicode=True))
|
||||
|
||||
# os args are gained differently on win32
|
||||
try:
|
||||
from click.utils import get_os_args
|
||||
args = get_os_args()
|
||||
except ImportError:
|
||||
# for whatever reason we are running an older Click version?
|
||||
args = sys.argv[1:]
|
||||
|
||||
if len(args) >= len(sys.argv):
|
||||
# Now some ugly preprocessing of our arguments starts. We have a somewhat difficult situation on our hands
|
||||
# here if we are running under Windows and want to be able to handle utf-8 command line parameters (think
|
||||
# plugin parameters such as names or something, e.g. for the "dev plugin:new" command) while at the same
|
||||
# time also supporting sys.argv rewriting for debuggers etc (e.g. PyCharm).
|
||||
#
|
||||
# So what we try to do here is solve this... Generally speaking, sys.argv and whatever Windows returns
|
||||
# for its CommandLineToArgvW win32 function should have the same length. If it doesn't however and
|
||||
# sys.argv is shorter than the win32 specific command line arguments, obviously stuff was cut off from
|
||||
# sys.argv which also needs to be cut off of the win32 command line arguments.
|
||||
#
|
||||
# So this is what we do here.
|
||||
|
||||
# -1 because first entry is the script that was called
|
||||
sys_args_length = len(sys.argv) - 1
|
||||
|
||||
# cut off stuff from the beginning
|
||||
args = args[-1 * sys_args_length:] if sys_args_length else []
|
||||
|
||||
main(args=args, prog_name="octoprint-gcode-analysis")
|
||||
|
|
|
|||
Loading…
Reference in a new issue