mirror-nourybot/cmd/nourybot/catbox.go
lyx0 9f75c8c31b 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
2023-10-02 00:35:27 +02:00

200 lines
4 KiB
Go

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))
}
}