gt:         if (matcher.find()) {
context: /*
   * Copyright (c) 2016. Sten Martinez
   *
   * 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 2 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, write to the Free Software Foundation, Inc.,
   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   */
  
  package net.longfalcon.newsj;
  
  import net.longfalcon.newsj.fs.FileSystemService;
  import net.longfalcon.newsj.fs.model.Directory;
  import net.longfalcon.newsj.model.Category;
  import net.longfalcon.newsj.model.Release;
  import net.longfalcon.newsj.model.TvRage;
  import net.longfalcon.newsj.persistence.CategoryDAO;
  import net.longfalcon.newsj.persistence.ReleaseDAO;
  import net.longfalcon.newsj.persistence.TvRageDAO;
  import net.longfalcon.newsj.service.TraktService;
  import net.longfalcon.newsj.util.ArrayUtil;
  import net.longfalcon.newsj.util.DateUtil;
  import net.longfalcon.newsj.util.StreamUtil;
  import net.longfalcon.newsj.util.ValidatorUtil;
  import net.longfalcon.newsj.ws.trakt.TraktEpisodeResult;
  import net.longfalcon.newsj.ws.trakt.TraktIdSet;
  import net.longfalcon.newsj.ws.trakt.TraktImage;
  import net.longfalcon.newsj.ws.trakt.TraktImages;
  import net.longfalcon.newsj.ws.trakt.TraktResult;
  import net.longfalcon.newsj.ws.trakt.TraktShowResult;
  import org.apache.commons.lang3.StringUtils;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.joda.time.DateTime;
  import org.springframework.stereotype.Service;
  import org.springframework.transaction.annotation.Propagation;
  import org.springframework.transaction.annotation.Transactional;
  
  import java.io.ByteArrayOutputStream;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.InputStream;
  import java.net.URL;
  import java.net.URLConnection;
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.List;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  /**
   * NOTE: TVRAGE is no longer a viable API to use. this whole api uses trakt, but tvrage ids. migrate to trakt/tvdb ids
   * in the future.
   * User: Sten Martinez
   * Date: 10/14/15
   * Time: 2:54 PM
   */
  @Service
  public class TVRageService {
      private static final Log _log = LogFactory.getLog(TVRageService.class);
  
      private ReleaseDAO releaseDAO;
      private CategoryDAO categoryDAO;
      private TvRageDAO tvRageDAO;
  
      private TraktService traktService;
      private FileSystemService fileSystemService;
  
      @Transactional(propagation = Propagation.SUPPORTS)
      public void processTvReleases(boolean lookupTvRage) {
          List<Category> movieCats = categoryDAO.findByParentId(CategoryService.CAT_PARENT_TV);
          List<Integer> ids = new ArrayList<>();
          for (Category category : movieCats) {
              ids.add(category.getId());
          }
          List<Release> releases = releaseDAO.findReleasesByRageIdAndCategoryId(-1, ids);
  
          if (!releases.isEmpty()) {
              _log.info("Processing tv for " + releases.size() + " releases");
              if (lookupTvRage) {
                  _log.info("Looking up tv info from the web");
              }
          }
  
          for (Release release : releases) {
              ShowInfo showInfo = parseNameEpSeason(release.getName());
              if (showInfo != null) {
                  // update release with season, ep, and airdate info (if available) from releasetitle
                  updateEpInfo(showInfo, release);
  
                  // find the trakt ID
                  long traktId = 0;
                  String cleanName = showInfo.getCleanName();
                  try {
                      _log.info("looking up " + cleanName + " in db");
                      traktId = getByTitle(cleanName);
                  } catch (Exception e) {
                      _log.error("unable to find tvinfo for " + cleanName + " - " + e.toString(), e);
                  }
  
                  if (traktId < 0 && traktId > -2 && lookupTvRage) {
                      // if it doesnt exist locally and lookups are allowed lets try to get it
                      _log.info("didnt find trakt id for \""+ cleanName +"\" in local db, checking web...");
  
                      traktId = getTraktMatch(showInfo);
  
                      if (traktId > 0) {
                          updateRageInfo(traktId, showInfo, release);
                      } else {
                          // no match
                          //add to tvrage with rageID = -2 and cleanName title only
                          _log.info("no trakt data found for " + cleanName + " - adding placeholder");
                          TvRage tvRage = new TvRage();
                          tvRage.setRageId(-2);
                          tvRage.setTraktId((long) -2);
                          tvRage.setReleaseTitle(cleanName);
                          tvRage.setCreateDate(new Date());
                          tvRage.setDescription("");
                          tvRageDAO.update(tvRage);
                          release.setRageId(tvRage.getId());
                      }
                  } else if (traktId > 0) {
                      if (lookupTvRage) {
                          // update airdate and ep title
                          updateEpisodeInfo(traktId, showInfo.getSeason(), showInfo.getEpisode(), release);
                      }
                      TvRage tvRage = tvRageDAO.findByTvTraktId(traktId);
                      release.setRageId(tvRage.getId());
  
                  }
  
              } else {
                  // not a tv episode, so set rageid to n/a
                  release.setRageId((long) -2);
              }
  
              releaseDAO.updateRelease(release);
          }
      }
  
      public void rebuildTvInfo(TvRage tvRage) {
          try {
              TraktResult traktResult = getTraktMatch(tvRage.getReleaseTitle());
              if (traktResult != null) {
                  TraktShowResult showResult = traktResult.getShowResult();
  
                  _log.info("found tvinfo for " + tvRage.getReleaseTitle());
  
                  tvRage.setTraktId(showResult.getIds().getTrakt());
                  tvRage.setRageId(showResult.getIds().getTvrage());
                  tvRage.setTvdbId(showResult.getIds().getTvdb());
                  tvRage.setReleaseTitle(showResult.getTitle());
                  TraktImages traktImages = showResult.getTraktImages();
                  try {
                      if (traktImages != null) {
                          TraktImage posterImage = traktImages.getPoster();
                          if (posterImage != null) {
                              String posterUrl = posterImage.getMedium();
                              if (ValidatorUtil.isNotNull(posterUrl)) {
                                  Directory tempDir = fileSystemService.getDirectory("/temp");
                                  File tempFile = tempDir.getTempFile("image_" + String.valueOf(System.currentTimeMillis()));
                                  FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
                                  URL url = new URL(posterUrl);
                                  URLConnection urlConnection = url.openConnection();
                                  urlConnection.setRequestProperty("User-Agent", "Java");
                                  StreamUtil.transferByteArray(urlConnection.getInputStream(), fileOutputStream, 1024);
                                  ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                                  InputStream tempFileInputStream = new FileInputStream(tempFile);
                                  StreamUtil.transferByteArray(tempFileInputStream, byteArrayOutputStream, 1024);
                                  tvRage.setImgData(byteArrayOutputStream.toByteArray());
                              }
                          }
                      }
                  } catch (Exception e) {
                      _log.warn("unable to add poster image for " + tvRage.getReleaseTitle(), e);
                  }
  
                  tvRage.setDescription(showResult.getOverview());
                  tvRageDAO.update(tvRage);
              }
          } catch (Exception e) {
              _log.error(e);
          }
      }
  
      // restrict to using trakt id since trakt only allows trakt id or imdb to search by episode
      private void updateEpisodeInfo(long traktShowId, String season, String episode, Release release) {
          try {
              int seasonNumber = 0;
              if (season.startsWith("S") || season.startsWith("s")) {
                  seasonNumber = Integer.parseInt(season.substring(1));
              } else {
                  seasonNumber = Integer.parseInt(season);
              }
              int episodeNumber = 0;
              if (episode.startsWith("E") || episode.startsWith("e")) {
                  episodeNumber = Integer.parseInt(episode.substring(1));
              } else {
                  episodeNumber = Integer.parseInt(episode);
              }
              TraktEpisodeResult traktEpisodeResult = null;
              try {
                  traktEpisodeResult = traktService.getEpisode(traktShowId, seasonNumber, episodeNumber);
              } catch (Exception e) {
                  _log.error("error fetching episode data for " + release.getSearchName() + " - " + e.toString());
                  _log.debug("",e);
              }
              if (traktEpisodeResult != null) {
                  release.setTvAirDate(traktEpisodeResult.getFirstAired());
                  release.setTvTitle(traktEpisodeResult.getTitle());
                  release.setSeason(String.valueOf(traktEpisodeResult.getSeason()));
                  release.setEpisode(String.valueOf(traktEpisodeResult.getNumber()));
              }
          } catch (NumberFormatException e) {
              _log.warn("Parse error: " + e.toString() + " for release " + release.getSearchName(), e);
          }
      }
  
      private TvRage updateRageInfo(long traktId, ShowInfo showInfo, Release release) {
          // find existing tvRage info
          String season = showInfo.getSeason();
          String episode = showInfo.getEpisode();
  
          _log.info("looking for existing tvinfo with trakt id " + traktId);
          TvRage tvRage = tvRageDAO.findByTvTraktId(traktId);
  
          if (tvRage == null) {
              // try looking by name
              tvRage = getTvInfoByTitle(showInfo.getCleanName());
          }
          if (tvRage == null) {
              tvRage = new TvRage();
              tvRage.setCreateDate(new Date());
          }
          //add
          _log.info("no existing tvinfo with trakt Id " + traktId + ", adding from Trakt");
          TraktResult[] traktResults = new TraktResult[0];
          try {
              traktResults = traktService.searchShowByTraktId(traktId);
          } catch (Exception e) {
              _log.error("error fetching show data for " + release.getSearchName() + " - " + e.toString());
              _log.debug("", e);
          }
          if (traktResults.length > 0) {
              TraktResult firstResult = traktResults[0];
              TraktShowResult showResult = firstResult.getShowResult();
  
              _log.info("found tvinfo for " + showInfo.getCleanName());
  
  
              tvRage.setTraktId(showResult.getIds().getTrakt());
              tvRage.setRageId(showResult.getIds().getTvrage());
              tvRage.setTvdbId(showResult.getIds().getTvdb());
              tvRage.setReleaseTitle(showResult.getTitle());
              // TODO: tvRage.setImgData();
  
              tvRage.setDescription(showResult.getOverview());
              tvRage.setCountry(showInfo.getCountry());
              tvRageDAO.update(tvRage);
              updateEpisodeInfo(showResult.getIds().getTrakt(), season, episode, release);
              release.setRageId(tvRage.getId());
          } else {
              // trakt id that we found before, didnt work this time. this is highly likely to a connectivity or other
              // issue that does not relate the release.
              _log.warn("no results from Trakt found for trakt id " + traktId);
          }
  
          releaseDAO.updateRelease(release);
          return tvRage;
      }
  
      private long getRageMatch(ShowInfo showInfo) {
          String cleanName = showInfo.getCleanName();
  
          try {
              TraktResult[] traktResults = new TraktResult[0];
              try {
                  traktResults = traktService.searchTvShowByName(cleanName.toLowerCase());
              } catch (Exception e) {
                  _log.error("error fetching show data for " + cleanName + " - " + e.toString());
                  _log.debug("", e);
              }
              if (traktResults.length > 0) {
                  TraktResult firstResult = traktResults[0];
                  if (firstResult.getScore() > 50) {
                      // probably the best match, we wont bother looking elsewhere.
                      if (firstResult.getShowResult() != null) {
                          _log.info("found +50% match: " + firstResult.getShowResult().getTitle());
                          return getRageIdFromTraktResultsSafe(firstResult);
                      } else {
                          return -2;// error
                      }
                  } else if (traktResults.length > 1) {
                      String firstResultName = firstResult.getShowResult().getTitle();
                      String secondResultName = traktResults[1].getShowResult().getTitle();
                      double firstSimilarityScore = StringUtils.getJaroWinklerDistance(cleanName, firstResultName);
                      double secondSimilarityScore = StringUtils.getJaroWinklerDistance(cleanName, secondResultName);
                      if (firstSimilarityScore > secondSimilarityScore) {
                          return getRageIdFromTraktResultsSafe(firstResult);
                      } else {
                          return getRageIdFromTraktResultsSafe(traktResults[1]);
                      }
                  }
                  return getRageIdFromTraktResultsSafe(firstResult);
              }
              _log.warn("no trakt show found for name " + cleanName);
              return -2; // not found
          } catch (Exception e) {
              _log.error(e.toString(), e);
              return -2; // error
          }
      }
  
      private long getTraktMatch(ShowInfo showInfo) {
          String cleanName = showInfo.getCleanName();
          _log.info("searching trakt for show " + cleanName);
          try {
              TraktResult[] traktResults = new TraktResult[0];
              try {
                  traktResults = traktService.searchTvShowByName(cleanName.toLowerCase());
              } catch (Exception e) {
                  _log.error("error fetching show data for " + cleanName + " - " + e.toString());
                  _log.debug("", e);
              }
              if (traktResults.length > 0) {
                  TraktResult firstResult = traktResults[0];
                  if (firstResult.getScore() > 50) {
                      // probably the best match, we wont bother looking elsewhere.
                      if (firstResult.getShowResult() != null) {
                          _log.info("found +50% match: " + firstResult.getShowResult().getTitle());
                          return getTraktIdFromTraktResultsSafe(firstResult);
                      } else {
                          return -2;// error
                      }
                  } else if (traktResults.length > 1) {
                      String firstResultName = firstResult.getShowResult().getTitle();
                      String secondResultName = traktResults[1].getShowResult().getTitle();
                      double firstSimilarityScore = StringUtils.getJaroWinklerDistance(cleanName, firstResultName);
                      double secondSimilarityScore = StringUtils.getJaroWinklerDistance(cleanName, secondResultName);
                      if (firstSimilarityScore > secondSimilarityScore) {
                          return getTraktIdFromTraktResultsSafe(firstResult);
                      } else {
                          return getTraktIdFromTraktResultsSafe(traktResults[1]);
                      }
                  }
                  return getTraktIdFromTraktResultsSafe(firstResult);
              }
              return -1; // not found
          } catch (Exception e) {
              _log.error(e.toString(), e);
              return -2; // error
          }
      }
  
      private TraktResult getTraktMatch(String showname) {
          _log.info("searching trakt for show " + showname);
          try {
              TraktResult[] traktResults = new TraktResult[0];
              try {
                  traktResults = traktService.searchTvShowByName(showname.toLowerCase());
              } catch (Exception e) {
                  _log.error("error fetching show data for " + showname + " - " + e.toString());
                  _log.debug("", e);
              }
              if (traktResults.length > 0) {
                  TraktResult firstResult = traktResults[0];
                  if (firstResult.getScore() > 50) {
                      // probably the best match, we wont bother looking elsewhere.
                      if (firstResult.getShowResult() != null) {
                          _log.info("found +50% match: " + firstResult.getShowResult().getTitle());
                          return firstResult;
                      } else {
                          return null;// error
                      }
                  } else if (traktResults.length > 1) {
                      String firstResultName = firstResult.getShowResult().getTitle();
                      String secondResultName = traktResults[1].getShowResult().getTitle();
                      double firstSimilarityScore = StringUtils.getJaroWinklerDistance(showname, firstResultName);
                      double secondSimilarityScore = StringUtils.getJaroWinklerDistance(showname, secondResultName);
                      if (firstSimilarityScore > secondSimilarityScore) {
                          return firstResult;
                      } else {
                          return traktResults[1];
                      }
                  }
                  return firstResult;
              }
              return null; // not found
          } catch (Exception e) {
              _log.error(e.toString(), e);
              return null; // error
          }
      }
  
      private long getRageIdFromTraktResultsSafe(TraktResult traktResult) {
          try {
              if (traktResult == null) {
                  return -2;
              }
  
              TraktShowResult showResult = traktResult.getShowResult();
  
              if (showResult == null) {
                  return -2;
              }
  
              TraktIdSet traktIdSet = showResult.getIds();
  
              if (traktIdSet == null) {
                  return -2;
              }
  
              long rageId = traktIdSet.getTvrage();
              _log.info("found rage id: " + rageId);
              return rageId;
          } catch (NullPointerException e) {
              _log.error(e.toString(), e);
              return -2;
          }
      }
  
      private long getTraktIdFromTraktResultsSafe(TraktResult traktResult) {
          try {
              if (traktResult == null) {
                  return -2;
              }
  
              TraktShowResult showResult = traktResult.getShowResult();
  
              if (showResult == null) {
                  return -2;
              }
  
              TraktIdSet traktIdSet = showResult.getIds();
  
              if (traktIdSet == null) {
                  return -2;
              }
  
              long traktId = traktIdSet.getTrakt();
              _log.info("found trakt id: " + traktId);
              return traktId;
          } catch (NullPointerException e) {
              _log.error(e.toString(), e);
              return -2;
          }
      }
  
      private long getByTitle(String cleanName) {
          long traktId = -1;
          // check if we already have an entry for this show
          TvRage tvRage = tvRageDAO.findByReleaseTitle(cleanName);
          if (tvRage != null) {
              if (tvRage.getTraktId() != null) {
                  traktId = tvRage.getTraktId();
              }
              // TODO: update trakt ID for shows we dont have an id for
          } else {
              cleanName = cleanName.replace(" and ", " & ");
              tvRage = tvRageDAO.findByReleaseTitle(cleanName);
              if (tvRage != null) {
                  traktId = tvRage.getTraktId();
              }
          }
          return traktId;
      }
  
      private TvRage getTvInfoByTitle(String cleanName) {
          // check if we already have an entry for this show
          TvRage tvRage = tvRageDAO.findByReleaseTitle(cleanName);
          if (tvRage != null) {
              return tvRage;
          } else {
              cleanName = cleanName.replace(" and ", " & ");
              tvRage = tvRageDAO.findByReleaseTitle(cleanName);
              if (tvRage != null) {
                  return tvRage;
              }
          }
          return null;
      }
  
      private void updateEpInfo(ShowInfo showInfo, Release release) {
          String airDateString = showInfo.getAirDate();
          Date airDate = null;
          if (ValidatorUtil.isNotNull(airDateString)) {
              DateTime airDateTime = DateUtil.parseAirDate(airDateString);
              if (airDateTime != null) {
                  airDate = airDateTime.toDate();
              }
          }
  
          release.setSeriesFull(showInfo.getSeriesFull());
          release.setSeason(showInfo.getSeason());
          release.setEpisode(showInfo.getEpisode());
          release.setTvAirDate(airDate);
          releaseDAO.updateRelease(release);
      }
  
      private ShowInfo parseNameEpSeason(String name) {
  
          ShowInfo showInfo = new ShowInfo();
          //S01E01-E02
          //S01E01-02
          Pattern pattern = Pattern.compile("^(.*?)[\\. ]s(\\d{1,2})\\.?e(\\d{1,3})(?:\\-e?|\\-?e)(\\d{1,3})\\.", Pattern.CASE_INSENSITIVE);
          Matcher matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              showInfo.setSeason(matcher.group(2));
              showInfo.setEpisode(matcher.group(3) + "," + matcher.group(4));
          }
          //S01E0102 - lame no delimit numbering, regex would collide if there was ever 1000 ep season
          pattern = Pattern.compile("^(.*?)[\\. ]s(\\d{2})\\.?e(\\d{2})(\\d{2})\\.", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              showInfo.setSeason(matcher.group(2));
              showInfo.setEpisode(matcher.group(3) + "," + matcher.group(4));
          }
          //S01E01
          //S01.E01
          pattern = Pattern.compile("^(.*?)[\\. ]s(\\d{1,2})\\.?e(\\d{1,3})\\.?", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              showInfo.setSeason(matcher.group(2));
              showInfo.setEpisode(matcher.group(3));
          }
          //S01
          pattern = Pattern.compile("^(.*?)[\\. ]s(\\d{1,2})\\.", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              showInfo.setSeason(matcher.group(2));
              showInfo.setEpisode("all");
          }
          //S01D1
          //S1D1
          pattern = Pattern.compile("^(.*?)[\\. ]s(\\d{1,2})d(\\d{1})\\.", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              showInfo.setSeason(matcher.group(2));
              showInfo.setEpisode(matcher.group(3));
          }
          //1x01
          pattern = Pattern.compile("^(.*?)[\\. ](\\d{1,2})x(\\d{1,3})\\.", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              showInfo.setSeason(matcher.group(2));
              showInfo.setEpisode(matcher.group(3));
          }
          //2009.01.01
          //2009-01-01
          pattern = Pattern.compile("^(.*?)[\\. ](19|20)(\\d{2})[\\.\\-](\\d{2})[\\.\\-](\\d{2})\\.", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              showInfo.setSeason(matcher.group(2)+matcher.group(3));
              showInfo.setEpisode(matcher.group(4)+"/"+matcher.group(5));
              showInfo.setAirDate(matcher.group(2)+matcher.group(3)+"-"+matcher.group(4)+"-"+matcher.group(5)); //yy-m-d
          }
          //01.01.2009
          pattern = Pattern.compile("^(.*?)[\\. ](\\d{2}).(\\d{2})\\.(19|20)(\\d{2})\\.", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              showInfo.setSeason(matcher.group(4)+matcher.group(5));
              showInfo.setEpisode(matcher.group(2)+"/"+matcher.group(3));
              showInfo.setAirDate(matcher.group(4)+matcher.group(5)+"-"+matcher.group(2)+"-"+matcher.group(3)); //yy-m-d
          }
          //01.01.09
          pattern = Pattern.compile("^(.*?)[\\. ](\\d{2}).(\\d{2})\\.(\\d{2})\\.", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              String yearString = matcher.group(4);
              int year = Integer.parseInt(yearString);
              showInfo.setSeason((year <= 99 && year > 15) ? "19"+matcher.group(4) : "20"+matcher.group(4));
              showInfo.setEpisode(matcher.group(2) + "/" + matcher.group(3));
              showInfo.setAirDate(showInfo.getSeason()+"-"+matcher.group(2)+"-"+matcher.group(3)); //yy-m-d
          }
          //2009.E01
          pattern = Pattern.compile("^(.*?)[\\. ]20(\\d{2})\\.e(\\d{1,3})\\.", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              showInfo.setSeason("20"+matcher.group(2));
              showInfo.setEpisode(matcher.group(3));
          }
          //2009.Part1
          pattern = Pattern.compile("^(.*?)[\\. ]20(\\d{2})\\.Part(\\d{1,2})\\.", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              showInfo.setSeason("20"+matcher.group(2));
              showInfo.setEpisode(matcher.group(3));
          }
          //Part1/Pt1
          pattern = Pattern.compile("^(.*?)[\\. ](?:Part|Pt)\\.?(\\d{1,2})\\.", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              showInfo.setSeason("1");
              showInfo.setEpisode(matcher.group(2));
          }
          //e.g. The.Pacific.Pt.VI.HDTV.XviD-XII / Part.IV
          pattern = Pattern.compile("^(.*?)[\\. ](?:Part|Pt)\\.?([ivx]+)", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
          if (matcher.find()) {
              showInfo.setName(matcher.group(1));
              showInfo.setSeason("1");
              String epLow = matcher.group(2).toLowerCase();
              int e = 0;
              switch(epLow) {
                  case "i": e = 1; break;
                  case "ii": e = 2; break;
                  case "iii": e = 3; break;
                  case "iv": e = 4; break;
                  case "v": e = 5; break;
                  case "vi": e = 6; break;
                  case "vii": e = 7; break;
                  case "viii": e = 8; break;
                  case "ix": e = 9; break;
                  case "x": e = 10; break;
                  case "xi": e = 11; break;
                  case "xii": e = 12; break;
                  case "xiii": e = 13; break;
                  case "xiv": e = 14; break;
                  case "xv": e = 15; break;
                  case "xvi": e = 16; break;
                  case "xvii": e = 17; break;
                  case "xviii": e = 18; break;
                  case "xix": e = 19; break;
                  case "xx": e = 20; break;
              }
              showInfo.setEpisode(String.valueOf(e));
          }
          //e.g. Band.Of.Brothers.EP06.Bastogne.DVDRiP.XviD-DEiTY
          pattern = Pattern.compile("^(.*?)[\\. ]EP?\\.?(\\d{1,3})", Pattern.CASE_INSENSITIVE);
          matcher = pattern.matcher(name);
  