/* * Copyright (C) 2014 Fastboot Mobile, LLC. * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, see <http://www.gnu.org/licenses>. */ package com.fastbootmobile.encore.framework; import android.content.Context; import com.fastbootmobile.encore.app.R; import com.fastbootmobile.encore.model.Playlist; import com.fastbootmobile.encore.model.Song; import com.fastbootmobile.encore.providers.ProviderAggregator; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; /** * This class generates automatic playlists from the listen logger */ public class AutoPlaylistHelper { public static final String REF_SPECIAL_FAVORITES = "__omni:playlist:special:favorites"; public static final String REF_SPECIAL_MOST_PLAYED = "__omni:playlist:special:mostplayed"; /** * Generates and returns a playlist containing all the liked entries * @param ctx The context * @return A playlist containing the songs that have been favorited/liked */ public static Playlist getFavoritesPlaylist(Context ctx) { final ProviderAggregator aggregator = ProviderAggregator.getDefault(); final ListenLogger logger = new ListenLogger(ctx); List<ListenLogger.LogEntry> likes = logger.getLikedEntries(); Playlist playlist = new Playlist(REF_SPECIAL_FAVORITES); playlist.setName(ctx.getString(R.string.favorite_songs)); playlist.setOfflineCapable(false); playlist.setOfflineStatus(Playlist.OFFLINE_STATUS_NO); playlist.setIsLoaded(true); for (ListenLogger.LogEntry like : likes) { // Ensure the songs are cached as they're coming from multiple providers if (aggregator.retrieveSong(like.getReference(), like.getIdentifier()) != null) { playlist.addSong(like.getReference()); } } return playlist; } /** * Generates and returns a playlist containing the 100 most played songs * @param ctx The context * @return A playlist containing the most 100 played songs */ public static Playlist getMostPlayedPlaylist(Context ctx) { final ProviderAggregator aggregator = ProviderAggregator.getDefault(); final ListenLogger logger = new ListenLogger(ctx); List<ListenLogger.LogEntry> likes = logger.getEntries(0); Playlist playlist = new Playlist(REF_SPECIAL_MOST_PLAYED); playlist.setName(ctx.getString(R.string.most_played)); playlist.setOfflineCapable(false); playlist.setOfflineStatus(Playlist.OFFLINE_STATUS_NO); playlist.setIsLoaded(true); HashMap<String, Integer> occurrences = new HashMap<>(); for (ListenLogger.LogEntry like : likes) { final String ref = like.getReference(); // Ensure the songs are cached as they're coming from multiple providers Song song = aggregator.retrieveSong(ref, like.getIdentifier()); // A null song indicates either the song has gone unavailable or the provider has been // removed. We should not add it. if (song != null) { if (occurrences.containsKey(like.getReference())) { occurrences.put(ref, occurrences.get(ref) + 1); } else { occurrences.put(ref, 1); } } } int number = 0; TreeMap<String, Integer> sortedSongs = new TreeMap<>(new ValueComparator(occurrences)); sortedSongs.putAll(occurrences); Set<String> references = sortedSongs.keySet(); for (String ref : references) { if (ref != null) { playlist.addSong(ref); ++number; if (number == 100) { break; } } } return playlist; } private static class ValueComparator implements Comparator<String> { private Map<String, Integer> mBase; public ValueComparator(Map<String, Integer> base) { mBase = base; } // Note: this comparator imposes orderings that are inconsistent with equals. public int compare(String a, String b) { if (mBase.get(a) >= mBase.get(b)) { return -1; } else { return 1; } // returning 0 would merge keys } } }