aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbozo.kopic <bozo@kopic.xyz>2022-09-26 23:11:28 +0200
committerbozo.kopic <bozo@kopic.xyz>2022-09-26 23:11:28 +0200
commit99c4a3dcd0def97e979ca100a1f91a425fd02dd9 (patch)
tree288128203a5485e93579b89ff05726dce71d7275
parent8f60e0a1ba5d2402c14f6c6c99177500d5c83f63 (diff)
new version cleanup
-rw-r--r--Dockerfile (renamed from Dockerfile.heroku)11
-rw-r--r--README.rst8
-rw-r--r--VERSION2
-rw-r--r--heroku.yml7
-rw-r--r--requirements.pip.dev.txt2
-rw-r--r--requirements.pip.runtime.txt2
-rw-r--r--src_c/opcut.c12
-rw-r--r--src_doit/__init__.py9
-rw-r--r--src_doit/dist/__init__.py38
-rw-r--r--src_doit/dist/container/Dockerfile6
-rw-r--r--src_doit/dist/windows/opcut-server.cmd (renamed from src_doit/dist/windows/opcut-server.bat)0
-rw-r--r--src_doit/dist/windows/opcut.cmd (renamed from src_doit/dist/windows/opcut.bat)0
-rw-r--r--src_js/states.js2
-rw-r--r--src_py/opcut/common.py11
-rw-r--r--src_py/opcut/server.py33
15 files changed, 56 insertions, 87 deletions
diff --git a/Dockerfile.heroku b/Dockerfile
index 03ca85f..e01a1b2 100644
--- a/Dockerfile.heroku
+++ b/Dockerfile
@@ -1,15 +1,16 @@
-FROM python:3.9-slim-bullseye as opcut-base
+FROM python:3.10-slim-bullseye as opcut-base
WORKDIR /opcut
RUN apt update -qy && \
apt install -qy pkg-config gcc libcairo2-dev
FROM opcut-base as opcut-build
WORKDIR /opcut
-COPY . .
RUN apt install -qy nodejs yarnpkg git gcc-mingw-w64-x86-64-win32 && \
ln -sT /usr/bin/yarnpkg /usr/bin/yarn && \
- ln -sT /usr/bin/x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-cc && \
- pip install -qq -r requirements.pip.dev.txt && \
+ ln -sT /usr/bin/x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-cc
+COPY . .
+RUN pip install -qq -r requirements.pip.dev.txt && \
+ doit clean_all && \
doit
FROM opcut-base as opcut-run
@@ -17,3 +18,5 @@ WORKDIR /opcut
COPY --from=opcut-build /opcut/build/py/dist/*.whl .
RUN pip install -qq *.whl && \
rm *.whl
+EXPOSE 8080
+CMD ["/usr/local/bin/opcut", "server"]
diff --git a/README.rst b/README.rst
index ba5bb42..e262beb 100644
--- a/README.rst
+++ b/README.rst
@@ -1,7 +1,7 @@
opcut
=====
-`https://opcut.herokuapp.com/`
+`https://opcut.kopic.xyz/`_
`opcut` is cutting stock problem optimizer
(`https://en.wikipedia.org/wiki/Cutting_stock_problem`) utilizing multiple
@@ -14,6 +14,11 @@ panels and guillotine cuts (end-to-end cuts). This project includes:
Git repository is available at `<https://github.com/bozokopic/opcut.git>`_.
+Public instance `https://opcut.kopic.xyz/`_ is constrained with limited
+resources and should be used only for functionality evaluation purposes.
+In case of complex and repetitive calculations, please consider running
+self hosted instance.
+
Runtime requirements
--------------------
@@ -133,6 +138,7 @@ creates wheel package inside `build` directory.
TODO
----
+* ui svg rewrite
* unit tests
* changelog
* alternative hosting (https://opcut.herokuapp.com is shutting down)
diff --git a/VERSION b/VERSION
index 25a5afd..1d0ba9e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.4.0-dev
+0.4.0
diff --git a/heroku.yml b/heroku.yml
deleted file mode 100644
index 71420a4..0000000
--- a/heroku.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-build:
- docker:
- web:
- dockerfile: Dockerfile.heroku
- target: opcut-run
-run:
- web: opcut server --port $PORT
diff --git a/requirements.pip.dev.txt b/requirements.pip.dev.txt
index 33d4612..1efce28 100644
--- a/requirements.pip.dev.txt
+++ b/requirements.pip.dev.txt
@@ -1,3 +1,3 @@
-r requirements.pip.runtime.txt
-hat-doit ~= 0.11.3
+hat-doit ~= 0.11.4
diff --git a/requirements.pip.runtime.txt b/requirements.pip.runtime.txt
index 9d02fa1..16bcd3e 100644
--- a/requirements.pip.runtime.txt
+++ b/requirements.pip.runtime.txt
@@ -1,4 +1,4 @@
aiohttp ~= 3.8.1
hat-aio ~= 0.7.0
-hat-json ~= 0.5.8
+hat-json ~= 0.5.10
pycairo ~= 1.21.0
diff --git a/src_c/opcut.c b/src_c/opcut.c
index f60e236..5e4205a 100644
--- a/src_c/opcut.c
+++ b/src_c/opcut.c
@@ -131,7 +131,8 @@ static void free_unused_until(opcut_allocator_t *a, opcut_unused_t *unused,
}
-static inline double compare_item(opcut_params_t *params, size_t id1, size_t id2) {
+static inline double compare_item(opcut_params_t *params, size_t id1,
+ size_t id2) {
return params->items[id1].area - params->items[id2].area;
}
@@ -155,8 +156,8 @@ static inline void swap_ids(size_t *ids, size_t pos1, size_t pos2) {
}
-static size_t partition_item_ids(opcut_params_t *params,
- size_t *item_ids, ssize_t start, ssize_t stop) {
+static size_t partition_item_ids(opcut_params_t *params, size_t *item_ids,
+ ssize_t start, ssize_t stop) {
ssize_t pivot = start - 1;
for (size_t i = start; i < stop; ++i)
if (compare_item(params, item_ids[i], item_ids[stop]) >= 0)
@@ -168,7 +169,7 @@ static size_t partition_item_ids(opcut_params_t *params,
static void sort_item_ids(opcut_params_t *params, size_t *item_ids,
- ssize_t start, ssize_t stop) {
+ ssize_t start, ssize_t stop) {
if (start >= stop || stop < 0)
return;
@@ -215,7 +216,6 @@ static void insert_unused(opcut_unused_t **list, opcut_unused_t *el) {
}
-
static size_t *create_initial_item_ids(opcut_allocator_t *a,
opcut_params_t *params) {
if (!params->items_len)
@@ -307,8 +307,6 @@ static void calculate_fitness(opcut_params_t *params, result_t *result,
}
-
-
static inline bool item_fits_unused(opcut_item_t *item, opcut_unused_t *unused,
bool rotate) {
if (rotate && !item->can_rotate)
diff --git a/src_doit/__init__.py b/src_doit/__init__.py
index c25a42c..2639ffe 100644
--- a/src_doit/__init__.py
+++ b/src_doit/__init__.py
@@ -44,10 +44,11 @@ json_schema_repo_path = src_py_dir / 'opcut/json_schema_repo.json'
def task_clean_all():
"""Clean all"""
- return {'actions': [(common.rm_rf, [build_dir,
- ui_dir,
- json_schema_repo_path,
- src_py_dir / 'opcut/bin'])]}
+ return {'actions': [(common.rm_rf, [
+ build_dir,
+ ui_dir,
+ json_schema_repo_path,
+ *src_py_dir.glob('opcut/_libopcut.*')])]}
def task_wheel():
diff --git a/src_doit/dist/__init__.py b/src_doit/dist/__init__.py
index 6c490fa..51add24 100644
--- a/src_doit/dist/__init__.py
+++ b/src_doit/dist/__init__.py
@@ -6,8 +6,7 @@ from hat.doit import common
__all__ = ['task_dist',
- 'task_dist_windows',
- 'task_dist_container']
+ 'task_dist_windows']
package_path = Path(__file__).parent
@@ -18,9 +17,8 @@ cache_dir = Path('cache')
wheel_dir = build_dir / 'py/dist'
dist_dir = build_dir / 'dist'
dist_windows_dir = dist_dir / f'opcut-{common.get_version()}-windows'
-dist_container_dir = dist_dir / f'opcut-{common.get_version()}-container'
-win_python_url = 'https://www.python.org/ftp/python/3.9.7/python-3.9.7-embed-amd64.zip' # NOQA
+win_python_url = 'https://www.python.org/ftp/python/3.10.7/python-3.10.7-embed-amd64.zip' # NOQA
cache_win_python_path = cache_dir / win_python_url.split('/')[-1]
@@ -28,8 +26,7 @@ def task_dist():
"""Build distribution"""
return {'actions': None,
- 'task_dep': ['dist_windows',
- 'dist_container']}
+ 'task_dep': ['dist_windows']}
def task_dist_windows():
@@ -52,14 +49,14 @@ def task_dist_windows():
with zipfile.ZipFile(str(cache_win_python_path)) as f:
f.extractall(str(python_dir))
- python_lib_path = python_dir / 'python39.zip'
+ python_lib_path = python_dir / 'python310.zip'
python_lib_dir = python_dir / 'lib'
common.mkdir_p(dist_windows_dir / 'python/lib')
with zipfile.ZipFile(str(python_lib_path)) as f:
f.extractall(str(python_lib_dir))
common.rm_rf(python_lib_path)
- (python_dir / 'python39._pth').write_text(
+ (python_dir / 'python310._pth').write_text(
'..\\packages\n'
'lib\n'
'.\n'
@@ -87,28 +84,3 @@ def task_dist_windows():
return {'actions': [build],
'task_dep': ['wheel']}
-
-
-def task_dist_container():
- """Build container distribution"""
-
- def build():
- common.rm_rf(dist_container_dir)
- common.mkdir_p(dist_container_dir.parent)
- common.cp_r(package_path / 'container', dist_container_dir)
-
- for i in wheel_dir.glob('*.whl'):
- common.cp_r(i, dist_container_dir / i.name)
-
- name = f'opcut:{common.get_version()}'
- img_path = dist_dir / f'{dist_container_dir.name}.tar'
-
- subprocess.run(['podman', 'build', '-q', '-t', name, '.'],
- cwd=str(dist_container_dir),
- check=True)
-
- subprocess.run(['podman', 'save', '-q', '-o', str(img_path), name],
- check=True)
-
- return {'actions': [build],
- 'task_dep': ['wheel']}
diff --git a/src_doit/dist/container/Dockerfile b/src_doit/dist/container/Dockerfile
deleted file mode 100644
index 32978c1..0000000
--- a/src_doit/dist/container/Dockerfile
+++ /dev/null
@@ -1,6 +0,0 @@
-FROM python:3.9-slim-bullseye
-COPY *.whl .
-RUN apt update -qy && \
- apt install -qy pkg-config gcc libcairo2-dev && \
- pip install -qq *.whl && \
- rm *.whl
diff --git a/src_doit/dist/windows/opcut-server.bat b/src_doit/dist/windows/opcut-server.cmd
index 25ce4f9..25ce4f9 100644
--- a/src_doit/dist/windows/opcut-server.bat
+++ b/src_doit/dist/windows/opcut-server.cmd
diff --git a/src_doit/dist/windows/opcut.bat b/src_doit/dist/windows/opcut.cmd
index 68ae30a..68ae30a 100644
--- a/src_doit/dist/windows/opcut.bat
+++ b/src_doit/dist/windows/opcut.cmd
diff --git a/src_js/states.js b/src_js/states.js
index bc50eb3..5f1599d 100644
--- a/src_js/states.js
+++ b/src_js/states.js
@@ -1,7 +1,7 @@
export const main = {
form: {
- method: 'forward_greedy',
+ method: 'forward_greedy_native',
cut_width: 0.3,
min_initial_usage: true,
panels: [],
diff --git a/src_py/opcut/common.py b/src_py/opcut/common.py
index 5f6f26b..0bda8c5 100644
--- a/src_py/opcut/common.py
+++ b/src_py/opcut/common.py
@@ -1,5 +1,5 @@
-from pathlib import Path
import enum
+import importlib.resources
import typing
from hat import json
@@ -7,11 +7,10 @@ from hat import json
mm: float = 72 / 25.4
-package_path: Path = Path(__file__).parent
-
-json_schema_repo: json.SchemaRepository = json.SchemaRepository(
- json.json_schema_repo,
- json.SchemaRepository.from_json(package_path / 'json_schema_repo.json'))
+with importlib.resources.path(__package__, 'json_schema_repo.json') as _path:
+ json_schema_repo: json.SchemaRepository = json.SchemaRepository(
+ json.json_schema_repo,
+ json.SchemaRepository.from_json(_path))
class Panel(typing.NamedTuple):
diff --git a/src_py/opcut/server.py b/src_py/opcut/server.py
index 939222c..379a571 100644
--- a/src_py/opcut/server.py
+++ b/src_py/opcut/server.py
@@ -1,5 +1,6 @@
-from pathlib import Path
import asyncio
+import contextlib
+import importlib.resources
import subprocess
import sys
@@ -10,27 +11,29 @@ import aiohttp.web
from opcut import common
-static_dir: Path = common.package_path / 'ui'
-
-
async def create(host: str,
port: int
) -> 'Server':
server = Server()
server._async_group = aio.Group()
- app = aiohttp.web.Application()
- app.add_routes([
- aiohttp.web.get('/', server._root_handler),
- aiohttp.web.post('/calculate', server._calculate_handler),
- aiohttp.web.post('/generate', server._generate_handler),
- aiohttp.web.static('/', static_dir)])
-
- runner = aiohttp.web.AppRunner(app)
- await runner.setup()
- server.async_group.spawn(aio.call_on_cancel, runner.cleanup)
-
try:
+ exit_stack = contextlib.ExitStack()
+ static_dir = exit_stack.enter_context(
+ importlib.resources.path(__package__, 'ui'))
+ server.async_group.spawn(aio.call_on_cancel, exit_stack.close)
+
+ app = aiohttp.web.Application()
+ app.add_routes([
+ aiohttp.web.get('/', server._root_handler),
+ aiohttp.web.post('/calculate', server._calculate_handler),
+ aiohttp.web.post('/generate', server._generate_handler),
+ aiohttp.web.static('/', static_dir)])
+
+ runner = aiohttp.web.AppRunner(app)
+ await runner.setup()
+ server.async_group.spawn(aio.call_on_cancel, runner.cleanup)
+
site = aiohttp.web.TCPSite(runner=runner,
host=host,
port=port,