Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions prophet/plugins/veniceimg/config/config.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package config

type Config struct {
Enabled bool `mapstructure:"enabled" toml:"enabled"`
ApiKey string `mapstructure:"api-key" toml:"api-key"`
Enabled bool `mapstructure:"enabled" toml:"enabled"`
VeniceKey string `mapstructure:"venice-key" toml:"venice-key"`
StorageKey string `mapstructure:"storage-key" toml:"storage-key"`
}

// DefaultConfig returns a default configuration for veniceimg.
func DefaultConfig() *Config {
return &Config{
Enabled: false,
ApiKey: "",
Enabled: false,
VeniceKey: "",
StorageKey: "",
}
}

Expand All @@ -23,5 +25,8 @@ const DefaultConfigTemplate = `
enabled = "{{ .Veniceimg.Enabled }}"

# API Key used when making VeniceImg API requests
api-key = "{{ .Veniceimg.ApiKey }}"
venice-key = "{{ .Veniceimg.VeniceKey }}"

# API Key used when saving the image to Filebase
storage-key = "{{ .Veniceimg.StorageKey }}"
`
101 changes: 75 additions & 26 deletions prophet/plugins/veniceimg/veniceimg.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,25 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"image"
"io"
"mime/multipart"
"net/http"

"github.com/gen2brain/webp"
"github.com/nfnt/resize"
_ "golang.org/x/image/webp"
)

type Plugin struct {
veniceimg veniceimgClient
storage storageClient
}

func New(apiKey string) Plugin {
c := &http.Client{}

func New(veniceKey, storageKey string) Plugin {
return Plugin{
veniceimg: veniceimgClient{
c: c,
apiKey: apiKey,
c: &http.Client{},
veniceKey: veniceKey,
},
storage: storageClient{
c: &http.Client{},
storageKey: storageKey,
},
}
}
Expand Down Expand Up @@ -52,30 +52,32 @@ func (p Plugin) Execute(ctx context.Context, input []byte) ([]byte, error) {
return nil, err
}

img, _, err := image.Decode(bytes.NewReader(imgBytes))
cid, err := p.storage.uploadToFilebase(ctx, "image.webp", imgBytes)
if err != nil {
return nil, err
}

newImage := resize.Resize(256, 0, img, resize.Lanczos3)

buf := new(bytes.Buffer)

options := webp.Options{Lossless: false, Quality: 80}
if err := webp.Encode(buf, newImage, options); err != nil {
return nil, err
urls := map[string]string{
"filebase": "https://ipfs.filebase.io/ipfs/" + cid,
"ipfs": "https://ipfs.io/ipfs/" + cid,
"pinata": "https://gateway.pinata.cloud/ipfs/" + cid,
}

return buf.Bytes(), nil
return json.Marshal(urls)
}

func (p Plugin) Verify(ctx context.Context, input, output []byte) error {
return nil
}

type veniceimgClient struct {
c *http.Client
apiKey string
c *http.Client
veniceKey string
}

type storageClient struct {
c *http.Client
storageKey string
}

type generatePayload struct {
Expand All @@ -85,8 +87,6 @@ type generatePayload struct {
Prompt string `json:"prompt"`
Steps int `json:"steps"`
StylePreset string `json:"style_preset"`
Height int `json:"height"`
Width int `json:"width"`
}

type timing struct {
Expand All @@ -111,8 +111,6 @@ func (c *veniceimgClient) generate(ctx context.Context, model string, prompt str
Prompt: prompt,
Steps: steps,
StylePreset: stylePreset,
Height: 1024,
Width: 1024,
})
if err != nil {
return generateResponse{}, err
Expand All @@ -126,7 +124,7 @@ func (c *veniceimgClient) generate(ctx context.Context, model string, prompt str
}

req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+c.apiKey)
req.Header.Set("Authorization", "Bearer "+c.veniceKey)

httpRes, err := c.c.Do(req)
if err != nil {
Expand All @@ -145,3 +143,54 @@ func (c *veniceimgClient) generate(ctx context.Context, model string, prompt str

return res, nil
}

type filebaseAddResponse struct {
Name string `json:"Name"`
Hash string `json:"Hash"`
Size string `json:"Size"`
}

func (c *storageClient) uploadToFilebase(ctx context.Context, filename string, fileBytes []byte) (string, error) {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)

part, err := writer.CreateFormFile("file", filename)
if err != nil {
return "", err
}

if _, err := io.Copy(part, bytes.NewReader(fileBytes)); err != nil {
return "", err
}

if err := writer.Close(); err != nil {
return "", err
}

req, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://rpc.filebase.io/api/v0/add", body)
if err != nil {
return "", err
}

req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("Authorization", "Bearer "+c.storageKey)

client := http.DefaultClient

resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("filebase upload failed: %s", resp.Status)
}

var res filebaseAddResponse
if err := json.NewDecoder(resp.Body).Decode(&res); err != nil {
return "", err
}

return res.Hash, nil
}
3 changes: 2 additions & 1 deletion warden/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ func registerProphetHandlers(appOpts servertypes.AppOptions) {
}

if cast.ToBool(appOpts.Get("veniceimg.enabled")) {
prophet.Register("veniceimg", veniceimg.New(cast.ToString(appOpts.Get("veniceimg.api-key"))))
prophet.Register("veniceimg", veniceimg.New(cast.ToString(appOpts.Get("veniceimg.venice-key")),
cast.ToString(appOpts.Get("veniceimg.storage-key"))))
}
}

Expand Down
Loading