fix the mess downloads/uploads are

This commit is contained in:
lyx0 2023-10-05 19:33:07 +02:00
parent 4626fd13ee
commit 8532494aab
4 changed files with 239 additions and 342 deletions

View file

@ -84,10 +84,10 @@ func (app *application) handleCommand(message twitch.PrivateMessage) {
}
case "cb":
go commands.DownloadCatbox(target, cmdParams[1], app.TwitchClient, app.Log)
go commands.NewDownload("catbox", target, cmdParams[1], app.TwitchClient, app.Log)
case "dl":
go commands.Download(target, cmdParams[1], fileUploaderURL, app.TwitchClient, app.Log)
go commands.NewDownload("custom", target, cmdParams[1], app.TwitchClient, app.Log)
case "mail":
app.SendEmail("Test command used!", "This is an email test")

View file

@ -1,256 +0,0 @@
// The whole catbox upload functionality has been copied from
// here so that I could use it with litterbox:
// https://github.com/wabarc/go-catbox/blob/main/catbox.go <3
//
// Copyright 2021 Wayback Archiver. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.
package commands
import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"net/url"
"os"
"path/filepath"
"time"
"github.com/gempir/go-twitch-irc/v4"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/wabarc/helper"
"github.com/wader/goutubedl"
"go.uber.org/zap"
)
const (
ENDPOINT = "https://litterbox.catbox.moe/resources/internals/api.php"
)
type Catbox struct {
Client *http.Client
Time string
Userhash string
TwitchClient *twitch.Client
Log *zap.SugaredLogger
}
func NewCat(twitchClient *twitch.Client, log *zap.SugaredLogger) *Catbox {
client := &http.Client{
Timeout: 300 * time.Second,
}
return &Catbox{
Client: client,
Time: "24h",
TwitchClient: twitchClient,
Log: log,
}
}
func DownloadCatbox(target, link string, tc *twitch.Client, log *zap.SugaredLogger) (reply string) {
cat := NewCat(tc, log)
go cat.downloadCatbox(target, link)
return ""
}
func (cat *Catbox) downloadCatbox(target, link string) {
goutubedl.Path = "yt-dlp"
var fileName string
cat.TwitchClient.Say(target, "Downloading... dankCircle")
result, err := goutubedl.New(context.Background(), link, goutubedl.Options{})
if err != nil {
cat.Log.Errorln(err)
}
// I don't know why but I need to set it to mp4, otherwise if
// I use `result.Into.Ext` catbox won't play the video in the
// browser and say this message:
// `No video with supported format and MIME type found.`
rExt := "mp4"
downloadResult, err := result.Download(context.Background(), "best")
if err != nil {
cat.Log.Errorln(err)
}
cat.TwitchClient.Say(target, "Downloaded.")
uuidFilename, err := uuid.NewUUID()
fileName = fmt.Sprintf("%s.%s", uuidFilename, rExt)
if err != nil {
cat.Log.Errorln(err)
}
f, err := os.Create(fileName)
cat.TwitchClient.Say(target, fmt.Sprintf("Filename: %s", fileName))
if err != nil {
cat.Log.Errorln(err)
}
defer f.Close()
if _, err = io.Copy(f, downloadResult); err != nil {
cat.Log.Errorln(err)
}
downloadResult.Close()
f.Close()
if url, err := cat.fileUpload(fileName); err != nil {
cat.TwitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %v", err))
} else {
cat.TwitchClient.Say(target, url)
}
}
// 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("time", cat.Time)
//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) {
defer os.Remove(path)
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("time", cat.Time)
m.WriteField("userhash", cat.Userhash)
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
}

View file

@ -4,10 +4,7 @@ import (
"context"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
"time"
"github.com/gempir/go-twitch-irc/v4"
"github.com/google/uuid"
@ -15,28 +12,29 @@ import (
"go.uber.org/zap"
)
type downloader struct {
twitchClient *twitch.Client
type Downloader struct {
TwitchClient *twitch.Client
Log *zap.SugaredLogger
URL string
}
func Download(target, link, fileUploadURL string, tc *twitch.Client, log *zap.SugaredLogger) (reply string) {
dloader := &downloader{
func NewDownload(destination, target, link string, tc *twitch.Client, log *zap.SugaredLogger) {
dl := &Downloader{
TwitchClient: tc,
Log: log,
twitchClient: tc,
URL: fileUploadURL,
}
go dloader.dlxd(target, link)
return ""
switch destination {
case "catbox":
dl.CatboxDownload(target, link)
case "custom":
dl.CustomDownload(target, link)
}
}
func (dl *downloader) dlxd(target, link string) {
func (dl *Downloader) CustomDownload(target, link string) {
goutubedl.Path = "yt-dlp"
dl.twitchClient.Say(target, "Downloading... dankCircle")
dl.TwitchClient.Say(target, "[custom] Downloading... dankCircle")
result, err := goutubedl.New(context.Background(), link, goutubedl.Options{})
if err != nil {
dl.Log.Errorln(err)
@ -46,13 +44,14 @@ func (dl *downloader) dlxd(target, link string) {
if err != nil {
dl.Log.Errorln(err)
}
dl.twitchClient.Say(target, "Downloaded.")
fn, err := uuid.NewUUID()
dl.TwitchClient.Say(target, "Downloaded.")
uuidFilename, err := uuid.NewUUID()
if err != nil {
dl.Log.Errorln(err)
}
f, err := os.Create(fmt.Sprintf("%s.%s", fn, rExt))
dl.twitchClient.Say(target, fmt.Sprintf("Filename: %s.%s", fn, rExt))
fileName := fmt.Sprintf("%s.%s", uuidFilename, rExt)
f, err := os.Create(fileName)
dl.TwitchClient.Say(target, fmt.Sprintf("Filename: %s", fileName))
if err != nil {
dl.Log.Errorln(err)
@ -68,82 +67,49 @@ func (dl *downloader) dlxd(target, link string) {
// dl.twitchClient.Say(target, "ResidentSleeper ..")
// time.Sleep(duration)
dl.upload(target, fmt.Sprintf("%s.%s", fn, rExt))
go NewUpload("custom", fileName, target, dl.TwitchClient, dl.Log)
}
func (dl *downloader) upload(target, path string) {
dl.twitchClient.Say(target, "Uploading... dankCircle")
pr, pw := io.Pipe()
form := multipart.NewWriter(pw)
func (dl *Downloader) CatboxDownload(target, link string) {
goutubedl.Path = "yt-dlp"
var fileName string
go func() {
defer pw.Close()
err := form.WriteField("name", "xd")
if err != nil {
dl.twitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
return
}
file, err := os.Open(path) // path to image file
if err != nil {
dl.twitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
return
}
w, err := form.CreateFormFile("file", path)
if err != nil {
dl.twitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
return
}
_, err = io.Copy(w, file)
if err != nil {
dl.twitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
return
}
form.Close()
}()
req, err := http.NewRequest(http.MethodPost, dl.URL, pr)
dl.TwitchClient.Say(target, "Downloading... dankCircle")
result, err := goutubedl.New(context.Background(), link, goutubedl.Options{})
if err != nil {
dl.twitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
return
dl.Log.Errorln(err)
}
req.Header.Set("Content-Type", form.FormDataContentType())
httpClient := http.Client{
Timeout: 300 * time.Second,
}
resp, err := httpClient.Do(req)
// I don't know why but I need to set it to mp4, otherwise if
// I use `result.Into.Ext` catbox won't play the video in the
// browser and say this message:
// `No video with supported format and MIME type found.`
rExt := "mp4"
downloadResult, err := result.Download(context.Background(), "best")
if err != nil {
dl.twitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
dl.Log.Errorln("Error while sending HTTP request:", err)
return
dl.Log.Errorln(err)
}
defer resp.Body.Close()
dl.twitchClient.Say(target, "Uploaded PogChamp")
body, err := io.ReadAll(resp.Body)
dl.TwitchClient.Say(target, "Downloaded.")
uuidFilename, err := uuid.NewUUID()
if err != nil {
dl.twitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
dl.Log.Errorln("Error while reading response:", err)
return
dl.Log.Errorln(err)
}
fileName = fmt.Sprintf("%s.%s", uuidFilename, rExt)
f, err := os.Create(fileName)
dl.TwitchClient.Say(target, fmt.Sprintf("Filename: %s", fileName))
if err != nil {
dl.Log.Errorln(err)
}
defer f.Close()
if _, err = io.Copy(f, downloadResult); err != nil {
dl.Log.Errorln(err)
}
var reply = string(body[:])
downloadResult.Close()
f.Close()
dl.twitchClient.Say(target, fmt.Sprintf("Removing file: %s", path))
os.Remove(path)
dl.twitchClient.Say(target, reply)
go NewUpload("catbox", fileName, target, dl.TwitchClient, dl.Log)
}

187
internal/commands/upload.go Normal file
View file

@ -0,0 +1,187 @@
// The whole catbox upload functionality has been copied from
// here so that I could use it with litterbox:
// https://github.com/wabarc/go-catbox/blob/main/catbox.go <3
//
// Copyright 2021 Wayback Archiver. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.
package commands
import (
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
"path/filepath"
"time"
"github.com/gempir/go-twitch-irc/v4"
"go.uber.org/zap"
)
const (
CUSTOM_ENDPOINT = "https://i.yaf.ee/upload"
CATBOX_ENDPOINT = "https://litterbox.catbox.moe/resources/internals/api.php"
)
type Uploader struct {
Client *http.Client
Time string
Userhash string
TwitchClient *twitch.Client
Log *zap.SugaredLogger
}
func NewUpload(destination, fileName, target string, twitchClient *twitch.Client, log *zap.SugaredLogger) {
client := &http.Client{
Timeout: 300 * time.Second,
}
ul := &Uploader{
Client: client,
Time: "24h",
TwitchClient: twitchClient,
Log: log,
}
switch destination {
case "catbox":
go ul.CatboxUpload(target, fileName)
case "custom":
go ul.CustomUpload(target, fileName)
}
}
func (ul *Uploader) CatboxUpload(target, fileName string) {
defer os.Remove(fileName)
file, err := os.Open(fileName)
if err != nil {
ul.TwitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
return
}
defer file.Close()
// if size := helper.FileSize(fileName); 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("time", ul.Time)
part, err := m.CreateFormFile("fileToUpload", filepath.Base(file.Name()))
if err != nil {
ul.TwitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
return
}
if _, err = io.Copy(part, file); err != nil {
return
}
}()
req, _ := http.NewRequest(http.MethodPost, CATBOX_ENDPOINT, r)
req.Header.Add("Content-Type", m.FormDataContentType())
resp, err := ul.Client.Do(req)
if err != nil {
ul.TwitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
ul.TwitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
return
}
reply := string(body)
ul.TwitchClient.Say(target, fmt.Sprintf("Removing file: %s", fileName))
ul.TwitchClient.Say(target, reply)
}
func (ul *Uploader) CustomUpload(target, path string) {
defer os.Remove(path)
ul.TwitchClient.Say(target, "Uploading... dankCircle")
pr, pw := io.Pipe()
form := multipart.NewWriter(pw)
go func() {
defer pw.Close()
err := form.WriteField("name", "xd")
if err != nil {
ul.TwitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
return
}
file, err := os.Open(path) // path to image file
if err != nil {
ul.TwitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
return
}
w, err := form.CreateFormFile("file", path)
if err != nil {
ul.TwitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
return
}
_, err = io.Copy(w, file)
if err != nil {
ul.TwitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
return
}
form.Close()
}()
req, err := http.NewRequest(http.MethodPost, CUSTOM_ENDPOINT, pr)
if err != nil {
ul.TwitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
return
}
req.Header.Set("Content-Type", form.FormDataContentType())
httpClient := http.Client{
Timeout: 300 * time.Second,
}
resp, err := httpClient.Do(req)
if err != nil {
ul.TwitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
ul.Log.Errorln("Error while sending HTTP request:", err)
return
}
defer resp.Body.Close()
ul.TwitchClient.Say(target, "Uploaded PogChamp")
body, err := io.ReadAll(resp.Body)
if err != nil {
ul.TwitchClient.Say(target, fmt.Sprintf("Something went wrong FeelsBadMan: %q", err))
os.Remove(path)
ul.Log.Errorln("Error while reading response:", err)
return
}
var reply = string(body[:])
ul.TwitchClient.Say(target, fmt.Sprintf("Removing file: %s", path))
ul.TwitchClient.Say(target, reply)
}