package download import ( "errors" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "log" "math/rand" "net/url" "os" "os/exec" "regexp" "strconv" "strings" "time" "watn3y/bloaterbotv3/botIO" "watn3y/bloaterbotv3/config" ) func Download(update tgbotapi.Update, bot *tgbotapi.BotAPI) { log.Println("[download] Downloading Video URL " + update.Message.CommandArguments() + " for " + strconv.FormatInt(update.Message.From.ID, 10) + " in chat " + strconv.FormatInt(update.Message.Chat.ID, 10)) commandArgs := strings.Fields(update.Message.CommandArguments()) var arg string if len(commandArgs) >= 0 { arg = commandArgs[0] } else { log.Println("[download] Failed to download Video URL " + update.Message.CommandArguments() + " NO URL") message := tgbotapi.MessageConfig{ BaseChat: tgbotapi.BaseChat{ChatID: update.Message.Chat.ID, ReplyToMessageID: update.Message.MessageID}, Text: "Please specify a valid YouTube or Reddit URL to download a Video", } botIO.SendMessage(message, bot) return } service := matchURL(arg) if service == "" { log.Println("[download] Failed to download Video URL " + update.Message.CommandArguments() + " INVALID URL") message := tgbotapi.MessageConfig{ BaseChat: tgbotapi.BaseChat{ChatID: update.Message.Chat.ID, ReplyToMessageID: update.Message.MessageID}, Text: "Please specify a valid YouTube or Reddit URL to download a Video", } botIO.SendMessage(message, bot) return } downloadTarget := randomString(20) videoDownloaded := runYTDL(arg, downloadTarget) if !videoDownloaded { message := tgbotapi.MessageConfig{ BaseChat: tgbotapi.BaseChat{ChatID: update.Message.Chat.ID, ReplyToMessageID: update.Message.MessageID}, Text: "Something went wrong while downloading your video :(", } botIO.SendMessage(message, bot) return } files, err := os.ReadDir("./videos/" + downloadTarget) if err != nil { log.Println("[download] Failed to process Video URL "+update.Message.CommandArguments(), " FAILED TO READ DIRECTORY: ", err.Error()) message := tgbotapi.MessageConfig{ BaseChat: tgbotapi.BaseChat{ChatID: update.Message.Chat.ID, ReplyToMessageID: update.Message.MessageID}, Text: "Something went wrong while downloading your video :(", } botIO.SendMessage(message, bot) return } if len(files) >= 2 { log.Println("[download] Failed to process Video URL "+update.Message.CommandArguments(), " TOO MANY FILES") message := tgbotapi.MessageConfig{ BaseChat: tgbotapi.BaseChat{ChatID: update.Message.Chat.ID, ReplyToMessageID: update.Message.MessageID}, Text: "Something went wrong while downloading your video :(", } botIO.SendMessage(message, bot) return } /*fExt := filepath.Ext(config.BotConfig.Download.Prefix + "/" + downloadTarget + "/" + files[0].Name() imageTypes := []string{"jpg","jpeg","png"} if commonlogic.ContainsString(imageTypes,fExt) { } else if fExt == "mp4" { } else { }*/ message := tgbotapi.MessageConfig{ BaseChat: tgbotapi.BaseChat{ChatID: update.Message.Chat.ID, ReplyToMessageID: update.Message.MessageID}, DisableWebPagePreview: false, Text: "Downloaded! You can get your video at: " + config.BotConfig.Download.Prefix + "/" + downloadTarget + "/" + url.PathEscape(files[0].Name()) + "\n It will be available for 30 Minutes.", } botIO.SendMessage(message, bot) time.Sleep(30 * time.Minute) err = os.RemoveAll("./videos/" + downloadTarget) if err != nil { log.Println("[download] Failed to remove old Video "+update.Message.CommandArguments(), err.Error()) return } } func randomString(n int) string { rand.Seed(time.Now().UnixNano()) var letters = []rune("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") b := make([]rune, n) for i := range b { b[i] = letters[rand.Intn(len(letters))] } return string(b) } func runYTDL(URL string, targetDir string) (success bool) { cmd := exec.Command("yt-dlp", "-f", "bv*[ext=mp4]+ba[ext=m4a] / bv*+ba/b", "--no-playlist", "-o", "videos/"+targetDir+"/"+"%(title)s.%(ext)s", URL) out, err := cmd.CombinedOutput() var ( ee *exec.ExitError pe *os.PathError ) if errors.As(err, &ee) { log.Println("[download.ytdl] Failed to download Video URL "+URL, " NON ZERO EXIT CODE: ", ee.ExitCode()) success = false } else if errors.As(err, &pe) { log.Println("[download.ytdl] Failed to download Video URL "+URL, " OS PATH ERROR: ", pe.Error()) success = false } else if err != nil { log.Println("[download.ytdl] Failed to download Video URL "+URL, " GENERAL ERROR: ", err.Error()) success = false } else { log.Println("[download.ytdl] Downloaded Video URL " + URL) success = true } if config.BotConfig.DebugMode { print(string(out)) } return success } func matchURL(URL string) (matchedURL string) { parsedURL, err := url.Parse(URL) if err != nil { log.Fatal(err) } var domainRegex = regexp.MustCompile(`(youtube\.com$)|(youtu\.be$)|(reddit\.com$)`) m := domainRegex.FindStringSubmatch(parsedURL.Hostname()) if len(m) >= 1 { return m[0] } else { return "" } } func serverFile(file os.File) { }