public String getFileList() { if (!isMultiFileVideo()) return file; else { String files = ""; // get a mapof all the file labels and the corresponding file Map<String, String> fileMap = new TreeMap<String, String>(); for (Iterator<MyLibraryFile> it = duplicateVideos.iterator(); it.hasNext(); ) { MyLibraryFile video = it.next(); if (video.getFileLabel().toLowerCase().contains("full")) { return video.getFile(); // this is a full file, dont need to get the others } fileMap.put(video.getFileLabel(), video.getFile()); // get only unique file labels } // no full files exist, return a list of the parts, in order // the list is already alphabetical, so assume the files are in the correct order, jsut pick a // source String sourceId = null; boolean useAllFiles = false; for (Map.Entry<String, String> entry : fileMap.entrySet()) { // use the first source in the list String label = entry.getKey(); String file = entry.getValue(); if (sourceId == null && !useAllFiles) { // look for the identifier, that is everything up to the part x of the label if (label.toLowerCase().contains("part")) sourceId = label.substring(0, label.toLowerCase().indexOf("part")); else useAllFiles = true; // since we can't find the part identifier, just use all files } if (useAllFiles || label.startsWith(sourceId)) { files += file + LINE_BRK; } } return files.replaceAll( "\\r\\n" + "$", ""); // remove the last line break ($ means end of string) } }
public static boolean doHuluCBS(MyLibraryFile video, boolean isHulu, boolean isCBS) { String matchingPattern = null; if (!video.knownType() || video.isTvShow()) { Pattern seasonEpisodePattern = Pattern.compile("s[0-9]+e[0-9]+", Pattern.CASE_INSENSITIVE); Matcher seasonEpisodeMatcher = seasonEpisodePattern.matcher(video.getFullPath()); boolean match = seasonEpisodeMatcher.find(); if (match) { matchingPattern = seasonEpisodeMatcher.group(); video.setType(TV_SHOW); } else if (!video.isTvShow()) // dont over-ride config param video.setType(MOVIE); } boolean success; if (video.isTvShow()) success = addHuluOrCBSTvEpisodeMetaData(video, matchingPattern); else if (video.isMovie()) { video.setTitle(video.getFileLabel()); success = valid(video.getTitle()); } else // do hulu/cbs have music videos? { Logger.WARN( "Cannot Archive: Type of content cannot be auto-determined for Hulu video: " + video.getFullPathEscaped()); success = false; } Logger.DEBUG( (isCBS ? "CBS" : "Hulu") + ": success=" + success + "; " + (video.isTvShow() ? "TV: series=" + video.getSeries() + "; title=" + video.getTitle() + ", " + "season=" + video.getSeasonNumber() + ", episode=" + video.getEpisodeNumber() : "Movie: " + video.getTitle()) + " --- " + video.getFullPathEscaped()); return success; }
public static void copyVideoMetaData(MyLibraryFile source, MyLibraryFile dest) { dest.setTitle(source.getTitle()); dest.setType(source.getType()); dest.setArtist(source.getArtist()); dest.setEpisodeNumber(source.getEpisodeNumber()); dest.setFileLabel(source.getFileLabel()); dest.setFinalLocation(source.getFinalLocation()); dest.setHasBeenLookedUpOnTVDB(source.hasBeenLookedUpOnTVDB()); dest.setMultiFileVideo(source.isMultiFileVideo()); dest.setOriginalAirDate(source.getOriginalAirDate()); if (source.isDuplicate()) dest.setAsDuplicateTo(source.getOriginalVideo()); else dest.setOriginalVideo(source.getOriginalVideo()); dest.setSeasonNumber(source.getSeasonNumber()); dest.setSeries(source.getSeries()); dest.setSkippedBecauseAlreadyArchived(source.skippedBecauseAlreadyArchived); dest.setSubfolder(source.getSubfolder()); dest.setTVDBId(source.getTVDBId()); dest.setYear(source.getYear()); }
private static boolean addHuluOrCBSTvEpisodeMetaData( MyLibraryFile video, String seasonEpisodeNaming) { // parse season/episode numbers try { // get the series and title boolean normalMethodSuccess = Archiver.addTVMetaDataFromSxxExx(video, seasonEpisodeNaming); if (!normalMethodSuccess) { // This means the series title comes before this in the fileLabel // looks like: "Pretty Little Liars - s1e1 - Pilot" or "Pretty Little Liars - s1e1: Pilot" String[] splitters = new String[] {" - " + seasonEpisodeNaming + " - ", " - " + seasonEpisodeNaming + ": "}; for (String matchOn : splitters) { int matchIndex = video.getFileLabel().indexOf(matchOn); if (matchIndex != -1) { video.setSeries(video.getFileLabel().substring(0, matchIndex)); // get the title video.setTitle( video .getFileLabel() .substring(matchIndex + matchOn.length(), video.getFileLabel().length())); break; } } } if (!valid(video.getSeries())) { Logger.WARN("Series cannot be found from Hulu/CBS path: " + video.getFullPathEscaped()); return false; } // get the title (not required for scraping if (!valid(video.getTitle())) { Logger.INFO( "Title cannot be parsed for this video, it will be set to the file name: \"" + video.getFileLabel() + "\""); video.setTitle(video.getFileLabel()); } return true; } catch (Exception x) { Logger.WARN( "This Hulu/CBS video was thought to be a TV show, but the season/episode numbers and/or title could not be parsed: " + video.getFullPathEscaped(), x); return false; } }
private static boolean addNetflixTVSeriesAndTitle(MyLibraryFile video) { try { // find series and title String series = null, title = null; try // this method must be tried first (even though it matches less files); try using the // filename spit at ":"... catches things line Bob the Builder: Call in the Crew { if (video .getFileLabel() .contains(": ")) // somethign like /Bob the Builder: Call in the Crew { String[] sa = video.getFileLabel().split(": "); if (sa.length != 2) throw new Exception("File label contains more than one ':'. Cannot parse."); series = sa[0]; title = sa[1].trim(); boolean is24 = (series.trim().equals("24") || video.getFullPathEscaped().contains("/24/")) && (title.toLowerCase().contains("a.m") || title.toLowerCase().contains("p.m")); if (!is24) // exclude 24 becuase the series should be an integer { series = "24"; if (isInt(series)) // this is actually the episode number, not the series. { series = null; throw new Exception("Incorrect series (Integer found as series name)"); } } } else throw new Exception("No colon in file label, try secondary method"); } catch ( Exception x) // try secondary method, getting series as the parent folder and the file label // being the title { series = null; // Netflix/Instant Queue/#/30 Days/30 Days: Season 3/S03E03 - Animal Rights String[] folders = video.getFullPath().split(com.bradvido.xbmc.util.Constants.DELIM); if (folders.length > 1) { String parentFolder = folders[folders.length - 2]; // 30 Days: Season 3 if (valid(parentFolder) && parentFolder.contains(": ")) { series = parentFolder.substring(0, parentFolder.indexOf(": ")); } } // try looking in the folder(s) above this show for the series if (series == null) { // couldn't find it the conventional way if (Archiver.getSeriesFromParentFolder(video)) { series = video .getSeries(); // series was set in getSeriesFromParentFolder(). get it back // here for further checks } else { // didn't work try secondary method String[] serieses = video.getFullPath().split(com.bradvido.xbmc.util.Constants.DELIM); series = serieses[serieses.length - 2]; // the folder above the file name if (series.contains( ":")) // catches folders named like so: /Busytown Mysteries: Series 2/ series = series.substring(0, series.indexOf(":")); } } // get title (usually split from SxxExx by one of these) title = video.getFileLabel(); // S03E01 - Working in a Coal Mine String[] splitters = new String[] {" - ", ":"}; for (String splitter : splitters) { if (title.contains(splitter)) { title = title.substring(title.indexOf(splitter) + splitter.length(), title.length()); break; } } } if (!valid(series)) throw new Exception("Series cannot be parsed..."); video.setSeries(series.trim()); if (!valid(title)) throw new Exception("Title cannot be parsed..."); video.setTitle(title.trim()); return true; // successfully got the series and title // Logger.INFO( "Netflix episode meta data: series="+file.getSeries()+"; // title="+file.getTitle()+", season="+file.getSeasonNumber()+", // episode="+file.getEpidoseNumber()); } catch (Exception x) { if (!valid(video.getSeries()) || !valid(video.getTitle())) { Logger.WARN( "Cannot parse, and cannot lookup Netflix TV show (series=" + video.getSeries() + ", title=" + video.getTitle() + ")" + LINE_BRK + video.getFullPathEscaped() + LINE_BRK + x.getMessage()); return false; } else { Logger.INFO( "Cannot parse, but can lookup Netflix TV show (series=" + video.getSeries() + ", title=" + video.getTitle() + ")" + LINE_BRK + video.getFullPathEscaped() + LINE_BRK + x.getMessage()); Logger.INFO("Attempting to find metadata on TheTVDB.com"); return TVDB.lookupTVShow(video); } } }
public static boolean doNetflix(MyLibraryFile video) { // pattern one, matches most normal TV season/episode patterns for netflix Pattern seasonEpisodePattern = Pattern.compile( "^S[0-9]+E[0-9]+", Pattern .CASE_INSENSITIVE); // Netflix/Instant Queue/#/30 Days/30 Days: Season 3/S03E01 - // Working in a Coal Mine Matcher seasonEpisodeMatcher = seasonEpisodePattern.matcher(video.getFileLabel()); // S03E01 - Working in a Coal Mine // another pattern to find when no season/series word is specified Pattern seasonEpisodePattern2 = Pattern.compile( "/[0-9]+/S?[0-9]+E?[0-9]+"); // Netflix/Instant Queue/Alphabetical/B/Blue's Clues/5/28: // Our Neighborhood Festival Matcher seasonEpisodeMatcher2 = seasonEpisodePattern2.matcher(video.getFullPathEscaped()); // pattern that matches absolutely numbered TV shows (no season) Pattern absoluteEpisodePattern = Pattern.compile( "^[0-9][0-9]:"); // Netflix/Instant Queue/Alphabetical/B/The Blue Planet: Tidal Seas/01: // Tidal Seas Matcher absoluteEpisodeMatcher = absoluteEpisodePattern.matcher( video .getFileLabel()); // only chck the file name because we are using the ^ start of // string regex identifier if (!video.knownType() || video.isTvShow()) { // get season and episode numbers try { if (seasonEpisodeMatcher.find()) // looks like "S03E01" { video.setType(TV_SHOW); String SxxExx = seasonEpisodeMatcher.group(); Archiver.addTVMetaDataFromSxxExx(video, SxxExx); } else if (seasonEpisodeMatcher2.find()) { video.setType(TV_SHOW); String match = seasonEpisodeMatcher2.group(); // "/5/28:" String[] parts = (match.substring(1, match.indexOf(":"))).split("/"); // "5/28" int seasonNum = Integer.parseInt(parts[0]); int episodeNum = Integer.parseInt(parts[1]); video.setSeasonNumber(seasonNum); video.setEpisodeNumber(episodeNum); } else if (absoluteEpisodeMatcher.find()) { // catch something like this, which is really TV, but has no season number Logger.INFO( "This appears to be a TV episode with no Season info. Will attempt TVDB lookup, and if it fails, default to season zero: " + video.getFullPathEscaped()); video.setType(TV_SHOW); addNetflixTVSeriesAndTitle(video); // need series/title before lookup if (!TVDB.lookupTVShow(video)) { video.setSeasonNumber(0); // TODO: generate info for this automatically since it will not be scraped successfully String match = absoluteEpisodeMatcher.group(); // "01:" video.setEpisodeNumber( Integer.parseInt( match.substring( 0, match.indexOf(":")))); // parse the number from something like "01:" } } else { Logger.DEBUG( "This netflix source does not match any known TV patterns. assuming it is a movie: " + video.getFullPathEscaped()); video.setType(MOVIE); } } catch ( Exception x) // Netflix/Instant Queue/H/Heroes/Heroes: Season 4/S04E01 - Orientation/S04E11 - // Thanksgiving { Logger.WARN( "Cannot parse season/episode numbers for netflix TV source: " + video.getFullPathEscaped(), x); } } // netflix doesn't have music videos afaik Logger.DEBUG( "Found PlayOn Netflix: " + (video.isTvShow() ? "TV " : "Movie") + ": " + video.getFullPathEscaped()); if (video.isTvShow()) return addNetflixTVSeriesAndTitle(video); // parse netflix info from label/path else if (video.isMovie()) { video.setTitle(video.getFileLabel()); // just use the label as the title return valid(video.getFileLabel()); } else { Logger.WARN( "Cannot Arvhive Playon Netflix video: Type of content cannot be auto-determined for: " + video.getFullPathEscaped()); return false; } }
public static boolean doComedyCentral(MyLibraryFile video) { // parse dailyshow/colbert report dates from label. Looks like "February 15, 2011 - January // Jones" String fullPath = video.getFullPathEscaped(); boolean dailyShow = fullPath.toLowerCase().contains("/the daily show with jon stewart/"); boolean colbert = fullPath.toLowerCase().contains("/the colbert report/"); boolean southpark = fullPath.toLowerCase().contains("/south park/"); if (dailyShow || colbert) { if (dailyShow) { video.setTVDBId("71256"); video.setSeries("The Daily Show with Jon Stewart"); } if (colbert) { video.setTVDBId("79274"); video.setSeries("The Colbert Report"); } if (!video.getFileLabel().contains(" - ")) { Logger.WARN( "Cannot parse Daily Show/Colbert Report episode because ' - ' was not found in the title"); return false; } SimpleDateFormat dailyShowSDF = new SimpleDateFormat("MMMM dd, yyyy"); String[] labelParts = video.getFileLabel().split(" - "); String textDate = labelParts[0]; String title = labelParts[1]; video.setTitle(title); Date airDate = null; try { airDate = dailyShowSDF.parse(textDate); video.setOriginalAirDate(tools.toTVDBAiredDate(airDate)); Logger.DEBUG("Original Air date = " + video.getOriginalAirDate()); } catch (Exception x) { Logger.WARN( "The PlayOn Comedy Central Daily Show/Colbert Report episode named \"" + video.getFileLabel() + "\" cannot be looked up " + "because a date could be parsed from the title using date format: " + dailyShowSDF.toPattern(), x); } boolean successfulLookup = TVDB.lookupTVShow(video); if (!successfulLookup) Logger.WARN( "TVDB lookup failed for Daily Show/Cobert report episode: " + video.getFullPathEscaped()); return successfulLookup; } else if (southpark) { // like: /South Park/Season 02/s02e13 - Cow Days Pattern seasonEpisodePattern = Pattern.compile("^s[0-9]+e[0-9]+ - ", Pattern.CASE_INSENSITIVE); Matcher seasonMatcher = seasonEpisodePattern.matcher(video.getFileLabel().trim()); if (seasonMatcher.find()) { try { video.setType(TV_SHOW); String match = seasonMatcher.group(); video.setSeasonNumber( Integer.parseInt( match.toLowerCase().substring(match.indexOf("s") + 1, match.indexOf("e")))); video.setEpisodeNumber( Integer.parseInt( match.toLowerCase().substring(match.indexOf("e") + 1, match.indexOf(" - ")))); video.setTitle( video .getFileLabel() .substring( video.getFileLabel().indexOf(match) + match.length(), video.getFileLabel().length())); video.setSeries("South Park"); return true; } catch (Exception x) { Logger.WARN( "Failed to parse PlayOn Comedy Central South park episode: " + video.getFullPathEscaped(), x); return false; } } else { Logger.INFO( "Cannot find SxxExx pattern in PlayOn Comedy Central SouthPark filename, cannot archive: " + video.getFileLabel()); return false; } } else // unknown type { Logger.INFO( "This PlayOn Comedy Central video does not have custom parsing available, will try standard parse: " + video.getFullPathEscaped()); return false; } }