001package net.filebot.web;
002
003import static java.util.Arrays.*;
004import static java.util.Collections.*;
005import static net.filebot.web.WebRequest.*;
006
007import java.io.Serializable;
008import java.net.URL;
009import java.time.Instant;
010import java.time.LocalDate;
011import java.util.List;
012import java.util.Locale;
013import java.util.Map;
014import java.util.stream.Stream;
015
016public class SeriesDetails extends SeriesInfo implements Serializable {
017
018        // common properties
019        protected String overview;
020        protected String poster;
021
022        protected String originalName;
023        protected String originalLanguage;
024        protected String[] country;
025
026        // TheMovieDB properties
027        protected int[] seasons;
028        protected Double popularity;
029        protected SimpleDate endDate;
030        protected Map<String, String> certifications;
031        protected String[] keywords;
032
033        // TheTVDB properties
034        protected String slug;
035        protected Integer imdbId;
036        protected String[] airsDays;
037        protected String airsTime;
038        protected Instant lastUpdated;
039
040        public SeriesDetails() {
041                // used by deserializer
042        }
043
044        public SeriesDetails(SeriesDetails other) {
045                super(other);
046
047                this.overview = other.overview;
048                this.poster = other.poster;
049                this.originalName = other.originalName;
050                this.originalLanguage = other.originalLanguage;
051                this.country = other.country;
052
053                this.seasons = other.seasons;
054                this.popularity = other.popularity;
055                this.endDate = other.endDate;
056                this.certifications = other.certifications;
057
058                this.slug = other.slug;
059                this.imdbId = other.imdbId;
060                this.overview = other.overview;
061                this.airsDays = other.airsDays;
062                this.airsTime = other.airsTime;
063                this.lastUpdated = other.lastUpdated;
064        }
065
066        public SeriesDetails(Datasource database, SortOrder order, Locale language, Integer id, String type) {
067                super(database, order, language, id, type);
068        }
069
070        // common properties
071
072        public String getOverview() {
073                return overview;
074        }
075
076        public void setOverview(String overview) {
077                this.overview = overview;
078        }
079
080        public void setPoster(URL poster) {
081                this.poster = poster == null ? null : poster.toExternalForm();
082        }
083
084        public URL getPoster() {
085                return parseURL(poster);
086        }
087
088        public String getOriginalName() {
089                return originalName;
090        }
091
092        public void setOriginalName(String originalName) {
093                this.originalName = originalName;
094        }
095
096        public String getOriginalLanguage() {
097                return originalLanguage;
098        }
099
100        public void setOriginalLanguage(String originalLanguage) {
101                this.originalLanguage = originalLanguage;
102        }
103
104        public List<String> getCountry() {
105                return country == null || country.length == 0 ? emptyList() : unmodifiableList(asList(country));
106        }
107
108        public void setCountry(String[] country) {
109                this.country = country;
110        }
111
112        // TheMovieDB properties
113
114        public int[] getSeasons() {
115                return seasons.clone();
116        }
117
118        public void setSeasons(int[] seasons) {
119                this.seasons = seasons;
120        }
121
122        public Double getPopularity() {
123                return popularity;
124        }
125
126        public void setPopularity(Double popularity) {
127                this.popularity = popularity;
128        }
129
130        public SimpleDate getEndDate() {
131                return endDate;
132        }
133
134        public void setEndDate(SimpleDate endDate) {
135                this.endDate = endDate;
136        }
137
138        public Map<String, String> getCertifications() {
139                return certifications == null || certifications.isEmpty() ? emptyMap() : unmodifiableMap(certifications);
140        }
141
142        public void setCertifications(Map<String, String> certifications) {
143                this.certifications = certifications;
144        }
145
146        public List<String> getKeywords() {
147                return keywords == null || keywords.length == 0 ? emptyList() : unmodifiableList(asList(keywords));
148        }
149
150        public void setKeywords(String[] keywords) {
151                this.keywords = keywords;
152        }
153
154        // TheTVDB properties
155
156        public String getSlug() {
157                return slug;
158        }
159
160        public void setSlug(String slug) {
161                this.slug = slug;
162        }
163
164        public Integer getImdbId() {
165                return imdbId;
166        }
167
168        public void setImdbId(Integer imdbId) {
169                this.imdbId = imdbId;
170        }
171
172        public List<String> getAirsDays() {
173                return airsDays == null || airsDays.length == 0 ? emptyList() : unmodifiableList(asList(airsDays));
174        }
175
176        public void setAirsDays(String[] airsDays) {
177                this.airsDays = airsDays;
178        }
179
180        public String getAirsTime() {
181                return airsTime;
182        }
183
184        public void setAirsTime(String airsTime) {
185                this.airsTime = airsTime;
186        }
187
188        public Instant getLastUpdated() {
189                return lastUpdated;
190        }
191
192        public void setLastUpdated(Instant lastUpdated) {
193                this.lastUpdated = lastUpdated;
194        }
195
196        public boolean hasEnded() {
197                // using TheMovieDB properties
198                return "Ended".equalsIgnoreCase(status);
199        }
200
201        public boolean isContinuing() {
202                // using TheTVDB properties
203                return "Continuing".equalsIgnoreCase(status);
204        }
205
206        public boolean isRecent() {
207                // using TheMovieDB properties
208                if (endDate != null && endDate.toLocalDate().until(LocalDate.now()).toTotalMonths() < 2) {
209                        return true;
210                }
211                // using TheTVDB properties (or TheMovieDB properties if end date is undefined)
212                if (startDate != null && startDate.toLocalDate().plusYears(seasons == null ? 0 : seasons.length - 1).until(LocalDate.now()).toTotalMonths() < 6) {
213                        return true;
214                }
215                return false;
216        }
217
218        public boolean isAiringToday() {
219                // using TheTVDBv2 properties
220                if (airsDays != null && stream(airsDays).anyMatch("Weekdays"::equalsIgnoreCase)) {
221                        return true;
222                }
223                // using TheTVDBv4 / TheTVDBv2 properties
224                if (airsDays != null && Stream.of(LocalDate.now(), LocalDate.now().minusDays(1)).anyMatch(d -> stream(airsDays).anyMatch(d.getDayOfWeek().name()::equalsIgnoreCase))) {
225                        return true;
226                }
227                return false;
228        }
229
230        @Override
231        public SeriesDetails clone() {
232                return new SeriesDetails(this);
233        }
234
235}