-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathtriangles.go
118 lines (107 loc) · 3.52 KB
/
triangles.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package main
import (
"context"
"fmt"
"io"
"math/rand"
"net/http"
"os"
"path/filepath"
"time"
"github.com/docopt/docopt-go"
"github.com/fiatjaf/lntxbot/t"
"github.com/fogleman/primitive/primitive"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
"github.com/nfnt/resize"
)
func handleTriangles(ctx context.Context, opts docopt.Opts, message *tgbotapi.Message) {
u := ctx.Value("initiator").(*User)
msats, err := parseAmountString(opts["<n>"].(string))
if err != nil {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": err})
return
}
n := int(msats / 1000)
if n > 150 {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": "max is 150"})
return
}
// check balance
if !u.checkBalanceFor(ctx, msats, "triangles") {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": "not enough balance"})
return
}
if message.ReplyToMessage == nil {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": "must be sent as a reply to an image"})
return
}
if message.ReplyToMessage.Photo == nil {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": "must be sent as a reply to an image"})
return
}
photo := (*message.ReplyToMessage.Photo)[0]
if photo.FileSize > 1000000 {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": "image too large"})
return
}
// prepare files (this is not really necessary, we should just load stuff from memory)
inputpath := filepath.Join(os.TempDir(), "triangles-"+photo.FileID+"in.png")
outputpath := filepath.Join(os.TempDir(), "triangles-"+photo.FileID+"out.png")
defer os.RemoveAll(inputpath)
defer os.RemoveAll(outputpath)
// download file
dl, err := bot.GetFile(tgbotapi.FileConfig{FileID: photo.FileID})
if err != nil {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": err.Error()})
return
}
resp, err := http.Get(dl.Link(s.TelegramBotToken))
if err != nil {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": err.Error()})
return
}
defer resp.Body.Close()
file, err := os.Create(inputpath)
if err != nil {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": err.Error()})
return
}
defer file.Close()
if _, err := io.Copy(file, resp.Body); err != nil {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": err.Error()})
return
}
// generate primitive image
rand.Seed(time.Now().UTC().UnixNano())
input, err := primitive.LoadImage(inputpath)
if _, err := io.Copy(file, resp.Body); err != nil {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": err.Error()})
return
}
size := uint(256)
if size > 0 {
input = resize.Thumbnail(size, size, input, resize.Bilinear)
}
bg := primitive.MakeColor(primitive.AverageImageColor(input))
model := primitive.NewModel(input, bg, 1024, 1)
for i := 0; i < int(n); i++ {
model.Step(primitive.ShapeTypeTriangle, 128, 0)
}
if err := primitive.SavePNG(outputpath, model.Context.Image()); err != nil {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": err.Error()})
return
}
// send message
sendable := tgbotapi.NewPhotoUpload(message.Chat.ID, outputpath)
sendable.BaseChat.ReplyToMessageID = message.MessageID
imgMessage, err := bot.Send(sendable)
if err != nil {
send(ctx, message.Chat.ID, message, u, t.ERROR, t.T{"Err": "failed to send result"})
return
}
// subtract balance and notify
if err := u.payToInternalService(ctx, msats, fmt.Sprintf("Trianglize image with %d triangles.", n), "triangles"); err == nil {
send(ctx, message.Chat.ID, imgMessage, u, t.PAIDMESSAGE, t.T{"Sats": float64(msats) / 1000})
return
}
}