/// <summary> /// Suggest songs for the user to sing. Based off of the song history of the current user. /// Some song suggestions given based on collaborative filtering with other user's song histories. /// Some suggestions based on other songs by artists sang. Returns most popular songs if prior /// information not available. /// </summary> /// <param name="venueID">The venue to suggest songs at.</param> /// <param name="userKey">The user's key.</param> /// <param name="start">Ignored.</param> /// <param name="count">The number of song suggestions.</param> /// <returns>The outcome of the operation</returns> public List<Song> MobileGetSongSuggestions(int venueID, long userKey, int start, int count) { start = 0; int count1 = count - count / 4; try { int mobileID = -1; using (DatabaseConnectivity db = new DatabaseConnectivity()) { #region SongSuggestionBoilerPlate List<Song> finalSuggestions = new List<Song>(); // Try to establish a database connection ExpResponse r = db.OpenConnection(); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); // Convert the userKey to MobileID r = MobileKeyToID(userKey, out mobileID, db); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); // Make sure the venueID exists. r = db.DJGetStatus(venueID); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); int venueStatus; if (!int.TryParse(r.message.Trim(), out venueStatus)) { r.setErMsgStk(true, "MobileGetPlayLists venueID parse fail (Bad venueID given?)", Environment.StackTrace); return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); } #endregion // The user's distinct song history. List<KeyValuePair<string[], int>> songsAndCount; // Song Title/Artist and how many times it shows up. r = db.MobileGetDistictSongHistory(mobileID, 0, 10, out songsAndCount); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); // Get song suggestions based on what other people sang. List<Song> suggestCollab; r = SuggestCollabFilter(songsAndCount, mobileID, venueID, count1, out suggestCollab, db); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); // Add these songs to fill up to half of the final suggestions. for (int i = 0; i < suggestCollab.Count; i++) { Song s = suggestCollab[i]; r = Common.LoadSongRating(ref s, mobileID, db); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); finalSuggestions.Add(s); } if (finalSuggestions.Count < count) { // Get song suggestions based off of artist List<Song> suggestByArtist; // Suggest songs not sung by the user, but which have an artist the user has sung. r = SuggestSongsNotSungByMostSungArtists(count - finalSuggestions.Count, mobileID, venueID, out suggestByArtist, db); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); // Add the artist suggestions to fill out the suggetsions. foreach (Song s in suggestByArtist) { Song song; r = Common.GetSongInformation(s.ID, venueID, mobileID, out song, db, false); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); finalSuggestions.Add(song); } } if (finalSuggestions.Count < count) { // If we are lacking songs still, get from popular songs. List<Song> popSongs; List<int> popCounts; r = db.GetMostPopularSongs(venueID, 0, count - finalSuggestions.Count, out popSongs, out popCounts); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); foreach (Song s in popSongs) { Song song; r = Common.GetSongInformation(s.ID, venueID, mobileID, out song, db, false); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); finalSuggestions.Add(song); } } return finalSuggestions; } } catch (Exception e) { ExpResponse r = new ExpResponse(true, "Exception in Suggest Song:", e.StackTrace); return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); } }
/// <summary> /// Gets the most or the least popular songs at a venue. /// </summary> /// <param name="DJKey">The unique DJ key.</param> /// <param name="limitToVenue">If true, results are only from this DJ's venue, otherwise, results are from all venues.</param> /// <param name="start">Results start at the given index.</param> /// <param name="count">Sets the number of results.</param> /// <param name="songs">Out list of songs.</param> /// <param name="counts">Out list of counts that contains how many times that song shows up. Indexes match song indexes. ie counts[2] is the number of times songs[2] was sung.</param> /// <returns></returns> public Response DJGetMostPopularSongs(long DJKey, bool limitToVenue, int start, int count, out List<Song> songs, out List<int> counts) { int DJID = -1; songs = new List<Song>(); counts = new List<int>(); List<Song> songIDs; using (DatabaseConnectivity db = new DatabaseConnectivity()) { // Try to establish a database connection Response r = db.OpenConnection(); if (r.error) return r; // Attempt to convert DJKey to DJID r = DJKeyToID(DJKey, out DJID, db); if (r.error) return r; int chosenVenue = -1; if(limitToVenue) chosenVenue = DJID; r = db.GetMostPopularSongs(chosenVenue, start, count, out songIDs, out counts); if (r.error) return r; foreach(Song s in songIDs) { Song fullSong; Common.GetSongInformation(s.ID, DJID, -1, out fullSong, db, true); songs.Add(fullSong); } return r; } }
/// <summary> /// Gets the most popular songs associated with a venue or all venues. /// </summary> /// <param name="venueID">The venueID of the venue, if -1, searches all venues.</param> /// <param name="start">The starting index of results.</param> /// <param name="count">The count of results.</param> /// <returns></returns> public List<Song> MobileGetMostPopularSongs(int venueID, int start, int count) { List<Song> songs = new List<Song>(); List<int> counts = new List<int>(); List<Song> songIDs; using (DatabaseConnectivity db = new DatabaseConnectivity()) { // Try to establish a database connection ExpResponse r = db.OpenConnection(); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); // Validate venueID if the any venueID not given. if (venueID != -1) { // Make sure the venueID exists. r = db.DJGetStatus(venueID); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); int venueStatus; if (!int.TryParse(r.message.Trim(), out venueStatus)) { r.setErMsgStk(true, "Could not parse venueID", Environment.StackTrace); return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); } } r = db.GetMostPopularSongs(venueID, start, count, out songIDs, out counts); if (r.error) return Common.LogErrorRetGen<List<Song>>(r, null, Common.LogFile.Mobile); foreach (Song s in songIDs) { Song fullSong; Common.GetSongInformation(s.ID, venueID, -1, out fullSong, db, false); songs.Add(fullSong); } return songs; } }