add files

This commit is contained in:
Tim Müller
2022-03-19 22:28:54 +01:00
commit e6cae5f497
66 changed files with 5255 additions and 0 deletions

View File

@@ -0,0 +1,156 @@
using SpotifyAPI.Web;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using DSharpPlus;
using System.Linq;
using Microsoft.Extensions.Logging;
using TomatenMusic.Music.Entitites;
using TomatenMusic.Services;
using TomatenMusic.Music;
using Lavalink4NET;
using Lavalink4NET.Player;
namespace TomatenMusic.Services
{
public interface ISpotifyService
{
public Task<MusicActionResponse> ConvertURL(string url);
public Task<SpotifyPlaylist> PopulateSpotifyPlaylistAsync(SpotifyPlaylist playlist);
public Task<SpotifyPlaylist> PopulateSpotifyAlbumAsync(SpotifyPlaylist playlist);
public Task<LavalinkTrack> PopulateTrackAsync(LavalinkTrack track);
}
public class SpotifyService : SpotifyClient, ISpotifyService
{
public ILogger _logger { get; set; }
public IAudioService _audioService { get; set; }
public SpotifyService(SpotifyClientConfig config, ILogger<SpotifyService> logger, IAudioService audioService) : base(config)
{
_logger = logger;
_audioService = audioService;
}
public async Task<MusicActionResponse> ConvertURL(string url)
{
string trackId = url
.Replace("https://open.spotify.com/track/", "")
.Replace("https://open.spotify.com/album/", "")
.Replace("https://open.spotify.com/playlist/", "")
.Substring(0, 22);
if (url.StartsWith("https://open.spotify.com/track"))
{
FullTrack sTrack = await Tracks.Get(trackId);
_logger.LogInformation($"Searching youtube from spotify with query: {sTrack.Name} {String.Join(" ", sTrack.Artists)}");
var track = await _audioService.GetTrackAsync($"{sTrack.Name} {String.Join(" ", sTrack.Artists.ConvertAll(artist => artist.Name))}", Lavalink4NET.Rest.SearchMode.YouTube);
if (track == null) throw new ArgumentException("This Spotify Track was not found on Youtube");
return new MusicActionResponse(await FullTrackContext.PopulateAsync(track, trackId));
}
else if (url.StartsWith("https://open.spotify.com/album"))
{
List<LavalinkTrack> tracks = new List<LavalinkTrack>();
FullAlbum album = await Albums.Get(trackId);
foreach (var sTrack in await PaginateAll(album.Tracks))
{
_logger.LogInformation($"Searching youtube from spotify with query: {sTrack.Name} {String.Join(" ", sTrack.Artists.ConvertAll(artist => artist.Name))}");
var track = await _audioService.GetTrackAsync($"{sTrack.Name} {String.Join(" ", sTrack.Artists.ConvertAll(artist => artist.Name))}", Lavalink4NET.Rest.SearchMode.YouTube);
if (track == null) throw new ArgumentException("This Spotify Track was not found on Youtube");
tracks.Add(await FullTrackContext.PopulateAsync(track, sTrack.Uri));
}
Uri uri;
Uri.TryCreate(url, UriKind.Absolute, out uri);
SpotifyPlaylist playlist = new SpotifyPlaylist(album.Name, album.Id, tracks, uri);
await PopulateSpotifyAlbumAsync(playlist);
return new MusicActionResponse(playlist: playlist);
}
else if (url.StartsWith("https://open.spotify.com/playlist"))
{
List<LavalinkTrack> tracks = new List<LavalinkTrack>();
FullPlaylist spotifyPlaylist = await Playlists.Get(trackId);
foreach (var sTrack in await PaginateAll(spotifyPlaylist.Tracks))
{
if (sTrack.Track is FullTrack)
{
FullTrack fullTrack = (FullTrack)sTrack.Track;
_logger.LogInformation($"Searching youtube from spotify with query: {fullTrack.Name} {String.Join(" ", fullTrack.Artists.ConvertAll(artist => artist.Name))}");
var track = await _audioService.GetTrackAsync($"{fullTrack.Name} {String.Join(" ", fullTrack.Artists.ConvertAll(artist => artist.Name))}", Lavalink4NET.Rest.SearchMode.YouTube);
if (track == null) throw new ArgumentException("This Spotify Track was not found on Youtube");
tracks.Add(await FullTrackContext.PopulateAsync(track, fullTrack.Uri));
}
}
Uri uri;
Uri.TryCreate(url, UriKind.Absolute, out uri);
SpotifyPlaylist playlist = new SpotifyPlaylist(spotifyPlaylist.Name, spotifyPlaylist.Id, tracks, uri);
await PopulateSpotifyPlaylistAsync(playlist);
return new MusicActionResponse(playlist: playlist);
}
return null;
}
public async Task<SpotifyPlaylist> PopulateSpotifyPlaylistAsync(SpotifyPlaylist playlist)
{
var list = await this.Playlists.Get(playlist.Identifier);
playlist.Description = list.Description;
playlist.AuthorUri = new Uri(list.Owner.Uri);
playlist.AuthorName = list.Owner.DisplayName;
playlist.Followers = list.Followers.Total;
playlist.Url = new Uri(list.Uri);
playlist.AuthorThumbnail = new Uri(list.Owner.Images.First().Url);
return playlist;
}
public async Task<SpotifyPlaylist> PopulateSpotifyAlbumAsync(SpotifyPlaylist playlist)
{
var list = await this.Albums.Get(playlist.Identifier);
playlist.Description = list.Label;
playlist.AuthorUri = new Uri(list.Artists.First().Uri);
playlist.AuthorName = list.Artists.First().Name;
playlist.Followers = list.Popularity;
playlist.Url = new Uri(list.Uri);
return playlist;
}
public async Task<LavalinkTrack> PopulateTrackAsync(LavalinkTrack track)
{
FullTrackContext context = (FullTrackContext)track.Context;
if (context.SpotifyIdentifier == null)
return track;
var spotifyTrack = await this.Tracks.Get(context.SpotifyIdentifier);
context.SpotifyAlbum = spotifyTrack.Album;
context.SpotifyArtists = spotifyTrack.Artists;
context.SpotifyPopularity = spotifyTrack.Popularity;
context.SpotifyUri = new Uri(spotifyTrack.Uri);
track.Context = context;
return track;
}
}
}

View File

@@ -0,0 +1,127 @@
using Google.Apis.Services;
using Google.Apis.YouTube.v3;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using TomatenMusic.Music.Entitites;
using System.Linq;
using Google.Apis.YouTube.v3.Data;
using Microsoft.Extensions.Logging;
using static TomatenMusic.TomatenMusicBot;
using Lavalink4NET.Player;
using Microsoft.Extensions.DependencyInjection;
using Lavalink4NET;
namespace TomatenMusic.Services
{
public class YoutubeService
{
public YouTubeService Service { get; }
public ILogger<YoutubeService> _logger { get; set; }
public YoutubeService(ILogger<YoutubeService> logger, ConfigJson config)
{
Service = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = config.YoutubeAPIKey,
ApplicationName = "TomatenMusic"
});
_logger = logger;
}
public async Task<LavalinkTrack> PopulateTrackInfoAsync(LavalinkTrack track)
{
var video = await GetVideoAsync(track.TrackIdentifier);
var channel = await GetChannelAsync(video.Snippet.ChannelId);
FullTrackContext context = track.Context == null ? new FullTrackContext() : (FullTrackContext)track.Context;
if (channel.Statistics.SubscriberCount != null)
context.YoutubeAuthorSubs = (ulong) channel.Statistics.SubscriberCount;
context.YoutubeAuthorThumbnail = new Uri(channel.Snippet.Thumbnails.High.Url);
context.YoutubeAuthorUri = new Uri($"https://www.youtube.com/channel/{channel.Id}");
context.YoutubeDescription = video.Snippet.Description;
if (video.Statistics.LikeCount != null)
context.YoutubeLikes = (ulong) video.Statistics.LikeCount;
context.YoutubeTags = video.Snippet.Tags;
context.YoutubeThumbnail = new Uri(video.Snippet.Thumbnails.High.Url);
context.YoutubeUploadDate = (DateTime)video.Snippet.PublishedAt;
context.YoutubeViews = (ulong)video.Statistics.ViewCount;
context.YoutubeCommentCount = video.Statistics.CommentCount;
track.Context = context;
return track;
}
public async Task<List<LavalinkTrack>> PopulateMultiTrackListAsync(IEnumerable<LavalinkTrack> tracks)
{
List<LavalinkTrack> newTracks = new List<LavalinkTrack>();
foreach (var track in tracks)
newTracks.Add(await PopulateTrackInfoAsync(track));
return newTracks;
}
public async Task<LavalinkPlaylist> PopulatePlaylistAsync(YoutubePlaylist playlist)
{
var list = await GetPlaylistAsync(playlist.Identifier);
var channel = await GetChannelAsync(list.Snippet.ChannelId);
string desc = list.Snippet.Description;
playlist.Description = desc.Substring(0, Math.Min(desc.Length, 4092)) + (desc.Length > 4092 ? "..." : " ");
playlist.Thumbnail = new Uri(list.Snippet.Thumbnails.High.Url);
playlist.CreationTime = (DateTime)list.Snippet.PublishedAt;
playlist.YoutubeItem = list;
playlist.AuthorThumbnail = new Uri(channel.Snippet.Thumbnails.High.Url);
playlist.AuthorUri = new Uri($"https://www.youtube.com/playlist?list={playlist.Identifier}");
return playlist;
}
public async Task<Video> GetVideoAsync(string id)
{
var search = Service.Videos.List("contentDetails,id,liveStreamingDetails,localizations,player,recordingDetails,snippet,statistics,status,topicDetails");
search.Id = id;
var response = await search.ExecuteAsync();
return response.Items.First();
}
public async Task<Channel> GetChannelAsync(string id)
{
var search = Service.Channels.List("brandingSettings,contentDetails,contentOwnerDetails,id,localizations,snippet,statistics,status,topicDetails");
search.Id = id;
var response = await search.ExecuteAsync();
return response.Items.First();
}
public async Task<Playlist> GetPlaylistAsync(string id)
{
var search = Service.Playlists.List("snippet,contentDetails,status");
search.Id = id;
var response = await search.ExecuteAsync();
return response.Items.First();
}
public async Task<SearchResult> GetRelatedVideoAsync(string id)
{
var search = Service.Search.List("snippet");
search.RelatedToVideoId = id;
search.Type = "video";
var response = await search.ExecuteAsync();
return response.Items.First(s => s.Snippet != null);
}
public async Task<LavalinkTrack> GetRelatedTrackAsync(string id)
{
var audioService = TomatenMusicBot.ServiceProvider.GetRequiredService<IAudioService>();
var video = await GetRelatedVideoAsync(id);
var loadResult = await audioService.GetTrackAsync($"https://youtu.be/{video.Id.VideoId}");
if (loadResult == null)
throw new Exception("An Error occurred while processing the Request");
return await FullTrackContext.PopulateAsync(loadResult);
}
}
}