using System; using System.Net; using System.Text.RegularExpressions; namespace Sony.Filtr.Contracts.Entities { [Serializable] public class SpotifyLink : IEquatable { public SpotifyLink(string link, bool urlDecode = false) { if (urlDecode) link = WebUtility.UrlDecode(link); Url = GetSpotifyHttpUrl(link); Uri = FormatSpotifyUri(link); } public static SpotifyLink ParseUserLink(string usernameOrLink) { if (usernameOrLink.StartsWith("http://open.spotify.com/user/") || usernameOrLink.StartsWith("https://open.spotify.com/user/") || usernameOrLink.StartsWith("spotify:user:")) { return new SpotifyLink(usernameOrLink); } return new SpotifyLink(string.Format("spotify:user:{0}", usernameOrLink.ToLowerInvariant())); } public static SpotifyLink FromTrackId(string trackId) { if (trackId.StartsWith("http://open.spotify.com/track/") || trackId.StartsWith("https://open.spotify.com/track/") || trackId.StartsWith("spotify:track:")) { return new SpotifyLink(trackId); } return new SpotifyLink(string.Format("spotify:track:{0}", trackId.Trim())); } public static SpotifyLink FromAlbumId(string albumId) { if (albumId.StartsWith("http://open.spotify.com/album/") || albumId.StartsWith("https://open.spotify.com/album/") || albumId.StartsWith("spotify:album:")) { return new SpotifyLink(albumId); } return new SpotifyLink(string.Format("spotify:album:{0}", albumId.Trim())); } public static SpotifyLink FromArtistId(string artistId) { if (artistId.StartsWith("http://open.spotify.com/artist/") || artistId.StartsWith("https://open.spotify.com/artist/") || artistId.StartsWith("spotify:artist:")) { return new SpotifyLink(artistId); } return new SpotifyLink(string.Format("spotify:artist:{0}", artistId.Trim())); } public static SpotifyLink FromPlaylistId(string playlistId) { if (string.IsNullOrWhiteSpace(playlistId)) throw new ArgumentException("Must specify PlaylistId"); return new SpotifyLink($"spotify:playlist:{playlistId.Trim()}"); } public string Url { get; set; } public string Uri { get; set; } public string GetSpotifyHttpUrl(string spotifyUri) { if (spotifyUri.Contains("http://open.spotify.com") || spotifyUri.Contains("https://open.spotify.com")) return spotifyUri; return string.Format("https://open.spotify.com/{0}", spotifyUri.Replace("spotify:", "").Replace(':', '/')); } public static string FormatSpotifyUri(string spotifyUri) { if (!spotifyUri.Contains("http://open.spotify.com") && !spotifyUri.Contains("https://open.spotify.com")) { return spotifyUri; } return string.Format("spotify:{0}", spotifyUri.Replace("http://open.spotify.com/", string.Empty).Replace("https://open.spotify.com/", string.Empty).Replace("/", ":")); } [Obsolete] public string ExtractSpotifyPlaylistUserName() { var match = Regex.Match(Uri, "spotify:user:(.*):playlist"); if (match != null && match.Groups.Count > 1) return match.Groups[1].Value; return null; } public string ExtractSpotifyUserName() { if (Uri.StartsWith("spotify:user:")) return Uri.Replace("spotify:user:", string.Empty); return null; } public string ExtractTrackID() { var match = Regex.Match(Uri, "spotify:track:(.*)"); if (match != null && match.Groups.Count > 1) return match.Groups[1].Value; return null; } public string ExtractArtistID() { var match = Regex.Match(Uri, "spotify:artist:(.*)"); if (match != null && match.Groups.Count > 1) return match.Groups[1].Value; return null; } public string ExtractAlbumID() { var match = Regex.Match(Uri, "spotify:album:(.*)"); if (match != null && match.Groups.Count > 1) return match.Groups[1].Value; return null; } public string ExtractPlaylistID() { return ExtracktPlaylistIdFromValidUri(this.Uri); } private static string ExtracktPlaylistIdFromValidUri(string uri) { var match = Regex.Match(uri, "spotify:user:(.*):playlist:(.*)"); if (match != null && match.Groups.Count > 1) { return match.Groups[2].Value; } match = Regex.Match(uri, "spotify:playlist:(.*)"); if (match != null && match.Groups.Count > 1) { return match.Groups[1].Value; } return null; } public static string ExtrackPlaylistID(string link) { return ExtracktPlaylistIdFromValidUri(FormatSpotifyUri(link)); } public bool IsPlaylist() { return Regex.IsMatch(Uri, "spotify:user:(.*):playlist") || Regex.IsMatch(Uri, "spotify:playlist:(.*)"); } public bool IsArtist() { return Uri.StartsWith("spotify:artist:"); } public bool IsAlbum() { return Uri.StartsWith("spotify:album:"); } public bool IsTrack() { return Uri.StartsWith("spotify:track:"); } public override int GetHashCode() { return Uri.GetHashCode(); } public override bool Equals(object obj) { return this.Equals(obj as SpotifyLink); } public bool Equals(SpotifyLink other) { if (other == null) return false; if (string.IsNullOrWhiteSpace(Uri) || string.IsNullOrWhiteSpace(other.Uri)) return false; var uri = Uri.Trim().ToLowerInvariant(); var otherUri = other.Uri.Trim().ToLowerInvariant(); var uriDecoded = WebUtility.UrlDecode(uri); var otherUriDecoded = WebUtility.UrlDecode(otherUri); return (uri == otherUri) || (uri == otherUriDecoded) || (uriDecoded == otherUri) || (uriDecoded == otherUriDecoded); } public static bool operator ==(SpotifyLink a, SpotifyLink b) { // If both are null, or both are same instance, return true. if (ReferenceEquals(a, b)) { return true; } // If one is null, but not both, return false. if (((object)a == null) || ((object)b == null)) { return false; } // Return true if the fields match: return a.Equals(b); } public static bool operator !=(SpotifyLink a, SpotifyLink b) { return !(a == b); } public override string ToString() { return Uri; } } }