Skip to content

Commit d1acb08

Browse files
committed
Merge branch 'main' into beta
2 parents 08ea535 + d5ff98e commit d1acb08

12 files changed

Lines changed: 66 additions & 19 deletions

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y openscad
33
ADD . /case
44
RUN pip3 install -e /case/customizer/
55
ENV LOG_LEVEL=info
6+
ENV CUSTOMIZER_THREADS=6
67
ENV MODULE_NAME=obs_case_customizer.app

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ If you encounter any problems or have feature requests, please open an issue on
1010
GitHub. If you need assistance related to the contents of this repository,
1111
please ask in the [project forums](https://forum.openbikesensor.org).
1212

13+
## Cloning
14+
If you want to build your own case using openscad instead of using the
15+
readymade exports or if you want to start the customizer be aware
16+
that you need to clone including git submodules:
17+
18+
```
19+
git clone --recursive https://github.com/openbikesensor/OpenBikeSensor3DPrintableCase
20+
# ... or if you forgot the --recursive argument, you can run this in the
21+
# repository's directory later:
22+
git submodule update --init --recursive
23+
```
1324

1425
## About the files
1526

@@ -349,9 +360,11 @@ OpenSCAD is a special case of course: Here submitting `.stl` (for now) and the
349360

350361
### Customizer webservice
351362

352-
To run the customizer webservice you run it from the dockerfile:
363+
To run the customizer webservice you run it from the dockerfile (and be sure
364+
that you cloned the repo recursively before building the cointainer:
353365

354366
```
367+
git submodule update --init --recursive
355368
docker build . -t customizer
356369
docker run --rm -p 8001:80 customizer
357370
```

customizer/setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
packages=setuptools.find_packages(where="src"),
2525
python_requires=">=3.6",
2626
install_requires=[
27+
"aiofiles",
2728
"fastapi",
2829
"python-multipart",
2930
"jinja2",

customizer/src/obs_case_customizer/app.py

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from websockets.exceptions import ConnectionClosed
2525

2626
THREADS = int(os.environ.get('CUSTOMIZER_THREADS', 1))
27-
TIMEOUT = int(os.environ.get('CUSTOMIZER_JOB_TIMEOUT', 1200))
27+
TIMEOUT = int(os.environ.get('CUSTOMIZER_JOB_TIMEOUT', 2400))
2828
QUEUESIZE = int(os.environ.get('CUSTOMIZER_QUEUE_LENGTH', 20))
2929
TEMPLATEDIR = pkg_resources.resource_filename(__name__, 'templates')
3030

@@ -71,10 +71,19 @@ def field_type(entry, default_value):
7171
return "file"
7272
elif isinstance(default_value, bool):
7373
return "bool"
74+
if entry == "parts_list":
75+
return "parts_list"
7476
else:
7577
return "string"
7678

7779

80+
def all_parts():
81+
return [*ALL_PARTS, *[f"logo/CustomLogo/MainCase{l}-{inv}-{mn}"
82+
for l in ["", "Lid"]
83+
for inv in ["inverted", "normal"]
84+
for mn in ["main", "highlight"]]]
85+
86+
7887
templates.env.filters['field_type'] = field_type
7988

8089

@@ -90,9 +99,9 @@ def models(root):
9099

91100
async def queue_runner():
92101
while True:
93-
fun, arg = await queue.get()
94-
logging.info(f"running {arg}")
95-
await fun(arg)
102+
fun, kwargs = await queue.get()
103+
logging.info(f"running {kwargs}")
104+
await fun(**kwargs)
96105

97106

98107
@app.on_event('startup')
@@ -175,12 +184,10 @@ def package_to_zip(source: Path, target: Path):
175184
zf.write(name, zipped_name)
176185

177186

178-
async def run_job(uid, parts=None):
187+
async def run_job(uid=None, parts=None):
179188
global job_durations
180189
starttime = datetime.datetime.now()
181190

182-
if parts == None:
183-
parts = ALL_PARTS
184191
dir_to_work = Path(tempfile.gettempdir()) / uid
185192
logfile = dir_to_work / "log.txt"
186193
variables_file = dir_to_work / "variables.json"
@@ -192,6 +199,16 @@ async def run_job(uid, parts=None):
192199
"parts": parts,
193200
"status": "working",
194201
}
202+
203+
if parts == None:
204+
parts = ALL_PARTS
205+
if job_config.use_custom_logo:
206+
parts.extend([f"logo/CustomLogo/MainCase{l}-{inv}-{mn}"
207+
for l in ["", "Lid"]
208+
for inv in ["inverted", "normal"]
209+
for mn in ["main", "highlight"]])
210+
info["parts"] = parts
211+
195212
write_info_json = lambda: json.dump(info, info_file.open("wt"))
196213

197214
with tempfile.TemporaryDirectory() as temp:
@@ -202,13 +219,6 @@ async def run_job(uid, parts=None):
202219
await copy_build_files_to_build_dir(dir_to_work, temp, job_config.use_custom_logo)
203220

204221
try:
205-
if job_config.use_custom_logo:
206-
parts.extend([f"logo/CustomLogo/MainCase{l}-{inv}-{mn}"
207-
for l in ["", "Lid"]
208-
for inv in ["inverted", "normal"]
209-
for mn in ["main", "highlight"]])
210-
info["parts"] = parts
211-
write_info_json()
212222

213223
make_targets = [f'export/{name}.stl' for name in parts]
214224

@@ -282,6 +292,7 @@ async def _as_form(**data):
282292
@as_form
283293
class CustomVariables(BaseModel):
284294
use_custom_logo: bool = True
295+
fix_svg: bool = False
285296
MainCase_back_rider: bool = True
286297
MainCase_top_rider: bool = True
287298
MainCase_back_rider_cable: bool = True
@@ -313,7 +324,8 @@ class RunningJob(CustomVariables):
313324
def form_get(request: Request):
314325
# TODO: Switch to CustomVariables.schema for the generation of the <form>
315326
variables = CustomVariables()
316-
fields = [("main_case_logo_svg", ""), ("main_case_lid_logo_svg", ""), *variables.dict().items()]
327+
fields = [("main_case_logo_svg", ""), ("main_case_lid_logo_svg", ""), ("parts_list", all_parts()),
328+
*variables.dict().items()]
317329
return templates.TemplateResponse('customizer.html', context={'request': request, 'fields': fields})
318330

319331

@@ -371,7 +383,10 @@ async def jobstate(websocket: WebSocket, uid: uuid.UUID):
371383
async def form_post(request: Request,
372384
main_case_logo_svg: Optional[bytes] = File(None),
373385
main_case_lid_logo_svg: Optional[bytes] = File(None),
386+
parts_list: Optional[list] = None,
374387
variables: CustomVariables = Depends(CustomVariables.as_form)):
388+
if set(parts_list) - set(all_parts()):
389+
raise HTTPException(status_code=400, detail="Only valid parts can be generated")
375390
uid = str(uuid.uuid4())
376391
work_dir = Path(tempfile.gettempdir()) / uid
377392
logging.info(work_dir)
@@ -395,7 +410,7 @@ async def form_post(request: Request,
395410
variables_json_file.open("w").write(variables.json())
396411

397412
try:
398-
queue.put_nowait((run_job, uid))
413+
queue.put_nowait((run_job, dict(uid=uid, parts=parts_list)))
399414
except asyncio.QueueFull:
400415
return HTTPException(status_code=503, detail="Queue is full, please try again later")
401416

customizer/src/obs_case_customizer/templates/customizer.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@
3434
<input type="checkbox" {{'checked="checked"' if value else ''}} name="{{entry}}" id="{{entry}}" />
3535
{% elif ft == "file" %}
3636
<input type="file" name="{{entry}}" id="{{entry}}" accept="image/svg+xml"/>
37+
{% elif ft == "parts_list" %}
38+
<select name="parts_list" size="{{ value|length }}"multiple>
39+
{% for part in value %}
40+
<option value="{{part}}" selected>{{part}}</option>
41+
{% endfor %}
42+
</select>
3743
{% else %}
3844
<input type="text" title="{{entry}}" name="{{entry}}" id="{{entry}}" value="{{value}}"/>
3945
{% endif %}

lib/utils.scad

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,13 @@ module ScrewHoleM3(depth, head_depth=0, elongation=0) {
133133
elongation=elongation
134134
);
135135
}
136+
137+
module load_svg(filename) {
138+
// some SVG produce strange geometry. This is a bit slower but fixes the issues.
139+
if (fix_svg) {
140+
offset(delta = epsilon) import(filename);
141+
}
142+
else {
143+
import(filename);
144+
}
145+
}

src/MainCase/MainCase.scad

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ if (logo_generate_templates) {
577577
mirror([0, 1, 0])
578578
rotate([0, 0, -90])
579579
translate([0, -72-72, 0])
580-
import(str("../../logo/", logo_name, "/MainCase.svg"));
580+
load_svg(str("../../logo/", logo_name, "/MainCase.svg"));
581581
}
582582
}
583583

0 commit comments

Comments
 (0)