//TODO: make this function faster. hashtable, limit result set private Boolean isAdvertisement(Song song) { StringBuilder strb = new StringBuilder(); strb.Append(SPOTIFY_API_URI); strb.Append(Uri.EscapeDataString(song.ArtistName)); strb.Append("%20"); strb.Append(Uri.EscapeDataString(song.SongTitle)); WebClient wc = new WebClient(); try { string jsonResponse = wc.DownloadString(strb.ToString()); JObject jo = (JObject)JsonConvert.DeserializeObject(jsonResponse); foreach (JObject result in jo["tracks"]) { if (result["name"].ToString().Equals(song.SongTitle, StringComparison.InvariantCultureIgnoreCase)) { // If our song title matches, we then need to check the artist as well because some names of ads are actually valid song titles! foreach (JObject resultArtist in result["artists"]) { if (resultArtist["name"].ToString().Equals(song.ArtistName, StringComparison.InvariantCultureIgnoreCase)) { return false; } } } } } catch (Exception e) // TODO: stop being lazy about exception handling and handle the web exception instead of the generic one. { addLog("ERROR: got exception - " + e.ToString()); return false; } return true; }
/* * Adds song by artistName to the blockTable. Single block. */ public void addSong(Song song) { if (song.ArtistName == null || song.SongTitle == null || song.ArtistName.Length == 0 || song.SongTitle.Length == 0) { throw new ArgumentException("Null or zero-length artist or song specified."); } else { Artist reqArtist = new Artist(song.ArtistName); if (dict.ContainsKey(reqArtist) && dict[reqArtist] == null) return; // artist's songs are all blocked, ignore and return if (!dict.ContainsKey(reqArtist)) { dict.Add(reqArtist, new HashSet<Song>()); } dict[reqArtist].Add(song); count++; } }
/* * Just a shortcut to remove an old song->add a new song */ public void updateSong(Song oldSong, Song newSong) { removeSong(oldSong); addSong(newSong); }
/* * Removes song by artistName from the blockTable. */ public void removeSong(Song song) { if (song.ArtistName == null || song.SongTitle == null || song.ArtistName.Length == 0 || song.SongTitle.Length == 0) { throw new ArgumentException("Null or zero-length artist or song specified."); } Artist reqArtist = new Artist(song.ArtistName); if (dict.ContainsKey(reqArtist)) { if (dict[reqArtist] == null) return; // can't remove one song from a globally blocked artist. dict[reqArtist].Remove(song); count--; } }
/* * Does the blockTable contain song by artistName? */ public Boolean contains(Song song) { if (song == null || song.ArtistName == null || song.SongTitle == null) { return false; } Artist reqArtist = new Artist(song.ArtistName); return dict.ContainsKey(reqArtist) && (dict[reqArtist] == null || dict[reqArtist].Contains(song)); // true if the artistname is in the dict, and we either have an artist full block or the artist's dictionary object contains the song... }
/* * Retreives the current 'now playing' item by parsing Spotify's window title. */ public void UpdateNowPlaying() { if (!controller.isListening()) return; Process[] processes = Process.GetProcessesByName("spotify"); // we need to refresh the spotify process each time, because spotify tends to change process id when hiding/unhiding. if (processes.Length > 0) { foreach (Process process in processes) { spotProc = process; spotifyASC = controller.getSpotifyAudioSession(spotProc.Id); if (spotifyASC != null) { break; } } if (spotifyASC == null) { controller.addLog("ERROR: couldn't find the necessary spotify process to attach to"); return; } String[] theItem = spotProc.MainWindowTitle.Split('-'); if (theItem.Length >= 2) { String title = theItem[1].Trim(); String artist = theItem[0].Trim(); controller.addLog("Artist: " + artist + ", Title: " + theItem[1]); currSong = new Song(artist, title); lastItem = spotProc.MainWindowTitle; } else { currSong = null; controller.addLog("WARN: couldn't parse the artist/title from the raw window title."); } } else { controller.addLog("ERROR: expected to find multiple spotify processes, found one or none"); } }