using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sony.Filtr.Core.Data; using Sony.Filtr.ErrorLogging; using Sony.Filtr.PersistentCaching; using Sony.Filtr.PlaylistGeneration.Data; using Spotifony.Core.Data; using Sony.Core.Data; using MusicMatch.Core.Data; using System.Threading.Tasks; namespace Sony.Filtr.PlaylistGeneration.Caching { public class RedisCacheProvider : ICacheProvider { private const string autocompleteRedisKey = "Artist-Autocomplete"; private const char fullWordMarker = '*'; #region Similar Artists public bool Active { get { return (PersistentCachingManager.Instance.Connection != null && PersistentCachingManager.Instance.Connection.State == BookSleeve.RedisConnectionBase.ConnectionState.Open); } } public void CacheSimilarArtists(Artist artist, List similarArtists) { return; //We leave this to the database and couchbase-cache. } public List FetchSimilarArtistsFromCache(string artistName) { return null; //We leave this to the database and couchbase-cache. } #endregion #region Tracks public void CacheTopTracks(Artist artist, IEnumerable tracks) { return; //We leave this to the database and couchbase-cache. /* if (!Active) return; var conn = PersistentCachingManager.Instance.Connection; int i = 0; foreach (var track in tracks) { conn.SortedSets.Add(0, "TopTracks:" + RedisSafeKey(track.ArtistName), Encoding.Unicode.GetBytes(RedisSafeKey(track.ArtistName + track.Name)), i); CacheTrack(track); i++; } */ } //public Track CacheTrack(Track track) //{ // if (!Active) // return null; // var conn = PersistentCachingManager.Instance.Connection; // conn.Hashes.Set(0, "TrackInfo:" + RedisSafeKey(track.ArtistName + track.Name), track.GetRedisValuePair()); // return track; //} public IEnumerable FetchTopTracksFromCache(Artist artist) { return null; //We leave this to the database and couchbase-cache. /* if (!Active) return null; var conn = PersistentCachingManager.Instance.Connection; var get = conn.SortedSets.Range(0, "TopTracks:" + RedisSafeKey(artist.Name), 0, 100); List tracks = new List(); foreach (var trackValue in get.Result) { string trackKey = RedisHelper.GetString(trackValue.Key); var getTrack = conn.Hashes.GetAll(0, "TrackInfo:" + trackKey); var track = ConstructTrack(getTrack.Result); if (track != null) tracks.Add(track); } return tracks; */ } //private bool IsInTerritory(Spotifony.Core.Data.Track t, string territoryCode) //{ // return (territoryCode == null || t.Territories.Contains(territoryCode, StringComparer.CurrentCultureIgnoreCase)); //} #endregion #region Artist public void CacheArtist(Artist artist) { if (!Active) return; var conn = PersistentCachingManager.Instance.Connection; conn.Hashes.Set(0, "artist:" + RedisSafeKey(artist.Name), artist.GetRedisValuePair()); conn.Sets.Add(0, "ArtistSet", artist.Name); } public Artist FetchArtistFromCache(Lastfm.Services.Artist artist) { return FetchArtistFromCache(artist.Name); } public Artist FetchArtistFromCache(string artistName) { if (!Active) return null; var conn = PersistentCachingManager.Instance.Connection; var artistHash = conn.Hashes.GetAll(0, "artist:" + RedisSafeKey(artistName)); var result = conn.Wait(artistHash); if (result != null && result.Keys.Any()) return ConstructArtist(result); return null; } #endregion public void CacheGenreMatch(Sony.Filtr.Application.Application application, Artist artist, IEnumerable genres) { if (!Active) return; var conn = PersistentCachingManager.Instance.Connection; foreach (var genre in genres) { var key = "GenreMatch:" + application.ID.ToString() + RedisSafeKey(artist.Name); var value = Encoding.Unicode.GetBytes(genre.Genre + "|" + genre.ID); conn.SortedSets.Add(0, key, value, genre.Score); } } public IEnumerable FetchGenreMatchFromCache(Sony.Filtr.Application.Application application, Artist artist) { if (!Active) return null; List genreMatches = new List(); var conn = PersistentCachingManager.Instance.Connection; var key = "GenreMatch:" + application.ID.ToString() + RedisSafeKey(artist.Name); var get = conn.SortedSets.Range(0, key, 0, int.MaxValue); foreach (var genreValue in get.Result) { string genreString = RedisHelper.GetString(genreValue.Key); var splitValue = genreString.Split('|'); var name = splitValue.FirstOrDefault(); var id = int.Parse(splitValue.LastOrDefault()); genreMatches.Add(new GenreMatch(name, (int)genreValue.Value) { ID = id }); } return genreMatches; } public void CacheGenreArtists(Genre genre, IEnumerable artists) { if (!Active) return; var conn = PersistentCachingManager.Instance.Connection; foreach (var artist in artists) { conn.SortedSets.Add(0, "GenreArtistMatch:" + RedisSafeKey(genre.Name), Encoding.Unicode.GetBytes(artist.Artist.Name), artist.Match); } } public IEnumerable FetchGenreArtists(Genre genre) { if (!Active) return null; try { List artistMatches = new List(); var conn = PersistentCachingManager.Instance.Connection; var get = conn.SortedSets.Range(0, "GenreArtistMatch:" + RedisSafeKey(genre.Name), 0, 100); var values = conn.Wait(get); foreach (var genreValue in values) { string artist = RedisHelper.GetString(genreValue.Key); artistMatches.Add(new SimilarArtistMatch(PlaylistGenerationManager.Instance.GetArtist(artist), (int)genreValue.Value)); } return artistMatches; } catch (Exception ex) { ErrorLoggingManager.Instance.LogError(ex); return null; } } private string RedisSafeKey(string p) { return p.Replace(" ", "_").ToLower(); } private Artist ConstructArtist(Dictionary result) { var name = RedisHelper.GetString(result["Name"]); var artist = new Artist(name); if (result.ContainsKey("IsSonyArtist")) artist.IsSonyArtist = RedisHelper.GetBool(result["IsSonyArtist"]); if (result.ContainsKey("ImageUrl")) artist.ImageUrl = RedisHelper.GetString(result["ImageUrl"]); if (result.ContainsKey("LastFMImageID")) artist.LastFMImageID = RedisHelper.GetString(result["LastFMImageID"]); if (result.ContainsKey("Listeners")) artist.Listeners = RedisHelper.GetInt(result["Listeners"]); if (result.ContainsKey("PlayCount")) artist.PlayCount = RedisHelper.GetInt(result["PlayCount"]); return artist; } public Track ConstructTrack(Dictionary hashValues) { if (hashValues == null || !hashValues.Any()) return null; var name = RedisHelper.GetString(hashValues["Title"]); var artistName = RedisHelper.GetString(hashValues["ArtistName"]); var track = new Track(artistName, name); if (hashValues.ContainsKey("Territories")) track.Territories = RedisHelper.GetString(hashValues["Territories"]).Split(' '); if (hashValues.ContainsKey("SpotifyUrl")) track.SpotifyLink = new SpotifyLink(RedisHelper.GetString(hashValues["SpotifyUrl"])); if (hashValues.ContainsKey("IsSonyTrack")) track.IsSonyTrack = RedisHelper.GetBool(hashValues["IsSonyTrack"]); return track; } public string GetCacheProviderName() { return "MusicMatch.PlaylistGeneration.Caching.RedisCacheProvider"; } public void CacheArtistTags(Artist artist, List tags) { return; } public List FetchArtistTagsFromCache(Artist artist) { return null; } public List> FetchTopTrackForTag(string tag) { return null; } public void CacheTopTrackForTag(string tag, List> topTracks) { return; } public void CacheSearchTracks(string mood, string genre, List> tracks) { return; } public List> FetchSearchTracks(string mood, string genre) { return null; } public void CacheTrackTags(Track track, List tags) { return; } public List FetchTrackTagsFromCache(Track track) { return null; } public Task> FetchExtendedTopTracksForArtistAsync(string artistName) { return Task.FromResult>(null); } public Task CacheExtendedTopTracksForArtist(string artistName, List tracks) { return Task.FromResult(0); } public List> FetchArtistMood(string artistName) { return null; } public void CacheArtistMood(string artistName, List> moods) { return; } public void CacheExtendedTopTracksForTag(string tag, List groupedExtendedTracks) { return; } public List FetchExtendedTopTracksForTag(string tag) { return null; } } }