diff --git a/_assets/i18n.json b/_assets/i18n.json index 9cc0e3d6..e7dbd75e 100644 --- a/_assets/i18n.json +++ b/_assets/i18n.json @@ -224,7 +224,8 @@ "toptracks-embed-title": "%s Top Tracks", "set-username-success": "You set `%s` as your username. <:blobsalute:317043033004703744>\n(This is saved across servers.)", "no-stats-available": "No stats available on this server yet. ", - "embed-footer-imageurl": "https://i.imgur.com/p8wijg4.png" + "embed-footer-imageurl": "https://i.imgur.com/p8wijg4.png", + "lastfm-no-youtube": "YouTube is currently not available.\nPlease try again later." }, "weather": { "address-not-found": "I can't find the location you are looking for. <:blobthinking:317028940885524490>", diff --git a/modules/plugins/lastfm.go b/modules/plugins/lastfm.go index 2c8fa272..323e11bd 100644 --- a/modules/plugins/lastfm.go +++ b/modules/plugins/lastfm.go @@ -10,6 +10,7 @@ import ( "github.com/Seklfreak/Robyul2/cache" "github.com/Seklfreak/Robyul2/helpers" "github.com/Seklfreak/Robyul2/metrics" + "github.com/Seklfreak/Robyul2/services/youtube" "github.com/bradfitz/slice" "github.com/bwmarrin/discordgo" "github.com/dustin/go-humanize" @@ -20,8 +21,9 @@ import ( type LastFm struct{} const ( - lastfmHexColor = "#d51007" - lastfmFriendlyUser = "https://www.last.fm/user/%s" + lastfmHexColor = "#d51007" + lastfmFriendlyUser = "https://www.last.fm/user/%s" + lastfmYouTubeFriendlyUrl = "https://youtu.be/%s" ) var ( @@ -399,12 +401,70 @@ func (m *LastFm) Action(command string, content string, msg *discordgo.Message, Inline: false, }) } + if youtube.HasYouTubeService() { + searchResult, err := youtube.GetYouTubeService().SearchQuerySingle( + []string{lastTrack.Artist.Name, lastTrack.Name}, "video") + helpers.RelaxLog(err) + if err == nil && searchResult != nil && searchResult.Snippet != nil { + lastTrackEmbed.Description += "\navailable on [YouTube](" + fmt.Sprintf(lastfmYouTubeFriendlyUrl, searchResult.Id.VideoId) + ")" + lastTrackEmbed.Footer.Text += " and YouTube" + } + } _, err = helpers.SendEmbed(msg.ChannelID, lastTrackEmbed) helpers.RelaxEmbed(err, msg.ChannelID, msg.ID) } else { helpers.SendMessage(msg.ChannelID, helpers.GetText("plugins.lastfm.no-recent-tracks")) return } + case "yt", "youtube": + if !youtube.HasYouTubeService() { + helpers.SendMessage(msg.ChannelID, helpers.GetText("lastfm.no-youtube")) + return + } + if len(args) >= 2 { + lastfmUsername = args[1] + targetUser, err := helpers.GetUserFromMention(lastfmUsername) + if err == nil { + lastfmUsername = m.getLastFmUsername(targetUser.ID) + } + } + + channel, err := helpers.GetChannel(msg.ChannelID) + helpers.Relax(err) + + if lastfmUsername == "" { + helpers.SendMessage(msg.ChannelID, helpers.GetTextF("plugins.lastfm.too-few", helpers.GetPrefixForServer(channel.GuildID))) + return + } + session.ChannelTyping(msg.ChannelID) + lastfmRecentTracks, err := lastfmClient.User.GetRecentTracks(lastfm.P{ + "limit": 2, + "user": lastfmUsername, + }) + metrics.LastFmRequests.Add(1) + if err != nil { + if e, ok := err.(*lastfm.LastfmError); ok { + helpers.SendMessage(msg.ChannelID, fmt.Sprintf("Error: `%s`", e.Message)) + return + } + } + if lastfmRecentTracks.Total > 0 { + lastTrack := lastfmRecentTracks.Tracks[0] + searchResult, err := youtube.GetYouTubeService().SearchQuerySingle( + []string{lastTrack.Artist.Name, lastTrack.Name}, "video") + helpers.RelaxLog(err) + if err != nil || searchResult == nil || searchResult.Snippet == nil { + helpers.SendMessage(msg.ChannelID, helpers.GetText("lastfm.no-youtube")) + return + } + messageContent := "**" + searchResult.Snippet.Title + "** on " + searchResult.Snippet.ChannelTitle + "\n" + messageContent += fmt.Sprintf(lastfmYouTubeFriendlyUrl, searchResult.Id.VideoId) + _, err = helpers.SendMessage(msg.ChannelID, messageContent) + helpers.RelaxEmbed(err, msg.ChannelID, msg.ID) + } else { + helpers.SendMessage(msg.ChannelID, helpers.GetText("plugins.lastfm.no-recent-tracks")) + return + } case "topalbums", "topalbum": timeLookup := "overall" timeString := "all time" diff --git a/modules/plugins/youtube/feeds.go b/modules/plugins/youtube/feeds.go index 46927d80..e8557ade 100644 --- a/modules/plugins/youtube/feeds.go +++ b/modules/plugins/youtube/feeds.go @@ -5,20 +5,21 @@ import ( "sync/atomic" "time" + youtubeService "github.com/Seklfreak/Robyul2/services/youtube" + "github.com/Seklfreak/Robyul2/helpers" "github.com/Seklfreak/Robyul2/models" - "github.com/Seklfreak/Robyul2/modules/plugins/youtube/service" "github.com/bwmarrin/discordgo" rethink "github.com/gorethink/gorethink" "github.com/sirupsen/logrus" ) type feeds struct { - service *service.Service + service *youtubeService.Service running uint32 } -func (f *feeds) Init(e *service.Service) { +func (f *feeds) Init(e *youtubeService.Service) { if e == nil { helpers.Relax(fmt.Errorf("feeds loop initialize failed")) } diff --git a/modules/plugins/youtube/handler.go b/modules/plugins/youtube/handler.go index e9c6277c..e9e4f373 100644 --- a/modules/plugins/youtube/handler.go +++ b/modules/plugins/youtube/handler.go @@ -7,13 +7,13 @@ import ( "github.com/Seklfreak/Robyul2/helpers" "github.com/Seklfreak/Robyul2/models" - "github.com/Seklfreak/Robyul2/modules/plugins/youtube/service" + youtubeService "github.com/Seklfreak/Robyul2/services/youtube" "github.com/bwmarrin/discordgo" "github.com/dustin/go-humanize" ) type Handler struct { - service service.Service + service youtubeService.Service feedsLoop feeds } @@ -39,6 +39,7 @@ func (h *Handler) Init(session *discordgo.Session) { h.service.Init(youtubeConfigFileName) h.feedsLoop.Init(&h.service) + youtubeService.SetYouTubeService(&h.service) } func (h *Handler) Action(command string, content string, msg *discordgo.Message, session *discordgo.Session) { diff --git a/services/youtube/cache.go b/services/youtube/cache.go new file mode 100644 index 00000000..fe4a91b4 --- /dev/null +++ b/services/youtube/cache.go @@ -0,0 +1,35 @@ +package youtube + +import ( + "errors" + "sync" +) + +var ( + youtubeServiceClient *Service + youtubeServiceClientMutex sync.RWMutex +) + +func SetYouTubeService(s *Service) { + youtubeServiceClientMutex.Lock() + youtubeServiceClient = s + youtubeServiceClientMutex.Unlock() +} + +func HasYouTubeService() bool { + if youtubeServiceClient == nil { + return false + } + return true +} + +func GetYouTubeService() *Service { + youtubeServiceClientMutex.RLock() + defer youtubeServiceClientMutex.RUnlock() + + if youtubeServiceClient == nil { + panic(errors.New("tried to get youtube service before cache#SetYouTubeService() was called")) + } + + return youtubeServiceClient +} diff --git a/modules/plugins/youtube/service/quota.go b/services/youtube/quota.go similarity index 99% rename from modules/plugins/youtube/service/quota.go rename to services/youtube/quota.go index ce73116e..075e2357 100644 --- a/modules/plugins/youtube/service/quota.go +++ b/services/youtube/quota.go @@ -1,4 +1,4 @@ -package service +package youtube import ( "sync" diff --git a/modules/plugins/youtube/service/service.go b/services/youtube/service.go similarity index 99% rename from modules/plugins/youtube/service/service.go rename to services/youtube/service.go index dc393a84..e9b8f323 100644 --- a/modules/plugins/youtube/service/service.go +++ b/services/youtube/service.go @@ -1,4 +1,4 @@ -package service +package youtube import ( "context" diff --git a/modules/plugins/youtube/service/urlfilter.go b/services/youtube/urlfilter.go similarity index 98% rename from modules/plugins/youtube/service/urlfilter.go rename to services/youtube/urlfilter.go index ced8106e..fb27634c 100644 --- a/modules/plugins/youtube/service/urlfilter.go +++ b/services/youtube/urlfilter.go @@ -1,4 +1,4 @@ -package service +package youtube import "regexp" diff --git a/modules/plugins/youtube/service/urlfilter_test.go b/services/youtube/urlfilter_test.go similarity index 98% rename from modules/plugins/youtube/service/urlfilter_test.go rename to services/youtube/urlfilter_test.go index 6e319385..9b051d11 100644 --- a/modules/plugins/youtube/service/urlfilter_test.go +++ b/services/youtube/urlfilter_test.go @@ -1,4 +1,4 @@ -package service +package youtube import "testing"