From 63b3b5128884eaa027ac9fd4722796adf901885f Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 20:44:09 +0100 Subject: [PATCH 01/37] Started adding verbose messages for the console --- Goopfile.lock | 8 ++++++++ main.go | 5 ++++- service_youtube.go | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 Goopfile.lock diff --git a/Goopfile.lock b/Goopfile.lock new file mode 100644 index 0000000..887e548 --- /dev/null +++ b/Goopfile.lock @@ -0,0 +1,8 @@ +code.google.com/p/gcfg #c2d3050044d0 +github.com/golang/protobuf #0f7a9caded1fb3c9cc5a9b4bcf2ff633cc8ae644 +github.com/jmoiron/jsonq #7c27c8eb9f6831555a4209f6a7d579159e766a3c +github.com/layeh/gopus #2f86fa22bc209cc0ccbc6418dfbad9199e3dbc78 +github.com/layeh/gumble/gumble #8b9989d9c4090874546c45ceaa6ff21e95705bc4 +github.com/layeh/gumble/gumble_ffmpeg #c9fcce8fc4b71c7c53a5d3d9d48a1e001ad19a19 +github.com/layeh/gumble/gumbleutil #abf58b0ea8b2661897f81cf69c2a6a3e37152d74 +github.com/timshannon/go-openal #f4fbb66b2922de93753ac8069ff62d20a56a7450 diff --git a/main.go b/main.go index 88bf38e..68aff92 100644 --- a/main.go +++ b/main.go @@ -35,6 +35,7 @@ type mumbledj struct { homeDir string playlistSkips map[string][]string cache *SongCache + verbose bool } // OnConnect event. First moves MumbleDJ into the default channel specified @@ -164,7 +165,7 @@ func main() { } var address, port, username, password, channel, pemCert, pemKey, accesstokens string - var insecure bool + var insecure, verbose bool flag.StringVar(&address, "server", "localhost", "address for Mumble server") flag.StringVar(&port, "port", "64738", "port for Mumble server") @@ -175,6 +176,7 @@ func main() { flag.StringVar(&pemKey, "key", "", "path to user PEM key for MumbleDJ") flag.StringVar(&accesstokens, "accesstokens", "", "list of access tokens for channel auth") flag.BoolVar(&insecure, "insecure", false, "skip certificate checking") + flag.BoolVar(&verbose, "verbose", false, "prints out debug messages to the console") flag.Parse() dj.config = gumble.Config{ @@ -201,6 +203,7 @@ func main() { } dj.defaultChannel = strings.Split(channel, "/") + dj.verbose = &verbose dj.client.Attach(gumbleutil.Listener{ Connect: dj.OnConnect, diff --git a/service_youtube.go b/service_youtube.go index b93b30a..d5ece7f 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -131,6 +131,11 @@ func NewYouTubeSong(user, id, offset string, playlist *YouTubePlaylist) (*YouTub dontSkip: false, } dj.queue.AddSong(song) + + if dj.verbose { + fmt.Printf("%s added track %s\n", song.Submitter, song.Title()) + } + return song, nil } return nil, errors.New("Song exceeds the maximum allowed duration.") @@ -139,14 +144,31 @@ func NewYouTubeSong(user, id, offset string, playlist *YouTubePlaylist) (*YouTub // Download downloads the song via youtube-dl if it does not already exist on disk. // All downloaded songs are stored in ~/.mumbledj/songs and should be automatically cleaned. func (s *YouTubeSong) Download() error { + + // Checks to see if song is already downloaded if _, err := os.Stat(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, s.Filename())); os.IsNotExist(err) { + + if dj.verbose { + fmt.Printf("Downloading %s\n", s.Title) + } + cmd := exec.Command("youtube-dl", "--output", fmt.Sprintf(`~/.mumbledj/songs/%s`, s.Filename()), "--format", "m4a", "--", s.ID()) if err := cmd.Run(); err == nil { if dj.conf.Cache.Enabled { dj.cache.CheckMaximumDirectorySize() } + + if dj.verbose { + fmt.Printf("%s downloaded\n", s.Title()) + } + return nil } + + if dj.verbose { + fmt.Printf("%s failed to download\n", s.Title()) + } + return errors.New("Song download failed.") } return nil @@ -199,6 +221,11 @@ func (s *YouTubeSong) Play() { dj.client.Self.Channel.Send(fmt.Sprintf(message, s.Thumbnail(), s.ID(), s.Title(), s.Duration(), s.Submitter(), s.Playlist().Title()), false) } + + if dj.verbose { + fmt.Printf("Now playing %s\n", s.Title()) + } + go func() { dj.audioStream.Wait() dj.queue.OnSongFinished() @@ -212,6 +239,9 @@ func (s *YouTubeSong) Delete() error { filePath := fmt.Sprintf("%s/.mumbledj/songs/%s.m4a", dj.homeDir, s.ID()) if _, err := os.Stat(filePath); err == nil { if err := os.Remove(filePath); err == nil { + if dj.verbose { + fmt.Printf("Deleting %s\n", s.Title()) + } return nil } return errors.New("Error occurred while deleting audio file.") @@ -402,6 +432,9 @@ func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) { dontSkip: false, } dj.queue.AddSong(playlistSong) + if dj.verbose { + fmt.Printf("%s added song %s\n", playlistSong.Submitter, playlistSong.Title()) + } } } return playlist, nil From 8928ea3b3dd4f477fca6e949fea8fb8adfde3e34 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 20:55:06 +0100 Subject: [PATCH 02/37] Fixing build error --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 68aff92..ab41f9a 100644 --- a/main.go +++ b/main.go @@ -203,7 +203,7 @@ func main() { } dj.defaultChannel = strings.Split(channel, "/") - dj.verbose = &verbose + dj.verbose = verbose dj.client.Attach(gumbleutil.Listener{ Connect: dj.OnConnect, From 7b737b03ab1bbee2771fa242c1612b465c8f64c0 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:13:40 +0100 Subject: [PATCH 03/37] Started work on interfacing services --- commands.go | 18 +++++++++++++++++- service.go | 11 +++++++++++ service_youtube.go | 45 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/commands.go b/commands.go index a313ae6..7bc5c22 100644 --- a/commands.go +++ b/commands.go @@ -158,12 +158,28 @@ func parseCommand(user *gumble.User, username, command string) { } } -// add performs !add functionality. Checks input URL for YouTube format, and adds +// add performs !add functionality. Checks input URL for service, and adds // the URL to the queue if the format matches. func add(user *gumble.User, username, url string) { if url == "" { dj.SendPrivateMessage(user, NO_ARGUMENT_MSG) } else { + var urlService *Service + + // Checks all services to see if any can take the URL + for _, service := range services { + if service.URLRegex(url) { + urlService = service + } + } + + if urlService == nil { + dj.SendPrivateMessage(user, INVALID_URL_MSG) + } + // else { + // urlService.NewRequest(user, url) + // } + youtubePatterns := []string{ `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, diff --git a/service.go b/service.go index 205c277..1015395 100644 --- a/service.go +++ b/service.go @@ -7,6 +7,13 @@ package main +// Service interface. Each service should implement these functions +type Service interface { + ServiceName() string + URLRegex(string) bool // Can service deal with URL + NewRequest(*gumble.User, string) error // Create song/playlist and add to the queue +} + // Song interface. Each service will implement these // functions in their Song types. type Song interface { @@ -37,3 +44,7 @@ type Playlist interface { ID() string Title() string } + +var services = []Service{ + YoutubeService{}, +} diff --git a/service_youtube.go b/service_youtube.go index d5ece7f..23a9b68 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -24,6 +24,47 @@ import ( "github.com/layeh/gumble/gumble_ffmpeg" ) +// --------------- +// YOUTUBE SERVICE +// --------------- + +type YouTubeService struct { +} + +// Name of the service +func (yt *YoutubeService) ServiceName() string { + return "Youtube" +} + +// Checks to see if service will accept URL +func (yt *YoutubeService) URLRegex(url) bool { + youtubePatterns := []string{ + `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, + `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, + `https?:\/\/youtu.be\/([\w-]+)(\?t=\d*m?\d*s?)?`, + `https?:\/\/youtube.com\/v\/([\w-]+)(\?t=\d*m?\d*s?)?`, + `https?:\/\/www.youtube.com\/v\/([\w-]+)(\?t=\d*m?\d*s?)?`, + `https?:\/\/www\.youtube\.com\/playlist\?list=([\w-]+)`, + } + matchFound := false + + for _, pattern := range youtubePatterns { + if re, err := regexp.Compile(pattern); err == nil { + if re.MatchString(url) { + matchFound = true + break + } + } + } + + return matchFound +} + +// Creates the requested song/playlist and adds to the queue +func (yt *YoutubeService) NewRequest(user, url) { + +} + // ------------ // YOUTUBE SONG // ------------ @@ -149,7 +190,7 @@ func (s *YouTubeSong) Download() error { if _, err := os.Stat(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, s.Filename())); os.IsNotExist(err) { if dj.verbose { - fmt.Printf("Downloading %s\n", s.Title) + fmt.Printf("Downloading %s\n", s.Title()) } cmd := exec.Command("youtube-dl", "--output", fmt.Sprintf(`~/.mumbledj/songs/%s`, s.Filename()), "--format", "m4a", "--", s.ID()) @@ -433,7 +474,7 @@ func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) { } dj.queue.AddSong(playlistSong) if dj.verbose { - fmt.Printf("%s added song %s\n", playlistSong.Submitter, playlistSong.Title()) + fmt.Printf("%s added song %s\n", playlistSong.Submitter(), playlistSong.Title()) } } } From 5e0f48803fcd879149f066031b36f98e68a9b538 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:17:42 +0100 Subject: [PATCH 04/37] Fixing build issues --- service_youtube.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/service_youtube.go b/service_youtube.go index 23a9b68..67bc4e0 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -32,12 +32,12 @@ type YouTubeService struct { } // Name of the service -func (yt *YoutubeService) ServiceName() string { +func (yt YoutubeService) ServiceName() string { return "Youtube" } // Checks to see if service will accept URL -func (yt *YoutubeService) URLRegex(url) bool { +func (yt YoutubeService) URLRegex(url) bool { youtubePatterns := []string{ `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, @@ -61,7 +61,7 @@ func (yt *YoutubeService) URLRegex(url) bool { } // Creates the requested song/playlist and adds to the queue -func (yt *YoutubeService) NewRequest(user, url) { +func (yt YoutubeService) NewRequest(user, url) { } From 28332a78ab750b6c13d7b3dc843ed27da002bacc Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:24:35 +0100 Subject: [PATCH 05/37] Fixing build issues --- service.go | 2 +- service_youtube.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/service.go b/service.go index 1015395..cad8963 100644 --- a/service.go +++ b/service.go @@ -46,5 +46,5 @@ type Playlist interface { } var services = []Service{ - YoutubeService{}, + new(YoutubeService), } diff --git a/service_youtube.go b/service_youtube.go index 67bc4e0..23a9b68 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -32,12 +32,12 @@ type YouTubeService struct { } // Name of the service -func (yt YoutubeService) ServiceName() string { +func (yt *YoutubeService) ServiceName() string { return "Youtube" } // Checks to see if service will accept URL -func (yt YoutubeService) URLRegex(url) bool { +func (yt *YoutubeService) URLRegex(url) bool { youtubePatterns := []string{ `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, @@ -61,7 +61,7 @@ func (yt YoutubeService) URLRegex(url) bool { } // Creates the requested song/playlist and adds to the queue -func (yt YoutubeService) NewRequest(user, url) { +func (yt *YoutubeService) NewRequest(user, url) { } From 6bae3203e84ff24948090ab4f40a5ef41841c5fd Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:27:23 +0100 Subject: [PATCH 06/37] Fixing build issues --- service.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/service.go b/service.go index cad8963..af598ef 100644 --- a/service.go +++ b/service.go @@ -7,6 +7,13 @@ package main +import ( + "github.com/layeh/gopus" + "github.com/layeh/gumble/gumble" + "github.com/layeh/gumble/gumble_ffmpeg" + "github.com/layeh/gumble/gumbleutil" +) + // Service interface. Each service should implement these functions type Service interface { ServiceName() string From a876a9801428c653f8d7d83c9cb1f93c6e687c5f Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:29:50 +0100 Subject: [PATCH 07/37] Fixing build issues --- service.go | 3 --- service_youtube.go | 5 +++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/service.go b/service.go index af598ef..dabaa69 100644 --- a/service.go +++ b/service.go @@ -8,10 +8,7 @@ package main import ( - "github.com/layeh/gopus" "github.com/layeh/gumble/gumble" - "github.com/layeh/gumble/gumble_ffmpeg" - "github.com/layeh/gumble/gumbleutil" ) // Service interface. Each service should implement these functions diff --git a/service_youtube.go b/service_youtube.go index 23a9b68..0be1734 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -21,6 +21,7 @@ import ( "time" "github.com/jmoiron/jsonq" + "github.com/layeh/gumble/gumble" "github.com/layeh/gumble/gumble_ffmpeg" ) @@ -37,7 +38,7 @@ func (yt *YoutubeService) ServiceName() string { } // Checks to see if service will accept URL -func (yt *YoutubeService) URLRegex(url) bool { +func (yt *YoutubeService) URLRegex(url string) bool { youtubePatterns := []string{ `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, @@ -61,7 +62,7 @@ func (yt *YoutubeService) URLRegex(url) bool { } // Creates the requested song/playlist and adds to the queue -func (yt *YoutubeService) NewRequest(user, url) { +func (yt *YoutubeService) NewRequest(user *gumble.User, url string) { } From 7ce5572d9c864b023d5b695994f93ba44c33b7d9 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:31:10 +0100 Subject: [PATCH 08/37] Fixing build issues --- service.go | 2 +- service_youtube.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/service.go b/service.go index dabaa69..b1e8ff2 100644 --- a/service.go +++ b/service.go @@ -50,5 +50,5 @@ type Playlist interface { } var services = []Service{ - new(YoutubeService), + new(*YoutubeService), } diff --git a/service_youtube.go b/service_youtube.go index 0be1734..4abd1f6 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -33,12 +33,12 @@ type YouTubeService struct { } // Name of the service -func (yt *YoutubeService) ServiceName() string { +func (yt YoutubeService) ServiceName() string { return "Youtube" } // Checks to see if service will accept URL -func (yt *YoutubeService) URLRegex(url string) bool { +func (yt YoutubeService) URLRegex(url string) bool { youtubePatterns := []string{ `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, @@ -62,7 +62,7 @@ func (yt *YoutubeService) URLRegex(url string) bool { } // Creates the requested song/playlist and adds to the queue -func (yt *YoutubeService) NewRequest(user *gumble.User, url string) { +func (yt YoutubeService) NewRequest(user *gumble.User, url string) { } From 3f9613e0f3ba5aab6dbcff036844d129fd5f3cdc Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:34:35 +0100 Subject: [PATCH 09/37] Fixing build issues --- service.go | 4 ---- service_youtube.go | 12 ++++++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/service.go b/service.go index b1e8ff2..4c4a03b 100644 --- a/service.go +++ b/service.go @@ -48,7 +48,3 @@ type Playlist interface { ID() string Title() string } - -var services = []Service{ - new(*YoutubeService), -} diff --git a/service_youtube.go b/service_youtube.go index 4abd1f6..b99d48f 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -29,16 +29,20 @@ import ( // YOUTUBE SERVICE // --------------- -type YouTubeService struct { +var services = []Service{ + Youtube{}, +} + +type YouTube struct { } // Name of the service -func (yt YoutubeService) ServiceName() string { +func (y Youtube) ServiceName() string { return "Youtube" } // Checks to see if service will accept URL -func (yt YoutubeService) URLRegex(url string) bool { +func (y Youtube) URLRegex(url string) bool { youtubePatterns := []string{ `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, @@ -62,7 +66,7 @@ func (yt YoutubeService) URLRegex(url string) bool { } // Creates the requested song/playlist and adds to the queue -func (yt YoutubeService) NewRequest(user *gumble.User, url string) { +func (y Youtube) NewRequest(user *gumble.User, url string) { } From 6352f600980a8f871defff2ed1d426d3ce66c403 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:35:27 +0100 Subject: [PATCH 10/37] Fixing build issues --- service_youtube.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/service_youtube.go b/service_youtube.go index b99d48f..1420492 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -29,11 +29,11 @@ import ( // YOUTUBE SERVICE // --------------- -var services = []Service{ - Youtube{}, +type YouTube struct { } -type YouTube struct { +var services = []Service{ + Youtube{}, } // Name of the service From df35fccb97f46b17d09dcf19316735199d8ad453 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:38:21 +0100 Subject: [PATCH 11/37] Fixing build issues --- main.go | 3 +++ service_youtube.go | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index ab41f9a..ddf6404 100644 --- a/main.go +++ b/main.go @@ -148,11 +148,14 @@ var dj = mumbledj{ cache: NewSongCache(), } +var services []Service + // main primarily performs startup tasks. Grabs and parses commandline // args, sets up the gumble client and its listeners, and then connects to the server. func main() { PerformStartupChecks() + services = []Service{Youtube{}} if currentUser, err := user.Current(); err == nil { dj.homeDir = currentUser.HomeDir diff --git a/service_youtube.go b/service_youtube.go index 1420492..18f8f6d 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -32,10 +32,6 @@ import ( type YouTube struct { } -var services = []Service{ - Youtube{}, -} - // Name of the service func (y Youtube) ServiceName() string { return "Youtube" From 578a4eb6260817b7e9251fc7d429b8cb5172d0a8 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:39:39 +0100 Subject: [PATCH 12/37] Fixing build issues --- main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index ddf6404..376acb8 100644 --- a/main.go +++ b/main.go @@ -148,14 +148,14 @@ var dj = mumbledj{ cache: NewSongCache(), } -var services []Service +var services []*Service // main primarily performs startup tasks. Grabs and parses commandline // args, sets up the gumble client and its listeners, and then connects to the server. func main() { PerformStartupChecks() - services = []Service{Youtube{}} + services = []*Service{Youtube{}} if currentUser, err := user.Current(); err == nil { dj.homeDir = currentUser.HomeDir From f50c1b9d1bab5e77d387c5b3b48e7654a3f9b487 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:46:13 +0100 Subject: [PATCH 13/37] Fixing build issues --- main.go | 2 +- service_youtube.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index 376acb8..4f28da0 100644 --- a/main.go +++ b/main.go @@ -155,7 +155,7 @@ var services []*Service func main() { PerformStartupChecks() - services = []*Service{Youtube{}} + services = []Service{new(Youtube)} if currentUser, err := user.Current(); err == nil { dj.homeDir = currentUser.HomeDir diff --git a/service_youtube.go b/service_youtube.go index 18f8f6d..67aefb7 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -33,12 +33,12 @@ type YouTube struct { } // Name of the service -func (y Youtube) ServiceName() string { +func (y *Youtube) ServiceName() string { return "Youtube" } // Checks to see if service will accept URL -func (y Youtube) URLRegex(url string) bool { +func (y *Youtube) URLRegex(url string) bool { youtubePatterns := []string{ `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, @@ -62,7 +62,7 @@ func (y Youtube) URLRegex(url string) bool { } // Creates the requested song/playlist and adds to the queue -func (y Youtube) NewRequest(user *gumble.User, url string) { +func (y *Youtube) NewRequest(user *gumble.User, url string) { } From 5d02cdb4a5de984a906f2dd65564c70a3f4a60e1 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:48:56 +0100 Subject: [PATCH 14/37] Fixing build issues --- commands.go | 2 +- main.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/commands.go b/commands.go index 7bc5c22..2e8f205 100644 --- a/commands.go +++ b/commands.go @@ -164,7 +164,7 @@ func add(user *gumble.User, username, url string) { if url == "" { dj.SendPrivateMessage(user, NO_ARGUMENT_MSG) } else { - var urlService *Service + var urlService Service // Checks all services to see if any can take the URL for _, service := range services { diff --git a/main.go b/main.go index 4f28da0..ddf6404 100644 --- a/main.go +++ b/main.go @@ -148,14 +148,14 @@ var dj = mumbledj{ cache: NewSongCache(), } -var services []*Service +var services []Service // main primarily performs startup tasks. Grabs and parses commandline // args, sets up the gumble client and its listeners, and then connects to the server. func main() { PerformStartupChecks() - services = []Service{new(Youtube)} + services = []Service{Youtube{}} if currentUser, err := user.Current(); err == nil { dj.homeDir = currentUser.HomeDir From 634c948ddfce8d0538794a014e9cf4b179afeff5 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:49:53 +0100 Subject: [PATCH 15/37] Fixing build issues --- service_youtube.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/service_youtube.go b/service_youtube.go index 67aefb7..18f8f6d 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -33,12 +33,12 @@ type YouTube struct { } // Name of the service -func (y *Youtube) ServiceName() string { +func (y Youtube) ServiceName() string { return "Youtube" } // Checks to see if service will accept URL -func (y *Youtube) URLRegex(url string) bool { +func (y Youtube) URLRegex(url string) bool { youtubePatterns := []string{ `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, @@ -62,7 +62,7 @@ func (y *Youtube) URLRegex(url string) bool { } // Creates the requested song/playlist and adds to the queue -func (y *Youtube) NewRequest(user *gumble.User, url string) { +func (y Youtube) NewRequest(user *gumble.User, url string) { } From 4cfb1c19f9f2249ae50571bd7d7f83a5f3b45559 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 22:52:45 +0100 Subject: [PATCH 16/37] Fixing build issues --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index ddf6404..6f7e2ab 100644 --- a/main.go +++ b/main.go @@ -155,7 +155,7 @@ var services []Service func main() { PerformStartupChecks() - services = []Service{Youtube{}} + services = []Service{new(Youtube)} if currentUser, err := user.Current(); err == nil { dj.homeDir = currentUser.HomeDir From 8604bae69ca98a1c8c002418cf2117e8a44eaf78 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 23:00:32 +0100 Subject: [PATCH 17/37] Fixing build issues --- main.go | 3 --- service.go | 2 ++ service_youtube.go | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/main.go b/main.go index 6f7e2ab..ab41f9a 100644 --- a/main.go +++ b/main.go @@ -148,14 +148,11 @@ var dj = mumbledj{ cache: NewSongCache(), } -var services []Service - // main primarily performs startup tasks. Grabs and parses commandline // args, sets up the gumble client and its listeners, and then connects to the server. func main() { PerformStartupChecks() - services = []Service{new(Youtube)} if currentUser, err := user.Current(); err == nil { dj.homeDir = currentUser.HomeDir diff --git a/service.go b/service.go index 4c4a03b..541605b 100644 --- a/service.go +++ b/service.go @@ -48,3 +48,5 @@ type Playlist interface { ID() string Title() string } + +var services = []Service{YouTube{}} diff --git a/service_youtube.go b/service_youtube.go index 18f8f6d..f36050b 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -33,12 +33,12 @@ type YouTube struct { } // Name of the service -func (y Youtube) ServiceName() string { +func (y YouTube) ServiceName() string { return "Youtube" } // Checks to see if service will accept URL -func (y Youtube) URLRegex(url string) bool { +func (y YouTube) URLRegex(url string) bool { youtubePatterns := []string{ `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, @@ -62,7 +62,7 @@ func (y Youtube) URLRegex(url string) bool { } // Creates the requested song/playlist and adds to the queue -func (y Youtube) NewRequest(user *gumble.User, url string) { +func (y YouTube) NewRequest(user *gumble.User, url string) { } From 31f467591c537254c042f043d15f8ca131dc15da Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 23:01:31 +0100 Subject: [PATCH 18/37] Fixing build issues --- service_youtube.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/service_youtube.go b/service_youtube.go index f36050b..41a0e28 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -62,8 +62,8 @@ func (y YouTube) URLRegex(url string) bool { } // Creates the requested song/playlist and adds to the queue -func (y YouTube) NewRequest(user *gumble.User, url string) { - +func (y YouTube) NewRequest(user *gumble.User, url string) error { + return nil } // ------------ From 13feac24bde26974067d96723d347bc3d5c8a652 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 23:30:59 +0100 Subject: [PATCH 19/37] Fixing build issues --- commands.go | 5 ++--- service_youtube.go | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/commands.go b/commands.go index 2e8f205..0d32d30 100644 --- a/commands.go +++ b/commands.go @@ -175,10 +175,9 @@ func add(user *gumble.User, username, url string) { if urlService == nil { dj.SendPrivateMessage(user, INVALID_URL_MSG) + } else { + urlService.NewRequest(user, url) } - // else { - // urlService.NewRequest(user, url) - // } youtubePatterns := []string{ `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, diff --git a/service_youtube.go b/service_youtube.go index 41a0e28..587f564 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -63,7 +63,27 @@ func (y YouTube) URLRegex(url string) bool { // Creates the requested song/playlist and adds to the queue func (y YouTube) NewRequest(user *gumble.User, url string) error { - return nil + var matches, shortURL, startOffset + youtubePlaylistPattern := `https?:\/\/www\.youtube\.com\/playlist\?list=([\w-]+)` + if re, err := regexp.Compile(youtubePlaylistPattern); err == nil { + if re.MatchString(url) { + if dj.HasPermission(username, dj.conf.Permissions.AdminAddPlaylists) { + shortURL = re.FindStringSubmatch(url)[1] + NewYouTubePlaylist(username, shortURL) + } else { + return errors.new("NO_PLAYLIST_PERMISSION") + } + } else { + matches = re.FindAllStringSubmatch(url, -1) + shortURL = matches[0][1] + if len(matches[0]) == 3 { + startOffset = matches[0][2] + } + NewYouTubeSong(user, shortURL, startOffset, nil) + } + return nil + } + return err } // ------------ From 1ec27383af810732321fa0ce4b340fab98ac3181 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 23:35:19 +0100 Subject: [PATCH 20/37] Fixing build issues --- service_youtube.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/service_youtube.go b/service_youtube.go index 587f564..640b244 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -63,15 +63,14 @@ func (y YouTube) URLRegex(url string) bool { // Creates the requested song/playlist and adds to the queue func (y YouTube) NewRequest(user *gumble.User, url string) error { - var matches, shortURL, startOffset youtubePlaylistPattern := `https?:\/\/www\.youtube\.com\/playlist\?list=([\w-]+)` if re, err := regexp.Compile(youtubePlaylistPattern); err == nil { if re.MatchString(url) { - if dj.HasPermission(username, dj.conf.Permissions.AdminAddPlaylists) { - shortURL = re.FindStringSubmatch(url)[1] - NewYouTubePlaylist(username, shortURL) + if dj.HasPermission(user.Name, dj.conf.Permissions.AdminAddPlaylists) { + shortURL := re.FindStringSubmatch(url)[1] + NewYouTubePlaylist(user.Name, shortURL) } else { - return errors.new("NO_PLAYLIST_PERMISSION") + return errors.New("NO_PLAYLIST_PERMISSION") } } else { matches = re.FindAllStringSubmatch(url, -1) @@ -79,7 +78,7 @@ func (y YouTube) NewRequest(user *gumble.User, url string) error { if len(matches[0]) == 3 { startOffset = matches[0][2] } - NewYouTubeSong(user, shortURL, startOffset, nil) + NewYouTubeSong(user.Name, shortURL, startOffset, nil) } return nil } From 381da0faca82f7c0818fae99f47a3fb5272a7e2f Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 23:36:50 +0100 Subject: [PATCH 21/37] Fixing build issues --- service_youtube.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/service_youtube.go b/service_youtube.go index 640b244..09768ff 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -63,17 +63,20 @@ func (y YouTube) URLRegex(url string) bool { // Creates the requested song/playlist and adds to the queue func (y YouTube) NewRequest(user *gumble.User, url string) error { + shortURL := "" + startOffset := "" youtubePlaylistPattern := `https?:\/\/www\.youtube\.com\/playlist\?list=([\w-]+)` + if re, err := regexp.Compile(youtubePlaylistPattern); err == nil { if re.MatchString(url) { if dj.HasPermission(user.Name, dj.conf.Permissions.AdminAddPlaylists) { - shortURL := re.FindStringSubmatch(url)[1] + shortURL = re.FindStringSubmatch(url)[1] NewYouTubePlaylist(user.Name, shortURL) } else { return errors.New("NO_PLAYLIST_PERMISSION") } } else { - matches = re.FindAllStringSubmatch(url, -1) + matches := re.FindAllStringSubmatch(url, -1) shortURL = matches[0][1] if len(matches[0]) == 3 { startOffset = matches[0][2] From 2da725e736a4c5c5ae3cf24c4d4a31c4d616c32b Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 23:37:52 +0100 Subject: [PATCH 22/37] Fixing build issues --- service_youtube.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/service_youtube.go b/service_youtube.go index 09768ff..74e605b 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -84,8 +84,9 @@ func (y YouTube) NewRequest(user *gumble.User, url string) error { NewYouTubeSong(user.Name, shortURL, startOffset, nil) } return nil + } else { + return err } - return err } // ------------ From 603e1c443a63595c73f63265f8bd755050b0651f Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 23:41:27 +0100 Subject: [PATCH 23/37] Fixing build issues --- service_youtube.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/service_youtube.go b/service_youtube.go index 74e605b..15cecd6 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -71,7 +71,7 @@ func (y YouTube) NewRequest(user *gumble.User, url string) error { if re.MatchString(url) { if dj.HasPermission(user.Name, dj.conf.Permissions.AdminAddPlaylists) { shortURL = re.FindStringSubmatch(url)[1] - NewYouTubePlaylist(user.Name, shortURL) + NewYouTubePlaylist(user, shortURL) } else { return errors.New("NO_PLAYLIST_PERMISSION") } @@ -81,7 +81,7 @@ func (y YouTube) NewRequest(user *gumble.User, url string) error { if len(matches[0]) == 3 { startOffset = matches[0][2] } - NewYouTubeSong(user.Name, shortURL, startOffset, nil) + NewYouTubeSong(user, shortURL, startOffset, nil) } return nil } else { From 57e3c50e04f0c5695bb6f5b593942a0cc44ec5f7 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Mon, 27 Jul 2015 23:44:09 +0100 Subject: [PATCH 24/37] Fixing build issues --- service_youtube.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/service_youtube.go b/service_youtube.go index 15cecd6..74e605b 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -71,7 +71,7 @@ func (y YouTube) NewRequest(user *gumble.User, url string) error { if re.MatchString(url) { if dj.HasPermission(user.Name, dj.conf.Permissions.AdminAddPlaylists) { shortURL = re.FindStringSubmatch(url)[1] - NewYouTubePlaylist(user, shortURL) + NewYouTubePlaylist(user.Name, shortURL) } else { return errors.New("NO_PLAYLIST_PERMISSION") } @@ -81,7 +81,7 @@ func (y YouTube) NewRequest(user *gumble.User, url string) error { if len(matches[0]) == 3 { startOffset = matches[0][2] } - NewYouTubeSong(user, shortURL, startOffset, nil) + NewYouTubeSong(user.Name, shortURL, startOffset, nil) } return nil } else { From eb454af34f6a795d48f479cdff5774cf6266a70e Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 00:11:35 +0100 Subject: [PATCH 25/37] Fixing build issues --- service_youtube.go | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/service_youtube.go b/service_youtube.go index 74e605b..85ffa52 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -25,6 +25,15 @@ import ( "github.com/layeh/gumble/gumble_ffmpeg" ) +var youtubePlaylistPattern = `https?:\/\/www\.youtube\.com\/playlist\?list=([\w-]+)` +var youtubeVideoPatterns = []string{ + `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, + `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, + `https?:\/\/youtu.be\/([\w-]+)(\?t=\d*m?\d*s?)?`, + `https?:\/\/youtube.com\/v\/([\w-]+)(\?t=\d*m?\d*s?)?`, + `https?:\/\/www.youtube.com\/v\/([\w-]+)(\?t=\d*m?\d*s?)?`, +} + // --------------- // YOUTUBE SERVICE // --------------- @@ -39,43 +48,34 @@ func (y YouTube) ServiceName() string { // Checks to see if service will accept URL func (y YouTube) URLRegex(url string) bool { - youtubePatterns := []string{ - `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, - `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, - `https?:\/\/youtu.be\/([\w-]+)(\?t=\d*m?\d*s?)?`, - `https?:\/\/youtube.com\/v\/([\w-]+)(\?t=\d*m?\d*s?)?`, - `https?:\/\/www.youtube.com\/v\/([\w-]+)(\?t=\d*m?\d*s?)?`, - `https?:\/\/www\.youtube\.com\/playlist\?list=([\w-]+)`, - } - matchFound := false + return RegexpFromURL(url, append(youtubeVideoPatterns, []string{youtubePlaylistPattern}...)) != nil +} - for _, pattern := range youtubePatterns { +func RegexpFromURL(url string, patterns []string) *regexp.Regexp { + for _, pattern := range patterns { if re, err := regexp.Compile(pattern); err == nil { if re.MatchString(url) { - matchFound = true - break + return re } } } - - return matchFound + return nil } // Creates the requested song/playlist and adds to the queue func (y YouTube) NewRequest(user *gumble.User, url string) error { - shortURL := "" - startOffset := "" - youtubePlaylistPattern := `https?:\/\/www\.youtube\.com\/playlist\?list=([\w-]+)` - + var shortURL, startOffset = "" if re, err := regexp.Compile(youtubePlaylistPattern); err == nil { if re.MatchString(url) { if dj.HasPermission(user.Name, dj.conf.Permissions.AdminAddPlaylists) { shortURL = re.FindStringSubmatch(url)[1] - NewYouTubePlaylist(user.Name, shortURL) + _, err := NewYouTubePlaylist(user.Name, shortURL) + return err } else { return errors.New("NO_PLAYLIST_PERMISSION") } } else { + re = RegexpFromURL(url, youtubeVideoPatterns) matches := re.FindAllStringSubmatch(url, -1) shortURL = matches[0][1] if len(matches[0]) == 3 { @@ -83,7 +83,6 @@ func (y YouTube) NewRequest(user *gumble.User, url string) error { } NewYouTubeSong(user.Name, shortURL, startOffset, nil) } - return nil } else { return err } From c64ce68e856270947c3c9f98a68127459818b7ce Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 00:13:13 +0100 Subject: [PATCH 26/37] Fixing build issues --- service_youtube.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/service_youtube.go b/service_youtube.go index 85ffa52..1730a12 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -64,7 +64,7 @@ func RegexpFromURL(url string, patterns []string) *regexp.Regexp { // Creates the requested song/playlist and adds to the queue func (y YouTube) NewRequest(user *gumble.User, url string) error { - var shortURL, startOffset = "" + var shortURL, startOffset = "", "" if re, err := regexp.Compile(youtubePlaylistPattern); err == nil { if re.MatchString(url) { if dj.HasPermission(user.Name, dj.conf.Permissions.AdminAddPlaylists) { @@ -81,7 +81,8 @@ func (y YouTube) NewRequest(user *gumble.User, url string) error { if len(matches[0]) == 3 { startOffset = matches[0][2] } - NewYouTubeSong(user.Name, shortURL, startOffset, nil) + _, err := NewYouTubeSong(user.Name, shortURL, startOffset, nil) + return err } } else { return err From 962c894f7926df0f08657b8ea57015a5560156f7 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 00:19:10 +0100 Subject: [PATCH 27/37] Fixing build issues --- commands.go | 75 ++++++----------------------------------------------- 1 file changed, 8 insertions(+), 67 deletions(-) diff --git a/commands.go b/commands.go index 0d32d30..b144f6e 100644 --- a/commands.go +++ b/commands.go @@ -176,45 +176,15 @@ func add(user *gumble.User, username, url string) { if urlService == nil { dj.SendPrivateMessage(user, INVALID_URL_MSG) } else { + oldLength := dj.queue.Len() urlService.NewRequest(user, url) - } - - youtubePatterns := []string{ - `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, - `https?:\/\/youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, - `https?:\/\/youtu.be\/([\w-]+)(\?t=\d*m?\d*s?)?`, - `https?:\/\/youtube.com\/v\/([\w-]+)(\?t=\d*m?\d*s?)?`, - `https?:\/\/www.youtube.com\/v\/([\w-]+)(\?t=\d*m?\d*s?)?`, - } - matchFound := false - shortURL := "" - startOffset := "" - - for _, pattern := range youtubePatterns { - if re, err := regexp.Compile(pattern); err == nil { - if re.MatchString(url) { - matchFound = true - matches := re.FindAllStringSubmatch(url, -1) - shortURL = matches[0][1] - if len(matches[0]) == 3 { - startOffset = matches[0][2] - } - break - } - } - } - - if matchFound { - if newSong, err := NewYouTubeSong(username, shortURL, startOffset, nil); err == nil { - dj.client.Self.Channel.Send(fmt.Sprintf(SONG_ADDED_HTML, username, newSong.title), false) - if dj.queue.Len() == 1 && !dj.audioStream.IsPlaying() { - if err := dj.queue.CurrentSong().Download(); err == nil { - dj.queue.CurrentSong().Play() - } else { - dj.SendPrivateMessage(user, AUDIO_FAIL_MSG) - dj.queue.CurrentSong().Delete() - dj.queue.OnSongFinished() - } + if oldLength == 0 && dj.queue.Len() != 0 && !dj.audioStream.IsPlaying() { + if err := dj.queue.CurrentSong().Download(); err == nil { + dj.queue.CurrentSong().Play() + } else { + dj.SendPrivateMessage(user, AUDIO_FAIL_MSG) + dj.queue.CurrentSong().Delete() + dj.queue.OnSongFinished() } } else if fmt.Sprint(err) == "Song exceeds the maximum allowed duration." { dj.SendPrivateMessage(user, VIDEO_TOO_LONG_MSG) @@ -223,35 +193,6 @@ func add(user *gumble.User, username, url string) { } else { dj.SendPrivateMessage(user, INVALID_YOUTUBE_ID_MSG) } - } else { - // Check to see if we have a playlist URL instead. - youtubePlaylistPattern := `https?:\/\/www\.youtube\.com\/playlist\?list=([\w-]+)` - if re, err := regexp.Compile(youtubePlaylistPattern); err == nil { - if re.MatchString(url) { - if dj.HasPermission(username, dj.conf.Permissions.AdminAddPlaylists) { - shortURL = re.FindStringSubmatch(url)[1] - oldLength := dj.queue.Len() - if newPlaylist, err := NewYouTubePlaylist(username, shortURL); err == nil { - dj.client.Self.Channel.Send(fmt.Sprintf(PLAYLIST_ADDED_HTML, username, newPlaylist.title), false) - if oldLength == 0 && dj.queue.Len() != 0 && !dj.audioStream.IsPlaying() { - if err := dj.queue.CurrentSong().Download(); err == nil { - dj.queue.CurrentSong().Play() - } else { - dj.SendPrivateMessage(user, AUDIO_FAIL_MSG) - dj.queue.CurrentSong().Delete() - dj.queue.OnSongFinished() - } - } - } else { - dj.SendPrivateMessage(user, INVALID_YOUTUBE_ID_MSG) - } - } else { - dj.SendPrivateMessage(user, NO_PLAYLIST_PERMISSION_MSG) - } - } else { - dj.SendPrivateMessage(user, INVALID_URL_MSG) - } - } } } } From 020c12e67d295905cc8a23ef8e25fa6b42fe16cd Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 00:21:02 +0100 Subject: [PATCH 28/37] Fixing build issues --- commands.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/commands.go b/commands.go index b144f6e..b02b819 100644 --- a/commands.go +++ b/commands.go @@ -11,7 +11,6 @@ import ( "errors" "fmt" "os" - "regexp" "strconv" "strings" @@ -186,12 +185,6 @@ func add(user *gumble.User, username, url string) { dj.queue.CurrentSong().Delete() dj.queue.OnSongFinished() } - } else if fmt.Sprint(err) == "Song exceeds the maximum allowed duration." { - dj.SendPrivateMessage(user, VIDEO_TOO_LONG_MSG) - } else if fmt.Sprint(err) == "Invalid API key supplied." { - dj.SendPrivateMessage(user, INVALID_API_KEY) - } else { - dj.SendPrivateMessage(user, INVALID_YOUTUBE_ID_MSG) } } } From 1c5f0f33bf9ed5e60b16f713329377cc51b6bd9c Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 12:35:52 +0100 Subject: [PATCH 29/37] Fixing build issues --- commands.go | 23 ++++++---- main.go | 6 +++ service_youtube.go | 106 +++++---------------------------------------- 3 files changed, 33 insertions(+), 102 deletions(-) diff --git a/commands.go b/commands.go index b02b819..6a9ad2e 100644 --- a/commands.go +++ b/commands.go @@ -176,15 +176,22 @@ func add(user *gumble.User, username, url string) { dj.SendPrivateMessage(user, INVALID_URL_MSG) } else { oldLength := dj.queue.Len() - urlService.NewRequest(user, url) - if oldLength == 0 && dj.queue.Len() != 0 && !dj.audioStream.IsPlaying() { - if err := dj.queue.CurrentSong().Download(); err == nil { - dj.queue.CurrentSong().Play() - } else { - dj.SendPrivateMessage(user, AUDIO_FAIL_MSG) - dj.queue.CurrentSong().Delete() - dj.queue.OnSongFinished() + + if err := urlService.NewRequest(user, url); err == nil { + dj.client.Self.Channel.Send(SONG_ADDED_HTML, false) + + // Starts playing the new song if nothing else is playing + if oldLength == 0 && dj.queue.Len() != 0 && !dj.audioStream.IsPlaying() { + if err := dj.queue.CurrentSong().Download(); err == nil { + dj.queue.CurrentSong().Play() + } else { + dj.SendPrivateMessage(user, AUDIO_FAIL_MSG) + dj.queue.CurrentSong().Delete() + dj.queue.OnSongFinished() + } } + } else { + dj.SendPrivateMessage(user, err) } } } diff --git a/main.go b/main.go index ab41f9a..982d3a3 100644 --- a/main.go +++ b/main.go @@ -140,6 +140,12 @@ func PerformStartupChecks() { } } +func Verbose(msg string) { + if dj.verbose { + fmt.Printf(msg) + } +} + // dj variable declaration. This is done outside of main() to allow global use. var dj = mumbledj{ keepAlive: make(chan bool), diff --git a/service_youtube.go b/service_youtube.go index 1730a12..93e8030 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -25,6 +25,7 @@ import ( "github.com/layeh/gumble/gumble_ffmpeg" ) +// Regular expressions for youtube urls var youtubePlaylistPattern = `https?:\/\/www\.youtube\.com\/playlist\?list=([\w-]+)` var youtubeVideoPatterns = []string{ `https?:\/\/www\.youtube\.com\/watch\?v=([\w-]+)(\&t=\d*m?\d*s?)?`, @@ -115,7 +116,7 @@ func NewYouTubeSong(user, id, offset string, playlist *YouTubePlaylist) (*YouTub url := fmt.Sprintf("https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&id=%s&key=%s", id, os.Getenv("YOUTUBE_API_KEY")) if apiResponse, err = PerformGetRequest(url); err != nil { - return nil, err + return nil, errors.New(INVALID_API_KEY) } var offsetDays, offsetHours, offsetMinutes, offsetSeconds int64 @@ -192,18 +193,15 @@ func NewYouTubeSong(user, id, offset string, playlist *YouTubePlaylist) (*YouTub duration: durationString, thumbnail: thumbnail, skippers: make([]string, 0), - playlist: nil, + playlist: playlist, dontSkip: false, } dj.queue.AddSong(song) - - if dj.verbose { - fmt.Printf("%s added track %s\n", song.Submitter, song.Title()) - } + Verbose(song.Submitter + " added track " + song.Title() + "\n") return song, nil } - return nil, errors.New("Song exceeds the maximum allowed duration.") + return nil, errors.New(VIDEO_TOO_LONG_MSG) } // Download downloads the song via youtube-dl if it does not already exist on disk. @@ -212,28 +210,16 @@ func (s *YouTubeSong) Download() error { // Checks to see if song is already downloaded if _, err := os.Stat(fmt.Sprintf("%s/.mumbledj/songs/%s", dj.homeDir, s.Filename())); os.IsNotExist(err) { - - if dj.verbose { - fmt.Printf("Downloading %s\n", s.Title()) - } - + Verbose("Downloading " + s.Title() + "\n") cmd := exec.Command("youtube-dl", "--output", fmt.Sprintf(`~/.mumbledj/songs/%s`, s.Filename()), "--format", "m4a", "--", s.ID()) if err := cmd.Run(); err == nil { if dj.conf.Cache.Enabled { dj.cache.CheckMaximumDirectorySize() } - - if dj.verbose { - fmt.Printf("%s downloaded\n", s.Title()) - } - + Verbose(s.Title() + " downloaded\n") return nil } - - if dj.verbose { - fmt.Printf("%s failed to download\n", s.Title()) - } - + Verbose(s.Title() + " failed to download\n") return errors.New("Song download failed.") } return nil @@ -286,10 +272,7 @@ func (s *YouTubeSong) Play() { dj.client.Self.Channel.Send(fmt.Sprintf(message, s.Thumbnail(), s.ID(), s.Title(), s.Duration(), s.Submitter(), s.Playlist().Title()), false) } - - if dj.verbose { - fmt.Printf("Now playing %s\n", s.Title()) - } + Verbose("Now playing " + s.Title() + "\n") go func() { dj.audioStream.Wait() @@ -304,11 +287,10 @@ func (s *YouTubeSong) Delete() error { filePath := fmt.Sprintf("%s/.mumbledj/songs/%s.m4a", dj.homeDir, s.ID()) if _, err := os.Stat(filePath); err == nil { if err := os.Remove(filePath); err == nil { - if dj.verbose { - fmt.Printf("Deleting %s\n", s.Title()) - } + Verbose("Deleted " + s.Title() + "\n") return nil } + Verbose("Failed to delete " + s.Title() + "\n") return errors.New("Error occurred while deleting audio file.") } return nil @@ -435,72 +417,8 @@ func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) { for i := 0; i < numVideos; i++ { index := strconv.Itoa(i) - videoTitle, err := apiResponse.String("items", index, "snippet", "title") videoID, _ := apiResponse.String("items", index, "snippet", "resourceId", "videoId") - videoThumbnail, _ := apiResponse.String("items", index, "snippet", "thumbnails", "high", "url") - - // A completely separate API call just to get the duration of a video in a - // playlist? WHY GOOGLE, WHY?! - var durationResponse *jsonq.JsonQuery - url = fmt.Sprintf("https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id=%s&key=%s", - videoID, os.Getenv("YOUTUBE_API_KEY")) - if durationResponse, err = PerformGetRequest(url); err != nil { - return nil, err - } - videoDuration, _ := durationResponse.String("items", "0", "contentDetails", "duration") - - var days, hours, minutes, seconds int64 - timestampExp := regexp.MustCompile(`P(?P\d+D)?T(?P\d+H)?(?P\d+M)?(?P\d+S)?`) - timestampMatch := timestampExp.FindStringSubmatch(videoDuration) - timestampResult := make(map[string]string) - for i, name := range timestampExp.SubexpNames() { - if i < len(timestampMatch) { - timestampResult[name] = timestampMatch[i] - } - } - - if timestampResult["days"] != "" { - days, _ = strconv.ParseInt(strings.TrimSuffix(timestampResult["days"], "D"), 10, 32) - } - if timestampResult["hours"] != "" { - hours, _ = strconv.ParseInt(strings.TrimSuffix(timestampResult["hours"], "H"), 10, 32) - } - if timestampResult["minutes"] != "" { - minutes, _ = strconv.ParseInt(strings.TrimSuffix(timestampResult["minutes"], "M"), 10, 32) - } - if timestampResult["seconds"] != "" { - seconds, _ = strconv.ParseInt(strings.TrimSuffix(timestampResult["seconds"], "S"), 10, 32) - } - - totalSeconds := int((days * 86400) + (hours * 3600) + (minutes * 60) + seconds) - var durationString string - if hours != 0 { - if days != 0 { - durationString = fmt.Sprintf("%d:%02d:%02d:%02d", days, hours, minutes, seconds) - } else { - durationString = fmt.Sprintf("%d:%02d:%02d", hours, minutes, seconds) - } - } else { - durationString = fmt.Sprintf("%d:%02d", minutes, seconds) - } - - if dj.conf.General.MaxSongDuration == 0 || totalSeconds <= dj.conf.General.MaxSongDuration { - playlistSong := &YouTubeSong{ - submitter: user, - title: videoTitle, - id: videoID, - filename: videoID + ".m4a", - duration: durationString, - thumbnail: videoThumbnail, - skippers: make([]string, 0), - playlist: playlist, - dontSkip: false, - } - dj.queue.AddSong(playlistSong) - if dj.verbose { - fmt.Printf("%s added song %s\n", playlistSong.Submitter(), playlistSong.Title()) - } - } + NewYouTubeSong(user, videoID, "", playlist) } return playlist, nil } From fe7b78d9c7f1e77039838d26ce74a20ad3dab5d9 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 12:40:12 +0100 Subject: [PATCH 30/37] Fixing build issues --- commands.go | 2 +- service_youtube.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/commands.go b/commands.go index 6a9ad2e..c5f282f 100644 --- a/commands.go +++ b/commands.go @@ -191,7 +191,7 @@ func add(user *gumble.User, username, url string) { } } } else { - dj.SendPrivateMessage(user, err) + dj.SendPrivateMessage(user, err.Error()) } } } diff --git a/service_youtube.go b/service_youtube.go index 93e8030..552b455 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -197,7 +197,7 @@ func NewYouTubeSong(user, id, offset string, playlist *YouTubePlaylist) (*YouTub dontSkip: false, } dj.queue.AddSong(song) - Verbose(song.Submitter + " added track " + song.Title() + "\n") + Verbose(song.Submitter() + " added track " + song.Title() + "\n") return song, nil } From b4867c629d0b99a674120ab5565d7c6d7f221f4e Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 13:00:04 +0100 Subject: [PATCH 31/37] Fixing build issues --- service_youtube.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/service_youtube.go b/service_youtube.go index 552b455..2724b19 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -405,14 +405,14 @@ func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) { } // Retrieve items in playlist - url = fmt.Sprintf("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=25&playlistId=%s&key=%s", + url = fmt.Sprintf("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=2&playlistId=%s&key=%s", id, os.Getenv("YOUTUBE_API_KEY")) if apiResponse, err = PerformGetRequest(url); err != nil { return nil, err } numVideos, _ := apiResponse.Int("pageInfo", "totalResults") - if numVideos > 25 { - numVideos = 25 + if numVideos > 2 { + numVideos = 2 } for i := 0; i < numVideos; i++ { From 09637395ccc82349ee5cedbf9be0f21d10c8709d Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 13:12:49 +0100 Subject: [PATCH 32/37] Fixing build issues --- songqueue.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/songqueue.go b/songqueue.go index 3321ca2..24755a6 100644 --- a/songqueue.go +++ b/songqueue.go @@ -42,14 +42,14 @@ func (q *SongQueue) CurrentSong() Song { // NextSong moves to the next Song in SongQueue. NextSong() removes the first Song in the queue. func (q *SongQueue) NextSong() { - if q.CurrentSong().Playlist() != nil { - if s, err := q.PeekNext(); err == nil { - if s.Playlist() != nil && (q.CurrentSong().Playlist().ID() != s.Playlist().ID()) { + if s, err := q.PeekNext(); err == nil { + if q.CurrentSong().Playlist() != nil && s.Playlist() != nil { + if q.CurrentSong().Playlist().ID() != s.Playlist().ID() { q.CurrentSong().Playlist().DeleteSkippers() } - } else { - q.CurrentSong().Playlist().DeleteSkippers() } + } else { + q.CurrentSong().Playlist().DeleteSkippers() } q.queue = q.queue[1:] } From f8b3236ae166293daffc177dd7620dec50283e88 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 13:16:28 +0100 Subject: [PATCH 33/37] Fixing build issues --- service_youtube.go | 4 ++-- songqueue.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/service_youtube.go b/service_youtube.go index 2724b19..2a08c0d 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -110,7 +110,7 @@ type YouTubeSong struct { // NewYouTubeSong gathers the metadata for a song extracted from a YouTube video, and returns // the song. -func NewYouTubeSong(user, id, offset string, playlist *YouTubePlaylist) (*YouTubeSong, error) { +func NewYouTubeSong(user, id, offset string, list *YouTubePlaylist) (*YouTubeSong, error) { var apiResponse *jsonq.JsonQuery var err error url := fmt.Sprintf("https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&id=%s&key=%s", @@ -193,7 +193,7 @@ func NewYouTubeSong(user, id, offset string, playlist *YouTubePlaylist) (*YouTub duration: durationString, thumbnail: thumbnail, skippers: make([]string, 0), - playlist: playlist, + playlist: list, dontSkip: false, } dj.queue.AddSong(song) diff --git a/songqueue.go b/songqueue.go index 24755a6..5cf9e8d 100644 --- a/songqueue.go +++ b/songqueue.go @@ -43,7 +43,7 @@ func (q *SongQueue) CurrentSong() Song { // NextSong moves to the next Song in SongQueue. NextSong() removes the first Song in the queue. func (q *SongQueue) NextSong() { if s, err := q.PeekNext(); err == nil { - if q.CurrentSong().Playlist() != nil && s.Playlist() != nil { + if (q.CurrentSong().Playlist() != nil) && (s.Playlist() != nil) { if q.CurrentSong().Playlist().ID() != s.Playlist().ID() { q.CurrentSong().Playlist().DeleteSkippers() } From d5687e0c06c8ae7bcc34be6cbf4c26a884bf3003 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 13:20:17 +0100 Subject: [PATCH 34/37] Fixing build issues --- service_youtube.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service_youtube.go b/service_youtube.go index 2a08c0d..5f53800 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -193,7 +193,7 @@ func NewYouTubeSong(user, id, offset string, list *YouTubePlaylist) (*YouTubeSon duration: durationString, thumbnail: thumbnail, skippers: make([]string, 0), - playlist: list, + playlist: &list, dontSkip: false, } dj.queue.AddSong(song) From b78005272673f41a38b84373bab2fb82819811e1 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 13:29:14 +0100 Subject: [PATCH 35/37] Fixing build issues --- main.go | 5 +++++ service_youtube.go | 6 +++--- songqueue.go | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index 982d3a3..0979126 100644 --- a/main.go +++ b/main.go @@ -146,6 +146,11 @@ func Verbose(msg string) { } } +func isNil(a interface{}) bool { + defer func() { recover() }() + return a == nil || reflect.ValueOf(a).IsNil() +} + // dj variable declaration. This is done outside of main() to allow global use. var dj = mumbledj{ keepAlive: make(chan bool), diff --git a/service_youtube.go b/service_youtube.go index 5f53800..0303488 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -110,7 +110,7 @@ type YouTubeSong struct { // NewYouTubeSong gathers the metadata for a song extracted from a YouTube video, and returns // the song. -func NewYouTubeSong(user, id, offset string, list *YouTubePlaylist) (*YouTubeSong, error) { +func NewYouTubeSong(user, id, offset string, playlist *YouTubePlaylist) (*YouTubeSong, error) { var apiResponse *jsonq.JsonQuery var err error url := fmt.Sprintf("https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&id=%s&key=%s", @@ -193,7 +193,7 @@ func NewYouTubeSong(user, id, offset string, list *YouTubePlaylist) (*YouTubeSon duration: durationString, thumbnail: thumbnail, skippers: make([]string, 0), - playlist: &list, + playlist: playlist, dontSkip: false, } dj.queue.AddSong(song) @@ -236,7 +236,7 @@ func (s *YouTubeSong) Play() { if err := dj.audioStream.Play(); err != nil { panic(err) } else { - if s.Playlist() == nil { + if s.Playlist() == &nil { message := ` diff --git a/songqueue.go b/songqueue.go index 5cf9e8d..67db542 100644 --- a/songqueue.go +++ b/songqueue.go @@ -43,7 +43,7 @@ func (q *SongQueue) CurrentSong() Song { // NextSong moves to the next Song in SongQueue. NextSong() removes the first Song in the queue. func (q *SongQueue) NextSong() { if s, err := q.PeekNext(); err == nil { - if (q.CurrentSong().Playlist() != nil) && (s.Playlist() != nil) { + if !isNil(q.CurrentSong().Playlist()) && !isNil(s.Playlist()) { if q.CurrentSong().Playlist().ID() != s.Playlist().ID() { q.CurrentSong().Playlist().DeleteSkippers() } From 9a5f0adf33333e6ec9679aae222673bbd98e6af1 Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 13:31:10 +0100 Subject: [PATCH 36/37] Fixing build issues --- main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/main.go b/main.go index 0979126..6ef1170 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,7 @@ import ( "os/user" "strings" "time" + "reflect" "github.com/layeh/gopus" "github.com/layeh/gumble/gumble" From 6858011bc0a1c4fec1e5b19d92c18bdc08a05cbb Mon Sep 17 00:00:00 2001 From: MichaelOultram Date: Tue, 28 Jul 2015 13:32:09 +0100 Subject: [PATCH 37/37] Fixing build issues --- service_youtube.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service_youtube.go b/service_youtube.go index 0303488..7754935 100644 --- a/service_youtube.go +++ b/service_youtube.go @@ -236,7 +236,7 @@ func (s *YouTubeSong) Play() { if err := dj.audioStream.Play(); err != nil { panic(err) } else { - if s.Playlist() == &nil { + if isNil(s.Playlist()) { message := `