* added support for airdate in episode naming scheme (new binding "air")
* parse airdate in all episode list providers (TVRage, AniDB, TV.com, IMDb, TheTVDB)
This commit is contained in:
parent
8364015504
commit
5db098e95a
|
@ -19,6 +19,7 @@ import net.sf.ehcache.Element;
|
|||
import net.sourceforge.filebot.hash.HashType;
|
||||
import net.sourceforge.filebot.mediainfo.MediaInfo;
|
||||
import net.sourceforge.filebot.mediainfo.MediaInfo.StreamKind;
|
||||
import net.sourceforge.filebot.web.Date;
|
||||
import net.sourceforge.filebot.web.Episode;
|
||||
import net.sourceforge.tuned.FileUtilities;
|
||||
|
||||
|
@ -69,6 +70,12 @@ public class EpisodeBindingBean {
|
|||
}
|
||||
|
||||
|
||||
@Define("air")
|
||||
public Date airdate() {
|
||||
return episode.airdate();
|
||||
}
|
||||
|
||||
|
||||
@Define("vc")
|
||||
public String getVideoCodec() {
|
||||
// e.g. XviD, x264, DivX 5, MPEG-4 Visual, AVC, etc.
|
||||
|
|
|
@ -54,6 +54,7 @@ import net.sourceforge.filebot.ResourceManager;
|
|||
import net.sourceforge.filebot.Settings;
|
||||
import net.sourceforge.filebot.format.EpisodeBindingBean;
|
||||
import net.sourceforge.filebot.format.ExpressionFormat;
|
||||
import net.sourceforge.filebot.web.Date;
|
||||
import net.sourceforge.filebot.web.Episode;
|
||||
import net.sourceforge.filebot.web.EpisodeFormat;
|
||||
import net.sourceforge.tuned.DefaultThreadFactory;
|
||||
|
@ -290,7 +291,7 @@ class EpisodeFormatDialog extends JDialog {
|
|||
episode = EpisodeFormat.getInstance().parseObject(persistentSampleEpisode.getValue());
|
||||
} catch (Exception e) {
|
||||
// default sample
|
||||
episode = new Episode("Dark Angel", 3, 1, "Labyrinth");
|
||||
episode = new Episode("Dark Angel", "3", "1", "Labyrinth", null, new Date(2009, 6, 1));
|
||||
}
|
||||
|
||||
// restore media file
|
||||
|
|
|
@ -146,9 +146,10 @@ public class AnidbClient implements EpisodeListProvider {
|
|||
// ignore special episodes
|
||||
if (number != null && number.matches("\\d+")) {
|
||||
String title = selectString(".//title[@lang='en']", node);
|
||||
String airdate = selectString(".//date/@rel", node);
|
||||
|
||||
// no seasons for anime
|
||||
episodes.add(new Episode(animeTitle, null, number, title));
|
||||
episodes.add(new Episode(animeTitle, null, number, title, null, Date.parse(airdate, "yyyy-MM-dd")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
|
||||
import static java.util.Calendar.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
public class Date implements Serializable {
|
||||
|
||||
private int year;
|
||||
private int month;
|
||||
private int day;
|
||||
|
||||
|
||||
protected Date() {
|
||||
// used by serializer
|
||||
}
|
||||
|
||||
|
||||
public Date(int year, int month, int day) {
|
||||
this.year = year;
|
||||
this.month = month;
|
||||
this.day = day;
|
||||
}
|
||||
|
||||
|
||||
public int getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
|
||||
public int getMonth() {
|
||||
return month;
|
||||
}
|
||||
|
||||
|
||||
public int getDay() {
|
||||
return day;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%04d-%02d-%02d", year, month, day);
|
||||
}
|
||||
|
||||
|
||||
public String format(String pattern) {
|
||||
return new SimpleDateFormat(pattern).format(new GregorianCalendar(year, month, day).getTime());
|
||||
}
|
||||
|
||||
|
||||
public static Date parse(String string, String pattern) {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat(pattern, Locale.ROOT);
|
||||
formatter.setLenient(false); // enable strict mode (e.g. fail on invalid dates like 0000-00-00)
|
||||
|
||||
try {
|
||||
Calendar date = new GregorianCalendar(Locale.ROOT);
|
||||
date.setTime(formatter.parse(string));
|
||||
return new Date(date.get(YEAR), date.get(MONTH) + 1, date.get(DAY_OF_MONTH));
|
||||
} catch (ParseException e) {
|
||||
// no result if date is invalid
|
||||
Logger.getLogger(Date.class.getName()).log(Level.WARNING, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -12,30 +12,36 @@ public class Episode implements Serializable {
|
|||
private String season;
|
||||
private String episode;
|
||||
private String title;
|
||||
|
||||
// special number
|
||||
private String special;
|
||||
|
||||
// episode airdate
|
||||
private Date airdate;
|
||||
|
||||
|
||||
protected Episode() {
|
||||
// used by serializer
|
||||
}
|
||||
|
||||
|
||||
public Episode(String seriesName, int season, int episode, String title) {
|
||||
this(seriesName, String.valueOf(season), String.valueOf(episode), title, null);
|
||||
}
|
||||
|
||||
|
||||
public Episode(String seriesName, String season, String episode, String title) {
|
||||
this(seriesName, season, episode, title, null);
|
||||
this(seriesName, season, episode, title, null, null);
|
||||
}
|
||||
|
||||
|
||||
public Episode(String seriesName, String season, String episode, String title, String special) {
|
||||
public Episode(String seriesName, String season, String episode, String title, String special, Date airdate) {
|
||||
this.seriesName = seriesName;
|
||||
this.season = season;
|
||||
this.episode = episode;
|
||||
this.title = title;
|
||||
this.special = special;
|
||||
this.airdate = airdate;
|
||||
}
|
||||
|
||||
|
||||
public String getSeriesName() {
|
||||
return seriesName;
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,6 +73,11 @@ public class Episode implements Serializable {
|
|||
}
|
||||
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
|
||||
public String getSpecial() {
|
||||
return special;
|
||||
}
|
||||
|
@ -81,13 +92,8 @@ public class Episode implements Serializable {
|
|||
}
|
||||
|
||||
|
||||
public String getSeriesName() {
|
||||
return seriesName;
|
||||
}
|
||||
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
public Date airdate() {
|
||||
return airdate;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -97,13 +97,16 @@ public class IMDbClient implements EpisodeListProvider {
|
|||
List<Episode> episodes = new ArrayList<Episode>(nodes.size());
|
||||
|
||||
for (Node node : nodes) {
|
||||
String title = node.getTextContent().trim();
|
||||
String title = getTextContent(node);
|
||||
|
||||
Scanner numberScanner = new Scanner(node.getPreviousSibling().getTextContent()).useDelimiter("\\D+");
|
||||
String season = numberScanner.next();
|
||||
String episode = numberScanner.next();
|
||||
|
||||
episodes.add(new Episode(seriesName, season, episode, title));
|
||||
// e.g. 20 May 2003
|
||||
String airdate = selectString("./following::STRONG", node);
|
||||
|
||||
episodes.add(new Episode(seriesName, season, episode, title, null, Date.parse(airdate, "dd MMMMM yyyyy")));
|
||||
}
|
||||
|
||||
return episodes;
|
||||
|
|
|
@ -148,8 +148,9 @@ public class TVDotComClient implements EpisodeListProvider {
|
|||
|
||||
List<Node> nodes = selectNodes("id('episode_guide_list')//*[@class='info']", dom);
|
||||
|
||||
Pattern episodePattern = Pattern.compile("Season (\\d+). Episode (\\d+)");
|
||||
Pattern specialPattern = Pattern.compile("Special. Season (\\d+)");
|
||||
Pattern episodePattern = Pattern.compile("Season.(\\d+).+Episode.(\\d+)");
|
||||
Pattern specialPattern = Pattern.compile("Special..Season.(\\d+)");
|
||||
Pattern airdatePattern = Pattern.compile("(\\d{1,2}).(\\d{1,2}).(\\d{4})");
|
||||
|
||||
List<Episode> episodes = new ArrayList<Episode>(nodes.size());
|
||||
|
||||
|
@ -159,9 +160,11 @@ public class TVDotComClient implements EpisodeListProvider {
|
|||
|
||||
String season = null;
|
||||
String episode = null;
|
||||
Date airdate = null;
|
||||
|
||||
Matcher matcher;
|
||||
|
||||
// try to match episode information
|
||||
if ((matcher = episodePattern.matcher(meta)).find()) {
|
||||
// matches episode
|
||||
season = matcher.group(1);
|
||||
|
@ -170,12 +173,17 @@ public class TVDotComClient implements EpisodeListProvider {
|
|||
// matches special
|
||||
season = matcher.group(1);
|
||||
episode = "Special";
|
||||
} else {
|
||||
// no episode match
|
||||
continue;
|
||||
}
|
||||
|
||||
episodes.add(new Episode(searchResult.getName(), season, episode, title));
|
||||
// try to match airdate information
|
||||
if ((matcher = airdatePattern.matcher(meta)).find()) {
|
||||
airdate = Date.parse(matcher.group(), "MM/dd/yyyy"); // e.g. 5/20/2003
|
||||
}
|
||||
|
||||
// add episode if SxE info has been found
|
||||
if (season != null && episode != null) {
|
||||
episodes.add(new Episode(searchResult.getName(), season, episode, title, null, airdate));
|
||||
}
|
||||
}
|
||||
|
||||
// episodes are listed in reverse order
|
||||
|
|
|
@ -87,16 +87,17 @@ public class TVRageClient implements EpisodeListProvider {
|
|||
String title = getTextContent("title", node);
|
||||
String episodeNumber = getTextContent("seasonnum", node);
|
||||
String seasonNumber = getAttribute("no", node.getParentNode());
|
||||
Date airdate = Date.parse(getTextContent("airdate", node), "yyyy-MM-dd");
|
||||
|
||||
// check if we have season and episode number, if not it must be a special episode
|
||||
if (episodeNumber == null || seasonNumber == null) {
|
||||
// handle as special episode
|
||||
seasonNumber = getTextContent("season", node);
|
||||
int specialNumber = filterBySeason(specials, Integer.parseInt(seasonNumber)).size() + 1;
|
||||
specials.add(new Episode(seriesName, seasonNumber, "Special " + specialNumber, title, Integer.toString(specialNumber)));
|
||||
specials.add(new Episode(seriesName, seasonNumber, "Special " + specialNumber, title, Integer.toString(specialNumber), airdate));
|
||||
} else {
|
||||
// handle as normal episode
|
||||
episodes.add(new Episode(seriesName, seasonNumber, episodeNumber, title));
|
||||
episodes.add(new Episode(seriesName, seasonNumber, episodeNumber, title, null, airdate));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -135,6 +135,7 @@ public class TheTVDBClient implements EpisodeListProvider {
|
|||
String episodeName = getTextContent("EpisodeName", node);
|
||||
String episodeNumber = getTextContent("EpisodeNumber", node);
|
||||
String seasonNumber = getTextContent("SeasonNumber", node);
|
||||
Date airdate = Date.parse(getTextContent("FirstAired", node), "yyyy-MM-dd");
|
||||
|
||||
if (seasonNumber.equals("0")) {
|
||||
// handle as special episode
|
||||
|
@ -145,10 +146,10 @@ public class TheTVDBClient implements EpisodeListProvider {
|
|||
}
|
||||
|
||||
int specialNumber = filterBySeason(specials, Integer.parseInt(seasonNumber)).size() + 1;
|
||||
specials.add(new Episode(seriesName, seasonNumber, "Special " + specialNumber, episodeName, Integer.toString(specialNumber)));
|
||||
specials.add(new Episode(seriesName, seasonNumber, "Special " + specialNumber, episodeName, Integer.toString(specialNumber), airdate));
|
||||
} else {
|
||||
// handle as normal episode
|
||||
episodes.add(new Episode(seriesName, seasonNumber, episodeNumber, episodeName));
|
||||
episodes.add(new Episode(seriesName, seasonNumber, episodeNumber, episodeName, null, airdate));
|
||||
}
|
||||
|
||||
if (episodeNumber.equals("1")) {
|
||||
|
|
|
@ -85,6 +85,7 @@ public class AnidbClientTest {
|
|||
assertEquals("Herr Dr. Tenma", first.getTitle());
|
||||
assertEquals("1", first.getEpisode());
|
||||
assertEquals(null, first.getSeason());
|
||||
assertEquals("2004-04-07", first.airdate().toString());
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,6 +101,7 @@ public class AnidbClientTest {
|
|||
assertEquals("Shadow of the Moon, The Sea of Shadow - Chapter 1", first.getTitle());
|
||||
assertEquals("1", first.getEpisode());
|
||||
assertEquals(null, first.getSeason());
|
||||
assertEquals("2002-04-09", first.airdate().toString());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ public class IMDbClientTest {
|
|||
assertEquals("Unaired Pilot", first.getTitle());
|
||||
assertEquals("0", first.getEpisode());
|
||||
assertEquals("1", first.getSeason());
|
||||
assertEquals(null, first.airdate());
|
||||
|
||||
Episode last = list.get(144);
|
||||
|
||||
|
@ -81,6 +82,7 @@ public class IMDbClientTest {
|
|||
assertEquals("Chosen", last.getTitle());
|
||||
assertEquals("22", last.getEpisode());
|
||||
assertEquals("7", last.getSeason());
|
||||
assertEquals("2003-05-20", last.airdate().toString());
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,7 +94,7 @@ public class IMDbClientTest {
|
|||
|
||||
Episode first = list.get(0);
|
||||
|
||||
assertEquals("Mushi-Shi", first.getSeriesName());
|
||||
assertEquals("Mushishi", first.getSeriesName());
|
||||
assertEquals("Midori no za", first.getTitle());
|
||||
assertEquals("1", first.getEpisode());
|
||||
assertEquals("1", first.getSeason());
|
||||
|
|
|
@ -58,6 +58,7 @@ public class TVDotComClientTest {
|
|||
assertEquals("Chosen", chosen.getTitle());
|
||||
assertEquals("22", chosen.getEpisode());
|
||||
assertEquals("7", chosen.getSeason());
|
||||
assertEquals("2003-05-20", chosen.airdate().toString());
|
||||
}
|
||||
|
||||
|
||||
|
@ -74,6 +75,7 @@ public class TVDotComClientTest {
|
|||
assertEquals("Welcome to the Hellmouth (1)", first.getTitle());
|
||||
assertEquals("1", first.getEpisode());
|
||||
assertEquals("1", first.getSeason());
|
||||
assertEquals("1997-03-10", first.airdate().toString());
|
||||
}
|
||||
|
||||
|
||||
|
@ -90,6 +92,7 @@ public class TVDotComClientTest {
|
|||
assertEquals("Jaynestown", fourth.getTitle());
|
||||
assertEquals("4", fourth.getEpisode());
|
||||
assertEquals("1", fourth.getSeason());
|
||||
assertEquals("2002-10-18", fourth.airdate().toString());
|
||||
}
|
||||
|
||||
|
||||
|
@ -113,6 +116,7 @@ public class TVDotComClientTest {
|
|||
assertEquals("Exposé", episode.getTitle());
|
||||
assertEquals("14", episode.getEpisode());
|
||||
assertEquals("3", episode.getSeason());
|
||||
assertEquals("2007-03-28", episode.airdate().toString());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@ import static org.junit.Assert.*;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.filebot.web.TVRageClient.TVRageSearchResult;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.sourceforge.filebot.web.TVRageClient.TVRageSearchResult;
|
||||
|
||||
|
||||
public class TVRageClientTest {
|
||||
|
||||
|
@ -18,7 +18,7 @@ public class TVRageClientTest {
|
|||
*/
|
||||
private static TVRageSearchResult buffySearchResult = new TVRageSearchResult("Buffy the Vampire Slayer", 2930, "http://www.tvrage.com/Buffy_The_Vampire_Slayer");
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void search() throws Exception {
|
||||
List<SearchResult> results = tvrage.search("Buffy");
|
||||
|
@ -30,9 +30,10 @@ public class TVRageClientTest {
|
|||
assertEquals(buffySearchResult.getLink(), result.getLink());
|
||||
}
|
||||
|
||||
|
||||
private TVRageClient tvrage = new TVRageClient();
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void getEpisodeList() throws Exception {
|
||||
List<Episode> list = tvrage.getEpisodeList(buffySearchResult, 7);
|
||||
|
@ -45,6 +46,7 @@ public class TVRageClientTest {
|
|||
assertEquals("Chosen", chosen.getTitle());
|
||||
assertEquals("22", chosen.getEpisode());
|
||||
assertEquals("7", chosen.getSeason());
|
||||
assertEquals("2003-05-20", chosen.airdate().toString());
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,6 +62,7 @@ public class TVRageClientTest {
|
|||
assertEquals("Unaired Pilot", first.getTitle());
|
||||
assertEquals("00", first.getEpisode());
|
||||
assertEquals("0", first.getSeason());
|
||||
assertEquals(null, first.airdate());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ public class TheTVDBClientTest {
|
|||
assertEquals("Welcome to the Hellmouth (1)", first.getTitle());
|
||||
assertEquals("1", first.getEpisode());
|
||||
assertEquals("1", first.getSeason());
|
||||
assertEquals("1997-03-10", first.airdate().toString());
|
||||
|
||||
// check special episode
|
||||
Episode last = list.get(list.size() - 1);
|
||||
|
@ -73,6 +74,7 @@ public class TheTVDBClientTest {
|
|||
assertEquals("Unaired Pilot", last.getTitle());
|
||||
assertEquals("Special 1", last.getEpisode());
|
||||
assertEquals("1", last.getSeason());
|
||||
assertEquals(null, last.airdate());
|
||||
}
|
||||
|
||||
|
||||
|
@ -82,12 +84,13 @@ public class TheTVDBClientTest {
|
|||
|
||||
assertEquals(13, list.size());
|
||||
|
||||
Episode chosen = list.get(0);
|
||||
Episode first = list.get(0);
|
||||
|
||||
assertEquals("Wonderfalls", chosen.getSeriesName());
|
||||
assertEquals("Wax Lion", chosen.getTitle());
|
||||
assertEquals("1", chosen.getEpisode());
|
||||
assertEquals("1", chosen.getSeason());
|
||||
assertEquals("Wonderfalls", first.getSeriesName());
|
||||
assertEquals("Wax Lion", first.getTitle());
|
||||
assertEquals("1", first.getEpisode());
|
||||
assertEquals("1", first.getSeason());
|
||||
assertEquals("2004-03-12", first.airdate().toString());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ public class PreferencesMapTest {
|
|||
public void serializableAdapter() {
|
||||
Map<String, Episode> map = PreferencesMap.map(temp, new SerializableAdapter<Episode>());
|
||||
|
||||
Episode episode = new Episode("8 Simple Rules", 1, 1, "Pilot");
|
||||
Episode episode = new Episode("8 Simple Rules", "1", "1", "Pilot", null, null);
|
||||
|
||||
map.put("episode", episode);
|
||||
|
||||
|
|
Loading…
Reference in New Issue