From eda470158528ae5f740680329567d0c36bf9bb7c Mon Sep 17 00:00:00 2001 From: Stelios Georgiou Date: Wed, 9 Sep 2020 19:37:18 +0100 Subject: [PATCH] reddit links send to v.redd.it handler, more changes to file structure, cleanup --- download.go | 46 +++++++++++++-------------- download_test.go | 83 ++++++++++++++++++++++++++++++++++++------------ format.go | 23 +++++++------- format_test.go | 4 +-- handlers.go | 49 ++++++++++++++-------------- main.go | 15 ++++----- 6 files changed, 131 insertions(+), 89 deletions(-) diff --git a/download.go b/download.go index 20e8c23..8d7879c 100644 --- a/download.go +++ b/download.go @@ -7,47 +7,47 @@ import ( "path" ) -type rawMedia struct { +type media struct { os.FileInfo - Id string - Url string - Path string - Downloaded bool + Id string + Path string } // download handles retrieving the v.redd.it media. Initialises -// a rawMedia instance for each URL. -func download(URL string) (*rawMedia, error) { - f := rawMedia{ - Url: URL, - Id: path.Base(URL), - } - err := os.MkdirAll(path.Join(dir, f.Id), 0755) - if err != nil { - log.Printf("Error creating sub-directory: %v\n", err) +// a media instance for each URL. +func download(URL string) (*media, error) { + f := media{ + Id: path.Base(URL), } cmd := exec.Command( "youtube-dl", "-v", - "--id", // use id as name + //"--id", // use id as name + "--output", + f.Id, "--write-info-json", // save file information - "--restrict-filenames", + //"--restrict-filenames", "--merge-output-format", // Downloading the best available audio and video outputFormat, URL, ) cmd.Dir = path.Join(dir, f.Id) - - xerr := cmd.Run() - if xerr != nil { - log.Fatalf("Failed: %v\n", cmd.Args) + err := os.MkdirAll(cmd.Dir, 0755) + if err != nil { + log.Printf("Error creating sub-directory: %v", err) + cmd.Dir = dir + } + log.Print("...run youtube-dl...") + err = cmd.Run() + if err != nil { + log.Printf("Failed process: %v", cmd.Args) + return &f, err } - f.Path = path.Join(cmd.Dir, f.Id+originalExt) f.FileInfo, err = os.Stat(f.Path) if err != nil { - log.Println("Error finding downloaded file") + log.Print("Error finding downloaded file: ", err) } // TODO want to return output error from youtube-dl - return &f, xerr + return &f, err } diff --git a/download_test.go b/download_test.go index 47ea50d..45a3f52 100644 --- a/download_test.go +++ b/download_test.go @@ -3,27 +3,70 @@ package main import "testing" func TestDownloadVRedditLink(t *testing.T) { - URL := "https://v.redd.it/duir5tuwswl51" - _, err := download(URL) - if err != nil { - t.Errorf(`youtube-dl %q failed`, URL) + URLs := []string{ + "https://v.redd.it/duir5tuwswl51", + "https://v.redd.it/5ltubsoyawl51", + "https://v.redd.it/dttgnvp69wl51", + "https://v.redd.it/e497qwjsh1m51", } - URL = "https://v.redd.it/5ltubsoyawl51" - _, err = download(URL) - if err != nil { - t.Errorf(`youtube-dl %q failed`, URL) - } - URL = "https://v.redd.it/dttgnvp69wl51" - _, err = download(URL) - if err != nil { - t.Errorf(`youtube-dl %q failed`, URL) + for _, URL := range URLs { + _, err := download(URL) + if err != nil { + t.Errorf(`youtube-dl %q failed`, URL) + } } } -//func TestDownloadRedditLink(t *testing.T) { -// URL := "https://www.reddit.com/r/IdiotsInCars/comments/ioqqbf/i_know_ill_cut_in_front_of_this_semi/" -// _, err := download(URL) -// if err != nil { -// t.Errorf(`youtube-dl %q failed`, URL) -// } -//} +func TestDownloadRedditLink(t *testing.T) { + URLs := []string{ + "https://www.reddit.com/r/IdiotsInCars/comments/ioqqbf/i_know_ill_cut_in_front_of_this_semi/", + "https://www.reddit.com/r/AnimalsBeingBros/comments/ip89wl/possibly_the_most_patient_kitty_in_the_world_with/", + } + for _, URL := range URLs { + _, err := download(URL) + if err != nil { + t.Errorf(`youtube-dl %q failed`, URL) + // The following logs were producing some errors, have been removed + //t.Log(err) + //t.Logf("Id:\t%v,\nPath:\t%v,\nName:\t%v,\nSize:\t%v", f.Id, f.Path, f.Name(), f.Size()) + // Output: + /* + === RUN TestDownloadVRedditLink + 2020/09/09 19:18:57 ...run youtube-dl... + 2020/09/09 19:18:58 ...run youtube-dl... + 2020/09/09 19:18:59 ...run youtube-dl... + 2020/09/09 19:19:00 ...run youtube-dl... + 2020/09/09 19:19:00 Error finding downloaded file: stat downloads/e497qwjsh1m51/e497qwjsh1m51.mp4: no such file or directory + download_test.go:15: youtube-dl "https://v.redd.it/e497qwjsh1m51" failed + --- FAIL: TestDownloadVRedditLink (3.25s) + === RUN TestDownloadRedditLink + 2020/09/09 19:19:00 ...run youtube-dl... + 2020/09/09 19:19:04 ...run youtube-dl... + 2020/09/09 19:19:06 Error finding downloaded file: stat downloads/possibly_the_most_patient_kitty_in_the_world_with/possibly_the_most_patient_kitty_in_the_world_with.mp4: no such file or directory + download_test.go:27: youtube-dl "https://www.reddit.com/r/AnimalsBeingBros/comments/ip89wl/possibly_the_most_patient_kitty_in_the_world_with/" failed + download_test.go:28: stat downloads/possibly_the_most_patient_kitty_in_the_world_with/possibly_the_most_patient_kitty_in_the_world_with.mp4: no such file or directory + --- FAIL: TestDownloadRedditLink (5.44s) + panic: runtime error: invalid memory address or nil pointer dereference [recovered] + panic: runtime error: invalid memory address or nil pointer dereference + [signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0x6ed596] + + goroutine 7 [running]: + testing.tRunner.func1.1(0x73b8a0, 0xa459e0) + /usr/lib/golang/src/testing/testing.go:988 +0x30d + testing.tRunner.func1(0xc00011c900) + /usr/lib/golang/src/testing/testing.go:991 +0x3f9 + panic(0x73b8a0, 0xa459e0) + /usr/lib/golang/src/runtime/panic.go:969 +0x166 + dvembed.TestDownloadRedditLink(0xc00011c900) + /home/steli/source/dvembed/download_test.go:29 +0x1f6 + testing.tRunner(0xc00011c900, 0x7be460) + /usr/lib/golang/src/testing/testing.go:1039 +0xdc + created by testing.(*T).Run + /usr/lib/golang/src/testing/testing.go:1090 +0x372 + exit status 2 + FAIL dvembed 8.691s + + */ + } + } +} diff --git a/format.go b/format.go index 914f15e..fb0a428 100644 --- a/format.go +++ b/format.go @@ -8,16 +8,15 @@ import ( ) type convertedMedia struct { - rawMedia - Ext string + os.FileInfo + Id string + Path string } - - // format handles file conversion and formatting with ffmpeg. // Discord allows a maximum 8MB file upload, so this is only // required if the size limit is exceeded. -func format(f rawMedia) (*convertedMedia, error) { +func format(f media) (*convertedMedia, error) { cmd := exec.Command( "cmd", "-i "+f.Name(), @@ -32,13 +31,15 @@ func format(f rawMedia) (*convertedMedia, error) { if err != nil { log.Fatalf("Failed: %v\n", cmd.Args) } - var cm convertedMedia - cm.Path = path.Join(cmd.Dir, f.Id+convertedExt) - cm.rawMedia.FileInfo, err = os.Stat(cm.Path) - cm. + cm := convertedMedia{ + FileInfo: nil, + Id: f.Id, + Path: "", + } + cm.FileInfo, err = os.Stat(cm.Path) if err != nil { - log.Println("Error finding formatted file") + log.Print("Error finding formatted file") } // TODO want to return output error from ffmpeg - return f, nil + return &cm, nil } diff --git a/format_test.go b/format_test.go index cacc374..feea89d 100644 --- a/format_test.go +++ b/format_test.go @@ -7,12 +7,12 @@ import ( func TestFormat(t *testing.T) { type args struct { - m rawMedia + m media } tests := []struct { name string args args - want rawMedia + want media wantErr bool }{ // TODO: Add test cases. diff --git a/handlers.go b/handlers.go index 158f0a7..a7d1df3 100644 --- a/handlers.go +++ b/handlers.go @@ -5,38 +5,37 @@ import ( "log" "net/url" "os" - "path" "strings" ) func handleVredditLink(s *discordgo.Session, m *discordgo.MessageCreate) { c := m.ChannelID - log.Printf("Message by %s contains v.redd.it link: %s\n", m.Author.Username, m.Content) + log.Printf("Message by %s contains v.redd.it link: %s", m.Author.Username, m.Content) log.Print("Message sent on channel: ", c) uu := strings.Split(m.Content, " ") for _, u := range uu { - if strings.Contains(u, "v.redd.it") { + if strings.Contains(u, "v.redd.it") || strings.Contains(u, "reddit.com") { u, err := url.Parse(u) if err != nil { - log.Printf("Message segment: `%s`, did not parse as URl: %v\n", u, err) + log.Printf("Message segment: `%s`, did not parse as URl: %v", u, err) continue } - log.Printf("Message segment: `%s`, is valid URl\n", u) + log.Printf("Message segment: `%s`, is valid URl", u) f, err := download(u.String()) if err != nil { - log.Println("Error downloading f") + log.Print("Error downloading f: ", err) continue } if f.Size() > 8000000 { log.Printf("%v bytes is too large for Discord upload", f.Size()) continue } - blank := &discordgo.MessageEmbed{} - _, err = s.ChannelMessageEditEmbed(c, m.ID, blank) + blank := discordgo.MessageEmbed{} + _, err = s.ChannelMessageEditEmbed(c, m.ID, &blank) if err != nil { - log.Printf("Error removing %s's embedded v.redd.it image", m.Author.Username) + log.Printf("Error removing %s's embedded v.redd.it image: %v", m.Author.Username, err) } - o, err := os.Open(path.Join(dir, f.Id, f.Name())) + o, err := os.Open(f.Path) if err != nil { log.Print("Error reading ", f.Name()) } @@ -50,21 +49,21 @@ func handleVredditLink(s *discordgo.Session, m *discordgo.MessageCreate) { } func handleRedditLink(s *discordgo.Session, m *discordgo.MessageCreate) { - log.Printf("Message by %s contains reddit link: %s\n", m.Author.Username, m.Content) - // TODO check if standard reddit link contains v.redd.it media through reddit api - uu := strings.Split(m.Content, " ") - for _, u := range uu { - if strings.Contains(u, "reddit.com") { - u, err := url.Parse(u) - if err != nil { - log.Printf("Message segment: `%s`, did not parse as URl: %v\n", u, err) - continue - } - log.Printf("Message segment: `%s`, is valid URl\n", u) - // getVredditLink(URL) - handleVredditLink(s, m) - } - } + log.Printf("Message by %s contains reddit link: %s", m.Author.Username, m.Content) + //// TODO check if standard reddit link contains v.redd.it media through reddit api + //uu := strings.Split(m.Content, " ") + //for _, u := range uu { + // if strings.Contains(u, "reddit.com") { + // u, err := url.Parse(u) + // if err != nil { + // log.Printf("Message segment: `%s`, did not parse as URl: %v", u, err) + // continue + // } + // log.Printf("Message segment: `%s`, is valid URl", u) + // // getVredditLink(URL) + // } + //} + handleVredditLink(s, m) } func handleImgurTest(s *discordgo.Session, m *discordgo.MessageCreate) { diff --git a/main.go b/main.go index 5b42d97..8403325 100644 --- a/main.go +++ b/main.go @@ -20,19 +20,18 @@ const ( func main() { err := os.MkdirAll(dir, 0755) if err != nil { - log.Printf("Error creating base download directory: %v\n", err) + log.Printf("Error creating base download directory: %v", err) } dg, err := discordgo.New("Bot " + TOKEN) if err != nil { - log.Fatalln("Error creating session: ", err) + log.Fatal("Error creating session: ", err) } dg.AddHandler(messageCreate) dg.Identify.Intents = discordgo.MakeIntent(discordgo.IntentsGuildMessages) err = dg.Open() if err != nil { - log.Print("Error opening Discord connection, ", err) - return + log.Fatal("Error opening Discord connection, ", err) } log.Print("dvembed bot is now running. Press CTRL-C to exit.") sc := make(chan os.Signal, 1) @@ -44,7 +43,7 @@ func main() { //app.Name = "dvembed" //app.Description = "Properly embeds media from v.redd.it" //app, err = dg.ApplicationCreate(app) - //log.Printf("ApplicationCreate: err: %+v, app: %+v\n", err, app) + //log.Printf("ApplicationCreate: err: %+v, app: %+v", err, app) } @@ -54,15 +53,15 @@ func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { return //c, err := s.State.Channel(m.ChannelID) //if err != nil { - // log.Printf("Could not find channel: %v\n", err) + // log.Printf("Could not find channel: %v", err) // return //} //g, err := s.State.Guild(c.GuildID) //if err != nil { - // log.Printf("Could not find the guild for channel: %v, %v\n", c, err) + // log.Printf("Could not find the guild for channel: %v, %v", c, err) // return //} - //log.Println(g) + //log.Print(g) } switch { case strings.Contains(m.Content, "v.redd.it"):