org.runbuddy.libtomahawk.infosystem.hatchet.HatchetInfoPlugin.java Source code

Java tutorial

Introduction

Here is the source code for org.runbuddy.libtomahawk.infosystem.hatchet.HatchetInfoPlugin.java

Source

/* == This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
 *
 *   Copyright 2014, Enno Gottschalk <mrmaffen@googlemail.com>
 *
 *   Tomahawk 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.
 *
 *   Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 */
package org.runbuddy.libtomahawk.infosystem.hatchet;

import android.util.Log;

import com.google.gson.JsonObject;

import org.apache.commons.io.Charsets;
import org.runbuddy.libtomahawk.authentication.AuthenticatorUtils;
import org.runbuddy.libtomahawk.authentication.HatchetAuthenticatorUtils;
import org.runbuddy.libtomahawk.collection.Album;
import org.runbuddy.libtomahawk.collection.Artist;
import org.runbuddy.libtomahawk.collection.CollectionManager;
import org.runbuddy.libtomahawk.collection.HatchetCollection;
import org.runbuddy.libtomahawk.collection.Playlist;
import org.runbuddy.libtomahawk.infosystem.InfoPlugin;
import org.runbuddy.libtomahawk.infosystem.InfoRequestData;
import org.runbuddy.libtomahawk.infosystem.InfoSystem;
import org.runbuddy.libtomahawk.infosystem.QueryParams;
import org.runbuddy.libtomahawk.infosystem.SocialAction;
import org.runbuddy.libtomahawk.infosystem.User;
import org.runbuddy.libtomahawk.infosystem.hatchet.models.HatchetPlaylistEntries;
import org.runbuddy.libtomahawk.resolver.Query;
import org.runbuddy.libtomahawk.utils.ISO8601Utils;
import org.runbuddy.tomahawk.app.TomahawkApp;
import org.runbuddy.tomahawk.utils.ThreadManager;
import org.runbuddy.tomahawk.utils.TomahawkRunnable;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import retrofit.RetrofitError;
import retrofit.mime.TypedByteArray;

/**
 * Implementation to enable the InfoSystem to retrieve data from the Hatchet API. Documentation of
 * the API can be found here https://api.hatchet.is/apidocs/
 */
public class HatchetInfoPlugin implements InfoPlugin {

    private final static String TAG = HatchetInfoPlugin.class.getSimpleName();

    public static final String HATCHET_SEARCHITEM_TYPE_ALBUM = "album";

    public static final String HATCHET_SEARCHITEM_TYPE_ARTIST = "artist";

    public static final String HATCHET_SEARCHITEM_TYPE_USER = "user";

    public static final String HATCHET_SOCIALACTION_PARAMTYPE_FRIENDSFEED = "friendsFeed";

    public static final String HATCHET_SOCIALACTION_TYPE_LOVE = "love";

    public static final String HATCHET_SOCIALACTION_TYPE_FOLLOW = "follow";

    public static final String HATCHET_SOCIALACTION_TYPE_CREATECOMMENT = "createcomment";

    public static final String HATCHET_SOCIALACTION_TYPE_LATCHON = "latchOn";

    public static final String HATCHET_SOCIALACTION_TYPE_LATCHOFF = "latchOff";

    public static final String HATCHET_SOCIALACTION_TYPE_CREATEPLAYLIST = "createplaylist";

    public static final String HATCHET_SOCIALACTION_TYPE_DELETEPLAYLIST = "deleteplaylist";

    public static final String HATCHET_RELATIONSHIPS_TYPE_FOLLOW = "follow";

    public static final String HATCHET_RELATIONSHIPS_TYPE_LOVE = "love";

    public static final String HATCHET_RELATIONSHIPS_TARGETTYPE_ALBUM = "album";

    public static final String HATCHET_RELATIONSHIPS_TARGETTYPE_ARTIST = "artist";

    public static final int SOCIALACTIONS_LIMIT = 20;

    public static final int FRIENDSFEED_LIMIT = 50;

    private HatchetAuthenticatorUtils mHatchetAuthenticatorUtils;

    private final Store mStore;

    public HatchetInfoPlugin() {
        mStore = new Store();
    }

    /**
     * _fetch_ data from the Hatchet API (e.g. artist's top-hits, image etc.)
     */
    public void resolve(final InfoRequestData infoRequestData) {
        int priority;
        if (infoRequestData.getType() == InfoRequestData.INFOREQUESTDATA_TYPE_ARTISTS_TOPHITSANDALBUMS) {
            priority = TomahawkRunnable.PRIORITY_IS_INFOSYSTEM_HIGH;
        } else if (infoRequestData.getType() == InfoRequestData.INFOREQUESTDATA_TYPE_PLAYLISTS
                || infoRequestData.getType() == InfoRequestData.INFOREQUESTDATA_TYPE_USERS_LOVEDITEMS) {
            priority = TomahawkRunnable.PRIORITY_IS_INFOSYSTEM_LOW;
        } else {
            priority = TomahawkRunnable.PRIORITY_IS_INFOSYSTEM_MEDIUM;
        }
        TomahawkRunnable runnable = new TomahawkRunnable(priority) {
            @Override
            public void run() {
                try {
                    boolean success = getParseConvert(infoRequestData);
                    InfoSystem.get().reportResults(infoRequestData, success);
                } catch (IOException e) {
                    Log.e(TAG, "resolve: " + e.getClass() + ": " + e.getLocalizedMessage());
                }
            }
        };
        ThreadManager.get().execute(runnable);
    }

    /**
     * Core method of this InfoPlugin. Gets and parses the ordered results.
     *
     * @param infoRequestData InfoRequestData object containing the input parameters.
     * @return true if the type of the given InfoRequestData was valid and could be processed. false
     * otherwise
     */
    private boolean getParseConvert(InfoRequestData infoRequestData) throws IOException {
        QueryParams params = infoRequestData.getQueryParams();
        HatchetCollection hatchetCollection = CollectionManager.get().getHatchetCollection();
        Hatchet hatchet = mStore.getImplementation(infoRequestData.isBackgroundRequest());

        try {
            int type = infoRequestData.getType();
            if (type >= InfoRequestData.INFOREQUESTDATA_TYPE_USERS
                    && type < InfoRequestData.INFOREQUESTDATA_TYPE_USERS + 100) {
                JsonObject object = hatchet.getUsers(params.ids, params.name, params.random, params.count);
                if (object == null) {
                    return false;
                }
                List<User> users = mStore.storeRecords(object, User.class, type,
                        infoRequestData.isBackgroundRequest());
                infoRequestData.setResultList(users);
                return true;

            } else if (type >= InfoRequestData.INFOREQUESTDATA_TYPE_PLAYLISTS
                    && type < InfoRequestData.INFOREQUESTDATA_TYPE_PLAYLISTS + 100) {
                JsonObject object = hatchet.getPlaylists(params.playlist_id);
                if (object == null) {
                    return false;
                }
                List<Playlist> playlists = mStore.storeRecords(object, Playlist.class, type,
                        infoRequestData.isBackgroundRequest());
                infoRequestData.setResultList(playlists);
                return true;

            } else if (type >= InfoRequestData.INFOREQUESTDATA_TYPE_ARTISTS
                    && type < InfoRequestData.INFOREQUESTDATA_TYPE_ARTISTS + 100) {
                JsonObject object = hatchet.getArtists(params.ids, params.name);
                if (object == null) {
                    return false;
                }
                if (type == InfoRequestData.INFOREQUESTDATA_TYPE_ARTISTS_TOPHITSANDALBUMS) {
                    List<Query> topHits = mStore.storeRecords(object, Query.class, type,
                            infoRequestData.isBackgroundRequest());
                    Artist artist = Artist.get(params.name);
                    Playlist playlist = Playlist.fromQueryList(
                            TomahawkApp.PLUGINNAME_HATCHET + "_" + artist.getCacheKey(), null, null, topHits);
                    hatchetCollection.addArtistTopHits(artist, playlist);

                    List<Album> albums = mStore.storeRecords(object, Album.class, type,
                            infoRequestData.isBackgroundRequest());
                    if (albums.size() > 0) {
                        for (Album album : albums) {
                            hatchetCollection.addAlbum(album);
                        }
                        Album firstAlbum = albums.get(0);
                        hatchetCollection.addArtistAlbums(firstAlbum.getArtist(), albums);
                    }
                }
                List<Artist> artists = mStore.storeRecords(object, Artist.class, type,
                        infoRequestData.isBackgroundRequest());
                for (Artist artist : artists) {
                    hatchetCollection.addArtist(artist);
                }
                infoRequestData.setResultList(artists);
                return true;

            } else if (type >= InfoRequestData.INFOREQUESTDATA_TYPE_ALBUMS
                    && type < InfoRequestData.INFOREQUESTDATA_TYPE_ALBUMS + 100) {
                JsonObject object = hatchet.getAlbums(params.ids, params.name, params.artistname);
                if (object == null) {
                    return false;
                }
                if (type == InfoRequestData.INFOREQUESTDATA_TYPE_ALBUMS_TRACKS) {
                    List<Query> tracks = mStore.storeRecords(object, Query.class, type,
                            infoRequestData.isBackgroundRequest());
                    Artist artist = Artist.get(params.artistname);
                    Album album = Album.get(params.name, artist);
                    Playlist playlist = Playlist.fromQueryList(
                            TomahawkApp.PLUGINNAME_HATCHET + "_" + album.getCacheKey(), null, null, tracks);
                    playlist.setFilled(true);
                    hatchetCollection.addAlbumTracks(album, playlist);
                }
                List<Album> albums = mStore.storeRecords(object, Album.class, type,
                        infoRequestData.isBackgroundRequest());
                for (Album album : albums) {
                    hatchetCollection.addAlbum(album);
                }
                infoRequestData.setResultList(albums);
                return true;

            } else if (type == InfoRequestData.INFOREQUESTDATA_TYPE_SEARCHES) {
                JsonObject object = hatchet.getSearches(params.term);
                if (object == null) {
                    return false;
                }
                List<Search> searches = mStore.storeRecords(object, Search.class, type,
                        infoRequestData.isBackgroundRequest());
                infoRequestData.setResultList(searches);
                return true;

            } else if (type == InfoRequestData.INFOREQUESTDATA_TYPE_SOCIALACTIONS) {
                JsonObject object = hatchet.getSocialActions(null, params.userid, params.type,
                        ISO8601Utils.format(params.before_date), params.limit);
                if (object == null) {
                    return false;
                }
                List<SocialAction> socialActions = mStore.storeRecords(object, SocialAction.class, type,
                        infoRequestData.isBackgroundRequest(), params);
                infoRequestData.setResultList(socialActions);
                return true;
            }
        } catch (RetrofitError e) {
            Log.e(TAG, "getParseConvert: Request to " + e.getUrl() + " failed: " + e.getClass() + ": "
                    + e.getLocalizedMessage());
        }
        return false;
    }

    /**
     * Start the JSONSendTask to send the given InfoRequestData's json string
     */
    @Override
    public void send(final InfoRequestData infoRequestData, AuthenticatorUtils authenticatorUtils) {
        mHatchetAuthenticatorUtils = (HatchetAuthenticatorUtils) authenticatorUtils;
        TomahawkRunnable runnable = new TomahawkRunnable(TomahawkRunnable.PRIORITY_IS_INFOSYSTEM_MEDIUM) {
            @Override
            public void run() {
                ArrayList<String> doneRequestsIds = new ArrayList<>();
                doneRequestsIds.add(infoRequestData.getRequestId());
                Hatchet hatchet = mStore.getImplementation(infoRequestData.isBackgroundRequest());
                // Before we do anything, get the accesstoken
                boolean success = false;
                boolean discard = false;
                String accessToken = mHatchetAuthenticatorUtils.ensureAccessTokens();
                if (accessToken != null) {
                    String data = infoRequestData.getJsonStringToSend();
                    try {
                        if (infoRequestData.getType() == InfoRequestData.INFOREQUESTDATA_TYPE_PLAYBACKLOGENTRIES) {
                            hatchet.postPlaybackLogEntries(accessToken, new TypedByteArray(
                                    "application/json; charset=utf-8", data.getBytes(Charsets.UTF_8)));
                        } else if (infoRequestData.getType() == InfoRequestData.INFOREQUESTDATA_TYPE_PLAYLISTS) {
                            if (infoRequestData.getHttpType() == InfoRequestData.HTTPTYPE_POST) {
                                HatchetPlaylistEntries entries = hatchet.postPlaylists(accessToken,
                                        new TypedByteArray("application/json; charset=utf-8",
                                                data.getBytes(Charsets.UTF_8)));
                                List<HatchetPlaylistEntries> results = new ArrayList<>();
                                results.add(entries);
                                infoRequestData.setResultList(results);
                            } else if (infoRequestData.getHttpType() == InfoRequestData.HTTPTYPE_DELETE) {
                                hatchet.deletePlaylists(accessToken, infoRequestData.getQueryParams().playlist_id);
                            } else if (infoRequestData.getHttpType() == InfoRequestData.HTTPTYPE_PUT) {
                                hatchet.putPlaylists(accessToken, infoRequestData.getQueryParams().playlist_id,
                                        new TypedByteArray("application/json; charset=utf-8",
                                                data.getBytes(Charsets.UTF_8)));
                            }
                        } else if (infoRequestData
                                .getType() == InfoRequestData.INFOREQUESTDATA_TYPE_PLAYLISTS_PLAYLISTENTRIES) {
                            if (infoRequestData.getHttpType() == InfoRequestData.HTTPTYPE_POST) {
                                hatchet.postPlaylistsPlaylistEntries(accessToken, new TypedByteArray(
                                        "application/json; charset=utf-8", data.getBytes(Charsets.UTF_8)));
                            } else if (infoRequestData.getHttpType() == InfoRequestData.HTTPTYPE_DELETE) {
                                hatchet.deletePlaylistsPlaylistEntries(accessToken,
                                        infoRequestData.getQueryParams().entry_id,
                                        infoRequestData.getQueryParams().playlist_id);
                            }
                        } else if (infoRequestData
                                .getType() == InfoRequestData.INFOREQUESTDATA_TYPE_RELATIONSHIPS) {
                            if (infoRequestData.getHttpType() == InfoRequestData.HTTPTYPE_POST) {
                                hatchet.postRelationship(accessToken, new TypedByteArray(
                                        "application/json; charset=utf-8", data.getBytes(Charsets.UTF_8)));
                            } else if (infoRequestData.getHttpType() == InfoRequestData.HTTPTYPE_DELETE) {
                                hatchet.deleteRelationShip(accessToken,
                                        infoRequestData.getQueryParams().relationship_id);
                            }
                        }
                        success = true;
                        discard = true;
                    } catch (RetrofitError e) {
                        Log.e(TAG, "send: Request to " + e.getUrl() + " failed: " + e.getClass() + ": "
                                + e.getLocalizedMessage());
                        if (e.getResponse() != null && e.getResponse().getStatus() == 500) {
                            Log.e(TAG, "send: discarding oplog that has failed to be sent to " + e.getUrl());
                            discard = true;
                        }
                    }
                }
                InfoSystem.get().onLoggedOpsSent(doneRequestsIds, discard);
                InfoSystem.get().reportResults(infoRequestData, success);
            }
        };
        ThreadManager.get().execute(runnable);
    }
}