protected override void DoCheck(SetProgressDelegate prog, TVDoc.ScanSettings settings) { DirFilesCache dfc = new DirFilesCache(); foreach (IDownloadProvider source in sources) { List <TorrentEntry>?downloads = source.GetTorrentDownloads(); if (downloads is null) { continue; } IEnumerable <IGrouping <string, TorrentEntry> > keys = downloads.GroupBy(entry => entry.DownloadingTo); foreach (IGrouping <string, TorrentEntry> torrentKey in keys) { if (torrentKey.All(entry => CanRemove(entry, dfc))) { if (lastFoundEntry != null && lastFoundEpisode != null) { MDoc.TheActionList.Add(new ActionTRemove(source, lastFoundEntry, lastFoundEpisode)); } if (lastFoundEntry != null && lastFoundMovie != null) { MDoc.TheActionList.Add(new ActionTRemove(source, lastFoundEntry, lastFoundMovie)); } } lastFoundEntry = null; lastFoundEpisode = null; lastFoundMovie = null; } } }
protected override void Do() { IEnumerable <ProcessedEpisode> lpe = doc.Library.RecentEpisodes(TVSettings.Instance.WTWRecentDays); DirFilesCache dfc = new DirFilesCache(); //Write Contents to file using (System.IO.StreamWriter file = new System.IO.StreamWriter(Location())) { file.WriteLine(GenerateHeader()); foreach (ProcessedEpisode episode in lpe) { try { List <FileInfo> files = dfc.FindEpOnDisk(episode, false); if (!files.Any()) { continue; } string name = TVSettings.Instance.NamingStyle.NameFor(episode); int length = files.First().GetFilmLength(); file.WriteLine(GenerateRecord(episode, files.First(), name, length)); } catch (Exception ex) { LOGGER.Error(ex, $"Had to skip saving {episode?.Show?.ShowName} S{episode?.AppropriateSeasonNumber}E{episode?.AppropriateEpNum} saving to {Location()}"); } } file.WriteLine(GenerateFooter()); } }
protected override void Check([NotNull] ShowItem si, [NotNull] DirFilesCache dfc, TVDoc.ScanSettings settings) { Dictionary <int, List <string> > allFolders = si.AllExistngFolderLocations(); if (allFolders.Count == 0) // no folders defined for this show { return; // so, nothing to do. } //This is the code that will iterate over the DownloadIdentifiers and ask each to ensure that //it has all the required files for that show if (!string.IsNullOrEmpty(si.AutoAddFolderBase) && (allFolders.Any())) { Doc.TheActionList.Add(downloadIdentifiers.ProcessShow(si)); } //MS_TODO Put the banner refresh period into the settings file, we'll default to 3 months DateTime cutOff = DateTime.Now.AddMonths(-3); DateTime lastUpdate = si.BannersLastUpdatedOnDisk ?? DateTime.Now.AddMonths(-4); bool timeForBannerUpdate = (cutOff.CompareTo(lastUpdate) == 1); if (TVSettings.Instance.NeedToDownloadBannerFile() && timeForBannerUpdate) { Doc.TheActionList.Add( downloadIdentifiers.ForceUpdateShow(DownloadIdentifier.DownloadType.downloadImage, si)); si.BannersLastUpdatedOnDisk = DateTime.Now; Doc.SetDirty(); } // process each folder for each season... foreach (int snum in si.SeasonEpisodes.Keys.ToList()) { if (settings.Token.IsCancellationRequested) { return; } if (si.IgnoreSeasons.Contains(snum) || !allFolders.ContainsKey(snum)) { continue; } if ((snum == 0) && (si.CountSpecials)) { continue; } if ((snum == 0) && TVSettings.Instance.IgnoreAllSpecials) { continue; } // all the folders for this particular season List <string> folders = allFolders[snum]; CheckSeason(si, dfc, settings, snum, folders, timeForBannerUpdate); } // for each season of this show }
private void GenerateRightClickWatchMenu([NotNull] Season seas) { // for each episode in season, find it on disk bool first = true; DirFilesCache dfc = new DirFilesCache(); foreach (ProcessedEpisode epds in show.SeasonEpisodes[seas.SeasonNumber]) { List <FileInfo> fl = dfc.FindEpOnDisk(epds, false); if (fl.Count > 0) { if (first) { GenerateSeparator(gridSummary.showRightClickMenu); first = false; } int n = gridSummary.mLastFileList.Count; foreach (FileInfo fi in fl) { GenerateMenu(gridSummary.showRightClickMenu, "Watch: " + fi.FullName, (int)RightClickCommands.kWatchBase + n); gridSummary.mLastFileList.Add(fi); n++; } } } }
public static bool FileNeeded(DirectoryInfo?di, MovieConfiguration?si, DirFilesCache dfc) { if (di is null) { throw new ArgumentNullException(nameof(di)); } if (si is null) { throw new ArgumentNullException(nameof(si)); } foreach (FileInfo testFileInfo in FindMovieOnDisk(dfc, si)) { //We will check that the file that is found is not the one we are testing if (di.FullName == testFileInfo.FullName) { continue; } //We have found another file that matches return(false); } return(true); }
private IEnumerable <ProcessedEpisode> GetMissingEps() { int dd = TVSettings.Instance.WTWRecentDays; DirFilesCache dfc = new DirFilesCache(); return(GetMissingEps(dfc, Library.GetRecentAndFutureEps(dd))); }
private static ShowSummaryData.ShowSummarySeasonData GetSeasonDetails([NotNull] ShowItem si, int snum) { int epCount = 0; int epGotCount = 0; int epAiredCount = 0; DirFilesCache dfc = new DirFilesCache(); Season season = null; Dictionary <int, Season> seasons = si.AppropriateSeasons(); if (snum >= 0 && seasons.ContainsKey(snum)) { season = seasons[snum]; List <ProcessedEpisode> eis = si.SeasonEpisodes[snum]; foreach (ProcessedEpisode ei in eis) { epCount++; // if has air date and has been aired in the past if (ei.FirstAired != null && ei.FirstAired < DateTime.Now) { epAiredCount++; } List <FileInfo> fl = dfc.FindEpOnDisk(ei, false); if (fl.Count != 0) { epGotCount++; } } } return(new ShowSummaryData.ShowSummarySeasonData(snum, epCount, epAiredCount, epGotCount, season, si.IgnoreSeasons.Contains(snum))); }
private IEnumerable <Item> Go(ICollection <ShowItem> showList, TVDoc.ScanSettings settings) { //for each directory in settings directory //for each file in directory //for each saved show (order by recent) //is file already available? //if so add show to list of files to be removed DirFilesCache dfc = new DirFilesCache(); List <Item> returnActions = new List <Item>(); int totalDownloadFolders = TVSettings.Instance.DownloadFolders.Count; int c = 0; foreach (string dirPath in TVSettings.Instance.DownloadFolders.ToList()) { UpdateStatus(c++, totalDownloadFolders, dirPath); if (!Directory.Exists(dirPath)) { continue; } List <FileInfo> filesThatMayBeNeeded = new List <FileInfo>(); returnActions.AddNullableRange(ReviewFilesInDownloadDirectory(showList, dfc, dirPath, filesThatMayBeNeeded, settings)); returnActions.AddNullableRange(ReviewDirsInDownloadDirectory(showList, dfc, dirPath, filesThatMayBeNeeded, settings)); } return(returnActions); }
private static IEnumerable <ProcessedEpisode> GetMissingEps(DirFilesCache dfc, [NotNull] IEnumerable <ProcessedEpisode> lpe) { List <ProcessedEpisode> missing = new List <ProcessedEpisode>(); foreach (ProcessedEpisode pe in lpe) { List <FileInfo> fl = dfc.FindEpOnDisk(pe); bool foundOnDisk = fl.Any(file => file.Name.StartsWith(TVSettings.Instance.FilenameFriendly(TVSettings.Instance.NamingStyle.NameFor(pe)), StringComparison.OrdinalIgnoreCase)); bool alreadyAired; DateTime?airDate = pe.GetAirDateDt(true); if (airDate.HasValue) { alreadyAired = airDate.Value.CompareTo(DateTime.Now) < 0; } else { alreadyAired = true; } if (!foundOnDisk && alreadyAired && pe.Show.DoMissingCheck) { missing.Add(pe); } } return(missing); }
private void GenerateRightClickWatchMenu([NotNull] ProcessedSeason seas) { // for each episode in season, find it on disk bool first = true; DirFilesCache dfc = new DirFilesCache(); foreach (ProcessedEpisode epds in show.SeasonEpisodes[seas.SeasonNumber]) { List <FileInfo> fl = dfc.FindEpOnDisk(epds, false); if (fl.Count > 0) { if (first) { GenerateSeparator(gridSummary.showRightClickMenu); first = false; } foreach (FileInfo fi in fl) { ToolStripMenuItem tsi = new ToolStripMenuItem("Watch: " + fi.FullName); tsi.Click += (sender, args) => { Helpers.OpenFile(fi.FullName); }; gridSummary.showRightClickMenu.Items.Add(tsi); } } } }
private IEnumerable <ProcessedEpisode> GetMissingEps(DirFilesCache dfc, [NotNull] IEnumerable <ProcessedEpisode> lpe) { List <ProcessedEpisode> missing = new List <ProcessedEpisode>(); foreach (ProcessedEpisode pe in lpe) { bool foundOnDisk = dfc.FindEpOnDisk(pe).Any(); bool alreadyAired; DateTime?airDate = pe.GetAirDateDt(true); if (airDate.HasValue) { alreadyAired = airDate.Value.CompareTo(DateTime.Now) < 0; } else { alreadyAired = true; } if (!foundOnDisk && alreadyAired && (pe.Show.DoMissingCheck)) { missing.Add(pe); } } return(missing); }
protected override void Check([NotNull] ShowItem si, DirFilesCache dfc, TVDoc.ScanSettings settings) { if (!si.DoMissingCheck && !si.DoRename) { return; // skip } Dictionary <int, List <string> > flocs = si.AllProposedFolderLocations(); List <string> ignoredLocations = new List <string>(); foreach (int snum in si.GetSeasonKeys()) { // show MissingFolderAction for any folders that are missing // throw Exception if user cancels if (si.IgnoreSeasons.Contains(snum)) { continue; // ignore this season } if (snum == 0 && si.CountSpecials) { continue; // no specials season, they're merged into the seasons themselves } if (snum == 0 && TVSettings.Instance.IgnoreAllSpecials) { continue; } List <string> folders = new List <string>(); if (flocs.ContainsKey(snum)) { folders = flocs[snum]; } if (si.SeasonEpisodes[snum].All(episode => !MightWeProcess(episode, folders))) { //All episodes in this season are ignored continue; } if (folders.Count == 0 && si.AutoAddNewSeasons()) { // no folders defined for this season, and autoadd didn't find any, so suggest the autoadd folder name instead folders.Add(si.AutoFolderNameForSeason(snum)); } if (folders.Count == 0 && !si.AutoAddNewSeasons()) { // no folders defined for this season, and autoadd didn't find any, so suggest the autoadd folder name instead folders.Add(string.Empty); } CreateSeasonFolders(si, snum, folders, ignoredLocations); } // for each snum }
public void CheckIfActive(MovieConfiguration si, DirFilesCache dfc, TVDoc.ScanSettings settings) { if (Active()) { Check(si, dfc, settings); LogActionListSummary(); } }
protected override void DoCheck(SetProgressDelegate prog, TVDoc.ScanSettings settings) { ItemList newList = new ItemList(); ItemList toRemove = new ItemList(); DirFilesCache dfc = new DirFilesCache(); int currentItem = 0; int totalN = ActionList.Missing.Count + 1; UpdateStatus(currentItem, totalN, "Starting searching through library looking for files"); LOGGER.Info("Starting to look for missing items in the library"); foreach (var me in ActionList.MissingEpisodes.ToList()) { if (settings.Token.IsCancellationRequested) { return; } UpdateStatus(currentItem++, totalN, me.Filename); ItemList thisRound = new ItemList(); if (me.Episode?.Show is null) { LOGGER.Info($"Not looking for {me.Filename} in the library as the show/episode is null"); continue; } string baseFolder = me.Episode.Show.AutoAddFolderBase; LOGGER.Info($"Starting to look for {me.Filename} in the library: {baseFolder}"); List <FileInfo> matchedFiles = GetMatchingFilesFromFolder(baseFolder, dfc, me, settings, thisRound); foreach (string folderName in me.Episode.Show.AllFolderLocationsEpCheck(false) .Where(folders => folders.Value != null) .Where(folders => folders.Key == me.Episode.AppropriateProcessedSeason.SeasonNumber) .SelectMany(seriesFolders => seriesFolders.Value .Where(f => !string.IsNullOrWhiteSpace(f)) //No point looking here .Where(f => f != baseFolder))) { ProcessFolder(settings, me, folderName, dfc, thisRound, matchedFiles); } ProcessMissingItem(settings, newList, toRemove, me, thisRound, matchedFiles, TVSettings.Instance.UseFullPathNameToMatchLibraryFolders); } if (TVSettings.Instance.KeepTogether) { KeepTogether(newList, true); } ReorganiseToLeaveOriginals(newList); ActionList.Replace(toRemove, newList); }
public static bool FileNeeded(FileInfo fi, ShowConfiguration si, DirFilesCache dfc) { if (FindSeasEp(fi, out int seasF, out int epF, out _, si, out _)) { return(EpisodeNeeded(si, dfc, seasF, epF, fi)); } //We may need the file return(true); }
private bool CanRemove(TorrentEntry download, DirFilesCache dfc) { if (download.PercentDone < 100) { return(false); } if (!download.Finished) { return(false); } FileInfo x = new FileInfo(download.DownloadingTo); if (!x.IsMovieFile()) { return(false); } List <ProcessedEpisode>?pes = MatchEpisodes(x); List <MovieConfiguration>?movies = MatchMovies(x); bool matchesSomeMovies = !(movies is null || movies.Count == 0); bool matchesSomeShows = !(pes is null || pes.Count == 0); if (!matchesSomeMovies && !matchesSomeShows) { //File does not match any movies or shows return(false); } if (matchesSomeMovies && !movies !.All(movie => IsFound(dfc, movie))) { //Some Movies have not been copied yet - wait until they have return(false); } if (matchesSomeShows && !pes !.All(episode => IsFound(dfc, episode))) { //Some Episodes have not been copied yet - wait until they have return(false); } if (matchesSomeShows) { lastFoundEntry = download; lastFoundEpisode = pes !.First(); lastFoundMovie = null; return(true); } lastFoundEntry = download; lastFoundEpisode = null; lastFoundMovie = movies !.First(); return(true); }
private void FindMovie(TVDoc.ScanSettings settings, MovieItemMissing mim, DirFilesCache dfc, ItemList newList, ItemList toRemove) { if (!mim.MovieConfig.UseAutomaticFolders) { return; } (string targetFolder, string targetFolderEarlier, string targetFolderLater) = mim.MovieConfig.NeighbouringFolderNames(); TestShouldMove(targetFolderEarlier, targetFolder, dfc, newList, toRemove, mim); TestShouldMove(targetFolderLater, targetFolder, dfc, newList, toRemove, mim); }
private static bool IsOneFound([NotNull] StringBuilder output, DirFilesCache dfc, [NotNull] ProcessedEpisode pep, [NotNull] ProcessedEpisode comparePep, ref bool largerFileSize) { output.AppendLine("####### POSSIBLE DUPLICATE DUE TO NAME##########"); //Do the missing Test (ie is one missing and not the other) bool pepFound = dfc.FindEpOnDisk(pep).Any(); bool comparePepFound = dfc.FindEpOnDisk(comparePep).Any(); bool oneFound = pepFound ^ comparePepFound; if (oneFound) { output.AppendLine( "####### POSSIBLE DUPLICATE DUE TO ONE MISSING AND ONE FOUND ##########"); ProcessedEpisode possibleDupEpisode = pepFound ? pep : comparePep; //Test the file sizes in the season //More than 40% longer FileInfo possibleDupFile = dfc.FindEpOnDisk(possibleDupEpisode)[0]; int dupMovieLength = possibleDupFile.GetFilmLength(); List <int> otherMovieLengths = new List <int>(); foreach (FileInfo file in possibleDupFile.Directory.EnumerateFiles()) { if (file.IsMovieFile()) { otherMovieLengths.Add(file.GetFilmLength()); } } int averageMovieLength = otherMovieLengths.Count == 1 ?otherMovieLengths.Sum() :(otherMovieLengths.Sum() - dupMovieLength) / (otherMovieLengths.Count - 1); largerFileSize = dupMovieLength > averageMovieLength * 1.4; if (largerFileSize) { { output.AppendLine( "######################################################################"); output.AppendLine( "####### SURELY WE HAVE ONE NOW ##########"); output.AppendLine( $"####### {possibleDupEpisode.AiredEpNum}({possibleDupEpisode.Name}) has length {dupMovieLength} greater than the average in the directory of {averageMovieLength}"); output.AppendLine( "######################################################################"); } } } return(oneFound); }
protected override void DoCheck(SetProgressDelegate prog, ICollection <ShowItem> showList, TVDoc.ScanSettings settings) { MDoc.TheActionList = new ItemList(); if (TVSettings.Instance.RenameCheck) { MDoc.Stats().RenameChecksDone++; } if (TVSettings.Instance.MissingCheck) { MDoc.Stats().MissingChecksDone++; } if (settings.Type == TVSettings.ScanType.Full) { // only do episode count if we're doing all shows and seasons MDoc.CurrentStats.NsNumberOfEpisodes = 0; showList = MDoc.Library.Values; } DirFilesCache dfc = new DirFilesCache(); int c = 0; UpdateStatus(c, showList.Count, "Checking shows"); foreach (ShowItem si in showList.OrderBy(item => item.ShowName)) { UpdateStatus(c++, showList.Count, si.ShowName); if (settings.Token.IsCancellationRequested) { return; } LOGGER.Info("Rename and missing check: " + si.ShowName); try { new CheckAllFoldersExist(MDoc).CheckIfActive(si, dfc, settings); new MergeLibraryEpisodes(MDoc).CheckIfActive(si, dfc, settings); new RenameAndMissingCheck(MDoc).CheckIfActive(si, dfc, settings); } catch (TVRenameOperationInterruptedException) { throw; } catch (Exception e) { LOGGER.Error(e, $"Failed to scan {si.ShowName}. Please double check settings for this show: {si.TvdbCode}: {si.AutoAddFolderBase}"); } } // for each show MDoc.RemoveIgnored(); }
protected override void DoCheck(SetProgressDelegate prog, TVDoc.ScanSettings settings) { ItemList newList = new ItemList(); ItemList toRemove = new ItemList(); DirFilesCache dfc = new DirFilesCache(); int currentItem = 0; int totalN = ActionList.Missing.Count + 1; UpdateStatus(currentItem, totalN, "Starting searching through library looking for files"); LOGGER.Info("Starting to look for missing items in the library"); foreach (ItemMissing?me in ActionList.Missing.ToList()) { if (settings.Token.IsCancellationRequested) { return; } UpdateStatus(currentItem++, totalN, me.Filename); if (me is ShowItemMissing sim) { if (me.Episode?.Show is null) { LOGGER.Info($"Not looking for {me.Filename} in the library as the show/episode is null"); continue; } FindEpisode(settings, sim, dfc, newList, toRemove); } else if (me is MovieItemMissing mim) { FindMovie(settings, mim, dfc, newList, toRemove); } } if (TVSettings.Instance.KeepTogether) { KeepTogether(newList, true); } if (!TVSettings.Instance.LeaveOriginals) { ReorganiseToLeaveOriginals(newList); } ActionList.Replace(toRemove, newList); }
public static IEnumerable <FileInfo> FindMovieOnDisk(this DirFilesCache cache, MovieConfiguration si) { List <FileInfo> ret = new List <FileInfo>(); foreach (FileInfo fiTemp in si.Locations .Select(cache.GetFiles) .SelectMany(files => files.Where(fiTemp => fiTemp.IsMovieFile()))) { { ret.Add(fiTemp); } } return(ret); }
private ShowSummaryData.ShowSummarySeasonData getSeasonDetails(ShowItem si, SeriesInfo ser, int snum) { int epCount = 0; int epGotCount = 0; int epAiredCount = 0; DirFilesCache dfc = new DirFilesCache(); Season season = null; Dictionary <int, Season> seasons = si.DVDOrder ? ser.DVDSeasons : ser.AiredSeasons; if ((snum >= 0) && (seasons.ContainsKey(snum))) { season = seasons[snum]; List <ProcessedEpisode> eis; if (si.SeasonEpisodes.ContainsKey(snum)) { eis = si.SeasonEpisodes[snum]; // use processed episodes if they are available } else { eis = ShowItem.ProcessedListFromEpisodes(season.Episodes, si); } foreach (ProcessedEpisode ei in eis) { epCount++; // if has air date and has been aired in the past if (ei.FirstAired != null && ei.FirstAired < DateTime.Now) { epAiredCount++; } List <Alphaleonis.Win32.Filesystem.FileInfo> fl = TVDoc.FindEpOnDisk(dfc, ei, false); if (fl != null) { if (fl.Count != 0) { epGotCount++; } } } } return(new ShowSummaryData.ShowSummarySeasonData(snum, epCount, epAiredCount, epGotCount, season)); }
internal static List <PossibleDuplicateEpisode> FindDoubleEps([NotNull] TVDoc doc) { doc.PreventAutoScan("Find Double Episodes"); StringBuilder output = new StringBuilder(); List <PossibleDuplicateEpisode> returnValue = new List <PossibleDuplicateEpisode>(); output.AppendLine(""); output.AppendLine("##################################################"); output.AppendLine("DUPLICATE FINDER - Start"); output.AppendLine("##################################################"); DirFilesCache dfc = new DirFilesCache(); foreach (ShowItem si in doc.Library.Values) { foreach (KeyValuePair <int, List <ProcessedEpisode> > kvp in si.SeasonEpisodes) { //Ignore specials seasons if (kvp.Key == 0) { continue; } //Ignore seasons that all aired on same date DateTime?seasonMinAirDate = (from pep in kvp.Value select pep.FirstAired).Min(); DateTime?seasonMaxAirDate = (from pep in kvp.Value select pep.FirstAired).Max(); if (seasonMaxAirDate.HasValue && seasonMinAirDate.HasValue && seasonMaxAirDate == seasonMinAirDate) { continue; } //Search through each pair of episodes for the same season foreach (ProcessedEpisode pep in kvp.Value) { SearchForDuplicates(pep, output, si, kvp.Key, kvp.Value, dfc, returnValue); } } } output.AppendLine("##################################################"); output.AppendLine("DUPLICATE FINDER - End"); output.AppendLine("##################################################"); Logger.Info(output.ToString()); doc.AllowAutoScan(); return(returnValue); }
public static List <FileInfo> FindEpOnDisk([CanBeNull] DirFilesCache dfc, [NotNull] ShowItem si, [NotNull] Episode epi, bool checkDirectoryExist = true) { DirFilesCache cache = dfc ?? new DirFilesCache(); List <FileInfo> ret = new List <FileInfo>(); int seasWanted = si.DvdOrder ? epi.TheDvdSeason.SeasonNumber : epi.TheAiredSeason.SeasonNumber; int epWanted = si.DvdOrder ? epi.DvdEpNum : epi.AiredEpNum; int snum = seasWanted; Dictionary <int, List <string> > dirs = si.AllFolderLocationsEpCheck(checkDirectoryExist); if (!dirs.ContainsKey(snum)) { return(ret); } foreach (string folder in dirs[snum]) { FileInfo[] files = cache.GetFiles(folder); if (files is null) { continue; } foreach (FileInfo fiTemp in files.Where(fiTemp => fiTemp.IsMovieFile())) { if (!FindSeasEp(fiTemp, out int seasFound, out int epFound, out int _, si)) { continue; } if (seasFound == -1) { seasFound = seasWanted; } if ((seasFound == seasWanted) && (epFound == epWanted)) { ret.Add(fiTemp); } } } return(ret); }
public static string GetSeasonHtmlOverview([NotNull] this ShowItem si, [NotNull] Season s, bool includeDirectoryLinks) { StringBuilder sb = new StringBuilder(); DirFilesCache dfc = new DirFilesCache(); Color col = Color.FromName("ButtonFace"); sb.AppendLine(HTMLHeader(10, col)); sb.AppendSeason(s, si, col, includeDirectoryLinks); foreach (ProcessedEpisode ep in GetBestEpisodes(si, s)) { List <FileInfo> fl = dfc.FindEpOnDisk(ep); sb.AppendEpisode(ep, fl, col); } sb.AppendLine(HTMLFooter()); return(sb.ToString()); }
internal static List <PossibleMergedEpisode> FindDoubleEps(TVDoc doc, [NotNull] BackgroundWorker worker) { int total = doc.TvLibrary.Count; int current = 0; doc.PreventAutoScan("Find Double Episodes"); StringBuilder output = new StringBuilder(); List <PossibleMergedEpisode> returnValue = new List <PossibleMergedEpisode>(); output.AppendLine(""); output.AppendLine("##################################################"); output.AppendLine("MERGED EPISODES FINDER - Start"); output.AppendLine("##################################################"); DirFilesCache dfc = new DirFilesCache(); foreach (ShowConfiguration si in doc.TvLibrary.GetSortedShowItems()) { worker.ReportProgress(100 * current++ / total, si.ShowName); foreach (KeyValuePair <int, List <ProcessedEpisode> > kvp in si.ActiveSeasons) { //Ignore seasons that all aired on same date DateTime?seasonMinAirDate = (from pep in kvp.Value select pep.FirstAired).Min(); DateTime?seasonMaxAirDate = (from pep in kvp.Value select pep.FirstAired).Max(); if (seasonMaxAirDate.HasValue && seasonMinAirDate.HasValue && seasonMaxAirDate == seasonMinAirDate) { continue; } //Search through each pair of episodes for the same season foreach (ProcessedEpisode pep in kvp.Value) { SearchForDuplicates(pep, output, si, kvp.Key, kvp.Value, dfc, returnValue); } } } output.AppendLine("##################################################"); output.AppendLine("MERGED EPISODES FINDER - End"); output.AppendLine("##################################################"); Logger.Info(output.ToString()); doc.AllowAutoScan(); return(returnValue); }
public override void Run() { if (Active()) { try { //Create the directory if needed Directory.CreateDirectory(Path.GetDirectoryName(Location()) ?? ""); List <ProcessedEpisode> lpe = doc.Library.RecentEpisodes(TVSettings.Instance.WTWRecentDays); DirFilesCache dfc = new DirFilesCache(); //Write Contents to file using (StreamWriter file = new StreamWriter(Location())) { file.WriteLine(GenerateHeader()); foreach (ProcessedEpisode episode in lpe) { List <FileInfo> files = TVDoc.FindEpOnDisk(dfc, episode, false); if (!files.Any()) { continue; } string name = TVSettings.Instance.NamingStyle.NameFor(episode); int length = files.First().GetFilmLength(); file.WriteLine(GenerateRecord(episode, files.First(), name, length)); } file.WriteLine(GenerateFooter()); } LOGGER.Info("Output File to: {0}", Location()); } catch (Exception e) { LOGGER.Error(e, "Failed to Output File to: {0}", Location()); } } else { LOGGER.Trace("Skipped (Disabled) Output File to: {0}", Location()); } }
private List <FileInfo> GetMatchingFilesFromFolder(string?baseFolder, DirFilesCache dfc, ShowItemMissing me, TVDoc.ScanSettings settings, ItemList thisRound) { List <FileInfo> matchedFiles; if (string.IsNullOrWhiteSpace(baseFolder)) { matchedFiles = new List <FileInfo>(); } else { IEnumerable <FileInfo> testFiles = dfc.GetFilesIncludeSubDirs(baseFolder); matchedFiles = testFiles.Where(testFile => ReviewFile(me, thisRound, testFile, settings, false, false, false, TVSettings.Instance.UseFullPathNameToMatchLibraryFolders)).ToList(); } return(matchedFiles); }
private static List <FileInfo> FindEpOnDisk(DirFilesCache?dfc, ShowConfiguration si, ProcessedEpisode epi, bool checkDirectoryExist = true) { DirFilesCache cache = dfc ?? new DirFilesCache(); List <FileInfo> ret = new List <FileInfo>(); int seasWanted = epi.AppropriateSeasonNumber; int epWanted = epi.AppropriateEpNum; int snum = seasWanted; Dictionary <int, SafeList <string> > dirs = si.AllFolderLocationsEpCheck(checkDirectoryExist); if (!dirs.ContainsKey(snum)) { return(ret); } foreach (string folder in dirs[snum]) { FileInfo[] files = cache.GetFiles(folder); foreach (FileInfo fiTemp in files.Where(fiTemp => fiTemp.IsMovieFile())) { if (!FindSeasEp(fiTemp, out int seasFound, out int epFound, out int _, si)) { continue; } if (seasFound == -1) { seasFound = seasWanted; } if (seasFound == seasWanted && epFound == epWanted) { ret.Add(fiTemp); } } } return(ret); }
public static bool EpisodeNeeded([NotNull] ShowItem si, DirFilesCache dfc, int seasF, int epF, [NotNull] FileSystemInfo fi) { if (si is null) { throw new ArgumentNullException(nameof(si)); } if (fi is null) { throw new ArgumentNullException(nameof(fi)); } try { SeriesInfo s = si.TheSeries(); if (s is null) { //We have not downloaded the series, so have to assume that we need the episode/file return(true); } Episode ep = s.GetEpisode(seasF, epF, si.DvdOrder); ProcessedEpisode pep = new ProcessedEpisode(ep, si); foreach (FileInfo testFileInfo in FindEpOnDisk(dfc, si, pep)) { //We will check that the file that is found is not the one we are testing if (fi.FullName == testFileInfo.FullName) { continue; } //We have found another file that matches return(false); } } catch (SeriesInfo.EpisodeNotFoundException) { //Ignore exception, we may need the file return(true); } return(true); }
public void FillWhenToWatchList() { this.mInternalChange++; this.lvWhenToWatch.BeginUpdate(); int dd = TVSettings.Instance.WTWRecentDays; this.lvWhenToWatch.Groups["justPassed"].Header = "Aired in the last " + dd + " day" + ((dd == 1) ? "" : "s"); // try to maintain selections if we can List<ProcessedEpisode> selections = new List<ProcessedEpisode>(); foreach (ListViewItem lvi in this.lvWhenToWatch.SelectedItems) selections.Add((ProcessedEpisode)(lvi.Tag)); Season currentSeas = TreeNodeToSeason(this.MyShowTree.SelectedNode); ShowItem currentSI = this.TreeNodeToShowItem(this.MyShowTree.SelectedNode); this.lvWhenToWatch.Items.Clear(); System.Collections.Generic.List<DateTime> bolded = new System.Collections.Generic.List<DateTime>(); DirFilesCache dfc = new DirFilesCache(); foreach (ShowItem si in this.mDoc.GetShowItems(true)) { if (!si.ShowNextAirdate) continue; foreach (KeyValuePair<int, List<ProcessedEpisode>> kvp in si.SeasonEpisodes) { if (si.IgnoreSeasons.Contains(kvp.Key)) continue; // ignore this season List<ProcessedEpisode> eis = kvp.Value; bool nextToAirFound = false; foreach (ProcessedEpisode ei in eis) { DateTime? dt = ei.GetAirDateDT(true); if ((dt != null) && (dt.Value.CompareTo(DateTime.MaxValue) != 0)) { TimeSpan ts = dt.Value.Subtract(DateTime.Now); if (ts.TotalHours >= (-24 * dd)) // in the future (or fairly recent) { bolded.Add(dt.Value); if ((ts.TotalHours >= 0) && (!nextToAirFound)) { nextToAirFound = true; ei.NextToAir = true; } else ei.NextToAir = false; ListViewItem lvi = new System.Windows.Forms.ListViewItem(); lvi.Text = ""; for (int i = 0; i < 7; i++) lvi.SubItems.Add(""); this.UpdateWTW(dfc, ei, lvi); this.lvWhenToWatch.Items.Add(lvi); foreach (ProcessedEpisode pe in selections) { if (pe.SameAs(ei)) { lvi.Selected = true; break; } } } } } } } this.mDoc.UnlockShowItems(); this.lvWhenToWatch.Sort(); this.lvWhenToWatch.EndUpdate(); this.calCalendar.BoldedDates = bolded.ToArray(); if (currentSeas != null) this.SelectSeason(currentSeas); else if (currentSI != null) this.SelectShow(currentSI); this.UpdateToolstripWTW(); this.mInternalChange--; }
public void UpdateWTW(DirFilesCache dfc, ProcessedEpisode pe, ListViewItem lvi) { lvi.Tag = pe; // group 0 = just missed // 1 = this week // 2 = future / unknown DateTime? airdt = pe.GetAirDateDT(true); if (airdt == null) { // TODO: something! return; } DateTime dt = (DateTime)airdt; double ttn = (dt.Subtract(DateTime.Now)).TotalHours; if (ttn < 0) lvi.Group = this.lvWhenToWatch.Groups["justPassed"]; else if (ttn < (7 * 24)) lvi.Group = this.lvWhenToWatch.Groups["next7days"]; else if (!pe.NextToAir) lvi.Group = this.lvWhenToWatch.Groups["later"]; else lvi.Group = this.lvWhenToWatch.Groups["futureEps"]; int n = 1; lvi.Text = pe.SI.ShowName; lvi.SubItems[n++].Text = (pe.SeasonNumber != 0) ? pe.SeasonNumber.ToString() : "Special"; string estr = (pe.EpNum > 0) ? pe.EpNum.ToString() : ""; if ((pe.EpNum > 0) && (pe.EpNum2 != pe.EpNum) && (pe.EpNum2 > 0)) estr += "-" + pe.EpNum2; lvi.SubItems[n++].Text = estr; lvi.SubItems[n++].Text = dt.ToShortDateString(); lvi.SubItems[n++].Text = dt.ToString("t"); lvi.SubItems[n++].Text = dt.ToString("ddd"); lvi.SubItems[n++].Text = pe.HowLong(); lvi.SubItems[n++].Text = pe.Name; // icon.. if (airdt.Value.CompareTo(DateTime.Now) < 0) // has aired { List<FileInfo> fl = this.mDoc.FindEpOnDisk(dfc, pe); if ((fl != null) && (fl.Count > 0)) lvi.ImageIndex = 0; else if (pe.SI.DoMissingCheck) lvi.ImageIndex = 1; } }
private string GetSeasonHTMLOverview(ShowItem si,SeriesInfo ser, int snum ) { string body = ""; if (!string.IsNullOrEmpty(ser.GetItem("banner")) && !string.IsNullOrEmpty(TheTVDB.Instance.BannerMirror)) body += "<img width=758 height=140 src=\"" + TheTVDB.Instance.BannerMirror + "/banners/" + ser.GetItem("banner") + "\"><br/>"; Season s = ser.Seasons[snum]; List<ProcessedEpisode> eis = null; // int snum = s.SeasonNumber; if (si.SeasonEpisodes.ContainsKey(snum)) eis = si.SeasonEpisodes[snum]; // use processed episodes if they are available else eis = ShowItem.ProcessedListFromEpisodes(s.Episodes, si); string seasText = snum == 0 ? "Specials" : ("Season " + snum); if ((eis.Count > 0) && (eis[0].SeasonID > 0)) seasText = " - <A HREF=\"" + TheTVDB.Instance.WebsiteURL(si.TVDBCode, eis[0].SeasonID, false) + "\">" + seasText + "</a>"; else seasText = " - " + seasText; body += "<h1><A HREF=\"" + TheTVDB.Instance.WebsiteURL(si.TVDBCode, -1, true) + "\">" + si.ShowName + "</A>" + seasText + "</h1>"; DirFilesCache dfc = new DirFilesCache(); foreach (ProcessedEpisode ei in eis) { string epl = ei.NumsAsString(); // http://www.thetvdb.com/?tab=episode&seriesid=73141&seasonid=5356&id=108303&lid=7 string episodeURL = "http://www.thetvdb.com/?tab=episode&seriesid=" + ei.SeriesID + "&seasonid=" + ei.SeasonID + "&id=" + ei.EpisodeID; body += "<A href=\"" + episodeURL + "\" name=\"ep" + epl + "\">"; // anchor body += "<b>" + CustomName.NameForNoExt(ei, CustomName.OldNStyle(6)) + "</b>"; body += "</A>"; // anchor if (si.UseSequentialMatch && (ei.OverallNumber != -1)) body += " (#" + ei.OverallNumber + ")"; body += " <A HREF=\"" + TVSettings.Instance.BTSearchURL(ei) + "\" class=\"search\">Search</A>"; List<FileInfo> fl = this.mDoc.FindEpOnDisk(dfc, ei); if (fl != null) { foreach (FileInfo fi in fl) body += " <A HREF=\"file://" + fi.FullName + "\" class=\"search\">Watch</A>"; } DateTime? dt = ei.GetAirDateDT(true); if ((dt != null) && (dt.Value.CompareTo(DateTime.MaxValue) != 0)) body += "<p>" + dt.Value.ToShortDateString() + " (" + ei.HowLong() + ")"; body += "<p><p>"; if (TVSettings.Instance.ShowEpisodePictures) { body += "<table><tr>"; body += "<td width=100% valign=top>" + ei.Overview + "</td><td width=300 height=225>"; // 300x168 / 300x225 if (!string.IsNullOrEmpty(ei.GetItem("filename"))) body += "<img src=" + TheTVDB.Instance.BannerMirror + "/banners/_cache/" + ei.GetItem("filename") + ">"; body += "</td></tr></table>"; } else body += ei.Overview; body += "<p><hr><p>"; } // for each episode in this season return body; }
public List<FileInfo> FindEpOnDisk(DirFilesCache dfc, ShowItem si, Episode epi) { if (dfc == null) dfc = new DirFilesCache(); List<FileInfo> ret = new List<FileInfo>(); int seasWanted = epi.TheSeason.SeasonNumber; int epWanted = epi.EpNum; int snum = epi.TheSeason.SeasonNumber; if (!si.AllFolderLocations().ContainsKey(snum)) return ret; foreach (string folder in si.AllFolderLocations()[snum]) { FileInfo[] files = dfc.Get(folder); if (files == null) continue; foreach (FileInfo fiTemp in files) { int seasFound; int epFound; if (!TVSettings.Instance.UsefulExtension(fiTemp.Extension, false)) continue; // move on if (FindSeasEp(fiTemp, out seasFound, out epFound, si)) { if (seasFound == -1) seasFound = seasWanted; if ((seasFound == seasWanted) && (epFound == epWanted)) ret.Add(fiTemp); } } } return ret; }
protected override bool generate(System.IO.Stream str, List<ProcessedEpisode> elist) { DirFilesCache dfc = new DirFilesCache(); try { XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.NewLineOnAttributes = true; settings.Encoding = System.Text.Encoding.ASCII; using (XmlWriter writer = XmlWriter.Create(str, settings)) { writer.WriteStartDocument(); writer.WriteStartElement("WhenToWatch"); foreach (ProcessedEpisode ei in elist) { string niceName = TVSettings.Instance.NamingStyle.NameForExt(ei, null, 0); writer.WriteStartElement("item"); XMLHelper.WriteElementToXML(writer,"id",ei.TheSeries.TVDBCode); XMLHelper.WriteElementToXML(writer,"SeriesName",ei.TheSeries.Name); XMLHelper.WriteElementToXML(writer,"SeasonNumber",Helpers.pad(ei.SeasonNumber)); XMLHelper.WriteElementToXML(writer, "EpisodeNumber", Helpers.pad(ei.EpNum)); XMLHelper.WriteElementToXML(writer,"EpisodeName",ei.Name); writer.WriteStartElement("available"); DateTime? airdt = ei.GetAirDateDT(true); if (airdt.Value.CompareTo(DateTime.Now) < 0) // has aired { List<FileInfo> fl = mDoc.FindEpOnDisk(dfc, ei); if ((fl != null) && (fl.Count > 0)) writer.WriteValue("true"); else if (ei.SI.DoMissingCheck) writer.WriteValue("false"); } writer.WriteEndElement(); XMLHelper.WriteElementToXML( writer,"Overview",ei.Overview); writer.WriteStartElement("FirstAired"); DateTime? dt = ei.GetAirDateDT(true); if (dt != null) writer.WriteValue(dt.Value.ToString("F")); writer.WriteEndElement(); XMLHelper.WriteElementToXML( writer,"Rating",ei.EpisodeRating); XMLHelper.WriteElementToXML( writer,"filename",ei.GetItem("filename")); writer.WriteEndElement(); // item } writer.WriteEndElement(); writer.WriteEndDocument(); writer.Close(); } return true; } // try catch (Exception e) { MessageBox.Show(e.Message); return false; } }
public void ForceUpdateImages(ShowItem si) { this.TheActionList = new ItemList(); this.LockShowItems(); DirFilesCache dfc = new DirFilesCache(); System.Diagnostics.Debug.Print(DateTime.Now.ToLongTimeString() + " Force Update Images: " + si.ShowName); if (!string.IsNullOrEmpty(si.AutoAdd_FolderBase) && (si.AllFolderLocations().Count > 0)) { this.TheActionList.Add(DownloadIdentifiers.ForceUpdateShow(DownloadIdentifier.DownloadType.downloadImage, si)); si.BannersLastUpdatedOnDisk = System.DateTime.Now; this.SetDirty(); } // process each folder for each season... int[] numbers = new int[si.SeasonEpisodes.Keys.Count]; si.SeasonEpisodes.Keys.CopyTo(numbers, 0); Dictionary<int, List<string>> allFolders = si.AllFolderLocations(); foreach (int snum in numbers) { if ((si.IgnoreSeasons.Contains(snum)) || (!allFolders.ContainsKey(snum))) continue; // ignore/skip this season if ((snum == 0) && (si.CountSpecials)) continue; // don't process the specials season, as they're merged into the seasons themselves // all the folders for this particular season List<string> folders = allFolders[snum]; List<ProcessedEpisode> eps = si.SeasonEpisodes[snum]; foreach (string folder in folders) { //Image series checks here this.TheActionList.Add(DownloadIdentifiers.ForceUpdateSeason(DownloadIdentifier.DownloadType.downloadImage, si, folder, snum)); } } // for each season of this show this.UnlockShowItems(); this.RemoveIgnored(); }
public void RenameAndMissingCheck(SetProgressDelegate prog, List<ShowItem> showList) { this.TheActionList = new ItemList(); //int totalEps = 0; this.LockShowItems(); if (showList == null) showList = ShowItems; //foreach (ShowItem si in showlist) // if (si.DoRename) // totalEps += si.SeasonEpisodes.Count; if (TVSettings.Instance.RenameCheck) this.Stats().RenameChecksDone++; if (TVSettings.Instance.MissingCheck) this.Stats().MissingChecksDone++; prog.Invoke(0); if (showList == null) // only do episode count if we're doing all shows and seasons this.mStats.NS_NumberOfEpisodes = 0; DirFilesCache dfc = new DirFilesCache(); int c = 0; foreach (ShowItem si in showList) { if (this.ActionCancel) return; System.Diagnostics.Debug.Print(DateTime.Now.ToLongTimeString()+ " Rename and missing check: " + si.ShowName); c++; prog.Invoke(100 * c / showList.Count); if (si.AllFolderLocations().Count == 0) // no folders defined for this show continue; // so, nothing to do. //This is the code that will iterate over the DownloadIdentifiers and ask each to ensure that //it has all the required files for that show if (!string.IsNullOrEmpty(si.AutoAdd_FolderBase) && (si.AllFolderLocations().Count > 0)) { this.TheActionList.Add(DownloadIdentifiers.ProcessShow(si)); } //MS_TODO Put the bannerrefresh period into the settings file, we'l default to 3 months DateTime cutOff = System.DateTime.Now.AddMonths(-3); DateTime lastUpdate = si.BannersLastUpdatedOnDisk ?? System.DateTime.Now.AddMonths(-4); bool timeForBannerUpdate = (cutOff.CompareTo(lastUpdate) == 1); if (TVSettings.Instance.NeedToDownloadBannerFile() && timeForBannerUpdate) { this.TheActionList.Add(DownloadIdentifiers.ForceUpdateShow(DownloadIdentifier.DownloadType.downloadImage, si)); si.BannersLastUpdatedOnDisk = DateTime.Now; this.SetDirty(); } // process each folder for each season... int[] numbers = new int[si.SeasonEpisodes.Keys.Count]; si.SeasonEpisodes.Keys.CopyTo(numbers, 0); Dictionary<int, List<string>> allFolders = si.AllFolderLocations(); int lastSeason = 0; foreach (int n in numbers) if (n > lastSeason) lastSeason = n; foreach (int snum in numbers) { if (this.ActionCancel) return; if ((si.IgnoreSeasons.Contains(snum)) || (!allFolders.ContainsKey(snum))) continue; // ignore/skip this season if ((snum == 0) && (si.CountSpecials)) continue; // don't process the specials season, as they're merged into the seasons themselves // all the folders for this particular season List<string> folders = allFolders[snum]; bool folderNotDefined = (folders.Count == 0); if (folderNotDefined && (TVSettings.Instance.MissingCheck && !si.AutoAddNewSeasons)) continue; // folder for the season is not defined, and we're not auto-adding it List<ProcessedEpisode> eps = si.SeasonEpisodes[snum]; int maxEpisodeNumber = 0; foreach (ProcessedEpisode episode in eps) { if (episode.EpNum > maxEpisodeNumber) maxEpisodeNumber = episode.EpNum; } // base folder: if (!string.IsNullOrEmpty(si.AutoAdd_FolderBase) && (si.AllFolderLocations(false).Count > 0)) { // main image for the folder itself this.TheActionList.Add(DownloadIdentifiers.ProcessShow(si)); } foreach (string folder in folders) { if (this.ActionCancel) return; FileInfo[] files = dfc.Get(folder); if (files == null) continue; if (TVSettings.Instance.NeedToDownloadBannerFile() && timeForBannerUpdate) { //Image series checks here this.TheActionList.Add(DownloadIdentifiers.ForceUpdateSeason(DownloadIdentifier.DownloadType.downloadImage, si, folder, snum)); } bool renCheck = TVSettings.Instance.RenameCheck && si.DoRename && Directory.Exists(folder); // renaming check needs the folder to exist bool missCheck = TVSettings.Instance.MissingCheck && si.DoMissingCheck; //Image series checks here this.TheActionList.Add(DownloadIdentifiers.ProcessSeason(si,folder,snum)); FileInfo[] localEps = new FileInfo[maxEpisodeNumber + 1]; int maxEpNumFound = 0; if (!renCheck && !missCheck) continue; foreach (FileInfo fi in files) { if (this.ActionCancel) return; int seasNum; int epNum; if (!FindSeasEp(fi, out seasNum, out epNum, si)) continue; // can't find season & episode, so this file is of no interest to us if (seasNum == -1) seasNum = snum; #if !NOLAMBDA int epIdx = eps.FindIndex(x => ((x.EpNum == epNum) && (x.SeasonNumber == seasNum))); if (epIdx == -1) continue; // season+episode number don't correspond to any episode we know of from thetvdb ProcessedEpisode ep = eps[epIdx]; #else // equivalent of the 4 lines above, if compiling on MonoDevelop on Windows which, for // some reason, doesn't seem to support lambda functions (the => thing) ProcessedEpisode ep = null; foreach (ProcessedEpisode x in eps) { if (((x.EpNum == epNum) && (x.SeasonNumber == seasNum))) { ep = x; break; } } if (ep == null) continue; // season+episode number don't correspond to any episode we know of from thetvdb #endif FileInfo actualFile = fi; if (renCheck && TVSettings.Instance.UsefulExtension(fi.Extension, true)) // == RENAMING CHECK == { string newname = TVSettings.Instance.FilenameFriendly(TVSettings.Instance.NamingStyle.NameForExt(ep, fi.Extension, folder.Length)); if (newname != actualFile.Name) { actualFile = FileHelper.FileInFolder(folder, newname); // rename updates the filename this.TheActionList.Add(new ActionCopyMoveRename(ActionCopyMoveRename.Op.Rename, fi, actualFile, ep, null)); //The following section informs the DownloadIdentifers that we already plan to //copy a file inthe appropriate place and they do not need to worry about downloading //one for that purpse DownloadIdentifiers.notifyComplete(actualFile); } } if (missCheck && TVSettings.Instance.UsefulExtension(fi.Extension, false)) // == MISSING CHECK part 1/2 == { // first pass of missing check is to tally up the episodes we do have localEps[epNum] = actualFile; if (epNum > maxEpNumFound) maxEpNumFound = epNum; } } // foreach file in folder if (missCheck) // == MISSING CHECK part 2/2 (includes NFO and Thumbnails) == { // second part of missing check is to see what is missing! // look at the offical list of episodes, and look to see if we have any gaps DateTime today = DateTime.Now; TheTVDB.Instance.GetLock("UpToDateCheck"); foreach (ProcessedEpisode dbep in eps) { if ((dbep.EpNum > maxEpNumFound) || (localEps[dbep.EpNum] == null)) // not here locally { DateTime? dt = dbep.GetAirDateDT(true); bool dtOK = dt != null; bool notFuture = (dtOK && (dt.Value.CompareTo(today) < 0)); // isn't an episode yet to be aired bool noAirdatesUntilNow = true; // for specials "season", see if any season has any airdates // otherwise, check only up to the season we are considering for (int i = 1; i <= ((snum == 0) ? lastSeason : snum); i++) { if (this.HasAnyAirdates(si, i)) { noAirdatesUntilNow = false; break; } } // only add to the missing list if, either: // - force check is on // - there are no airdates at all, for up to and including this season // - there is an airdate, and it isn't in the future if (noAirdatesUntilNow || ((si.ForceCheckFuture || notFuture) && dtOK) || (si.ForceCheckNoAirdate && !dtOK)) { // then add it as officially missing this.TheActionList.Add(new ItemMissing(dbep, folder + System.IO.Path.DirectorySeparatorChar + TVSettings.Instance.FilenameFriendly(TVSettings.Instance.NamingStyle.NameForExt(dbep, null, folder.Length)))); } } else { // the file is here if (showList == null) this.mStats.NS_NumberOfEpisodes++; // do NFO and thumbnail checks if required FileInfo filo = localEps[dbep.EpNum]; // filename (or future filename) of the file this.TheActionList.Add(DownloadIdentifiers.ProcessEpisode(dbep, filo)); } } // up to date check, for each episode in thetvdb TheTVDB.Instance.Unlock("UpToDateCheck"); } // if doing missing check } // for each folder for this season of this show } // for each season of this show } // for each show this.UnlockShowItems(); this.RemoveIgnored(); }
public List<FileInfo> FindEpOnDisk(DirFilesCache dfc, ProcessedEpisode pe) { return this.FindEpOnDisk(dfc, pe.SI, pe); }