/** * The MIT License (MIT) * Copyright (c) 2012 David Carver * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package us.nineworlds.plex.rest; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; import us.nineworlds.plex.rest.config.IConfiguration; import us.nineworlds.plex.rest.model.impl.MediaContainer; /** * This class acts as a factory for retrieving items from Plex. * * This is a singleton so only one of these will ever exist currently. * * @author dcarver * */ public class PlexappFactory { private static PlexappFactory instance = null; private ResourcePaths resourcePath = null; private Serializer serializer = null; private PlexappFactory(IConfiguration config) { resourcePath = new ResourcePaths(config); serializer = new Persister(); } public static PlexappFactory getInstance(IConfiguration config) { if (instance == null) { instance = new PlexappFactory(config); } return instance; } /** * Retrieve the root metadata from the Plex Media Server. * * @return * @throws Exception */ public MediaContainer retrieveRootData() throws Exception { String rootURL = resourcePath.getRoot(); MediaContainer mediaContainer = serializeResource(rootURL); return mediaContainer; } /** * This retrieves the available libraries. This can include such * things as Movies, and TV shows. * * @return MediaContainer the media container for the library * @throws Exception */ public MediaContainer retrieveLibrary() throws Exception { String libraryURL = resourcePath.getLibraryURL(); MediaContainer mediaContainer = serializeResource(libraryURL); return mediaContainer; } /** * This retrieves the available libraries. This can include such * things as Movies, and TV shows. * * @return MediaContainer the media container for the library * @throws Exception */ public MediaContainer retrieveSections() throws Exception { String sectionsURL = resourcePath.getSectionsURL(); MediaContainer mediaContainer = serializeResource(sectionsURL); return mediaContainer; } /** * This retrieves the available libraries. This can include such * things as Movies, and TV shows. * * @return MediaContainer the media container for the library * @param key the section key * @throws Exception */ public MediaContainer retrieveSections(String key) throws Exception { String sectionsURL = resourcePath.getSectionsURL(key); MediaContainer mediaContainer = serializeResource(sectionsURL); return mediaContainer; } /** * For Movies this will return a MediaContainer with Videos. For * TV Shows this will return a MediaContainer with Directories. * * @param key * @param category * @return MediaContainer * @throws Exception */ public MediaContainer retrieveSections(String key, String category) throws Exception { String moviesURL = resourcePath.getSectionsURL(key, category); MediaContainer mediaContainer = serializeResource(moviesURL); return mediaContainer; } public MediaContainer retrieveSections(String key, String category, String secondaryCategory) throws Exception { String moviesURL = resourcePath.getSectionsURL(key, category, secondaryCategory); MediaContainer mediaContainer = serializeResource(moviesURL); return mediaContainer; } public MediaContainer retrieveSeasons(String key) throws Exception { String seasonsURL = resourcePath.getSeasonsURL(key); MediaContainer mediaContainer = serializeResource(seasonsURL); return mediaContainer; } public MediaContainer retrieveMusicMetaData(String key) throws Exception { String seasonsURL = resourcePath.getSeasonsURL(key); MediaContainer mediaContainer = serializeResource(seasonsURL); return mediaContainer; } public MediaContainer retrieveEpisodes(String key) throws Exception { String episodesURL = resourcePath.getEpisodesURL(key); MediaContainer mediaContainer = serializeResource(episodesURL); return mediaContainer; } public MediaContainer retrieveMovieMetaData(String key) throws Exception { String episodesURL = resourcePath.getMovieMetaDataURL(key); MediaContainer mediaContainer = serializeResource(episodesURL); return mediaContainer; } public MediaContainer searchMovies(String key, String query) throws Exception { String searchURL = resourcePath.getMovieSearchURL(key, query); MediaContainer mediaContainer = serializeResource(searchURL); return mediaContainer; } public MediaContainer searchEpisodes(String key, String query) throws Exception { String searchURL = resourcePath.getEpisodeSearchURL(key, query); MediaContainer mediaContainer = serializeResource(searchURL); return mediaContainer; } public String baseURL() { return resourcePath.getRoot(); } /** * Sets a video as watched. viewCount will be 1. * @param key * @return */ public boolean setWatched(String key) { String resourceURL = resourcePath.getWatchedUrl(key); return requestSuccessful(resourceURL); } /** * Sets a vide as unwatched. viewCount will not be present. * * @param key * @return */ public boolean setUnWatched(String key) { String resourceURL = resourcePath.getUnwatchedUrl(key); return requestSuccessful(resourceURL); } public boolean setProgress(String key, String offset) { String resourceURL = resourcePath.getProgressUrl(key, offset); return requestSuccessful(resourceURL); } /** * @param resourceURL * @param con * @return */ protected boolean requestSuccessful(String resourceURL) { HttpURLConnection con = null; try { URL url = new URL(resourceURL); con = (HttpURLConnection) url.openConnection(); con.setDefaultUseCaches(false); int responseCode = con.getResponseCode(); if (responseCode == 200) { return true; } } catch (Exception ex) { return false; } finally { if (con != null) { con.disconnect(); } } return false; } public String getProgressURL(String key, String offset) { return resourcePath.getProgressUrl(key, offset); } public String getMovieSearchURL(String key, String query) { return resourcePath.getMovieSearchURL(key, query); } public String getTVShowSearchURL(String key, String query) { return resourcePath.getMovieSearchURL(key, query); } public String getEpisodeSearchURL(String key, String query) { return resourcePath.getMovieSearchURL(key, query); } public String getMediaTagURL(String resourceType, String resourceName, String identifier) { return resourcePath.getMediaTagURL(resourceType, resourceName, identifier); } public String getSectionsURL(String key, String category) { return resourcePath.getSectionsURL(key, category); } public String getSectionsURL() { return resourcePath.getSectionsURL(); } public String getSectionsUrl(String key) { return resourcePath.getSectionsURL(key); } public String getMovieMetadataURL(String key) { return resourcePath.getMovieMetaDataURL(key); } public String getEpisodesURL(String key) { return resourcePath.getEpisodesURL(key); } public String getSeasonsURL(String key) { return resourcePath.getSeasonsURL(key); } public String getImageURL(String url, int width, int height) { return resourcePath.getImageURL(url, width, height); } /** * Given a resource's URL, read and return the serialized MediaContainer * @param resourceURL * @return * @throws MalformedURLException * @throws IOException * @throws Exception */ private MediaContainer serializeResource(String resourceURL) throws MalformedURLException, IOException, Exception { MediaContainer mediaContainer; URL url = new URL(resourceURL); HttpURLConnection con = (HttpURLConnection) url.openConnection(); // We only want the updated data if something has changed. con.addRequestProperty("Cache-Control", "max-age=0"); mediaContainer = serializer.read(MediaContainer.class, con.getInputStream(), false); return mediaContainer; } public MediaContainer serializeResourceFromString(String xmlString) throws Exception { MediaContainer container = serializer.read(MediaContainer.class, xmlString, false); return container; } }