From 5973ee7c135062d1faba6aedb002cf324d5cc268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Fri, 3 Jan 2025 14:55:25 +0100 Subject: [PATCH] feat: add print sizing --- crud.py | 14 +-- static/js/index.js | 2 +- static/js/public.js | 38 +++++-- tasks.py | 2 +- templates/pay2print/index.html | 8 +- templates/pay2print/photo.html | 179 ++++++++++++++++---------------- templates/pay2print/public.html | 2 +- views.py | 4 + views_api.py | 11 ++ 9 files changed, 153 insertions(+), 107 deletions(-) diff --git a/crud.py b/crud.py index fdd58cc..5d6f787 100644 --- a/crud.py +++ b/crud.py @@ -34,6 +34,13 @@ async def get_print(payment_hash: str) -> Optional[Print]: ) +async def delete_print(print_id: str) -> None: + await db.execute( + "DELETE FROM pay2print.print WHERE payment_hash = :id", + {"id": print_id}, + ) + + async def create_printer(user_id: str, data: CreatePrinter) -> Printer: printer = Printer( user_id=user_id, @@ -64,13 +71,6 @@ async def get_prints(printer_id: str) -> list[Print]: ) -async def delete_print(print_id: str) -> None: - await db.execute( - "DELETE FROM pay2print.print WHERE id = :id", - {"id": print_id}, - ) - - async def get_printer(printer_id: str) -> Optional[Printer]: return await db.fetchone( "SELECT * FROM pay2print.printer WHERE id = :id", diff --git a/static/js/index.js b/static/js/index.js index cb0bedb..ac45f15 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -98,7 +98,7 @@ window.app = Vue.createApp({ }, openFile(file_name) { const print = this.prints.find(print => print.file === file_name) - return `/pay2print/api/v1/file/${print.id}` + return `/pay2print/api/v1/file/${print.payment_hash}` }, getPrints(printer_id) { LNbits.api diff --git a/static/js/public.js b/static/js/public.js index 452c664..86e3e0d 100644 --- a/static/js/public.js +++ b/static/js/public.js @@ -16,7 +16,9 @@ window.app = Vue.createApp({ if (this.$refs.cameraStream) { navigator.mediaDevices .getUserMedia({ - video: {FacingMode: {exact: 'environment'}}, + video: { + FacingMode: 'user' + }, audio: false }) .then(stream => { @@ -32,15 +34,39 @@ window.app = Vue.createApp({ } }, methods: { + mmToPx(mm) { + const dpi = 300 + return Math.floor((mm * dpi) / 25.4) + }, takePicture() { this.picture = true this.webcam = false this.$refs.cameraStream.style.display = 'none' - this.$refs.canvas.width = this.$refs.cameraStream.videoWidth - this.$refs.canvas.height = this.$refs.cameraStream.videoHeight - this.$refs.canvas - .getContext('2d') - .drawImage(this.$refs.cameraStream, 0, 0) + const targetWidth = this.mmToPx(width) + const targetHeight = this.mmToPx(height) + this.$refs.canvas.width = targetWidth + this.$refs.canvas.height = targetHeight + const originalWidth = this.$refs.cameraStream.videoWidth + const originalHeight = this.$refs.cameraStream.videoHeight + const hRatio = targetWidth / originalWidth + const vRatio = targetHeight / originalHeight + const ratio = Math.min(hRatio, vRatio) + const centerShift_x = (targetWidth - originalWidth * ratio) / 2 + const centerShift_y = (targetHeight - originalHeight * ratio) / 2 + const ctx = this.$refs.canvas.getContext('2d') + ctx.fillStyle = '#fff' + ctx.fillRect(0, 0, targetWidth, targetHeight) + ctx.drawImage( + this.$refs.cameraStream, + 0, + 0, + originalWidth, + originalHeight, + centerShift_x, + centerShift_y, + originalWidth * ratio, + originalHeight * ratio + ) }, uploadPicture() { this.$refs.canvas.toBlob(blob => { diff --git a/tasks.py b/tasks.py index d6c1504..433c37d 100644 --- a/tasks.py +++ b/tasks.py @@ -29,4 +29,4 @@ async def on_invoice_paid(payment: Payment) -> None: try: await print_service(_print, printer) except Exception as exc: - logger.error(f"Error printing {_print.id}: {exc}") + logger.error(f"Error printing {_print.payment_hash}: {exc}") diff --git a/templates/pay2print/index.html b/templates/pay2print/index.html index 235de07..e180521 100644 --- a/templates/pay2print/index.html +++ b/templates/pay2print/index.html @@ -39,14 +39,14 @@ dense v-model.trim="printerDialog.data.width" type="text" - label="Width *" + label="Width (mm) *" >
Prints flat dense size="xs" - @click="openPrint(props.row.id)" + @click="openPrint(props.row.payment_hash)" target="_blank" icon="print" color="primary" @@ -241,7 +241,7 @@
Prints
flat dense size="xs" - @click="deletePrint(props.row.id)" + @click="deletePrint(props.row.payment_hash)" icon="cancel" color="pink" > diff --git a/templates/pay2print/photo.html b/templates/pay2print/photo.html index 86e4d34..102bf12 100644 --- a/templates/pay2print/photo.html +++ b/templates/pay2print/photo.html @@ -2,101 +2,106 @@ {% endblock %} {% block footer %}{% endblock %} {% block page_container %} - - -

- Make a photo, upload and pay to print! -

-

- Take picture - Upload and pay - Cancel -
- -

- Device does not support camera! -

-

- - +

+ Make a photo, upload and pay to print! +

+

+ Take picture -

Pay this invoice to print!

- - Copy invoice - Reset - -
- Upload and pay
-

- - Invoice paid, document is printing! -

-
- -
- Reset - - - + Cancel +
+ +

+ Device does not support camera! +

+

+ +
+

Pay this invoice to print!

+ + Copy invoice + Reset + +
+
+

+ + Invoice paid, document is printing! +

+
+ +
+ Reset + +
{% endblock %} {% block scripts %} {% endblock %} diff --git a/templates/pay2print/public.html b/templates/pay2print/public.html index 8bfc2e0..2ba4a95 100644 --- a/templates/pay2print/public.html +++ b/templates/pay2print/public.html @@ -13,7 +13,7 @@

multiple="false" field-name="file" @uploaded="uploaded" - url="uploadUrl" + :url="uploadUrl" > UploadPayment: ) +@pay2print_ext_api.delete( + "/print/{print_id}", dependencies=[Depends(require_admin_key)] +) +async def api_delete_print(print_id: str) -> None: + _print = await get_print(print_id) + if not _print: + raise HTTPException(HTTPStatus.NOT_FOUND, "Print not found.") + await delete_print(print_id) + + @pay2print_ext_api.get("/file/{print_id}", dependencies=[Depends(check_user_exists)]) async def api_show_file(print_id: str) -> FileResponse: _print = await get_print(print_id)