mirror of
https://github.com/lyx0/nourybot.git
synced 2024-11-13 19:49:55 +01:00
feat: add download command and upload to catbox
adds a ()dl command that downloads a video using yt-dlp, then uploads the videofile to catbox and sends the catbox link
This commit is contained in:
parent
67e7a2e655
commit
9f75c8c31b
4
Makefile
4
Makefile
|
@ -22,3 +22,7 @@ jqprod:
|
|||
./bin/${BINARY_NAME} -env="prod" | jq
|
||||
|
||||
|
||||
prod:
|
||||
cd cmd/nourybot && go build -o ${BINARY_NAME}
|
||||
mv cmd/nourybot/${BINARY_NAME} ./bin/${BINARY_NAME}
|
||||
./bin/${BINARY_NAME} -env="prod"
|
||||
|
|
199
cmd/nourybot/catbox.go
Normal file
199
cmd/nourybot/catbox.go
Normal file
|
@ -0,0 +1,199 @@
|
|||
package main
|
||||
|
||||
// This whole file has been pretty much straight up copied
|
||||
// from: https://github.com/wabarc/go-catbox/blob/main/catbox.go
|
||||
// since I couldn't otherwise use litterbox instead.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/wabarc/helper"
|
||||
)
|
||||
|
||||
const (
|
||||
//ENDPOINT = "https://catbox.moe/user/api.php"
|
||||
ENDPOINT = "https://litterbox.catbox.moe/resources/internals/api.php"
|
||||
)
|
||||
|
||||
type catbox struct {
|
||||
Client *http.Client
|
||||
Userhash string
|
||||
}
|
||||
|
||||
func New(client *http.Client) *catbox {
|
||||
if client == nil {
|
||||
client = &http.Client{
|
||||
Timeout: 300 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
return &catbox{
|
||||
Client: client,
|
||||
}
|
||||
}
|
||||
|
||||
// Upload file or URI to the Catbox. It returns an URL string and error.
|
||||
func (cat *catbox) Upload(v ...interface{}) (string, error) {
|
||||
if len(v) == 0 {
|
||||
return "", fmt.Errorf(`must specify file path or byte slice`)
|
||||
}
|
||||
|
||||
switch t := v[0].(type) {
|
||||
case string:
|
||||
path := t
|
||||
parse := func(s string, _ error) (string, error) {
|
||||
uri, err := url.Parse(s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return uri.String(), nil
|
||||
}
|
||||
switch {
|
||||
case helper.IsURL(path):
|
||||
return parse(cat.urlUpload(path))
|
||||
case helper.Exists(path):
|
||||
return parse(cat.fileUpload(path))
|
||||
default:
|
||||
return "", errors.New(`path invalid`)
|
||||
}
|
||||
case []byte:
|
||||
if len(v) != 2 {
|
||||
return "", fmt.Errorf(`must specify file name`)
|
||||
}
|
||||
return cat.rawUpload(t, v[1].(string))
|
||||
}
|
||||
return "", fmt.Errorf(`unhandled`)
|
||||
}
|
||||
|
||||
func (cat *catbox) rawUpload(b []byte, name string) (string, error) {
|
||||
r, w := io.Pipe()
|
||||
m := multipart.NewWriter(w)
|
||||
|
||||
go func() {
|
||||
defer w.Close()
|
||||
defer m.Close()
|
||||
|
||||
m.WriteField("reqtype", "fileupload")
|
||||
m.WriteField("userhash", cat.Userhash)
|
||||
part, err := m.CreateFormFile("fileToUpload", filepath.Base(name))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = io.Copy(part, bytes.NewBuffer(b)); err != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
req, _ := http.NewRequest(http.MethodPost, ENDPOINT, r)
|
||||
req.Header.Add("Content-Type", m.FormDataContentType())
|
||||
|
||||
resp, err := cat.Client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(body), nil
|
||||
}
|
||||
|
||||
func (cat *catbox) fileUpload(path string) (string, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// if size := helper.FileSize(path); size > 209715200 {
|
||||
// return "", fmt.Errorf("file too large, size: %d MB", size/1024/1024)
|
||||
// }
|
||||
|
||||
r, w := io.Pipe()
|
||||
m := multipart.NewWriter(w)
|
||||
|
||||
go func() {
|
||||
defer w.Close()
|
||||
defer m.Close()
|
||||
|
||||
m.WriteField("reqtype", "fileupload")
|
||||
//m.WriteField("userhash", cat.Userhash)
|
||||
m.WriteField("time", "24h")
|
||||
part, err := m.CreateFormFile("fileToUpload", filepath.Base(file.Name()))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = io.Copy(part, file); err != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
req, _ := http.NewRequest(http.MethodPost, ENDPOINT, r)
|
||||
req.Header.Add("Content-Type", m.FormDataContentType())
|
||||
|
||||
resp, err := cat.Client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(body), nil
|
||||
}
|
||||
|
||||
func (cat *catbox) urlUpload(uri string) (string, error) {
|
||||
b := new(bytes.Buffer)
|
||||
w := multipart.NewWriter(b)
|
||||
w.WriteField("reqtype", "urlupload")
|
||||
w.WriteField("userhash", cat.Userhash)
|
||||
w.WriteField("url", uri)
|
||||
|
||||
req, _ := http.NewRequest(http.MethodPost, ENDPOINT, b)
|
||||
req.Header.Add("Content-Type", w.FormDataContentType())
|
||||
|
||||
resp, err := cat.Client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(body), nil
|
||||
}
|
||||
|
||||
func (cat *catbox) Delete(files ...string) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *application) UploadCatbox(target, path string) {
|
||||
app.Send(target, "Uploading to catbox... dankCircle")
|
||||
|
||||
cat := New(nil)
|
||||
if url, err := cat.fileUpload(path); err != nil {
|
||||
app.Send(target, "Something went wrong FeelsBadMan")
|
||||
} else {
|
||||
app.Send(target, string(url))
|
||||
}
|
||||
}
|
|
@ -84,7 +84,7 @@ func (app *application) handleCommand(message twitch.PrivateMessage) {
|
|||
}
|
||||
|
||||
case "dl":
|
||||
reply, _ = app.Download(target, cmdParams[1])
|
||||
app.Download(target, cmdParams[1])
|
||||
|
||||
case "mail":
|
||||
app.SendEmail("Test command used!", "This is an email test")
|
||||
|
@ -184,12 +184,7 @@ func (app *application) handleCommand(message twitch.PrivateMessage) {
|
|||
app.EditUserLevel(cmdParams[3], cmdParams[4], message)
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the commandName exists as the "name" of a command in the database.
|
||||
// if it doesnt then ignore it.
|
||||
// ##################
|
||||
}
|
||||
|
||||
if reply != "" {
|
||||
app.Send(target, reply)
|
||||
return
|
||||
|
|
|
@ -2,37 +2,48 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/wader/goutubedl"
|
||||
)
|
||||
|
||||
func (app *application) Download(channel, link string) (string, error) {
|
||||
func (app *application) Download(target, link string) {
|
||||
goutubedl.Path = "yt-dlp"
|
||||
|
||||
app.Send(channel, "dankCircle")
|
||||
app.Send(target, "Downloading... dankCircle")
|
||||
result, err := goutubedl.New(context.Background(), link, goutubedl.Options{})
|
||||
if err != nil {
|
||||
app.Log.Fatal(err)
|
||||
app.Log.Errorln(err)
|
||||
}
|
||||
rExt := result.Info.Ext
|
||||
downloadResult, err := result.Download(context.Background(), "best")
|
||||
if err != nil {
|
||||
app.Log.Fatal(err)
|
||||
app.Log.Errorln(err)
|
||||
}
|
||||
app.Send(target, "Downloaded..")
|
||||
defer downloadResult.Close()
|
||||
f, err := os.Create("output.mp4")
|
||||
fn, err := uuid.NewUUID()
|
||||
if err != nil {
|
||||
app.Log.Fatal(err)
|
||||
app.Log.Errorln(err)
|
||||
}
|
||||
f, err := os.Create(fmt.Sprintf("%s.%s", fn, rExt))
|
||||
app.Send(target, fmt.Sprintf("Filename: %s.%s", fn, rExt))
|
||||
|
||||
if err != nil {
|
||||
app.Log.Errorln(err)
|
||||
}
|
||||
defer f.Close()
|
||||
io.Copy(f, downloadResult)
|
||||
|
||||
out, err := exec.Command("curl", "-L", "-F", "file=@output.mp4", "i.yaf.ee/upload").Output()
|
||||
if err != nil {
|
||||
app.Log.Fatal(err)
|
||||
if _, err = io.Copy(f, downloadResult); err != nil {
|
||||
app.Log.Errorln(err)
|
||||
}
|
||||
return string(out), nil
|
||||
|
||||
app.UploadCatbox(target, fmt.Sprintf("%s.%s", fn, rExt))
|
||||
|
||||
//os.Remove(fmt.Sprintf("%s.mp4", fn))
|
||||
|
||||
//app.TwitchClient.Say(channel, b.String())
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ type application struct {
|
|||
}
|
||||
|
||||
var envFlag string
|
||||
var ctx = context.Background()
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&envFlag, "env", "dev", "database connection to use: (dev/prod)")
|
||||
|
|
7
go.mod
7
go.mod
|
@ -14,10 +14,17 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/wabarc/go-catbox v0.1.0 // indirect
|
||||
github.com/wabarc/helper v0.0.0-20210718171053-59c70d0b20c2 // indirect
|
||||
github.com/wader/goutubedl v0.0.0-20230924165737-427b7fa536e6 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
golang.org/x/net v0.0.0-20210716203947-853a461950ff // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
mvdan.cc/xurls/v2 v2.2.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
24
go.sum
24
go.sum
|
@ -13,10 +13,15 @@ github.com/gempir/go-twitch-irc/v4 v4.0.0/go.mod h1:QsOMMAk470uxQ7EYD9GJBGAVqM/j
|
|||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jakecoffman/cron v0.0.0-20190106200828-7e2009c226a5 h1:kCvm3G3u+eTRbjfLPyfsfznJtraYEfZer/UvQ6CaQhI=
|
||||
github.com/jakecoffman/cron v0.0.0-20190106200828-7e2009c226a5/go.mod h1:6DM2KNNK69jRu0lAHmYK9LYxmqpNjYHOaNp/ZxttD4U=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
|
@ -29,6 +34,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
|
||||
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
|
||||
|
@ -37,6 +43,10 @@ github.com/shkh/lastfm-go v0.0.0-20191215035245-89a801c244e0/go.mod h1:n3nudMl17
|
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/wabarc/go-catbox v0.1.0 h1:/UhV9md3MJrjZtm+EToSyFjawXgPiHSExLNRqsWNisg=
|
||||
github.com/wabarc/go-catbox v0.1.0/go.mod h1:Zjs9Y55f2WOwGWwmKSCrUuMfwh+nDktkjub9jgHq4CQ=
|
||||
github.com/wabarc/helper v0.0.0-20210718171053-59c70d0b20c2 h1:6rMZse2rdD7N6GxHRZqHlkSptBWh/Vf9aHiFVQjlQNo=
|
||||
github.com/wabarc/helper v0.0.0-20210718171053-59c70d0b20c2/go.mod h1:uS6mimKlWkGvEZXkJ6JoW7LYnnB2JP6dLU9q7pgDaWQ=
|
||||
github.com/wader/goutubedl v0.0.0-20230924165737-427b7fa536e6 h1:KHJV3fnnKsdWdGu5IKrDAA0Oa5RzGwrJpfx+bvVAjLA=
|
||||
github.com/wader/goutubedl v0.0.0-20230924165737-427b7fa536e6/go.mod h1:5KXd5tImdbmz4JoVhePtbIokCwAfEhUVVx3WLHmjYuw=
|
||||
github.com/wader/osleaktest v0.0.0-20191111175233-f643b0fed071/go.mod h1:XD6emOFPHVzb0+qQpiNOdPL2XZ0SRUM0N5JHuq6OmXo=
|
||||
|
@ -47,12 +57,26 @@ go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
|||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210716203947-853a461950ff h1:j2EK/QoxYNBsXI4R7fQkkRUk8y6wnOBI+6hgPdP/6Ds=
|
||||
golang.org/x/net v0.0.0-20210716203947-853a461950ff/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
mvdan.cc/xurls/v2 v2.2.0 h1:NSZPykBXJFCetGZykLAxaL6SIpvbVy/UFEniIfHAa8A=
|
||||
mvdan.cc/xurls/v2 v2.2.0/go.mod h1:EV1RMtya9D6G5DMYPGD8zTQzaHet6Jh8gFlRgGRJeO8=
|
||||
|
|
Loading…
Reference in a new issue