aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbozo.kopic <bozo@kopic.xyz>2022-06-26 17:28:49 +0200
committerbozo.kopic <bozo@kopic.xyz>2022-06-26 17:28:49 +0200
commit75cc60fd42c58cadc28f5eb4499f197604254aba (patch)
tree48513c9c59dd24207100fc2cf2c3118c8145dd72
parent7ae36a21d031c3d71e9015823c61380f88b0595d (diff)
WIP native implementation
-rw-r--r--CONTRIBUTING1
-rw-r--r--README.rst84
-rw-r--r--VERSION2
-rw-r--r--peru.yaml12
-rw-r--r--requirements.pip.runtime.txt6
-rw-r--r--schemas/opcut.yaml54
-rw-r--r--schemas/openapi.yaml13
-rw-r--r--src_js/common.js9
-rw-r--r--src_js/states.js1
-rw-r--r--src_js/vt.js13
-rw-r--r--src_py/opcut/calculate.py (renamed from src_py/opcut/csp.py)18
-rw-r--r--src_py/opcut/common.py4
-rw-r--r--src_py/opcut/generate.py (renamed from src_py/opcut/output.py)14
-rw-r--r--src_py/opcut/main.py229
-rw-r--r--src_py/opcut/server.py44
15 files changed, 312 insertions, 192 deletions
diff --git a/CONTRIBUTING b/CONTRIBUTING
new file mode 100644
index 0000000..1333ed7
--- /dev/null
+++ b/CONTRIBUTING
@@ -0,0 +1 @@
+TODO
diff --git a/README.rst b/README.rst
index 19c3161..8e893a7 100644
--- a/README.rst
+++ b/README.rst
@@ -37,26 +37,70 @@ Install
`https://github.com/bozokopic/opcut/releases`
-Run
----
+Usage
+-----
-Running server (default listening address http://0.0.0.0:8080)::
+`opcut` command is interface for execution of three distinct actions:
- $ opcut server
+ * `opcut calculate ...`
+
+ Calculation of cutting stock problem. Input parameters and result is
+ formated as JSON data (JSON, YAML or TOML).
+
+ * `opcut generate ...`
+
+ Generate output representation (SVG, PDF, ...) based on calculation
+ result.
+
+ * `opcut server ...`
+
+ Run HTTP server providing single-page web application interface and
+ OpenAPI interface.
+ (default listening address is http://0.0.0.0:8080).
+
+For additional command line arguments, run ``opcut --help`` or
+``opcut <action> --help``.
+
+
+`opcut calculate`
+'''''''''''''''''
+
+Example::
-Running command line utility::
+ $ opcut calculate --input-format yaml --output result.json << EOF
+ cut_width: 1
+ panels:
+ panel1:
+ width: 100
+ height: 100
+ items:
+ item1:
+ width: 10
+ height: 10
+ can_rotate: false
+ EOF
- $ opcut calculate ...
- $ opcut generate_output ...
-Additional command line arguments::
+`opcut generate`
+''''''''''''''''
- $ opcut --help
+Example::
+
+ $ opcut generate --output output.pdf result.json
+
+
+`opcut server`
+''''''''''''''
+
+Example::
+
+ $ opcut server
Development requirements
------------------------
+* C99 compiler (gcc, clang, ...)
* nodejs >=7
* yarn
@@ -80,28 +124,26 @@ Default task::
creates wheel package inside `build` directory.
-TODO
-----
-
-* global
-
- * create CONTRIBUTING
+JSON Schema
+-----------
-* optimizer
+.. literalinclude:: schemas/opcut.yaml
+ :language: yaml
- * add additional algorithms
- * evaluate python implementations and do native rewrites if needed
-* back-end
+OpenAPI
+-------
- * additional output formats
+.. literalinclude:: schemas/openapi.yaml
+ :language: yaml
License
-------
opcut - cutting stock problem optimizer
-Copyright (C) 2017-2022 Bozo Kopic
+
+Copyright (C) 2017-2022 Bozo Kopic
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/VERSION b/VERSION
index d15723f..25a5afd 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.3.2
+0.4.0-dev
diff --git a/peru.yaml b/peru.yaml
index 991025f..b28cdc3 100644
--- a/peru.yaml
+++ b/peru.yaml
@@ -1,18 +1,6 @@
imports:
- jsmn: deps/jsmn
- argparse: deps/argparse
hat-util: deps/hat-util
-git module jsmn:
- url: https://github.com/zserge/jsmn
- pick: jsmn.h
-
-git module argparse:
- url: https://github.com/cofyc/argparse
- pick:
- - argparse.c
- - argparse.h
-
git module hat-util:
url: https://github.com/hat-open/hat-util
rev: 7f56bb0572aee5a33654118838f999eec04fbd86
diff --git a/requirements.pip.runtime.txt b/requirements.pip.runtime.txt
index 4499a99..db3c695 100644
--- a/requirements.pip.runtime.txt
+++ b/requirements.pip.runtime.txt
@@ -1,6 +1,4 @@
aiohttp ~= 3.8.1
-appdirs ~= 1.4.4
-click ~= 8.1.3
-hat-aio ~= 0.6.0
-hat-json ~= 0.5.5
+hat-aio ~= 0.6.1
+hat-json ~= 0.5.6
pycairo ~= 1.21.0
diff --git a/schemas/opcut.yaml b/schemas/opcut.yaml
index 47e0a7f..8dadb93 100644
--- a/schemas/opcut.yaml
+++ b/schemas/opcut.yaml
@@ -4,6 +4,8 @@ id: "opcut://opcut.yaml#"
definitions:
params:
type: object
+ description: |
+ calculation input parameters independent of calculation method
required:
- cut_width
- panels
@@ -11,20 +13,30 @@ definitions:
properties:
cut_width:
type: number
+ description: |
+ width of the guillotine cut
min_initial_usage:
type: boolean
+ description: |
+ minimize usage of initial panels
panels:
type: object
+ description: |
+ input panels (keys represent unique panel identifiers)
patternProperties:
".+":
"$ref": "opcut://opcut.yaml#/definitions/panel"
items:
type: object
+ description: |
+ required items (keys represent unique item identifiers)
patternProperties:
".+":
"$ref": "opcut://opcut.yaml#/definitions/item"
result:
type: object
+ description: |
+ calculation result
required:
- params
- used
@@ -34,24 +46,36 @@ definitions:
"$ref": "opcut://opcut.yaml#"
used:
type: array
+ description: |
+ resulting panels associated with required items
items:
"$ref": "opcut://opcut.yaml#/definitions/used"
unused:
type: array
+ description: |
+ resulting unused panels
items:
"$ref": "opcut://opcut.yaml#/definitions/unused"
panel:
type: object
+ description: |
+ single input panel
required:
- width
- height
properties:
width:
type: number
+ description: |
+ panel's initial width
height:
type: number
+ description: |
+ panel's initial height
item:
type: object
+ description: |
+ single required item
required:
- width
- height
@@ -59,12 +83,20 @@ definitions:
properties:
width:
type: number
+ description: |
+ items's width
height:
type: number
+ description: |
+ items's height
can_rotate:
type: boolean
+ description: |
+ can item be rotated (is grain direction irrelevant)
used:
type: object
+ description: |
+ single resulting panels associated with required item
required:
- panel
- item
@@ -74,16 +106,28 @@ definitions:
properties:
panel:
type: string
+ description: |
+ input panel identifier
item:
type: string
+ description: |
+ matching required item identifier
x:
type: number
+ description: |
+ used panel location based on input panel's width offset
y:
type: number
+ description: |
+ used panel location based on input panel's height offset
rotate:
type: boolean
+ description: |
+ is resulting panel rotated
unused:
type: object
+ description: |
+ single unused resulting panel
required:
- panel
- width
@@ -93,12 +137,22 @@ definitions:
properties:
panel:
type: string
+ description: |
+ input panel identifier
width:
type: number
+ description: |
+ unused resulting panel's width
height:
type: number
+ description: |
+ unused resulting panel's height
x:
type: number
+ description: |
+ used panel location based on input panel's width offset
y:
type: number
+ description: |
+ used panel location based on input panel's height offset
...
diff --git a/schemas/openapi.yaml b/schemas/openapi.yaml
index 442f685..e459030 100644
--- a/schemas/openapi.yaml
+++ b/schemas/openapi.yaml
@@ -2,16 +2,11 @@
openapi: 3.1.0
info:
title: opcut
- version: 0.0.1
+ version: 0.0.2
paths:
'/calculate':
post:
parameters:
- - name: native
- in: query
- required: false
- schema:
- type: boolean
- name: method
in: query
required: true
@@ -19,6 +14,8 @@ paths:
enum:
- greedy
- forward_greedy
+ - greedy_native
+ - forward_greedy_native
requestBody:
content:
application/json:
@@ -34,10 +31,10 @@ paths:
content:
text/plain:
description: error message
- '/generate_output':
+ '/generate':
post:
parameters:
- - name: output_type
+ - name: output_format
in: query
required: true
schema:
diff --git a/src_js/common.js b/src_js/common.js
index 7d4213c..b489914 100644
--- a/src_js/common.js
+++ b/src_js/common.js
@@ -10,7 +10,7 @@ import * as states from './states';
const calculateUrl = URI.resolve(window.location.href, './calculate');
-const generateOutputUrl = URI.resolve(window.location.href, './generate_output');
+const generateUrl = URI.resolve(window.location.href, './generate');
let panelCounter = 0;
let itemCounter = 0;
@@ -20,9 +20,8 @@ export async function calculate() {
r.set('calculating', true);
try {
const method = r.get('form', 'method');
- const native = r.get('form', 'native');
const params = createCalculateParams();
- const res = await fetch(`${calculateUrl}?method=${method}&native=${native}`, {
+ const res = await fetch(`${calculateUrl}?method=${method}`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(params)
@@ -45,10 +44,10 @@ export async function calculate() {
}
-export async function generateOutput() {
+export async function generate() {
try {
const result = r.get('result');
- const res = await fetch(`${generateOutputUrl}?output_type=pdf`, {
+ const res = await fetch(`${generateUrl}?output_format=pdf`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(result)
diff --git a/src_js/states.js b/src_js/states.js
index efc31b9..bf3584e 100644
--- a/src_js/states.js
+++ b/src_js/states.js
@@ -4,7 +4,6 @@ export const main = {
method: 'forward_greedy',
cut_width: 0.3,
min_initial_usage: false,
- native: false,
panels: [],
items: []
},
diff --git a/src_js/vt.js b/src_js/vt.js
index b016018..84d80a0 100644
--- a/src_js/vt.js
+++ b/src_js/vt.js
@@ -62,7 +62,9 @@ function leftPanel() {
['label', 'Method'],
selectInput(r.get('form', 'method'),
[['forward_greedy', 'Forward greedy'],
- ['greedy', 'Greedy']],
+ ['greedy', 'Greedy'],
+ ['forward_greedy_native', 'Forward greedy (native)'],
+ ['greedy_native', 'Greedy (native)'],],
val => r.set(['form', 'method'], val)),
['label', 'Cut width'],
numberInput(r.get('form', 'cut_width'),
@@ -71,11 +73,7 @@ function leftPanel() {
['label'],
checkboxInput('Minimize initial panel usage',
r.get('form', 'min_initial_usage'),
- val => r.set(['form', 'min_initial_usage'], val)),
- ['label'],
- checkboxInput('Use native implementation (experimental)',
- r.get('form', 'native'),
- val => r.set(['form', 'native'], val))
+ val => r.set(['form', 'min_initial_usage'], val))
],
['div.content',
leftPanelPanels(),
@@ -308,7 +306,7 @@ function rightPanel() {
['div.toolbar',
['button', {
on: {
- click: common.generateOutput
+ click: common.generate
}},
['span.fa.fa-file-pdf-o'],
' PDF'
@@ -465,7 +463,6 @@ function textInput(value, validator, onChange) {
function numberInput(value, validator, onChange) {
-
return ['input', {
props: {
type: 'number',
diff --git a/src_py/opcut/csp.py b/src_py/opcut/calculate.py
index eb08314..7ae14ce 100644
--- a/src_py/opcut/csp.py
+++ b/src_py/opcut/calculate.py
@@ -3,8 +3,8 @@ import itertools
from opcut import common
-def calculate(params: common.Params,
- method: common.Method
+def calculate(method: common.Method,
+ params: common.Params
) -> common.Result:
"""Calculate cutting stock problem"""
unused = [common.Unused(panel=panel,
@@ -23,6 +23,12 @@ def calculate(params: common.Params,
elif method == common.Method.FORWARD_GREEDY:
return _calculate_forward_greedy(result)
+ elif method == common.Method.GREEDY_NATIVE:
+ return _calculate_greedy_native(result)
+
+ elif method == common.Method.FORWARD_GREEDY_NATIVE:
+ return _calculate_forward_greedy_native(result)
+
raise ValueError('unsupported method')
@@ -62,6 +68,14 @@ def _calculate_forward_greedy(result):
return result
+def _calculate_greedy_native(result):
+ raise NotImplementedError()
+
+
+def _calculate_forward_greedy_native(result):
+ raise NotImplementedError()
+
+
def _get_next_results(result):
selected_item = None
used_items = {used.item.id for used in result.used}
diff --git a/src_py/opcut/common.py b/src_py/opcut/common.py
index 9fbb7dd..5f6f26b 100644
--- a/src_py/opcut/common.py
+++ b/src_py/opcut/common.py
@@ -67,9 +67,11 @@ class OutputSettings(typing.NamedTuple):
class Method(enum.Enum):
GREEDY = 'greedy'
FORWARD_GREEDY = 'forward_greedy'
+ GREEDY_NATIVE = 'greedy_native'
+ FORWARD_GREEDY_NATIVE = 'forward_greedy_native'
-class OutputType(enum.Enum):
+class OutputFormat(enum.Enum):
PDF = 'pdf'
SVG = 'svg'
diff --git a/src_py/opcut/output.py b/src_py/opcut/generate.py
index 65f8096..82c8d7b 100644
--- a/src_py/opcut/output.py
+++ b/src_py/opcut/generate.py
@@ -6,18 +6,18 @@ import cairo
from opcut import common
-def generate_output(result: common.Result,
- output_type: common.OutputType,
- panel_id: typing.Optional[str] = None,
- settings: common.OutputSettings = common.OutputSettings()
- ) -> bytes:
+def generate(result: common.Result,
+ output_format: common.OutputFormat,
+ panel_id: typing.Optional[str] = None,
+ settings: common.OutputSettings = common.OutputSettings()
+ ) -> bytes:
"""Generate output"""
ret = io.BytesIO()
- if output_type == common.OutputType.PDF:
+ if output_format == common.OutputFormat.PDF:
surface_cls = cairo.PDFSurface
- elif output_type == common.OutputType.SVG:
+ elif output_format == common.OutputFormat.SVG:
surface_cls = cairo.SVGSurface
else:
diff --git a/src_py/opcut/main.py b/src_py/opcut/main.py
index b1d66a8..f09fe71 100644
--- a/src_py/opcut/main.py
+++ b/src_py/opcut/main.py
@@ -1,4 +1,5 @@
from pathlib import Path
+import argparse
import asyncio
import contextlib
import logging.config
@@ -7,11 +8,10 @@ import typing
from hat import aio
from hat import json
-import click
from opcut import common
-import opcut.csp
-import opcut.output
+import opcut.calculate
+import opcut.generate
import opcut.server
@@ -19,107 +19,153 @@ params_schema_id: str = 'opcut://opcut.yaml#/definitions/params'
result_schema_id: str = 'opcut://opcut.yaml#/definitions/result'
-def _doc_enum_values(enum_cls):
- return ', '.join(str(i.value) for i in enum_cls)
+def create_argument_parser() -> argparse.ArgumentParser:
+ parser = argparse.ArgumentParser()
+ subparsers = parser.add_subparsers(dest='action')
+
+ def enum_values(enum_cls):
+ return ', '.join(str(i.value) for i in enum_cls)
+
+ calculate = subparsers.add_parser('calculate')
+ calculate.add_argument(
+ '--method', metavar='METHOD', type=common.Method,
+ default=common.Method.FORWARD_GREEDY,
+ help=f"calculate method ({enum_values(common.Method)})")
+ calculate.add_argument(
+ '--input-format', metavar='FORMAT', type=json.Format, default=None,
+ help=f"input params format ({enum_values(json.Format)})")
+ calculate.add_argument(
+ '--output-format', metavar='FORMAT', type=json.Format, default=None,
+ help=f"output result format ({enum_values(json.Format)})")
+ calculate.add_argument(
+ '--output', metavar='PATH', type=Path, default=Path('-'),
+ help=f"output result file path or - for stdout ({result_schema_id})")
+ calculate.add_argument(
+ 'params', type=Path, default=Path('-'),
+ help=f"input params file path or - for stdin ({params_schema_id})")
+
+ generate = subparsers.add_parser('generate')
+ generate.add_argument(
+ '--input-format', metavar='FORMAT', type=json.Format, default=None,
+ help=f"input result format ({enum_values(json.Format)})")
+ generate.add_argument(
+ '--output-format', metavar='FORMAT', type=common.OutputFormat,
+ default=common.OutputFormat.PDF,
+ help=f"output format ({enum_values(common.OutputFormat)})")
+ generate.add_argument(
+ '--panel', metavar='PANEL', default=None,
+ help="panel identifier")
+ generate.add_argument(
+ '--output', metavar='PATH', type=Path, default=Path('-'),
+ help="output file path or - for stdout")
+ generate.add_argument(
+ 'result', type=Path, default=Path('-'),
+ help=f"input result file path or - for stdin ({result_schema_id})")
+
+ server = subparsers.add_parser('server')
+ server.add_argument(
+ '--host', metavar='HOST', default='0.0.0.0',
+ help="listening host name (default 0.0.0.0)")
+ server.add_argument(
+ '--port', metavar='PORT', type=int, default=8080,
+ help="listening TCP port (default 8080)")
+ server.add_argument(
+ '--log-level', metavar='LEVEL', default='info',
+ choices=['critical', 'error', 'warning', 'info', 'debug', 'notset'],
+ help="log level (default info)")
+
+ return parser
-@click.group()
def main():
- """Application main entry point"""
-
-
-@main.command()
-@click.option('--method',
- default=common.Method.FORWARD_GREEDY,
- type=common.Method,
- help=f"calculate method ({_doc_enum_values(common.Method)})")
-@click.option('--output',
- default=None,
- metavar='PATH',
- type=Path,
- help=f"result file path ({result_schema_id})")
-@click.argument('params',
- required=False,
- default=None,
- metavar='PATH',
- type=Path)
+ parser = create_argument_parser()
+ args = parser.parse_args()
+
+ if args.action == 'calculate':
+ calculate(method=args.method,
+ input_format=args.input_format,
+ output_format=args.output_format,
+ result_path=args.output,
+ params_path=args.params)
+
+ elif args.action == 'generate':
+ generate(input_format=args.input_format,
+ output_format=args.output_format,
+ panel_id=args.panel,
+ output_path=args.output,
+ result_path=args.result)
+
+ elif args.action == 'server':
+ server(host=args.host,
+ port=args.port,
+ log_level=args.log_level)
+
+ else:
+ raise ValueError('unsupported action')
+
+
def calculate(method: common.Method,
- output: typing.Optional[Path],
- params: typing.Optional[Path]):
- """Calculate result based on parameters JSON"""
- params = (json.decode_file(params) if params and params != Path('-')
- else json.decode_stream(sys.stdin))
- common.json_schema_repo.validate(params_schema_id, params)
- params = common.params_from_json(params)
+ input_format: typing.Optional[json.Format],
+ output_format: typing.Optional[json.Format],
+ result_path: Path,
+ params_path: Path):
+ if input_format is None and params_path == Path('-'):
+ input_format = json.Format.JSON
+
+ if output_format is None and result_path == Path('-'):
+ output_format = json.Format.JSON
+
+ params_json = (json.decode_stream(sys.stdin, input_format)
+ if params_path == Path('-')
+ else json.decode_file(params_path, input_format))
+
+ common.json_schema_repo.validate(params_schema_id, params_json)
+ params = common.params_from_json(params_json)
try:
- res = opcut.csp.calculate(params, method)
+ result = opcut.calculate.calculate(method=method,
+ params=params)
except common.UnresolvableError:
sys.exit(42)
- res = common.result_to_json(res)
+ result_json = common.result_to_json(result)
- if output and output != Path('-'):
- json.encode_file(res, output)
- else:
- json.encode_stream(res, sys.stdout)
-
-
-@main.command()
-@click.option('--output-type',
- default=common.OutputType.PDF,
- type=common.OutputType,
- help=f"output type ({_doc_enum_values(common.OutputType)})")
-@click.option('--panel',
- default=None,
- help="panel identifier")
-@click.option('--output',
- default=None,
- metavar='PATH',
- type=Path,
- help="result file path")
-@click.argument('result',
- required=False,
- default=None,
- metavar='PATH',
- type=Path)
-def generate_output(output_type: common.OutputType,
- panel: typing.Optional[str],
- output: typing.Optional[Path],
- result: typing.Optional[Path]):
- """Generate output based on result JSON"""
- result = (json.decode_file(result) if result and result != Path('-')
- else json.decode_stream(sys.stdin))
- common.json_schema_repo.validate(result_schema_id, result)
- result = common.result_from_json(result)
-
- out = opcut.output.generate_output(result, output_type, panel)
-
- if output and output != Path('-'):
- output.write_bytes(out)
+ if result_path == Path('-'):
+ json.encode_stream(result_json, sys.stdout, output_format)
else:
+ json.encode_file(result_json, result_path, output_format)
+
+
+def generate(input_format: typing.Optional[json.Format],
+ output_format: common.OutputFormat,
+ panel_id: typing.Optional[str],
+ output_path: Path,
+ result_path: Path):
+ if input_format is None and result_path == Path('-'):
+ input_format = json.Format.JSON
+
+ result_json = (json.decode_stream(sys.stdin, input_format)
+ if result_path == Path('-')
+ else json.decode_file(result_path, input_format))
+
+ common.json_schema_repo.validate(result_schema_id, result_json)
+ result = common.result_from_json(result_json)
+
+ data = opcut.generate.generate(result=result,
+ output_format=output_format,
+ panel_id=panel_id)
+
+ if output_path == Path('-'):
stdout, sys.stdout = sys.stdout.detach(), None
- stdout.write(out)
-
-
-@main.command()
-@click.option('--host',
- default='0.0.0.0',
- help="listening host name")
-@click.option('--port',
- default=8080,
- type=int,
- help="listening TCP port")
-@click.option('--log-level',
- default='INFO',
- type=click.Choice(['CRITICAL', 'ERROR', 'WARNING', 'INFO',
- 'DEBUG', 'NOTSET']),
- help="log level")
+ stdout.write(data)
+ else:
+ output_path.write_bytes(data)
+
+
def server(host: str,
port: int,
log_level: str):
- """Run server"""
logging.config.dictConfig({
'version': 1,
'formatters': {
@@ -129,14 +175,15 @@ def server(host: str,
'console': {
'class': 'logging.StreamHandler',
'formatter': 'console',
- 'level': log_level}},
+ 'level': log_level.upper()}},
'root': {
- 'level': log_level,
+ 'level': log_level.upper(),
'handlers': ['console']},
'disable_existing_loggers': False})
async def run():
- server = await opcut.server.create(host, port)
+ server = await opcut.server.create(host=host,
+ port=port)
try:
await server.wait_closing()
diff --git a/src_py/opcut/server.py b/src_py/opcut/server.py
index cd7d048..939222c 100644
--- a/src_py/opcut/server.py
+++ b/src_py/opcut/server.py
@@ -1,6 +1,5 @@
from pathlib import Path
import asyncio
-import platform
import subprocess
import sys
@@ -24,7 +23,7 @@ async def create(host: str,
app.add_routes([
aiohttp.web.get('/', server._root_handler),
aiohttp.web.post('/calculate', server._calculate_handler),
- aiohttp.web.post('/generate_output', server._generate_output_handler),
+ aiohttp.web.post('/generate', server._generate_handler),
aiohttp.web.static('/', static_dir)])
runner = aiohttp.web.AppRunner(app)
@@ -65,19 +64,18 @@ class Server(aio.Resource):
return aiohttp.web.Response(status=400,
text="Invalid request")
- native = request.query.get('native') == 'true'
method = common.Method(request.query['method'])
params = common.params_from_json(data)
try:
- result = await _calculate(native, method, params)
+ result = await _calculate(method, params)
return aiohttp.web.json_response(result)
except common.UnresolvableError:
return aiohttp.web.Response(status=400,
text='Result is not solvable')
- async def _generate_output_handler(self, request):
+ async def _generate_handler(self, request):
try:
data = await request.json()
common.json_schema_repo.validate(
@@ -87,16 +85,16 @@ class Server(aio.Resource):
return aiohttp.web.Response(status=400,
text="Invalid request")
- output_type = common.OutputType(request.query['output_type'])
+ output_format = common.OutputFormat(request.query['output_format'])
panel = request.query.get('panel')
result = common.result_from_json(data)
- output = await _generate_output(output_type, panel, result)
+ output = await _generate(output_format, panel, result)
- if output_type == common.OutputType.PDF:
+ if output_format == common.OutputType.PDF:
content_type = 'application/pdf'
- elif output_type == common.OutputType.SVG:
+ elif output_format == common.OutputType.SVG:
content_type = 'image/svg+xml'
else:
@@ -106,8 +104,9 @@ class Server(aio.Resource):
content_type=content_type)
-async def _calculate(native, method, params):
- args = [*_get_calculate_cmd(native), '--method', method.value]
+async def _calculate(method, params):
+ args = [sys.executable, '-m', 'opcut', 'calculate',
+ '--method', method.value]
stdint_data = json.encode(common.params_to_json(params)).encode('utf-8')
p = await asyncio.create_subprocess_exec(*args,
@@ -125,8 +124,9 @@ async def _calculate(native, method, params):
raise Exception(stderr_data.decode('utf-8'))
-async def _generate_output(output_type, panel, result):
- args = [*_get_generate_output_cmd(), '--output-type', output_type.value,
+async def _generate(output_format, panel, result):
+ args = [sys.executable, '-m', 'opcut', 'generate',
+ '--output-format', output_format.value,
*(['--panel', panel] if panel else [])]
stdint_data = json.encode(common.result_to_json(result)).encode('utf-8')
@@ -140,21 +140,3 @@ async def _generate_output(output_type, panel, result):
return stdout_data
raise Exception(stderr_data.decode('utf-8'))
-
-
-def _get_calculate_cmd(native):
- if native and sys.platform == 'linux':
- if platform.machine() == 'x86_64':
- return [str(common.package_path /
- 'bin/linux_x86_64-opcut-calculate')]
-
- elif native and sys.platform == 'win32':
- if platform.machine() == 'amd64':
- return [str(common.package_path /
- 'bin/windows_amd64-opcut-calculate.exe')]
-
- return [sys.executable, '-m', 'opcut', 'calculate']
-
-
-def _get_generate_output_cmd():
- return [sys.executable, '-m', 'opcut', 'generate-output']