Skip to content

Commit

Permalink
feat: add text to print
Browse files Browse the repository at this point in the history
  • Loading branch information
dni committed Jan 3, 2025
1 parent 5973ee7 commit dc52a1f
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 23 deletions.
17 changes: 8 additions & 9 deletions static/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ window.app = Vue.createApp({
printsTable: {
columns: [
{
name: 'file',
name: 'payment_hash',
align: 'left',
label: 'file',
field: 'file'
label: 'payment_hash',
field: 'payment_hash'
},
{
name: 'id',
name: 'file',
align: 'left',
label: 'id',
field: 'id'
label: 'file',
field: 'file'
},
{
name: 'print_status',
Expand Down Expand Up @@ -96,9 +96,8 @@ window.app = Vue.createApp({
this.printerDialog.data = {...printer}
this.printerDialog.show = true
},
openFile(file_name) {
const print = this.prints.find(print => print.file === file_name)
return `/pay2print/api/v1/file/${print.payment_hash}`
openFile(payment_hash) {
return `/pay2print/api/v1/file/${payment_hash}`
},
getPrints(printer_id) {
LNbits.api
Expand Down
22 changes: 22 additions & 0 deletions static/js/public.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ window.app = Vue.createApp({
paid: false,
webcam: false,
picture: null,
message: '',
webcamError: ''
}
},
Expand Down Expand Up @@ -68,6 +69,27 @@ window.app = Vue.createApp({
originalHeight * ratio
)
},
uploadText() {
if (this.message.length === 0) return
const blob = new Blob([this.message], {type: 'plain/text'})
const formData = new FormData()
formData.append('file', blob, 'message.txt')
axios
.post(this.uploadUrl, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(response => {
this.invoice = response.data.payment_request
this.onPaid(response.data.payment_hash)
Quasar.Notify.create({
color: 'positive',
message: 'Text uploaded successfully'
})
})
.catch(LNbits.utils.notifyApiError)
},
uploadPicture() {
this.$refs.canvas.toBlob(blob => {
const formData = new FormData()
Expand Down
37 changes: 26 additions & 11 deletions templates/pay2print/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,16 @@ <h5 class="text-subtitle1 q-my-none">Printers</h5>
>
<q-tooltip>Public Photo Page</q-tooltip>
</q-btn>
<q-btn
flat
dense
size="xs"
icon="text_fields"
color="secondary"
:href="`/pay2print/text/${props.row.id}`"
>
<q-tooltip>Public Text Page</q-tooltip>
</q-btn>
</q-td>
<q-td
v-for="col in props.cols"
Expand Down Expand Up @@ -208,6 +218,7 @@ <h5 class="text-subtitle1 q-my-none">Prints</h5>
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th style="width: 2%"></q-th>
<q-th style="width: 2%"></q-th>
<q-th style="width: 2%"></q-th>
<q-th
Expand All @@ -223,6 +234,19 @@ <h5 class="text-subtitle1 q-my-none">Prints</h5>

<template v-slot:body="props">
<q-tr :props="props">
<q-td>
<q-btn
flat
dense
size="xs"
:href="openFile(props.row.payment_hash)"
target="_blank"
icon="download"
color="primary"
>
<q-tooltip>Download</q-tooltip>
</q-btn>
</q-td>
<q-td>
<q-btn
flat
Expand All @@ -231,7 +255,7 @@ <h5 class="text-subtitle1 q-my-none">Prints</h5>
@click="openPrint(props.row.payment_hash)"
target="_blank"
icon="print"
color="primary"
color="secondary"
>
<q-tooltip>Print</q-tooltip>
</q-btn>
Expand All @@ -254,16 +278,7 @@ <h5 class="text-subtitle1 q-my-none">Prints</h5>
:props="props"
auto-width
>
<div v-if="col.name === 'file'">
<q-btn
color="primary"
size="sm"
:href="openFile(col.value)"
target="_blank"
v-text="col.value"
></q-btn>
</div>
<div v-else v-text="col.value"></div>
<div v-text="col.value"></div>
</q-td>
</q-tr>
</template>
Expand Down
82 changes: 82 additions & 0 deletions templates/pay2print/text.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{% extends "public.html" %} {% block toolbar_title %} Printer {{ printer_id }}
{% endblock %} {% block footer %}{% endblock %} {% block page_container %}
<q-page-container>
<q-page>
<q-card class="q-mt-md">
<q-card-section v-if="invoice == null" class="q-mb-sm text-center">
<h2 class="text-h5">
Write a message to print
<p v-text="invoiceAmount"></p>
</h2>
<q-input
v-model="message"
label="Message"
type="text"
length="100"
dense
outlined
class="q-mb-md"
></q-input>
<q-btn
icon="cloud_upload"
@click="uploadText()"
size="1em"
color="primary"
class="q-mb-xs q-mt-sm cursor-pointer"
:disable="message == null || message.length == 0"
>Upload and pay</q-btn
>
</q-card-section>
<q-card-section
v-if="invoice != null && paid == false"
class="q-mb-sm text-center"
>
<h2 class="text-h6">Pay this invoice to print!</h2>
<lnbits-qrcode :value="invoice"></lnbits-qrcode>
<q-btn
icon="content_copy"
@click="copyText(invoice)"
size="1em"
color="primary"
class="q-mb-xs q-mt-sm cursor-pointer"
>Copy invoice</q-btn
>
<q-btn
icon="refresh"
@click="reset()"
size="1em"
color="secondary"
class="q-ml-md q-mb-xs q-mt-sm cursor-pointer"
>Reset
</q-btn>
</q-card-section>
<q-card-section
v-if="invoice != null && paid == true"
class="q-mb-sm text-center"
>
<h2 class="text-h6">
<q-icon name="done" size="3em" color="green"></q-icon>
Invoice paid, printing!
</h2>
<div>
<q-icon name="print" size="3em" color="grey"></q-icon>
</div>
<q-btn
icon="refresh"
@click="reset()"
size="1em"
color="secondary"
class="q-mt-sm q-mb-xs cursor-pointer"
>Reset
</q-btn>
</q-card-section>
</q-card>
</q-page>
</q-page-container>
{% endblock %} {% block scripts %}
<script>
const amount = {{ amount }};
const printer_id = "{{ printer_id }}";
</script>
<script src="{{ static_url_for('pay2print/static', path='js/public.js') }}"></script>
{% endblock %}
18 changes: 18 additions & 0 deletions views.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,21 @@ async def photo(printer_id: str, request: Request):
"height": printer.height,
},
)


@pay2print_ext_generic.get("/text/{printer_id}", response_class=HTMLResponse)
async def text(printer_id: str, request: Request):
printer = await get_printer(printer_id)
if not printer:
return template_renderer().TemplateResponse(
request, "error.html", {"err": "Printer not found"}, HTTPStatus.NOT_FOUND
)
return template_renderer(["pay2print/templates"]).TemplateResponse(
request,
"pay2print/text.html",
{
"printer_id": printer_id,
"amount": printer.amount,
"printer_name": printer.name,
},
)
13 changes: 10 additions & 3 deletions views_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from fastapi import APIRouter, Depends, HTTPException, UploadFile
from fastapi.responses import FileResponse
from lnbits.core.crud import get_wallet
from lnbits.core.models import WalletTypeInfo
from lnbits.core.models import User, WalletTypeInfo
from lnbits.core.services import create_invoice
from lnbits.decorators import check_user_exists, require_admin_key, require_invoice_key

Expand Down Expand Up @@ -104,11 +104,18 @@ async def api_delete_print(print_id: str) -> None:
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:
@pay2print_ext_api.get("/file/{print_id}")
async def api_show_file(
print_id: str, user: User = Depends(check_user_exists)
) -> FileResponse:
_print = await get_print(print_id)
if not _print:
raise HTTPException(HTTPStatus.NOT_FOUND, "Print not found.")
printer = await get_printer(_print.printer)
if not printer:
raise HTTPException(HTTPStatus.NOT_FOUND, "Printer not found.")
if printer.user_id != user.id:
raise HTTPException(HTTPStatus.FORBIDDEN, "Not your print.")

return FileResponse(print_file_path(_print.file), filename=_print.file)

Expand Down

0 comments on commit dc52a1f

Please sign in to comment.