diff --git a/pom.xml b/pom.xml
index 4ecb845..9fa7cea 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,7 +14,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.5.1.RELEASE
+ 2.1.9.RELEASE
@@ -39,6 +39,39 @@
spring-boot-configuration-processor
true
+
+ junit
+ junit
+ test
+
+
+ org.springframework
+ spring-test
+ 5.1.5.RELEASE
+ test
+
+
+ org.springframework.boot
+ spring-boot
+ 2.1.9.RELEASE
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+ 2.1.9.RELEASE
+
+
+ org.springframework.boot
+ spring-boot-test
+ 2.1.3.RELEASE
+ test
+
+
+ org.mockito
+ mockito-core
+ 2.23.4
+ test
+
@@ -51,5 +84,6 @@
+ ${project.basedir}/src/test
diff --git a/src/main/java/org/nuvola/tvshowtime/ApplicationLauncher.java b/src/main/java/org/nuvola/tvshowtime/ApplicationLauncher.java
index fbded82..aa94a82 100644
--- a/src/main/java/org/nuvola/tvshowtime/ApplicationLauncher.java
+++ b/src/main/java/org/nuvola/tvshowtime/ApplicationLauncher.java
@@ -18,268 +18,27 @@
package org.nuvola.tvshowtime;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.stream.Collectors;
-
-import org.nuvola.tvshowtime.business.plex.MediaContainer;
-import org.nuvola.tvshowtime.business.plex.User;
-import org.nuvola.tvshowtime.business.plex.Video;
-import org.nuvola.tvshowtime.business.tvshowtime.AccessToken;
-import org.nuvola.tvshowtime.business.tvshowtime.AuthorizationCode;
-import org.nuvola.tvshowtime.business.tvshowtime.Message;
-import org.nuvola.tvshowtime.config.PMSConfig;
-import org.nuvola.tvshowtime.config.TVShowTimeConfig;
-import org.nuvola.tvshowtime.util.DateUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
+import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.web.client.RestTemplate;
-
-import static org.nuvola.tvshowtime.util.Constants.MINUTE_IN_MILIS;
-import static org.nuvola.tvshowtime.util.Constants.PMS_WATCH_HISTORY;
-import static org.nuvola.tvshowtime.util.Constants.TVST_ACCESS_TOKEN_URI;
-import static org.nuvola.tvshowtime.util.Constants.TVST_AUTHORIZE_URI;
-import static org.nuvola.tvshowtime.util.Constants.TVST_CHECKIN_URI;
-import static org.nuvola.tvshowtime.util.Constants.TVST_CLIENT_ID;
-import static org.nuvola.tvshowtime.util.Constants.TVST_CLIENT_SECRET;
-import static org.nuvola.tvshowtime.util.Constants.TVST_RATE_REMAINING_HEADER;
-import static org.nuvola.tvshowtime.util.Constants.TVST_USER_AGENT;
-import static org.springframework.http.HttpMethod.POST;
@SpringBootApplication
@EnableScheduling
public class ApplicationLauncher {
- private static final Logger LOG = LoggerFactory.getLogger(ApplicationLauncher.class);
@Autowired
- private TVShowTimeConfig tvShowTimeConfig;
- @Autowired
- private PMSConfig pmsConfig;
-
- private RestTemplate tvShowTimeTemplate;
- private RestTemplate pmsTemplate;
- private AccessToken accessToken;
- private Timer tokenTimer;
-
- public static void main(String[] args) {
- SpringApplication.run(ApplicationLauncher.class, args);
- }
-
- @Scheduled(fixedDelay = Long.MAX_VALUE)
- public void init() {
- tvShowTimeTemplate = new RestTemplate();
+ private TvTimeService m_tvTimeService;
- File storeToken = new File(tvShowTimeConfig.getTokenFile());
- if (storeToken.exists()) {
- try {
- FileInputStream fileInputStream = new FileInputStream(storeToken);
- ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
- accessToken = (AccessToken) objectInputStream.readObject();
- objectInputStream.close();
- fileInputStream.close();
-
- LOG.info("AccessToken loaded from file with success : " + accessToken);
- } catch (Exception e) {
- LOG.error("Error parsing the AccessToken stored in 'session_token'.");
- LOG.error("Please remove the 'session_token' file, and try again.");
- LOG.error(e.getMessage());
-
- System.exit(1);
- }
-
- try {
- processWatchedEpisodes();
- } catch (Exception e) {
- LOG.error("Error during marking episodes as watched.");
- LOG.error(e.getMessage());
-
- System.exit(1);
- }
- } else {
- requestAccessToken();
- }
+ public static void main(String[] args) {
+ SpringApplication.run(ApplicationLauncher.class, args);
}
- private void requestAccessToken() {
- try {
- HttpHeaders headers = new HttpHeaders();
- headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
- HttpEntity entity = new HttpEntity<>("client_id=" + TVST_CLIENT_ID, headers);
-
- ResponseEntity content = tvShowTimeTemplate.exchange(TVST_AUTHORIZE_URI, POST, entity,
- AuthorizationCode.class);
- AuthorizationCode authorizationCode = content.getBody();
-
- if (authorizationCode.getResult().equals("OK")) {
- LOG.info("Linking with your TVShowTime account using the code " + authorizationCode.getDevice_code());
- LOG.info("Please open the URL " + authorizationCode.getVerification_url() + " in your browser");
- LOG.info("Connect with your TVShowTime account and type in the following code : ");
- LOG.info(authorizationCode.getUser_code());
- LOG.info("Waiting for you to type in the code in TVShowTime :-D ...");
-
- tokenTimer = new Timer();
- tokenTimer.scheduleAtFixedRate(new TimerTask() {
- @Override
- public void run() {
- loadAccessToken(authorizationCode.getDevice_code());
- }
- }, 1000 * authorizationCode.getInterval(), 1000 * authorizationCode.getInterval());
- } else {
- LOG.error("OAuth authentication TVShowTime failed.");
-
- System.exit(1);
- }
- } catch (Exception e) {
- LOG.error("OAuth authentication TVShowTime failed.");
- LOG.error(e.getMessage());
-
- System.exit(1);
- }
+ @EventListener(ApplicationReadyEvent.class)
+ public void init() throws Exception {
+ m_tvTimeService.init();
}
- private void loadAccessToken(String deviceCode) {
- String query = new StringBuilder("client_id=")
- .append(TVST_CLIENT_ID)
- .append("&client_secret=")
- .append(TVST_CLIENT_SECRET)
- .append("&code=")
- .append(deviceCode)
- .toString();
-
- HttpHeaders headers = new HttpHeaders();
- headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
- HttpEntity entity = new HttpEntity<>(query, headers);
-
- ResponseEntity content = tvShowTimeTemplate.exchange(TVST_ACCESS_TOKEN_URI, POST, entity,
- AccessToken.class);
- accessToken = content.getBody();
-
- if (accessToken.getResult().equals("OK")) {
- LOG.info("AccessToken from TVShowTime with success : " + accessToken);
- tokenTimer.cancel();
-
- storeAccessToken();
- processWatchedEpisodes();
- } else {
- if (!accessToken.getMessage().equals("Authorization pending")
- && !accessToken.getMessage().equals("Slow down")) {
- LOG.error("Unexpected error did arrive, please reload the service :-(");
- tokenTimer.cancel();
-
- System.exit(1);
- }
- }
- }
-
- private void storeAccessToken() {
- try {
- File storeToken = new File(tvShowTimeConfig.getTokenFile());
- FileOutputStream fileOutputStream = new FileOutputStream(storeToken);
- ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
- objectOutputStream.writeObject(accessToken);
- objectOutputStream.close();
- fileOutputStream.close();
-
- LOG.info("AccessToken store successfully inside a file...");
- } catch (Exception e) {
- LOG.error("Unexpected error did arrive when trying to store the AccessToken in a file ");
- LOG.error(e.getMessage());
-
- System.exit(1);
- }
- }
-
- private void processWatchedEpisodes() {
- pmsTemplate = new RestTemplate();
- String watchHistoryUrl = pmsConfig.getPath() + PMS_WATCH_HISTORY;
-
- if (pmsConfig.getToken() != null && !pmsConfig.getToken().isEmpty()) {
- watchHistoryUrl += "?X-Plex-Token=" + pmsConfig.getToken();
- LOG.info("Calling Plex with a X-Plex-Token...");
- }
-
- ResponseEntity response = pmsTemplate.getForEntity(watchHistoryUrl, MediaContainer.class);
- MediaContainer mediaContainer = response.getBody();
-
- for (Video video : mediaContainer.getVideo()) {
- LocalDateTime date = DateUtils.getDateTimeFromTimestamp(video.getViewedAt());
-
- // Mark as watched only episodes for configured user
- if (pmsConfig.getUsername() != null && video.getUser() != null) {
- List users = video.getUser().stream().filter(user -> user.getName().equals(pmsConfig.getUsername())).collect(Collectors.toList());
-
- if (users.stream().count() == 0) {
- continue;
- }
- }
-
- // Mark as watched only today and yesterday episodes
- if (DateUtils.isTodayOrYesterday(date) || pmsConfig.getMarkall() == true) {
- if (video.getType().equals("episode")) {
- String episode = new StringBuilder(video.getGrandparentTitle())
- .append(" - S")
- .append(video.getParentIndex())
- .append("E").append(video.getIndex())
- .toString();
-
- markEpisodeAsWatched(episode);
- } else {
- continue;
- }
- } else {
- LOG.info("All episodes are processed successfully ...");
- System.exit(0);
- }
- }
- }
-
- private void markEpisodeAsWatched(String episode) {
- HttpHeaders headers = new HttpHeaders();
- headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
- headers.add("User-Agent", TVST_USER_AGENT);
- HttpEntity entity = new HttpEntity<>("filename=" + episode, headers);
-
- String checkinUrl = new StringBuilder(TVST_CHECKIN_URI)
- .append("?access_token=")
- .append(accessToken.getAccess_token())
- .toString();
-
- ResponseEntity content = tvShowTimeTemplate.exchange(checkinUrl, POST, entity, Message.class);
- Message message = content.getBody();
-
- if (message.getResult().equals("OK")) {
- LOG.info("Mark " + episode + " as watched in TVShowTime");
- } else {
- LOG.error("Error while marking [" + episode + "] as watched in TVShowTime ");
- }
-
- // Check if we are below the Rate-Limit of the API
- int remainingApiCalls = Integer.parseInt(content.getHeaders().get(TVST_RATE_REMAINING_HEADER).get(0));
- if (remainingApiCalls == 0) {
- try {
- LOG.info("Consumed all available TVShowTime API calls slots, waiting for new slots ...");
- Thread.sleep(MINUTE_IN_MILIS);
- } catch (Exception e) {
- LOG.error(e.getMessage());
-
- System.exit(1);
- }
- }
- }
}
diff --git a/src/main/java/org/nuvola/tvshowtime/PlexService.java b/src/main/java/org/nuvola/tvshowtime/PlexService.java
new file mode 100644
index 0000000..f6ba0e4
--- /dev/null
+++ b/src/main/java/org/nuvola/tvshowtime/PlexService.java
@@ -0,0 +1,102 @@
+package org.nuvola.tvshowtime;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.nuvola.tvshowtime.business.plex.MetaData;
+import org.nuvola.tvshowtime.business.plex.PlexResponse;
+import org.nuvola.tvshowtime.config.PMSConfig;
+import org.nuvola.tvshowtime.util.DateUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.util.*;
+
+import static org.nuvola.tvshowtime.util.Constants.PMS_GET_ACCOUNTS;
+import static org.nuvola.tvshowtime.util.Constants.PMS_WATCH_HISTORY;
+
+@Service
+class PlexService {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PlexService.class);
+
+ @Autowired
+ private PMSConfig pmsConfig;
+ @Autowired
+ private RestTemplate pmsTemplate;
+ private Map m_users = new HashMap<>();
+ private String m_url;
+ private final static ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+ void getUsersInPlex() throws IOException {
+ m_url = pmsConfig.getPath() + PMS_GET_ACCOUNTS;
+ appendPlexToken();
+ LOG.debug("Get users from plex with url: " + m_url);
+ String response = pmsTemplate.getForObject(m_url, String.class);
+ PlexResponse plexResponse = OBJECT_MAPPER.readValue(response, PlexResponse.class);
+ plexResponse.getMediaContainer().getAccount().stream().filter(user -> !user.getName().equals("")).forEach(user -> m_users.put(user.getName(), user.getId()));
+ }
+
+ Map getUsers() {
+ return m_users;
+ }
+
+ Set getWatchedOnPlex() throws IOException {
+ //refresh m_users
+ getUsersInPlex();
+
+ Set watched = new HashSet<>();
+ m_url = pmsConfig.getPath() + PMS_WATCH_HISTORY;
+
+ appendPlexToken();
+ String response = pmsTemplate.getForObject(m_url, String.class);
+
+ PlexResponse plexResponse = OBJECT_MAPPER.readValue(response, PlexResponse.class);
+ LOG.debug(plexResponse.getMediaContainer().toString());
+
+ for (MetaData metaData : plexResponse.getMediaContainer().getMetaData()) {
+ LocalDateTime date = DateUtils.getDateTimeFromTimestamp(metaData.getViewedAt());
+
+ LOG.debug(metaData.toString());
+
+ // If present, mark as watched only episodes for configured user
+ if (pmsConfig.getUsername() != null) {
+ if (!metaData.getAccountID().equals(m_users.get(pmsConfig.getUsername()))) {
+ continue;
+ }
+ }
+
+ // Mark as watched only today and yesterday episodes
+ if (DateUtils.isTodayOrYesterday(date) || pmsConfig.getMarkall()) {
+ if (metaData.getType().equals("episode")) {
+ String episode = new StringBuilder(metaData.getGrandparentTitle())
+ .append(" - S")
+ .append(metaData.getParentIndex())
+ .append("E").append(metaData.getIndex())
+ .toString();
+
+ watched.add(episode);
+ }
+ /*
+ * Enable when TvTime should accept movie
+
+ else if (metaData.getType().equals("movie")) {
+ watched.add(metaData.getTitle());
+ }
+ */
+ }
+ }
+ return watched;
+ }
+
+ private void appendPlexToken() {
+ if (pmsConfig.getToken() != null && !pmsConfig.getToken().isEmpty()) {
+ m_url += "?X-Plex-Token=" + pmsConfig.getToken();
+ LOG.debug("Calling Plex with a X-Plex-Token = " + pmsConfig.getToken());
+ }
+ }
+
+}
diff --git a/src/main/java/org/nuvola/tvshowtime/TvTimeService.java b/src/main/java/org/nuvola/tvshowtime/TvTimeService.java
new file mode 100644
index 0000000..fec70c0
--- /dev/null
+++ b/src/main/java/org/nuvola/tvshowtime/TvTimeService.java
@@ -0,0 +1,203 @@
+package org.nuvola.tvshowtime;
+
+import org.nuvola.tvshowtime.business.tvshowtime.*;
+import org.nuvola.tvshowtime.config.TVShowTimeConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.*;
+import java.util.*;
+
+import static org.nuvola.tvshowtime.util.Constants.*;
+import static org.springframework.http.HttpMethod.POST;
+
+@Service
+class TvTimeService {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TvTimeService.class);
+
+ @Autowired
+ private TVShowTimeConfig tvShowTimeConfig;
+
+ @Autowired
+ private PlexService m_plexService;
+
+ @Autowired
+ private RestTemplate tvShowTimeTemplate;
+ private AccessToken accessToken;
+ private Timer tokenTimer;
+
+ void init() throws Exception {
+ File storeToken = new File(tvShowTimeConfig.getTokenFile());
+ if (storeToken.exists()) {
+ try {
+ FileInputStream fileInputStream = new FileInputStream(storeToken);
+ ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
+ accessToken = (AccessToken) objectInputStream.readObject();
+ objectInputStream.close();
+ fileInputStream.close();
+ LOG.info("AccessToken loaded from file with success : " + accessToken);
+ }
+ catch (Exception e) {
+ LOG.error("Error parsing the AccessToken stored in 'session_token'.");
+ LOG.error("Please remove the 'session_token' file, and try again.");
+ LOG.error(e.getMessage());
+ throw e;
+ }
+
+ try {
+ m_plexService.getUsersInPlex();
+ markEpisodesAsWatched(m_plexService.getWatchedOnPlex());
+ LOG.info("All episodes are processed successfully ...");
+ }
+ catch (Exception e) {
+ LOG.error("Error during marking episodes as watched.");
+ LOG.error("Error: ", e);
+ throw e;
+ }
+ }
+ else {
+ requestAccessToken();
+ LOG.info("Re-run the app to load info to TvTime ;-)");
+ }
+ }
+
+ void requestAccessToken() throws Exception {
+ LOG.info("RequestAccessToken....");
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ HttpEntity entity = new HttpEntity<>("client_id=" + TVST_CLIENT_ID, headers);
+
+ ResponseEntity content = tvShowTimeTemplate.exchange(TVST_AUTHORIZE_URI, POST, entity,
+ AuthorizationCode.class);
+ AuthorizationCode authorizationCode = content.getBody();
+
+ if (authorizationCode != null && authorizationCode.getResult().equals("OK")) {
+ LOG.info("Linking with your TVShowTime account using the code " + authorizationCode.getDevice_code());
+ LOG.info("Please open the URL " + authorizationCode.getVerification_url() + " in your browser");
+ LOG.info("Connect with your TVShowTime account and type in the following code : ");
+ LOG.info(">>> INSERT THE FOLLOWING CODE: " + authorizationCode.getUser_code() + " <<<");
+ LOG.info("Waiting for you to type in the code in TVShowTime :-D ...");
+
+ tokenTimer = new Timer();
+ tokenTimer.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ try {
+ loadAccessToken(authorizationCode.getDevice_code());
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }, 1000 * authorizationCode.getInterval(), 1000 * authorizationCode.getInterval());
+ }
+ else {
+ throw new Exception("OAuth authentication TVShowTime failed.");
+ }
+ }
+
+ void loadAccessToken(String deviceCode) throws Exception {
+ String query = new StringBuilder("client_id=")
+ .append(TVST_CLIENT_ID)
+ .append("&client_secret=")
+ .append(TVST_CLIENT_SECRET)
+ .append("&code=")
+ .append(deviceCode)
+ .toString();
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ HttpEntity entity = new HttpEntity<>(query, headers);
+
+ ResponseEntity content = tvShowTimeTemplate.exchange(TVST_ACCESS_TOKEN_URI, POST, entity,
+ AccessToken.class);
+ accessToken = content.getBody();
+
+ if (accessToken == null) {
+ throw new Exception("Access token is null");
+ }
+
+ if (accessToken.getResult().equals("OK")) {
+ LOG.info("AccessToken from TVShowTime with success : " + accessToken);
+ tokenTimer.cancel();
+ storeAccessToken();
+ markEpisodesAsWatched(m_plexService.getWatchedOnPlex());
+ }
+ else {
+ if (!accessToken.getMessage().equals("Authorization pending")
+ && !accessToken.getMessage().equals("Slow down")) {
+ LOG.error("Unexpected error did arrive, please reload the service :-(");
+ tokenTimer.cancel();
+ throw new Exception("Unexpected error did arrive, please reload the service :-(");
+ }
+ }
+ }
+
+ private void storeAccessToken() throws IOException {
+ try {
+ File storeToken = new File(tvShowTimeConfig.getTokenFile());
+ FileOutputStream fileOutputStream = new FileOutputStream(storeToken);
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
+ objectOutputStream.writeObject(accessToken);
+ objectOutputStream.close();
+ fileOutputStream.close();
+ LOG.info("AccessToken store successfully inside a file...");
+ }
+ catch (Exception e) {
+ LOG.error("Unexpected error did arrive when trying to store the AccessToken in a file ");
+ LOG.error(e.getMessage());
+ throw e;
+ }
+ }
+
+ void markEpisodesAsWatched(Set episodes) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ headers.add("User-Agent", TVST_USER_AGENT);
+
+ String checkInUrl = new StringBuilder(TVST_CHECKIN_URI)
+ .append("?access_token=")
+ .append(accessToken.getAccess_token())
+ .toString();
+
+ for (String episode : episodes) {
+ HttpEntity entity = new HttpEntity<>("filename=" + episode, headers);
+
+ ResponseEntity content = tvShowTimeTemplate.exchange(checkInUrl, POST, entity, Message.class);
+ Message message = content.getBody();
+
+ if (message != null && message.getResult().equals("OK")) {
+ LOG.info("Marked " + episode + " as watched in TVShowTime");
+ }
+ else {
+ LOG.error("Error while marking [" + episode + "] as watched in TVShowTime ");
+ }
+
+ // Check if we are below the Rate-Limit of the API
+ if (content.getHeaders().get(TVST_RATE_REMAINING_HEADER) != null
+ && !content.getHeaders().get(TVST_RATE_REMAINING_HEADER).isEmpty()) {
+
+ int remainingApiCalls = Integer.parseInt(content.getHeaders().get(TVST_RATE_REMAINING_HEADER).get(0));
+ long epocNewRateLimit = (Long.valueOf(content.getHeaders().get(TVST_RATE_RESET_HEADER).get(0)) * 1000);
+ if (remainingApiCalls == 0) {
+ try {
+ LOG.info("Consumed all available TVShowTime API calls slots, waiting for new slots at " + epocNewRateLimit);
+ epocNewRateLimit = epocNewRateLimit - System.currentTimeMillis();
+ if (epocNewRateLimit > 0) {
+ Thread.sleep(epocNewRateLimit);
+ }
+ }
+ catch (Exception e) {
+ LOG.error(e.getMessage());
+ }
+ }
+
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/nuvola/tvshowtime/business/plex/Account.java b/src/main/java/org/nuvola/tvshowtime/business/plex/Account.java
new file mode 100644
index 0000000..7df2cfa
--- /dev/null
+++ b/src/main/java/org/nuvola/tvshowtime/business/plex/Account.java
@@ -0,0 +1,108 @@
+/*
+ * tvshowtimeplex
+ * Copyright (C) 2017 Appulize - Maciej Swic
+ *
+ * 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 .
+ */
+
+package org.nuvola.tvshowtime.business.plex;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "Account")
+public class Account {
+ private Long id;
+ private String key;
+ private String name;
+ private String defaultAudioLanguage;
+ private Boolean autoSelectAudio;
+ private String defaultSubtitleLanguage;
+ private Integer subtitleMode;
+ private String thumb;
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getDefaultAudioLanguage() {
+ return defaultAudioLanguage;
+ }
+
+ public void setDefaultAudioLanguage(String defaultAudioLanguage) {
+ this.defaultAudioLanguage = defaultAudioLanguage;
+ }
+
+ public Boolean getAutoSelectAudio() {
+ return autoSelectAudio;
+ }
+
+ public void setAutoSelectAudio(Boolean autoSelectAudio) {
+ this.autoSelectAudio = autoSelectAudio;
+ }
+
+ public String getDefaultSubtitleLanguage() {
+ return defaultSubtitleLanguage;
+ }
+
+ public void setDefaultSubtitleLanguage(String defaultSubtitleLanguage) {
+ this.defaultSubtitleLanguage = defaultSubtitleLanguage;
+ }
+
+ public Integer getSubtitleMode() {
+ return subtitleMode;
+ }
+
+ public void setSubtitleMode(Integer subtitleMode) {
+ this.subtitleMode = subtitleMode;
+ }
+
+ public String getThumb() {
+ return thumb;
+ }
+
+ public void setThumb(String thumb) {
+ this.thumb = thumb;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @JsonProperty("title")
+ public String getTitle() {
+ return name;
+ }
+
+ public void setTitle(String title) {
+ this.name = title;
+ }
+}
diff --git a/src/main/java/org/nuvola/tvshowtime/business/plex/MediaContainer.java b/src/main/java/org/nuvola/tvshowtime/business/plex/MediaContainer.java
index 50ad752..1d2ede5 100644
--- a/src/main/java/org/nuvola/tvshowtime/business/plex/MediaContainer.java
+++ b/src/main/java/org/nuvola/tvshowtime/business/plex/MediaContainer.java
@@ -18,17 +18,22 @@
package org.nuvola.tvshowtime.business.plex;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
import java.util.List;
@XmlRootElement(name = "MediaContainer")
public class MediaContainer {
+ @JsonProperty("size")
private Integer size;
- private List