From be902a707acb84a39039cfcd4c5071e8fd1951b9 Mon Sep 17 00:00:00 2001 From: itasli Date: Tue, 18 Apr 2023 18:13:51 +0200 Subject: [PATCH] refactor refactored profile picture download function to support both jpeg & png disabled image download on invoice for now deleted unused file --- helpers.go | 40 ------------------------ invoice.go | 91 +++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 62 insertions(+), 69 deletions(-) delete mode 100644 helpers.go diff --git a/helpers.go b/helpers.go deleted file mode 100644 index 115ead6..0000000 --- a/helpers.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -import ( - "bytes" - "encoding/base64" - "errors" - "fmt" - "image" - "image/jpeg" - "net/http" - "strconv" - - "github.com/nfnt/resize" -) - -func base64ImageFromURL(url string) (string, error) { - resp, err := http.Get(url) - if err != nil { - return "", err - } - defer resp.Body.Close() - - if resp.StatusCode >= 300 { - return "", errors.New("image returned status " + strconv.Itoa(resp.StatusCode)) - } - - img, _, err := image.Decode(resp.Body) - if err != nil { - return "", fmt.Errorf("failed to decode image from %s: %w", url, err) - } - - img = resize.Resize(160, 0, img, resize.NearestNeighbor) - out := &bytes.Buffer{} - err = jpeg.Encode(out, img, &jpeg.Options{60}) - if err != nil { - return "", fmt.Errorf("failed to encode image: %w", err) - } - - return base64.StdEncoding.EncodeToString(out.Bytes()), nil -} diff --git a/invoice.go b/invoice.go index f314a7d..0d1043f 100644 --- a/invoice.go +++ b/invoice.go @@ -2,10 +2,12 @@ package main import ( "bytes" + "encoding/base64" + "errors" "fmt" "image" "image/jpeg" - "io/ioutil" + "image/png" "net/http" "strconv" "time" @@ -15,6 +17,11 @@ import ( "github.com/fiatjaf/go-lnurl" ) +const ( + thumbnailWidth = 160 + thumbnailHeight = 160 +) + func metaData(params *Params) lnurl.Metadata { metadata := lnurl.Metadata{ @@ -22,63 +29,89 @@ func metaData(params *Params) lnurl.Metadata { LightningAddress: fmt.Sprintf("%s@%s", params.Name, params.Domain), } - if params.Npub != "" && s.GetNostrProfile { + /* if params.Npub != "" && s.GetNostrProfile { NostrProfile, err := GetNostrProfileMetaData(params.Npub) if err == nil { addImageToMetaData(&metadata, NostrProfile.Picture) } - } + } */ return metadata } -// addImageMetaData add images an image to the LNURL metadata +// addImageToMetaData adds an image to the LNURL metadata func addImageToMetaData(metadata *lnurl.Metadata, imageurl string) { - + // Download and resize profile picture picture, err := DownloadProfilePicture(imageurl) if err != nil { log.Debug().Str("Downloading profile picture", err.Error()).Msg("Error") return } - metadata.Image.Ext = "jpeg" //filepath.Ext(imageurl) - metadata.Image.DataURI = imageurl + + // Determine image format + contentType := http.DetectContentType(picture) + var ext string + if contentType == "image/jpeg" { + ext = "jpeg" + } else if contentType == "image/png" { + ext = "png" + } else { + log.Debug().Str("Detecting image format", "unknown format").Msg("Error") + return + } + + // Set image metadata in LNURL metadata + metadata.Image.Ext = ext + metadata.Image.DataURI = "data:" + contentType + ";base64," + base64.StdEncoding.EncodeToString(picture) metadata.Image.Bytes = picture } func DownloadProfilePicture(url string) ([]byte, error) { - res, err := http.Get(url) + client := http.Client{ + Timeout: 5 * time.Second, + } + res, err := client.Get(url) if err != nil { - log.Debug().Str("http.Get ->", err.Error()).Msg("Error") - return nil, err + return nil, errors.New("failed to download image: " + err.Error()) + } + defer res.Body.Close() + + contentType := res.Header.Get("Content-Type") + if contentType != "image/jpeg" && contentType != "image/png" { + return nil, errors.New("unsupported image format") + } + + var img image.Image + switch contentType { + case "image/jpeg": + img, err = jpeg.Decode(res.Body) + case "image/png": + img, err = png.Decode(res.Body) } - data, err := ioutil.ReadAll(res.Body) if err != nil { - log.Debug().Str("ioutil.ReadAll ->", err.Error()).Msg("Error") - return nil, err + return nil, errors.New("failed to decode image: " + err.Error()) } - res.Body.Close() - img, _, err := image.Decode(bytes.NewReader(data)) - if err != nil { - return nil, err - } - // resize image - img = resize.Thumbnail(160, 160, img, resize.Lanczos3) + + img = resize.Thumbnail(thumbnailWidth, thumbnailHeight, img, resize.Lanczos3) + buf := new(bytes.Buffer) - _ = jpeg.Encode(buf, img, nil) - //ioutil.WriteFile("test.jpg", buf.Bytes(), 0666) + if contentType == "image/jpeg" { + if err := jpeg.Encode(buf, img, nil); err != nil { + return nil, errors.New("failed to encode image: " + err.Error()) + } + } else if contentType == "image/png" { + if err := png.Encode(buf, img); err != nil { + return nil, errors.New("failed to encode image: " + err.Error()) + } + } + return buf.Bytes(), nil } -func makeInvoice( - params *Params, - msat int, - pin *string, - zapEventSerializedStr string, - comment string, -) (bolt11 string, err error) { +func makeInvoice(params *Params, msat int, pin *string, zapEventSerializedStr string, comment string) (bolt11 string, err error) { // prepare params var backend BackendParams