/* * Copyright (C) 2005-2010 Team XBMC * http://xbmc.org * * 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 2, 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 XBMC Remote; see the file license. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html * */ package org.xbmc.jsonrpc.client; import java.util.ArrayList; import java.util.Iterator; import org.codehaus.jackson.JsonNode; import org.xbmc.api.business.INotifiableManager; import org.xbmc.api.data.ITvShowClient; import org.xbmc.api.data.IControlClient.ICurrentlyPlaying; import org.xbmc.api.info.PlayStatus; import org.xbmc.api.object.Actor; import org.xbmc.api.object.Episode; import org.xbmc.api.object.Genre; import org.xbmc.api.object.Host; import org.xbmc.api.object.ICoverArt; import org.xbmc.api.object.Season; import org.xbmc.api.object.TvShow; import org.xbmc.api.type.MediaType; import org.xbmc.api.type.SortType; import org.xbmc.jsonrpc.Connection; import android.graphics.Bitmap; /** * TV show client for JSON RPC. * <br /><pre> * </pre> * @author Team XBMC */ public class TvShowClient extends Client implements ITvShowClient { public TvShowClient(Connection connection) { super(connection); } public ArrayList<TvShow> getTvShows(INotifiableManager manager, int sortBy, String sortOrder, boolean hideWatched) { return getTvShows(manager, obj(), sortBy, sortOrder, hideWatched); } public ArrayList<TvShow> getTvShows(INotifiableManager manager, ObjNode obj, int sortBy, String sortOrder, boolean hideWatched) { sort(obj.p(PARAM_PROPERTIES, arr().add("plot").add("rating").add("premiered").add("genre").add("mpaa").add("studio").add("file").add("episode").add("playcount").add("art")), sortBy, sortOrder); final ArrayList<TvShow> tvshows = new ArrayList<TvShow>(); final JsonNode result = mConnection.getJson(manager, "VideoLibrary.GetTvShows", obj); final JsonNode jsonShows = result.get("tvshows"); if(jsonShows != null){ for (Iterator<JsonNode> i = jsonShows.getElements(); i.hasNext();) { JsonNode jsonShow = (JsonNode)i.next(); int playcount =getInt(jsonShow, "playcount"); if(playcount > 0 && hideWatched) continue; tvshows.add(new TvShow( getInt(jsonShow, "tvshowid"), getString(jsonShow, "label"), getString(jsonShow, "plot"), getDouble(jsonShow, "rating"), getString(jsonShow, "premiered"), getString(jsonShow, "genre"), getString(jsonShow, "mpaa"), getString(jsonShow, "studio"), getString(jsonShow, "file"), getInt(jsonShow, "episode"), playcount, getInt(jsonShow, "playcount") > 0, jsonShow.get("art") != null? getString(jsonShow.get("art"), "banner") : "" )); } } return tvshows; } /** * Gets all tv show actors from database * @return All tv show actors */ public ArrayList<Actor> getTvShowActors(INotifiableManager manager) { //TODO return new ArrayList<Actor>(); } /** * Gets all tv show genres from database * @return All tv show genres */ public ArrayList<Genre> getTvShowGenres(INotifiableManager manager) { ObjNode obj = sort(obj().p("type", "tvshow"), SortType.TITLE, "descending"); final ArrayList<Genre> genres = new ArrayList<Genre>(); final JsonNode result = mConnection.getJson(manager, "VideoLibrary.GetGenres", obj); final JsonNode jsonGenres = result.get("genres"); if(jsonGenres != null){ for (Iterator<JsonNode> i = jsonGenres.getElements(); i.hasNext();) { JsonNode jsonGenre = (JsonNode)i.next(); genres.add(new Genre( getInt(jsonGenre, "genreid"), getString(jsonGenre, "label") )); } } return genres; } /** * Gets all tv shows with the specified actor * @param manager * @param actor * @return */ public ArrayList<TvShow> getTvShows(INotifiableManager manager, Actor actor, int sortBy, String sortOrder, boolean hideWatched) { return getTvShows(manager, obj().p("filter", obj().p("actor", actor.name)), sortBy, sortOrder, hideWatched); } /** * Gets all tv shows for the specified genre * */ public ArrayList<TvShow> getTvShows(INotifiableManager manager, Genre genre, int sortBy, String sortOrder, boolean hideWatched) { return getTvShows(manager, obj().p("filter", obj().p("genreid", genre.id)), sortBy, sortOrder, hideWatched); } /** * Gets all seasons for the specified show * @param manager * @param show * @return */ public ArrayList<Season> getSeasons(INotifiableManager manager, TvShow show, boolean hideWatched) { ObjNode obj = sort(obj().p("tvshowid", show.id).p(PARAM_PROPERTIES, arr().add("season").add("playcount").add("thumbnail")), SortType.TITLE, "ascending"); final ArrayList<Season> seasons = new ArrayList<Season>(); final JsonNode result = mConnection.getJson(manager, "VideoLibrary.GetSeasons", obj); final JsonNode jsonSeasons = result.get("seasons"); if(jsonSeasons != null){ for (Iterator<JsonNode> i = jsonSeasons.getElements(); i.hasNext();) { JsonNode jsonShow = (JsonNode)i.next(); int playcount =getInt(jsonShow, "playcount"); if(playcount > 0 && hideWatched) continue; seasons.add(new Season( getInt(jsonShow, "season"), playcount > 0, show, getString(jsonShow, "thumbnail") )); } } return seasons; } /** * Gets all seasons for all shows * @param manager * @param show * @return */ public ArrayList<Season> getSeasons(INotifiableManager manager, int sortBy, String sortOrder, boolean hideWatched) { ArrayList<TvShow> shows = getTvShows(manager, sortBy, sortOrder, hideWatched); ArrayList<Season> seasons = new ArrayList<Season>(); for (TvShow tvShow : shows) { seasons.addAll(getSeasons(manager, tvShow, hideWatched)); } return seasons; } /** * Gets all Episodes for the specified show * @param manager * @param show * @return */ public ArrayList<Episode> getEpisodes(INotifiableManager manager, TvShow show, int sortBy, String sortOrder, boolean hideWatched) { return getEpisodes(manager, show, null, sortBy, sortOrder, hideWatched); } /** * Gets all Episodes for the specified season * @param manager * @param season * @return */ public ArrayList<Episode> getEpisodes(INotifiableManager manager, Season season, int sortBy, String sortOrder, boolean hideWatched) { return getEpisodes(manager, season.show, season, sortBy, sortOrder, hideWatched); } public ArrayList<Episode> getRecentlyAddedEpisodes(INotifiableManager manager, boolean hideWatched) { ObjNode obj = obj().p(PARAM_PROPERTIES, arr().add("title").add("plot").add("rating").add("writer").add("firstaired").add("playcount").add("director").add("season").add("episode").add("file").add("showtitle").add("thumbnail")); final ArrayList<Episode> episodes = new ArrayList<Episode>(); final JsonNode result = mConnection.getJson(manager, "VideoLibrary.GetRecentlyAddedEpisodes", obj); final JsonNode jsonEpisodes = result.get("episodes"); if(episodes != null){ for (Iterator<JsonNode> i = jsonEpisodes.getElements(); i.hasNext();) { JsonNode jsonEpisode = (JsonNode)i.next(); int playcount =getInt(jsonEpisode, "playcount"); if(playcount > 0 && hideWatched) continue; episodes.add(new Episode( getInt(jsonEpisode, "episodeid"), getString(jsonEpisode, "title"), getString(jsonEpisode, "plot"), getDouble(jsonEpisode, "rating"), getString(jsonEpisode, "writer"), getString(jsonEpisode, "firstaired"), playcount, getString(jsonEpisode, "director"), getInt(jsonEpisode, "season"), getInt(jsonEpisode, "episode"), "", getString(jsonEpisode, "file"), getString(jsonEpisode, "showtitle"), getString(jsonEpisode, "thumbnail") )); } } return episodes; } /** * Gets all Episodes for all shows * @param manager * @return */ public ArrayList<Episode> getEpisodes(INotifiableManager manager, int sortBy, String sortOrder, boolean hideWatched){ return getEpisodes(manager, obj(), sortBy, sortOrder, hideWatched); } public ArrayList<Episode> getEpisodes(INotifiableManager manager, ObjNode obj, int sortBy, String sortOrder, boolean hideWatched) { obj = sort(obj.p(PARAM_PROPERTIES, arr().add("title").add("plot").add("rating").add("writer").add("firstaired").add("playcount").add("director").add("season").add("episode").add("file").add("showtitle").add("thumbnail")), sortBy, sortOrder); final ArrayList<Episode> episodes = new ArrayList<Episode>(); final JsonNode result = mConnection.getJson(manager, "VideoLibrary.GetEpisodes", obj); final JsonNode jsonEpisodes = result.get("episodes"); if(jsonEpisodes != null){ for (Iterator<JsonNode> i = jsonEpisodes.getElements(); i.hasNext();) { JsonNode jsonEpisode = (JsonNode)i.next(); int playcount =getInt(jsonEpisode, "playcount"); if(playcount > 0 && hideWatched) continue; episodes.add(new Episode( getInt(jsonEpisode, "episodeid"), getString(jsonEpisode, "title"), getString(jsonEpisode, "plot"), getDouble(jsonEpisode, "rating"), getString(jsonEpisode, "writer"), getString(jsonEpisode, "firstaired"), playcount, getString(jsonEpisode, "director"), getInt(jsonEpisode, "season"), getInt(jsonEpisode, "episode"), "", getString(jsonEpisode, "file"), getString(jsonEpisode, "showtitle"), getString(jsonEpisode, "thumbnail") )); } } return episodes; } /** * Gets all Episodes for the specified show and season * @param manager * @param show * @param season * @return */ public ArrayList<Episode> getEpisodes(INotifiableManager manager, TvShow show, Season season, int sortBy, String sortOrder, boolean hideWatched) { return getEpisodes(manager, obj().p("tvshowid", show.id).p("season", season.number), sortBy, sortOrder, hideWatched); } public TvShow updateTvShowDetails(INotifiableManager manager, TvShow show) { ObjNode obj = obj().p("tvshowid", show.id).p(PARAM_PROPERTIES, arr().add("cast")); final ArrayList<Actor> actors = new ArrayList<Actor>(); final JsonNode result = mConnection.getJson(manager, "VideoLibrary.GetTvShowDetails", obj); if(result.size() > 0){ final JsonNode jsonCast = result.get("tvshowdetails").get("cast"); for (Iterator<JsonNode> i = jsonCast.getElements(); i.hasNext();) { JsonNode jsonActor = (JsonNode)i.next(); actors.add(new Actor( getInt(jsonActor,"actorid"), getString(jsonActor, "name"), getString(jsonActor, "thumbnail"), getString(jsonActor, "role") )); } show.actors = actors; } return show; } public Episode updateEpisodeDetails(INotifiableManager manager, Episode episode) { ObjNode obj = obj().p("episodeid", episode.id).p(PARAM_PROPERTIES, arr().add("cast")); final ArrayList<Actor> actors = new ArrayList<Actor>(); final JsonNode result = mConnection.getJson(manager, "VideoLibrary.GetEpisodeDetails", obj); if(result.size() > 0){ final JsonNode jsonCast = result.get("episodedetails").get("cast"); for (Iterator<JsonNode> i = jsonCast.getElements(); i.hasNext();) { JsonNode jsonActor = (JsonNode)i.next(); actors.add(new Actor( getInt(jsonActor,"actorid"), getString(jsonActor, "name"), getString(jsonActor, "thumbnail"), getString(jsonActor, "role") )); } episode.actors = actors; } return episode; } static ICurrentlyPlaying getCurrentlyPlaying(final JsonNode player, final JsonNode item) { return new ICurrentlyPlaying() { private static final long serialVersionUID = 5036994329211476714L; public String getTitle() { return getString(item, "showtitle"); } public int getTime() { return ControlClient.parseTime(player.get("time")); } public int getPlayStatus() { return getInt(player, "speed"); } public int getPlaylistPosition() { return getInt(player, "position"); } //Workarond for bug in Float.valueOf(): http://code.google.com/p/android/issues/detail?id=3156 public float getPercentage() { try{ return getInt(player, "percentage"); } catch (NumberFormatException e) { } return (float)getDouble(player, "percentage"); } public String getFilename() { return getString(item, "file"); } public int getDuration() { return ControlClient.parseTime(player.get("totaltime")); } public String getArtist() { if(getInt(item, "season") == 0) { return "Specials / Episode " + getInt(item, "episode"); } else { return "Season " + getInt(item, "season") + " / Episode " + getInt(item, "episode"); } } public String getAlbum() { return getString(item, "title"); } public int getMediaType() { return MediaType.VIDEO_TVSHOW; } public boolean isPlaying() { return getInt(player, "speed") == PlayStatus.PLAYING; } public int getHeight() { return 0; } public int getWidth() { return 0; } }; } /** * Returns a pre-resized movie cover. Pre-resizing is done in a way that * the bitmap at least as large as the specified size but not larger than * the double. * @param manager Postback manager * @param cover Cover object * @param size Minmal size to pre-resize to. * @return Thumbnail bitmap */ public Bitmap getCover(INotifiableManager manager, ICoverArt cover, int size) { String url = null; if(!TvShow.getThumbUri(cover).equals("")){ final JsonNode dl = mConnection.getJson(manager, "Files.PrepareDownload", obj().p("path", TvShow.getThumbUri(cover))); if(dl != null){ JsonNode details = dl.get("details"); if(details != null) url = mConnection.getUrl(getString(details, "path")); } } return getCover(manager, cover, size, url); } /** * Updates host info on the connection. * @param host */ public void setHost(Host host) { mConnection.setHost(host); } }