Example #1
0
        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;
                }
            }
        }
Example #2
0
        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());
            }
        }
Example #3
0
        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
        }
Example #4
0
            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++;
                        }
                    }
                }
            }
Example #5
0
        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);
        }
Example #6
0
        private IEnumerable <ProcessedEpisode> GetMissingEps()
        {
            int           dd  = TVSettings.Instance.WTWRecentDays;
            DirFilesCache dfc = new DirFilesCache();

            return(GetMissingEps(dfc, Library.GetRecentAndFutureEps(dd)));
        }
Example #7
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
            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);
                        }
                    }
                }
            }
Example #11
0
        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
        }
Example #13
0
 public void CheckIfActive(MovieConfiguration si, DirFilesCache dfc, TVDoc.ScanSettings settings)
 {
     if (Active())
     {
         Check(si, dfc, settings);
         LogActionListSummary();
     }
 }
Example #14
0
        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);
        }
Example #15
0
        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);
        }
Example #16
0
        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);
        }
Example #17
0
        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);
        }
Example #18
0
        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);
        }
Example #19
0
        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();
        }
Example #20
0
        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);
        }
Example #21
0
        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);
        }
Example #22
0
        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));
        }
Example #23
0
        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);
        }
Example #24
0
        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);
        }
Example #25
0
        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());
        }
Example #26
0
        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);
        }
Example #27
0
        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());
            }
        }
Example #28
0
        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);
        }
Example #29
0
        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);
        }
Example #30
0
        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);
        }
Example #31
0
        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--;
        }
Example #32
0
        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;
            }
        }
Example #33
0
        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;
        }
Example #34
0
        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;
        }
Example #35
0
        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;
            }

        }
Example #36
0
        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();

        }
Example #37
0
        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();
        }
Example #38
0
 public List<FileInfo> FindEpOnDisk(DirFilesCache dfc, ProcessedEpisode pe)
 {
     return this.FindEpOnDisk(dfc, pe.SI, pe);
 }