aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbozokopic <bozo.kopic@gmail.com>2018-04-18 17:08:42 +0200
committerbozokopic <bozo.kopic@gmail.com>2018-04-18 17:08:42 +0200
commit254515b18cdc9cfa73afb690eeb7d7f2a1fc299b (patch)
treebcba7694f94dfcb4cb6d74221407c202cdbe37bd
parent71893908e6f39772422ae45cb01038ca6e042f93 (diff)
WIP generate output - pycairo implementation
-rw-r--r--requirements.txt2
-rw-r--r--schemas_json/messages.yaml5
-rw-r--r--src_js/opcut/common.js5
-rw-r--r--src_js/opcut/vt.js2
-rw-r--r--src_py/opcut/common.py13
-rw-r--r--src_py/opcut/main.py23
-rw-r--r--src_py/opcut/output.py206
-rw-r--r--src_py/opcut/server.py12
8 files changed, 159 insertions, 109 deletions
diff --git a/requirements.txt b/requirements.txt
index dd3a7ab..d458021 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,4 +3,4 @@ pyyaml
jsonschema
aiohttp
flake8
-reportlab
+pycairo
diff --git a/schemas_json/messages.yaml b/schemas_json/messages.yaml
index 44b8c3a..7a4d210 100644
--- a/schemas_json/messages.yaml
+++ b/schemas_json/messages.yaml
@@ -35,12 +35,17 @@ definitions:
required:
- result
- output_type
+ - panel
properties:
result:
"$ref": "opcut://result.yaml#"
output_type:
enum:
- PDF
+ panel:
+ type:
+ - "null"
+ - string
response:
type: object
required:
diff --git a/src_js/opcut/common.js b/src_js/opcut/common.js
index 323fc76..48ba8d0 100644
--- a/src_js/opcut/common.js
+++ b/src_js/opcut/common.js
@@ -21,10 +21,11 @@ export function calculate() {
}
-export function generateOutput(output_type) {
+export function generateOutput(output_type, panel) {
const msg = {
output_type: output_type,
- result: r.get('result')
+ result: r.get('result'),
+ panel: panel
};
send(generateOutputUrl, msg).then(msg => parseGenerateOutputResponse(msg, output_type));
}
diff --git a/src_js/opcut/vt.js b/src_js/opcut/vt.js
index 139ca33..a2c8c3b 100644
--- a/src_js/opcut/vt.js
+++ b/src_js/opcut/vt.js
@@ -149,7 +149,7 @@ function rightPanel() {
['div.toolbar',
['button', {
on: {
- click: () => common.generateOutput('PDF')
+ click: () => common.generateOutput('PDF', null)
}},
['span.fa.fa-file-pdf-o'],
' PDF'
diff --git a/src_py/opcut/common.py b/src_py/opcut/common.py
index 184537f..3f24109 100644
--- a/src_py/opcut/common.py
+++ b/src_py/opcut/common.py
@@ -3,6 +3,8 @@ import enum
from opcut import util
+mm = 72 / 25.4
+
Params = util.namedtuple(
'Params',
['cut_width', 'float'],
@@ -44,10 +46,21 @@ Unused = util.namedtuple(
['x', 'float'],
['y', 'float'])
+OutputSettings = util.namedtuple(
+ 'OutputSettings',
+ ['pagesize', 'Tuple[float,float]', (210 * mm, 297 * mm)],
+ ['margin_top', 'float', 10 * mm],
+ ['margin_bottom', 'float', 20 * mm],
+ ['margin_left', 'float', 10 * mm],
+ ['margin_right', 'float', 10 * mm])
+
Method = enum.Enum('Method', [
'GREEDY',
'FORWARD_GREEDY'])
+OutputType = enum.Enum('OutputType', [
+ 'PDF'])
+
class UnresolvableError(Exception):
"""Exception raised when Result is not solvable"""
diff --git a/src_py/opcut/main.py b/src_py/opcut/main.py
index 6758267..7e39212 100644
--- a/src_py/opcut/main.py
+++ b/src_py/opcut/main.py
@@ -77,15 +77,16 @@ def output(args):
args: command line argument
"""
+ if not args.output_path:
+ return
with open(args.result_path, 'r', encoding='utf-8') as f:
result_json_data = yaml.safe_load(f)
opcut.json_validator.validate(result_json_data, 'opcut://result.yaml#')
result = common.json_data_to_result(result_json_data)
-
- if args.output_pdf_path:
- pdf_bytes = opcut.output.generate_pdf(result)
- with open(args.output_pdf_path, 'wb') as f:
- f.write(pdf_bytes)
+ output_bytes = opcut.output.generate_output(result, args.output_type,
+ args.output_panel_id)
+ with open(args.output_path, 'wb') as f:
+ f.write(output_bytes)
def _create_parser():
@@ -129,8 +130,16 @@ def _create_parser():
help="calculate result file path "
"(specified by opcut://result.yaml#)")
p.add_argument(
- '--output-pdf', default=None, metavar='path',
- dest='output_pdf_path', help="optional PDF output file path")
+ '--output-type', dest='output_type', type=common.OutputType,
+ default=common.OutputType.PDF,
+ choices=list(map(lambda x: x.name, common.OutputType)),
+ help="output type (default PDF)")
+ p.add_argument(
+ '--output-panel', default=None, metavar='panel_id',
+ dest='output_panel_id', help="output panel id")
+ p.add_argument(
+ '--output', default=None, metavar='path', dest='output_path',
+ help="optional output file path")
return parser
diff --git a/src_py/opcut/output.py b/src_py/opcut/output.py
index 311585e..a66b90f 100644
--- a/src_py/opcut/output.py
+++ b/src_py/opcut/output.py
@@ -1,108 +1,130 @@
import io
-from reportlab.pdfgen import canvas
-from reportlab.lib.units import mm
+import cairo
-from opcut import util
+from opcut import common
-def generate_pdf(result, pagesize_mm=(210, 297),
- margin_top_mm=10, margin_bottom_mm=20,
- margin_left_mm=10, margin_right_mm=10):
- """Generate PDF output
+def generate_output(result, output_type, panel_id=None,
+ settings=common.OutputSettings()):
+ """Generate output
Args:
- result (opcut.common.Result): result
- pagesize (Tuple[float,float]): page size as (with, height) in mm
- margin_top_mm (float): margin top in mm
- margin_bottom_mm (float): margin bottom in mm
- margin_left_mm (float): margin left in mm
- margin_right_mm (float): margin right in mm
+ result (common.Result): result
+ output_type (common.OutputType): output type
+ panel_id (Optional[str]): panel id (None represents all panels)
+ settings (common.OutputSettings): output settings
Returns:
bytes
"""
- pagesize = tuple(map(lambda x: x * mm, pagesize_mm))
- margin = _Margin(top=margin_top_mm * mm,
- right=margin_right_mm * mm,
- bottom=margin_bottom_mm * mm,
- left=margin_left_mm * mm)
ret = io.BytesIO()
- c = canvas.Canvas(ret, pagesize=pagesize)
- c.setFillColorRGB(0.9, 0.9, 0.9)
- for panel in result.params.panels:
- _pdf_write_panel(c, pagesize, margin, result, panel)
- c.save()
+ with cairo.PDFSurface(ret, settings.pagesize[0],
+ settings.pagesize[1]) as surface:
+ ctx = cairo.Context(surface)
+ # TODO
return ret.getvalue()
-def generate_csv(result):
- """Generate CSV output
-
- Args:
- result (opcut.common.Result): result
-
- Returns:
- bytes
-
- """
- return b''
-
-
-_Margin = util.namedtuple('_Margin', 'top', 'right', 'bottom', 'left')
-
-
-def _pdf_write_panel(c, pagesize, margin, result, panel):
- if (panel.width / panel.height >
- (pagesize[0] - margin.left - margin.right) /
- (pagesize[1] - margin.top - margin.bottom)):
- scale = (
- (pagesize[0] - (margin.left + margin.right) * mm) /
- panel.width)
- else:
- scale = (
- (pagesize[1] - (margin.top + margin.bottom) * mm) /
- panel.height)
- width = panel.width * scale
- height = panel.height * scale
- x0 = ((pagesize[0] - width) * margin.left /
- (margin.left + margin.right))
- y0 = ((pagesize[1] - height) * margin.bottom /
- (margin.top + margin.bottom))
- c.setFillColorRGB(0.5, 0.5, 0.5)
- c.rect(x0, y0, width, height, stroke=1, fill=1)
- for used in result.used:
- if used.panel != panel:
- continue
- _pdf_write_used(c, x0, y0, scale, result, used)
- for unused in result.unused:
- if unused.panel != panel:
- continue
- _pdf_write_unused(c, x0, y0, scale, result, unused)
- c.setFillColorRGB(0, 0, 0)
- c.drawCentredString(pagesize[0] / 2, margin.bottom / 2,
- panel.id)
- c.showPage()
-
-
-def _pdf_write_used(c, x0, y0, scale, result, used):
- width = used.item.width * scale
- height = used.item.height * scale
- if used.rotate:
- width, height = height, width
- x = used.x * scale + x0
- y = (used.panel.height - used.y) * scale + y0 - height
- c.setFillColorRGB(1, 1, 1)
- c.rect(x, y, width, height, stroke=0, fill=1)
- c.setFillColorRGB(0, 0, 0)
- c.drawCentredString(x + width / 2, y + height / 2 - 6, used.item.id)
-
-
-def _pdf_write_unused(c, x0, y0, scale, result, unused):
- width = unused.width * scale
- height = unused.height * scale
- x = unused.x * scale + x0
- y = (unused.panel.height - unused.y) * scale + y0 - height
- c.setFillColorRGB(0.9, 0.9, 0.9)
- c.rect(x, y, width, height, stroke=0, fill=1)
+# def generate_pdf(result, pagesize_mm=(210, 297),
+# margin_top_mm=10, margin_bottom_mm=20,
+# margin_left_mm=10, margin_right_mm=10):
+# """Generate PDF output
+#
+# Args:
+# result (opcut.common.Result): result
+# pagesize (Tuple[float,float]): page size as (with, height) in mm
+# margin_top_mm (float): margin top in mm
+# margin_bottom_mm (float): margin bottom in mm
+# margin_left_mm (float): margin left in mm
+# margin_right_mm (float): margin right in mm
+#
+# Returns:
+# bytes
+#
+# """
+# pagesize = tuple(map(lambda x: x * mm, pagesize_mm))
+# margin = _Margin(top=margin_top_mm * mm,
+# right=margin_right_mm * mm,
+# bottom=margin_bottom_mm * mm,
+# left=margin_left_mm * mm)
+# ret = io.BytesIO()
+# c = canvas.Canvas(ret, pagesize=pagesize)
+# c.setFillColorRGB(0.9, 0.9, 0.9)
+# for panel in result.params.panels:
+# _pdf_write_panel(c, pagesize, margin, result, panel)
+# c.save()
+# return ret.getvalue()
+#
+#
+# def generate_csv(result):
+# """Generate CSV output
+#
+# Args:
+# result (opcut.common.Result): result
+#
+# Returns:
+# bytes
+#
+# """
+# return b''
+#
+#
+# _Margin = util.namedtuple('_Margin', 'top', 'right', 'bottom', 'left')
+#
+#
+# def _pdf_write_panel(c, pagesize, margin, result, panel):
+# if (panel.width / panel.height >
+# (pagesize[0] - margin.left - margin.right) /
+# (pagesize[1] - margin.top - margin.bottom)):
+# scale = (
+# (pagesize[0] - (margin.left + margin.right) * mm) /
+# panel.width)
+# else:
+# scale = (
+# (pagesize[1] - (margin.top + margin.bottom) * mm) /
+# panel.height)
+# width = panel.width * scale
+# height = panel.height * scale
+# x0 = ((pagesize[0] - width) * margin.left /
+# (margin.left + margin.right))
+# y0 = ((pagesize[1] - height) * margin.bottom /
+# (margin.top + margin.bottom))
+# c.setFillColorRGB(0.5, 0.5, 0.5)
+# c.rect(x0, y0, width, height, stroke=1, fill=1)
+# for used in result.used:
+# if used.panel != panel:
+# continue
+# _pdf_write_used(c, x0, y0, scale, result, used)
+# for unused in result.unused:
+# if unused.panel != panel:
+# continue
+# _pdf_write_unused(c, x0, y0, scale, result, unused)
+# c.setFillColorRGB(0, 0, 0)
+# c.drawCentredString(pagesize[0] / 2, margin.bottom / 2,
+# panel.id)
+# c.showPage()
+#
+#
+# def _pdf_write_used(c, x0, y0, scale, result, used):
+# width = used.item.width * scale
+# height = used.item.height * scale
+# if used.rotate:
+# width, height = height, width
+# x = used.x * scale + x0
+# y = (used.panel.height - used.y) * scale + y0 - height
+# c.setFillColorRGB(1, 1, 1)
+# c.rect(x, y, width, height, stroke=0, fill=1)
+# c.setFillColorRGB(0, 0, 0)
+# c.drawCentredString(x + width / 2, y + height / 2 - 6, used.item.id)
+#
+#
+# def _pdf_write_unused(c, x0, y0, scale, result, unused):
+# width = unused.width * scale
+# height = unused.height * scale
+# x = unused.x * scale + x0
+# y = (unused.panel.height - unused.y) * scale + y0 - height
+# c.setFillColorRGB(0.9, 0.9, 0.9)
+# c.rect(x, y, width, height, stroke=0, fill=1)
+#
diff --git a/src_py/opcut/server.py b/src_py/opcut/server.py
index 02fc161..60b2623 100644
--- a/src_py/opcut/server.py
+++ b/src_py/opcut/server.py
@@ -68,8 +68,10 @@ async def _generate_output_handler(executor, request):
opcut.json_validator.validate(
msg, 'opcut://messages.yaml#/definitions/generate_output/request')
result = common.json_data_to_result(msg['result'])
- output_type = msg['output_type']
- output = await executor(_ext_generate_output, result, output_type)
+ output_type = common.OutputType[msg['output_type']]
+ panel = msg['panel']
+ output = await executor(_ext_generate_output, result, output_type,
+ panel)
output_json_data = base64.b64encode(output).decode('utf-8')
except asyncio.CancelledError:
raise
@@ -82,7 +84,5 @@ def _ext_calculate(params, method):
return opcut.csp.calculate(params, method)
-def _ext_generate_output(result, output_type):
- if output_type == 'PDF':
- return opcut.output.generate_pdf(result)
- raise ValueError('output_type {} not supported'.format(output_type))
+def _ext_generate_output(result, output_type, panel):
+ return opcut.output.generate_output(result, output_type, panel)