package com.sabdroidex.controllers.sickbeard;
import android.os.Debug;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.sabdroidex.controllers.SABController;
import com.sabdroidex.data.sickbeard.FuturePeriod;
import com.sabdroidex.data.sickbeard.Season;
import com.sabdroidex.data.sickbeard.Show;
import com.sabdroidex.data.sickbeard.ShowSearch;
import com.sabdroidex.data.sickbeard.Shows;
import com.sabdroidex.utils.Preferences;
import com.sabdroidex.utils.json.impl.SimpleJSONMarshaller;
import com.utils.ApacheCredentialProvider;
import com.utils.HttpUtil;
import org.json.JSONObject;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Collections;
public final class SickBeardController extends SABController {
private static final String TAG = "SickBeardController";
private static boolean executingRefreshShows = false;
private static boolean executingRefreshComing = false;
private static boolean executingCommand = false;
private static final String URL_TEMPLATE = "[SICKBEARD_URL]/[SICKBEARD_URL_EXTENTION]api/[SICKBEARD_API_KEY]?cmd=[COMMAND]";
private static final String URL_TVDB = "http://thetvdb.com/banners/posters/[TVDBID]";
private static final String URL_TVDB_SEASONS = "http://thetvdb.com/banners/seasons/[TVDBID]";
public static enum MESSAGE {
SHOWS, SHOW, FUTURE, SHOW_GETBANNER, SHOW_GETPOSTER, SHOW_ADDNEW, SB_SEARCHTVDB, UPDATE, SHOW_SEASONLIST, SHOW_SEASONS, EPISODE_SETSTATUS
}
/**
* Adds a show to SickBeard. For the location the configuration setting
* (default) is used -- if valid. The result sent to the {@link Handler}
* will be a {@link String} containing the status.
*
* @param messageHandler
* The message handler to be notified
* @param value
* The value which will be used to perform the action
*/
public static void addShow(final Handler messageHandler, final String value) {
// Already running or settings not ready
if (executingCommand || !Preferences.isSet(Preferences.SABNZBD_URL))
return;
Thread thread = new Thread() {
@Override
public void run() {
try {
Object results[] = new Object[2];
String addData = makeApiCall(MESSAGE.SHOW_ADDNEW.toString().toLowerCase(), "tvdbid=" + value);
/**
* Getting the values from the JSON Object
*/
JSONObject jsonObject = new JSONObject(addData);
results[0] = jsonObject;
results[1] = jsonObject.getString("result");
Message message = new Message();
message.setTarget(messageHandler);
message.what = MESSAGE.SHOW_ADDNEW.hashCode();
message.obj = results[1];
message.sendToTarget();
Thread.sleep(250);
SickBeardController.refreshShows(messageHandler);
}
catch (Throwable e) {
Log.w(TAG, e.getLocalizedMessage());
}
finally {
sendUpdateMessageStatus(messageHandler, "");
}
}
};
sendUpdateMessageStatus(messageHandler, MESSAGE.SHOW_ADDNEW.toString());
thread.start();
}
/**
* Search for a show to add to SickBeard.
*
* @param messageHandler
* The message handler to be notified
* @param value
* The value which will be used to perform the action
*/
public static void searchShow(final Handler messageHandler, final String value) {
/**
* If already running or Sickbeard is not configured
*/
if (executingCommand || !Preferences.isSet(Preferences.SABNZBD_URL))
return;
Thread thread = new Thread() {
@Override
public void run() {
try {
String searchData = makeApiCall(MESSAGE.SB_SEARCHTVDB.toString().toLowerCase(), "name="
+ URLEncoder.encode(value, "UTF-8"), "lang=en");
JSONObject jsonObject = new JSONObject(searchData);
if (!jsonObject.isNull("message") && !"".equals(jsonObject.getString("message"))) {
sendUpdateMessageStatus(messageHandler, "SickBeard : " + jsonObject.getString("message"));
}
else {
jsonObject = jsonObject.getJSONObject("data");
SimpleJSONMarshaller simpleJSONMarshaller = new SimpleJSONMarshaller(ShowSearch.class);
ShowSearch showSearch = (ShowSearch) simpleJSONMarshaller.unMarshal(jsonObject);
Message message = new Message();
message.setTarget(messageHandler);
message.what = MESSAGE.SB_SEARCHTVDB.hashCode();
message.obj = showSearch;
message.sendToTarget();
}
}
catch (Throwable e) {
Log.w(TAG, e.getLocalizedMessage());
}
finally {
sendUpdateMessageStatus(messageHandler, "");
}
}
};
sendUpdateMessageStatus(messageHandler, MESSAGE.SB_SEARCHTVDB.toString());
thread.start();
}
/**
* Refresh the shows that are in SickBeard. The result sent to the
* {@link Handler} will be an array of all the shows.
*
* @param messageHandler
* The message handler to be notified
*/
public static void refreshShows(final Handler messageHandler) {
/**
* If already running or Sickbeard is not configured
*/
if (executingRefreshShows || !Preferences.isSet(Preferences.SICKBEARD_URL))
return;
Thread thread = new Thread() {
@Override
public void run() {
String statusMessage = "";
try {
String queueData = makeApiCall(MESSAGE.SHOWS.toString().toLowerCase());
JSONObject jsonObject = new JSONObject(queueData);
Shows shows = null;
if (!jsonObject.isNull("message") && !"".equals(jsonObject.getString("message"))) {
sendUpdateMessageStatus(messageHandler, "SickBeard : " + jsonObject.getString("message"));
}
else {
jsonObject = jsonObject.getJSONObject("data");
SimpleJSONMarshaller jsonMarshaller = new SimpleJSONMarshaller(Shows.class);
shows = (Shows) jsonMarshaller.unMarshal(jsonObject);
Collections.sort(shows.getShowElements());
Message message = new Message();
message.setTarget(messageHandler);
message.what = MESSAGE.SHOWS.hashCode();
message.obj = shows;
message.sendToTarget();
}
}
catch (IOException e) {
Log.w(TAG, e.getLocalizedMessage());
statusMessage = e.getLocalizedMessage();
}
catch (Throwable e) {
Log.w(TAG, e.getLocalizedMessage());
}
finally {
executingRefreshShows = false;
sendUpdateMessageStatus(messageHandler, statusMessage);
}
}
};
executingRefreshShows = true;
thread.start();
}
/**
* Makes a call to retrieve all the episodes that will be available soon or
* those that have been missed.
*
* @param messageHandler
* The message handler to be notified
*/
public static void refreshFuture(final Handler messageHandler) {
/**
* If already running or Sickbeard is not configured
*/
if (executingRefreshComing || !Preferences.isSet(Preferences.SICKBEARD_URL))
return;
Thread thread = new Thread() {
@Override
public void run() {
try {
/**
* Getting the values from the JSON Object
*/
String queueData = makeApiCall(MESSAGE.FUTURE.toString().toLowerCase(), "sort=date");
JSONObject jsonObject = new JSONObject(queueData);
FuturePeriod futurePeriod = null;
if (!jsonObject.isNull("message") && !"".equals(jsonObject.getString("message"))) {
sendUpdateMessageStatus(messageHandler, "SickBeard : " + jsonObject.getString("message"));
}
else {
jsonObject = jsonObject.getJSONObject("data");
SimpleJSONMarshaller simpleJSONMarshaller = new SimpleJSONMarshaller(FuturePeriod.class);
futurePeriod = (FuturePeriod) simpleJSONMarshaller.unMarshal(jsonObject);
Message message = new Message();
message.setTarget(messageHandler);
message.what = MESSAGE.FUTURE.hashCode();
message.obj = futurePeriod;
message.sendToTarget();
}
}
catch (IOException e) {
Log.w(TAG, e.getLocalizedMessage());
}
catch (Throwable e) {
Log.w(TAG, e.getLocalizedMessage());
}
finally {
executingRefreshComing = false;
}
}
};
executingRefreshComing = true;
thread.start();
}
/**
* Makes a call to retrieve all seasons of a given show.
*
* @param messageHandler
* the handler that will be notified upon completion or error.
* @param value
* the showID
*/
public static void getShow(final Handler messageHandler, final String value) {
/**
* If Sickbeard is not configured
*/
if (!Preferences.isSet(Preferences.SICKBEARD_URL))
return;
Thread thread = new Thread() {
@Override
public void run() {
try {
String data = makeApiCall(MESSAGE.SHOW.toString().toLowerCase(), "tvdbid=" + value);
JSONObject jsonObject = new JSONObject(data);
Show show = null;
if (!jsonObject.isNull("message") && !"".equals(jsonObject.getString("message"))) {
sendUpdateMessageStatus(messageHandler, "SickBeard : " + jsonObject.getString("message"));
}
else {
jsonObject = jsonObject.getJSONObject("data");
SimpleJSONMarshaller jsonMarshaller = new SimpleJSONMarshaller(Show.class);
show = (Show) jsonMarshaller.unMarshal(jsonObject);
Collections.sort(show.getSeasonList());
}
Message message = new Message();
message.setTarget(messageHandler);
message.what = MESSAGE.SHOW.hashCode();
message.obj = show;
message.sendToTarget();
}
catch (IOException e) {
Log.w(TAG, e.getLocalizedMessage());
}
catch (Throwable e) {
Log.w(TAG, e.getLocalizedMessage());
}
}
};
thread.start();
}
/**
* Makes a call to retrieve all episodes of a given season for a specific
* show.
*
* @param messageHandler
* the handler that will be notified upon completion or error.
* @param showId the imdb ID of the show.
* @param seasonId the season ID of the show (season number)
*/
public static void getSeason(final Handler messageHandler, final String showId, final String seasonId) {
/**
* If Sickbeard is not configured
*/
if (!Preferences.isSet(Preferences.SICKBEARD_URL))
return;
Thread thread = new Thread() {
@Override
public void run() {
try {
String data = makeApiCall(MESSAGE.SHOW_SEASONS.toString().toLowerCase(), "tvdbid=" + showId, "season=" + seasonId);
JSONObject jsonObject = new JSONObject(data);
Season season = null;
if (!jsonObject.isNull("message") && !"".equals(jsonObject.getString("message"))) {
sendUpdateMessageStatus(messageHandler, "SickBeard : " + jsonObject.getString("message"));
}
else {
jsonObject = jsonObject.getJSONObject("data");
SimpleJSONMarshaller jsonMarshaller = new SimpleJSONMarshaller(Season.class);
season = (Season) jsonMarshaller.unMarshal(jsonObject);
Collections.sort(season.getEpisodes());
}
Message message = new Message();
message.setTarget(messageHandler);
message.what = MESSAGE.SHOW_SEASONS.hashCode();
message.obj = season;
message.sendToTarget();
}
catch (IOException e) {
Log.w(TAG, e.getLocalizedMessage());
}
catch (Throwable e) {
Log.w(TAG, e.getLocalizedMessage());
}
}
};
thread.start();
}
public static void setEpisodeStatus(final Handler messageHandler, final String tvdbId, final String seasonId, final String episode, final String status) {
/**
* If Sickbeard is not configured
*/
if (!Preferences.isSet(Preferences.SICKBEARD_URL))
return;
Thread thread = new Thread() {
@Override
public void run() {
String statusMessage = "";
try {
String data = makeApiCall(MESSAGE.EPISODE_SETSTATUS.toString().toLowerCase(), "tvdbid=" + tvdbId, "season=" + seasonId, "episode=" + episode, "status=" + status);
JSONObject jsonObject = new JSONObject(data);
if (!jsonObject.isNull("message") && !"".equals(jsonObject.getString("message"))) {
statusMessage = "SickBeard : " + jsonObject.getString("message");
}
}
catch (IOException e) {
Log.w(TAG, e.getLocalizedMessage());
}
catch (Throwable e) {
Log.w(TAG, e.getLocalizedMessage());
}
finally {
sendUpdateMessageStatus(messageHandler, statusMessage);
}
}
};
thread.start();
}
/**
* This functions handle the API calls to SickBeard to define the URL and
* parameters
*
* @param command
* The type of command that will be sent to SickBeard
* @return The result of the API call
* @throws Exception
* Thrown if there is any unexpected problem during the
* communication with the server
*/
public static String makeApiCall(String command) throws Exception {
return makeApiCall(command, "");
}
/**
* This functions handle the API calls to SickBeard to define the URL and
* parameters
*
* @param command
* The type of command that will be sent to SickBeard
* @param extraParams
* Any parameter that will have to be part of the URL
* @return The result of the API call
* @throws Exception
* Thrown if there is any unexpected problem during the
* communication with the server
*/
public static String makeApiCall(String command, String... extraParams) throws Exception {
/**
* Correcting the command names to be understood by SickBeard
*/
command = command.replace('_', '.');
String url = getFormattedUrl();
url = url.replace("[COMMAND]", command);
for (String xTraParam : extraParams) {
if (xTraParam != null && !xTraParam.trim().equals("")) {
url = url + "&" + xTraParam;
}
}
if (Debug.isDebuggerConnected()) {
Log.d(TAG, url);
}
return new String(HttpUtil.getInstance().getDataAsCharArray(url, ApacheCredentialProvider.getCredentialsProvider()));
}
/**
* This function gets the URL used to connect to the Sabnzbd server
*
* @return url A {@link String} containing the URL of the Sabnzbd server
*/
private static String getFormattedUrl() {
String url = URL_TEMPLATE;
/**
* Checking if there is a port to concatenate to the URL
*/
if ("".equals(Preferences.get(Preferences.SICKBEARD_PORT))) {
url = url.replace("[SICKBEARD_URL]", Preferences.get(Preferences.SICKBEARD_URL));
}
else {
url = url.replace("[SICKBEARD_URL]",
Preferences.get(Preferences.SICKBEARD_URL) + ":" + Preferences.get(Preferences.SICKBEARD_PORT));
}
/**
* Checking the url extention
*/
if ("".equals(Preferences.get(Preferences.SICKBEARD_URL_EXTENTION))) {
url = url.replace("[SICKBEARD_URL_EXTENTION]", Preferences.get(Preferences.SICKBEARD_URL_EXTENTION));
}
else {
url = url.replace("[SICKBEARD_URL_EXTENTION]", Preferences.get(Preferences.SICKBEARD_URL_EXTENTION) + "/");
}
/**
* Checking if there is an API Key from SickBeard to concatenate to the
* URL
*/
if ("".equals(Preferences.get(Preferences.SICKBEARD_API_KEY))) {
url = url.replace("[SICKBEARD_API_KEY]", "");
}
else {
url = url.replace("[SICKBEARD_API_KEY]", Preferences.get(Preferences.SICKBEARD_API_KEY) + "/");
}
if (!url.toUpperCase().startsWith("HTTP://") && !url.toUpperCase().startsWith("HTTPS://")) {
if (Preferences.isEnabled(Preferences.SICKBEARD_SSL)) {
url = "https://" + url;
}
else {
url = "http://" + url;
}
}
return url;
}
/**
* This function returns the URL of the banner for a given show
*
* @param command
* command The type of command that will be sent to SickBeard
* @param tvdbid
* The TvDBid of the show to get the banner for
* @return The URL of the banner
*/
public static String getImageURL(String command, Integer tvdbid) {
/**
* Correcting the command names to be understood by SickBeard
*/
command = command.replace('_', '.');
String url = getFormattedUrl();
url = url.replace("[COMMAND]", command);
url = url + "&tvdbid=" + tvdbid;
return url;
}
/**
* This function returns the URL of the poster for a given show
*
* @param tvdbid The TvDBid of the show to get the poster for
* @return The URL of the poster
*/
public static String getPosterURL(Integer tvdbid) {
String url = URL_TVDB;
url = url.replace("[TVDBID]", tvdbid + "-1.jpg");
return url;
}
/**
*
* @return
*/
@SuppressWarnings("unused")
private static String getPreferencesParams() {
String username = Preferences.get(Preferences.SABNZBD_USERNAME);
String password = Preferences.get(Preferences.SABNZBD_PASSWORD);
String credentials = "";
if (username != null && !"".equals(username)) {
credentials += "&ma_username=" + username;
}
if (password != null && !"".equals(password)) {
credentials += "&ma_password=" + password;
}
return credentials;
}
public static String getSeasonPosterURL(Integer tvdbid, Integer season) {
String url = URL_TVDB_SEASONS;
url = url.replace("[TVDBID]", tvdbid + "-" + season + "-2.jpg");
return url;
}
}