Merge pull request #1352 from lnbits/fix/OffShopImageSize

add image by URL and limit size on API
This commit is contained in:
calle 2023-01-12 15:45:49 +01:00 committed by GitHub
commit 717ae540b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 11 deletions

View file

@ -4,6 +4,15 @@ Vue.component(VueQrcode.name, VueQrcode)
const pica = window.pica()
function imgSizeFit(img, maxWidth = 1024, maxHeight = 768) {
let ratio = Math.min(
1,
maxWidth / img.naturalWidth,
maxHeight / img.naturalHeight
)
return {width: img.naturalWidth * ratio, height: img.naturalHeight * ratio}
}
const defaultItemData = {
unit: 'sat'
}
@ -23,6 +32,7 @@ new Vue({
},
itemDialog: {
show: false,
urlImg: true,
data: {...defaultItemData},
units: ['sat']
}
@ -41,6 +51,9 @@ new Vue({
openUpdateDialog(itemId) {
this.itemDialog.show = true
let item = this.offlineshop.items.find(item => item.id === itemId)
if (item.image.startsWith('data:')) {
this.itemDialog.urlImg = false
}
this.itemDialog.data = item
},
imageAdded(file) {
@ -48,17 +61,12 @@ new Vue({
let image = new Image()
image.src = blobURL
image.onload = async () => {
let fit = imgSizeFit(image, 100, 100)
let canvas = document.createElement('canvas')
canvas.setAttribute('width', 100)
canvas.setAttribute('height', 100)
await pica.resize(image, canvas, {
quality: 0,
alpha: true,
unsharpAmount: 95,
unsharpRadius: 0.9,
unsharpThreshold: 70
})
this.itemDialog.data.image = canvas.toDataURL()
canvas.setAttribute('width', fit.width)
canvas.setAttribute('height', fit.height)
output = await pica.resize(image, canvas)
this.itemDialog.data.image = output.toDataURL('image/jpeg', 0.4)
this.itemDialog = {...this.itemDialog}
}
},
@ -155,6 +163,7 @@ new Vue({
this.loadShop()
this.itemDialog.show = false
this.itemDialog.urlImg = true
this.itemDialog.data = {...defaultItemData}
},
toggleItem(itemId) {

View file

@ -237,7 +237,7 @@
<q-responsive v-if="itemDialog.data.id" :ratio="1">
<qrcode
:value="'lightning:' + itemDialog.data.lnurl"
:options="{width: 800}"
:options="{width: 300}"
class="rounded-borders"
></qrcode>
</q-responsive>
@ -266,7 +266,16 @@
type="text"
label="Brief description"
></q-input>
<q-input
v-if="itemDialog.urlImg"
filled
dense
v-model.trim="itemDialog.data.image"
type="url"
label="Image URL"
></q-input>
<q-file
v-else
filled
dense
capture="environment"
@ -288,6 +297,10 @@
/>
</template>
</q-file>
<q-toggle
:label="`${itemDialog.urlImg ? 'Insert image URL' : 'Upload image file'}`"
v-model="itemDialog.urlImg"
></q-toggle>
<q-input
filled
dense

View file

@ -60,6 +60,22 @@ async def api_add_or_update_item(
):
shop = await get_or_create_shop_by_wallet(wallet.wallet.id)
assert shop
if data.image:
image_is_url = data.image.startswith("https://") or data.image.startswith(
"http://"
)
if not image_is_url:
def size(b64string):
return int((len(b64string) * 3) / 4 - b64string.count("=", -2))
image_size = size(data.image) / 1024
if image_size > 100:
raise HTTPException(
status_code=HTTPStatus.BAD_REQUEST,
detail=f"Image size is too big, {int(image_size)}Kb. Max: 100kb, Compress the image at https://tinypng.com, or use an URL.",
)
if data.unit != "sat":
data.price = data.price * 100
if item_id == None: