Experimental support for episode level extended info (only supported with TheTVDB data)

This commit is contained in:
Reinhard Pointner 2016-10-31 07:19:11 +08:00
parent 8aecd9f868
commit 256b5be2d3
6 changed files with 178 additions and 4 deletions

View File

@ -3,6 +3,7 @@ package net.filebot.format;
import static java.util.Arrays.*;
import static java.util.regex.Pattern.*;
import static net.filebot.MediaTypes.*;
import static net.filebot.WebServices.*;
import static net.filebot.format.ExpressionFormatFunctions.*;
import static net.filebot.media.MediaDetection.*;
import static net.filebot.util.RegularExpressions.*;
@ -33,6 +34,8 @@ import groovy.lang.Closure;
import net.filebot.Language;
import net.filebot.similarity.Normalization;
import net.filebot.util.FileUtilities;
import net.filebot.web.Episode;
import net.filebot.web.EpisodeInfo;
import net.filebot.web.SimpleDate;
public class ExpressionFormatMethods {
@ -498,4 +501,14 @@ public class ExpressionFormatMethods {
return concat(self, other);
}
/**
* Episode utilities (EXPERIMENTAL)
*/
public static EpisodeInfo getInfo(Episode self) throws Exception {
if (TheTVDB.getIdentifier().equals(self.getSeriesInfo().getDatabase()))
return TheTVDBv2.getEpisodeInfo(self.getId(), Locale.ENGLISH);
return null;
}
}

View File

@ -601,9 +601,11 @@ public class MediaBindingBean {
}
@Define("director")
public Object getDirector() throws Exception {
public String getDirector() throws Exception {
if (infoObject instanceof Movie)
return getMovieInfo().getDirector();
if (infoObject instanceof Episode)
return getInfo(getEpisode()).getDirectors().iterator().next();
return null;
}

View File

@ -0,0 +1,120 @@
package net.filebot.web;
import static java.util.Arrays.*;
import static java.util.Collections.*;
import static java.util.stream.Collectors.*;
import java.io.Serializable;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
public class EpisodeInfo implements Serializable {
protected String database;
protected Integer seriesId;
protected Integer id;
protected String language;
protected Person[] people;
protected String overview;
protected Double rating;
protected Integer votes;
public EpisodeInfo() {
// used by deserializer
}
public EpisodeInfo(EpisodeInfo other) {
database = other.database;
seriesId = other.seriesId;
id = other.id;
language = other.language;
people = other.people == null ? null : other.people.clone();
overview = other.overview;
rating = other.rating;
votes = other.votes;
}
public EpisodeInfo(Datasource database, Locale language, Integer seriesId, Integer id, List<Person> people, String overview, Double rating, Integer votes) {
this.database = database.getIdentifier();
this.language = language.getLanguage();
this.seriesId = seriesId;
this.id = id;
this.people = people.toArray(new Person[0]);
this.overview = overview;
this.votes = votes;
this.rating = rating;
}
public String getDatabase() {
return database;
}
public Integer getSeriesId() {
return seriesId;
}
public Integer getId() {
return id;
}
public String getLanguage() {
return language;
}
public List<Person> getPeople() {
return unmodifiableList(asList(people));
}
public List<String> getDirectors() {
return stream(people).filter(Person::isDirector).map(Person::getName).collect(toList());
}
public List<String> getWriters() {
return stream(people).filter(Person::isWriter).map(Person::getName).collect(toList());
}
public List<String> getGuestStars() {
return stream(people).filter(Person::isActor).map(Person::getName).collect(toList());
}
public String getOverview() {
return overview;
}
public Double getRating() {
return rating;
}
public Integer getVotes() {
return votes;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof EpisodeInfo) {
EpisodeInfo other = (EpisodeInfo) obj;
return Objects.equals(id, other.id) && Objects.equals(database, other.database);
}
return false;
}
@Override
public int hashCode() {
return id == null ? 0 : id;
}
@Override
public EpisodeInfo clone() {
return new EpisodeInfo(this);
}
@Override
public String toString() {
return database + "::" + seriesId + "::" + id;
}
}

View File

@ -70,7 +70,7 @@ public class Person implements Serializable {
@Override
public String toString() {
return String.format("%s (%s)", name, isActor() ? character : job);
return String.format("%s (%s)", name, character != null ? character : job);
}
public static final String WRITER = "Writer";

View File

@ -276,8 +276,8 @@ public class TheTVDBClient extends AbstractEpisodeListProvider implements Artwor
return streamJsonObjects(response, "data").map(it -> getString(it, "abbreviation")).collect(toList());
}
public List<Person> getActors(int id, Locale locale) throws Exception {
Object response = requestJson("series/" + id + "/actors", locale, Cache.ONE_MONTH);
public List<Person> getActors(int seriesId, Locale locale) throws Exception {
Object response = requestJson("series/" + seriesId + "/actors", locale, Cache.ONE_MONTH);
// e.g. [id:68414, seriesId:78874, name:Summer Glau, role:River Tam, sortOrder:2, image:actors/68414.jpg, imageAuthor:513, imageAdded:0000-00-00 00:00:00, lastUpdated:2011-08-18 11:53:14]
return streamJsonObjects(response, "data").map(it -> {
@ -290,4 +290,29 @@ public class TheTVDBClient extends AbstractEpisodeListProvider implements Artwor
}).sorted(Person.CREDIT_ORDER).collect(toList());
}
public EpisodeInfo getEpisodeInfo(int id, Locale locale) throws Exception {
Object response = requestJson("episodes/" + id, locale, Cache.ONE_MONTH);
Object data = getMap(response, "data");
Integer seriesId = getInteger(data, "seriesId");
String overview = getString(data, "overview");
Double rating = getDecimal(data, "siteRating");
Integer votes = getInteger(data, "siteRatingCount");
List<Person> people = new ArrayList<Person>();
for (Object it : getArray(data, "directors")) {
people.add(new Person(it.toString(), Person.DIRECTOR));
}
for (Object it : getArray(data, "writers")) {
people.add(new Person(it.toString(), Person.WRITER));
}
for (Object it : getArray(data, "guestStars")) {
people.add(new Person(it.toString(), Person.ACTOR));
}
return new EpisodeInfo(this, locale, seriesId, id, people, overview, rating, votes);
}
}

View File

@ -164,4 +164,18 @@ public class TheTVDBClientTest {
assertEquals("http://thetvdb.com/banners/actors/68409.jpg", p.getImage().toString());
}
@Test
public void getEpisodeInfo() throws Exception {
EpisodeInfo i = db.getEpisodeInfo(296337, Locale.ENGLISH);
assertEquals("78845", i.getSeriesId().toString());
assertEquals("296337", i.getId().toString());
assertEquals(8.2, i.getRating(), 0.1);
assertEquals(6, i.getVotes(), 5);
assertEquals("When Jaye Tyler is convinced by a waxed lion to chase after a shinny quarter, she finds herself returning a lost purse to a lady (who instead of thanking her, is punched in the face), meeting an attractive and sweet bartender names Eric, introducing her sister, Sharon to the EPS newly divorced bachelor, Thomas, she knows, and later discovering her sister, Sharon's sexuality.", i.getOverview().toString());
assertEquals("[Todd Holland, Bryan Fuller, Todd Holland]", i.getDirectors().toString());
assertEquals("[Todd Holland, Bryan Fuller]", i.getWriters().toString());
assertEquals("[Scotch Ellis Loring, Gerry Fiorini, Kim Roberts, Corry Karpf, Curt Wu, Bailey Stocker, Lisa Marcos, Jorge Molina, Morgan Drmaj, Chantal Purdy, Kari Matchett, Neil Grayston, Anna Starnino, Melissa Grelo, Brandon Oakes, Scotch Ellis Loring, Ted Dykstra, Kathryn Greenwood, G]", i.getGuestStars().toString());
}
}