예제 #1
0
        protected override void DoCheck(SetProgressDelegate prog, ICollection <ShowItem> shows, TVDoc.ScanSettings settings)
        {
            returnActions   = new List <Item>();
            showList        = MDoc.Library.GetShowItems(); //We ignore the current set of shows being scanned to be secrure that no files are deleted for unscanned shows
            currentSettings = 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

            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) || currentSettings.Token.IsCancellationRequested)
                {
                    continue;
                }

                filesThatMayBeNeeded = new List <FileInfo>();

                ReviewFilesInDownloadDirectory(dirPath);
                ReviewDirsInDownloadDirectory(dirPath);
            }

            MDoc.TheActionList.AddNullableRange(returnActions);
        }
예제 #2
0
        protected override void DoCheck(SetProgressDelegate prog, TVDoc.ScanSettings settings)
        {
            BulkAddSeriesManager bam = new BulkAddSeriesManager(MDoc);

            bam.CheckFolders(settings.Token, prog, false, !settings.Unattended);
            AskUserAboutShows(settings, bam);

            if (!bam.AddItems.Any(s => s.CodeKnown))
            {
                return;
            }

            var idsToAdd = bam.AddItems.Where(s => s.CodeKnown).Select(folder => new { Code = folder.ProviderCode, folder.Provider }).ToList();

            bam.AddAllToMyShows();
            List <ShowConfiguration> addedShows = idsToAdd.Select(s => MDoc.TvLibrary.GetShowItem(s.Code, s.Provider)).ToList();

            //add each new show into the shows being scanned
            foreach (ShowConfiguration si in addedShows)
            {
                settings.Shows.Add(si);
            }
            LOGGER.Info("Added new shows called: {0}", addedShows.Select(si => si.ShowName).ToCsv());

            MDoc.TvAddedOrEdited(true, settings.Unattended, settings.Hidden, settings.Owner, addedShows);
        }
예제 #3
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;
                }
            }
        }
예제 #4
0
        protected override void DoCheck(SetProgressDelegate prog, TVDoc.ScanSettings settings)
        {
            // have a look around for any missing episodes
            List <Finder> appropriateFinders      = finders.Where(f => f.DisplayType() == CurrentType() && f.Active()).ToList();
            int           currentMatchingFinderId = 0;
            int           totalMatchingFinders    = appropriateFinders.Count;

            foreach (Finder f in appropriateFinders)
            {
                if (settings.Token.IsCancellationRequested)
                {
                    return;
                }

                if (!MDoc.TheActionList.Missing.Any())
                {
                    continue;
                }

                f.ActionList = MDoc.TheActionList;

                currentMatchingFinderId++;
                int startPos = 100 * (currentMatchingFinderId - 1) / totalMatchingFinders;
                int endPos   = 100 * currentMatchingFinderId / totalMatchingFinders;
                f.Check(prog, startPos, endPos, settings);
            }
        }
예제 #5
0
        protected override void DoCheck(SetProgressDelegate prog, TVDoc.ScanSettings settings)
        {
            BulkAddSeriesManager bam = new BulkAddSeriesManager(MDoc);

            bam.CheckFolders(settings.Token, prog, false, !settings.Unattended);
            AskUserAboutShows(settings, bam);

            if (!bam.AddItems.Any(s => s.CodeKnown))
            {
                return;
            }

            List <int> idsToAdd = bam.AddItems.Where(s => s.CodeKnown).Select(folder => folder.TVDBCode).ToList();

            bam.AddAllToMyShows();

            MDoc.SetDirty();
            MDoc.DoDownloadsFG(settings.Unattended, settings.Hidden, settings.Owner);

            List <ShowConfiguration> addedShows = idsToAdd.Select(s => MDoc.TvLibrary.GetShowItem(s)).ToList();

            //add each new show into the shows being scanned
            foreach (ShowConfiguration si in addedShows)
            {
                settings.Shows.Add(si);
            }
            LOGGER.Info("Added new shows called: {0}", addedShows.Select(si => si.ShowName).ToCsv());

            MDoc.DoWhenToWatch(true, settings.Unattended, settings.Hidden, settings.Owner);

            MDoc.WriteUpcoming();
            MDoc.WriteRecent();
        }
예제 #6
0
        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 void ProcessFolder(TVDoc.ScanSettings settings, [NotNull] ItemMissing me, [NotNull] string folderName, [NotNull] DirFilesCache dfc,
                                   ItemList thisRound, [NotNull] List <FileInfo> matchedFiles)
        {
            LOGGER.Info($"Starting to look for {me.Filename} in the library folder: {folderName}");
            FileInfo[] files = dfc.GetFiles(folderName);
            if (files is null)
            {
                return;
            }

            foreach (FileInfo testFile in files)
            {
                if (!ReviewFile(me, thisRound, testFile, settings, false, false, false,
                                TVSettings.Instance.UseFullPathNameToMatchLibraryFolders))
                {
                    continue;
                }

                if (!matchedFiles.Contains(testFile))
                {
                    matchedFiles.Add(testFile);
                    LOGGER.Info($"Found {me.Filename} at: {testFile}");
                }
            }
        }
        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
        }
예제 #9
0
        protected override void DoCheck(SetProgressDelegate prog, TVDoc.ScanSettings settings)
        {
            if (TVSettings.Instance.SearchJSONManualScanOnly && settings.Unattended)
            {
                LOGGER.Info("Searching JSON Wepages is cancelled as this is an unattended scan");
                return;
            }
            int c = ActionList.Missing.Count + 1;
            int n = 0;

            UpdateStatus(n, c, "Searching on JSON Page...");

            ItemList newItems = new ItemList();
            ItemList toRemove = new ItemList();
            UrlCache cache    = new UrlCache();

            try
            {
                foreach (ShowItemMissing action in ActionList.MissingEpisodes.ToList())
                {
                    if (settings.Token.IsCancellationRequested)
                    {
                        return;
                    }

                    UpdateStatus(n++, c, action.Filename);

                    FindMissingEpisode(action, toRemove, newItems, cache);
                }
            }
            catch (WebException e)
            {
                LOGGER.LogWebException(
                    $"Failed to access: {TVSettings.Instance.SearchJSONURL} got the following message:", e);
            }
            catch (AggregateException aex) when(aex.InnerException is WebException ex)
            {
                LOGGER.LogWebException(
                    $"Failed to access: {TVSettings.Instance.SearchJSONURL} got the following message:", ex);
            }
            catch (AggregateException ex) when(ex.InnerException is HttpRequestException hex)
            {
                LOGGER.LogHttpRequestException($"Could not download RSS page at: {TVSettings.Instance.SearchJSONURL} got the following message: ", hex);
            }
            catch (HttpRequestException htec) when(htec.InnerException is WebException ex)
            {
                LOGGER.LogWebException(
                    $"Failed to access: {TVSettings.Instance.SearchJSONURL} got the following message:", ex);
            }
            catch (HttpRequestException htec)
            {
                LOGGER.Warn($"Failed to access: {TVSettings.Instance.SearchJSONURL} got the following message: {htec.Message}");
            }
            catch (JsonReaderException ex)
            {
                LOGGER.Warn(ex, $"Failed to Parse {TVSettings.Instance.SearchJSONURL} into JSON - Please check that the URL is valid JSON format.");
            }
            ActionList.Replace(toRemove, newItems);
        }
예제 #10
0
 public void CheckIfActive(MovieConfiguration si, DirFilesCache dfc, TVDoc.ScanSettings settings)
 {
     if (Active())
     {
         Check(si, dfc, settings);
         LogActionListSummary();
     }
 }
예제 #11
0
        protected override void DoCheck(SetProgressDelegate prog, TVDoc.ScanSettings settings)
        {
            if (settings.Unattended && TVSettings.Instance.SearchJackettManualScanOnly)
            {
                LOGGER.Info("Searching Jackett is cancelled as this is an unattended scan");
                return;
            }

            if (settings.Type == TVSettings.ScanType.Full && TVSettings.Instance.StopJackettSearchOnFullScan && settings.Shows.Any())
            {
                LOGGER.Info("Searching Jackett is cancelled as this is a full scan");
                return;
            }

            int c = ActionList.Missing.Count + 2;
            int n = 1;

            UpdateStatus(n, c, "Searching with Jackett...");

            ItemList newItems = new ItemList();
            ItemList toRemove = new ItemList();

            try
            {
                foreach (ItemMissing action in ActionList.Missing.ToList())
                {
                    if (settings.Token.IsCancellationRequested)
                    {
                        return;
                    }

                    UpdateStatus(n++, c, action.Filename);

                    if (action is ShowItemMissing showItemMissing)
                    {
                        FindMissingEpisode(showItemMissing, toRemove, newItems);
                    }
                    else
                    {
                        FindMissingEpisode((MovieItemMissing)action, toRemove, newItems);
                    }
                }
            }
            catch (WebException e)
            {
                LOGGER.LogWebException($"Failed to access: {e.Response.ResponseUri} got the following message:", e);
            }
            catch (AggregateException aex) when(aex.InnerException is WebException ex)
            {
                LOGGER.LogWebException($"Failed to access: {ex.Response.ResponseUri} got the following message:", ex);
            }
            catch (HttpRequestException htec) when(htec.InnerException is WebException ex)
            {
                LOGGER.LogWebException($"Failed to access: {ex.Response.ResponseUri} got the following message:", ex);
            }

            ActionList.Replace(toRemove, newItems);
        }
예제 #12
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);
        }
        protected override void DoCheck(SetProgressDelegate prog,
                                        TVDoc.ScanSettings settings)
        {
            //for each directory in settings directory
            //for each file in directory
            //for each saved show (order by recent)
            //does show match selected file?
            //if so add cachedSeries to list of cachedSeries scanned
            if (!Active())
            {
                LOGGER.Info("Not looking for new media as 'Auto-Add' is turned off");
                return;
            }

            //Don't support unattended mode
            if (settings.Unattended || settings.Hidden)
            {
                LOGGER.Info("Not looking for new media as app is unattended");
                return;
            }

            IEnumerable <FileInfo>    possibleShowNames = GetPossibleShowNameStrings();
            List <MediaConfiguration> addedShows        = FinderHelper.FindMedia(possibleShowNames, MDoc, settings.Owner);

            IEnumerable <ShowConfiguration> addedTVShows = addedShows.OfType <ShowConfiguration>();

            if (addedTVShows.Any())
            {
                MDoc.TvLibrary.AddRange(addedTVShows);
                MDoc.ShowAddedOrEdited(false, false, false, settings.Owner);
                MDoc.ShowAddedOrEdited(true, false, false, settings.Owner);
                //add each new show into the shows being scanned
                foreach (ShowConfiguration si in addedTVShows)
                {
                    settings.Shows.Add(si);
                }
                LOGGER.Info("Added new shows called: {0}", addedTVShows.Select(s => s.ShowName).ToCsv());
            }


            IEnumerable <MovieConfiguration> addedMovies = addedShows.OfType <MovieConfiguration>();

            if (addedMovies.Any())
            {
                MDoc.FilmLibrary.AddRange(addedMovies);
                MDoc.MovieAddedOrEdited(false, false, false, settings.Owner);
                MDoc.MovieAddedOrEdited(true, false, false, settings.Owner);

                foreach (MovieConfiguration si in addedMovies)
                {
                    settings.Movies.Add(si);
                }
                LOGGER.Info("Added new movies called: {0}", addedMovies.Select(s => s.ShowName).ToCsv());
            }
        }
예제 #14
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);
        }
예제 #15
0
        protected override void DoCheck(SetProgressDelegate prog, TVDoc.ScanSettings settings)
        {
            List <TorrentEntry>?downloading = source.GetTorrentDownloads();

            if (downloading is null)
            {
                LOGGER.Warn($"Failed to get current downloads from {source.Name()}");
                return;
            }
            SearchForAppropriateDownloads(downloading, DownloadApp.qBitTorrent, settings);
        }
예제 #16
0
        protected override void DoCheck(SetProgressDelegate prog, TVDoc.ScanSettings settings)
        {
            if (TVSettings.Instance.SearchRSSManualScanOnly && settings.Unattended)
            {
                LOGGER.Info("Searching RSS Feeds is cancelled as this is an unattended scan");
                return;
            }
            int c = ActionList.Missing.Count + 2;
            int n = 1;

            UpdateStatus(n, c, "Searching on RSS Feed...");

            // ReSharper disable once InconsistentNaming
            RssItemList RSSList = new RssItemList();

            foreach (string s in TVSettings.Instance.RSSURLs)
            {
                RSSList.DownloadRSS(s, TVSettings.Instance.RSSUseCloudflare, "RSS");
            }

            ItemList newItems = new ItemList();
            ItemList toRemove = new ItemList();

            foreach (ShowItemMissing action in ActionList.MissingEpisodes.ToList())
            {
                if (settings.Token.IsCancellationRequested)
                {
                    return;
                }

                UpdateStatus(n++, c, action.Filename);

                ProcessedEpisode pe = action.MissingEpisode;
                ItemList         newItemsForThisMissingEpisode = new ItemList();

                foreach (RSSItem rss in RSSList.Where(rss => RssMatch(rss, pe)))
                {
                    LOGGER.Info(
                        $"Adding {rss.URL} from RSS feed as it appears to be match for {pe.Show.ShowName} {pe}");

                    ItemDownloading eventualItem = new ItemDownloading(new FutureTorrentEntry(rss.URL, action.TheFileNoExt), action.MissingEpisode, action.TheFileNoExt, DownloadingFinder.DownloadApp.qBitTorrent, action);
                    newItemsForThisMissingEpisode.Add(new ActionTDownload(rss, action, eventualItem));
                    toRemove.Add(action);
                }

                foreach (ActionTDownload x in FindDuplicates(newItemsForThisMissingEpisode))
                {
                    newItemsForThisMissingEpisode.Remove(x);
                }

                newItems.AddNullableRange(newItemsForThisMissingEpisode);
            }
            ActionList.Replace(toRemove, newItems);
        }
예제 #17
0
        private void AskUserAboutShows(TVDoc.ScanSettings settings, [NotNull] BulkAddSeriesManager bam)
        {
            foreach (PossibleNewTvShow folder in bam.AddItems)
            {
                if (settings.Token.IsCancellationRequested)
                {
                    break;
                }

                AskUserAboutShow(folder, settings.Owner);
            }
        }
예제 #18
0
        private void AskUserAboutShows(TVDoc.ScanSettings settings, [NotNull] BulkAddManager bam)
        {
            foreach (FoundFolder folder in bam.AddItems)
            {
                if (settings.Token.IsCancellationRequested)
                {
                    break;
                }

                AskUserAboutShow(folder);
            }
        }
예제 #19
0
        protected override void DoCheck(SetProgressDelegate prog, ICollection <ShowItem> showList,
                                        TVDoc.ScanSettings settings)
        {
            ItemList newList  = new ItemList();
            ItemList toRemove = new ItemList();

            int fileCount = CountFilesInDownloadDirs();

            DirCache dirCache = new DirCache();

            foreach (string s in TVSettings.Instance.DownloadFolders.ToList())
            {
                if (settings.Token.IsCancellationRequested)
                {
                    return;
                }

                dirCache.AddFolder(prog, 0, fileCount, s, true);
            }

            int currentItem = 0;
            int totalN      = ActionList.MissingItems().Count() + 1;

            UpdateStatus(currentItem, totalN, "Starting searching through files");

            foreach (ItemMissing me in ActionList.MissingItems().ToList())
            {
                if (settings.Token.IsCancellationRequested)
                {
                    return;
                }

                UpdateStatus(currentItem++, totalN, me.Filename);

                ItemList        thisRound    = new ItemList();
                List <FileInfo> matchedFiles = FindMatchedFiles(settings, dirCache, me, thisRound);

                ProcessMissingItem(settings, newList, toRemove, me, thisRound, matchedFiles, TVSettings.Instance.UseFullPathNameToMatchSearchFolders);
            }

            if (TVSettings.Instance.KeepTogether)
            {
                KeepTogether(newList, false);
            }

            if (!TVSettings.Instance.LeaveOriginals)
            {
                ReorganiseToLeaveOriginals(newList);
            }

            ActionList.Replace(toRemove, newList);
        }
예제 #20
0
        protected override void DoCheck(SetProgressDelegate prog, TVDoc.ScanSettings settings)
        {
            if (string.IsNullOrEmpty(TVSettings.Instance.SABAPIKey) || string.IsNullOrEmpty(TVSettings.Instance.SABHostPort))
            {
                LOGGER.Warn("Searching SABnzbd Feeds is cancelled as the key and host/port are not provided in Preferences.");
                return;
            }

            // get list of files being downloaded by SABnzbd
            XElement x = GetSabDownload(TVSettings.Instance.SABHostPort, TVSettings.Instance.SABAPIKey);

            if (x is null)
            {
                return;
            }

            ItemList newList  = new ItemList();
            ItemList toRemove = new ItemList();
            int      c        = ActionList.Missing.Count + 1;
            int      n        = 0;

            foreach (ShowItemMissing action in ActionList.MissingEpisodes.ToList())
            {
                if (settings.Token.IsCancellationRequested)
                {
                    return;
                }

                UpdateStatus(n++, c, action.Filename);

                if (action.Episode?.Show is null)
                {
                    continue;
                }

                string simpleShowName = Helpers.SimplifyName(action.Episode.Show.ShowName);

                if (string.IsNullOrWhiteSpace(simpleShowName))
                {
                    continue;
                }

                foreach (QueueSlotsSlot te in x.Descendants("slots").Select(slot => CreateQueueSlotsSlot(slot, simpleShowName, action)).Where(te => !(te is null)))
                {
                    toRemove.Add(action);
                    newList.Add(new ItemDownloading(te, action.Episode, action.TheFileNoExt, DownloadApp.SABnzbd, action));
                    break;
                }
            }

            ActionList.Replace(toRemove, newList);
        }
예제 #21
0
        protected override void Check(ShowConfiguration si, DirFilesCache dfc, TVDoc.ScanSettings settings)
        {
            Dictionary <int, SafeList <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.ActiveSeasons.Keys())
            {
                if (settings.Token.IsCancellationRequested)
                {
                    return;
                }

                if (!allFolders.ContainsKey(snum))
                {
                    continue;
                }

                // all the folders for this particular season
                SafeList <string> folders = allFolders[snum];

                CheckSeason(si, dfc, settings, snum, folders, timeForBannerUpdate);
            } // for each season of this show
        }
예제 #22
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);
        }
예제 #23
0
        protected void ProcessMissingItem(TVDoc.ScanSettings settings, ItemList newList, ItemList toRemove, ItemMissing me, ItemList thisRound, [NotNull] List <FileInfo> matchedFiles, bool useFullPath)
        {
            if (matchedFiles.Count == 1)
            {
                if (!OtherActionsMatch(matchedFiles[0], me, settings, useFullPath))
                {
                    if (!FinderHelper.BetterShowsMatch(matchedFiles[0], me.Episode.Show, useFullPath, MDoc))
                    {
                        toRemove.Add(me);
                        newList.AddRange(thisRound);
                    }
                    else
                    {
                        LOGGER.Warn($"Ignoring potential match for {me.Episode.Show.ShowName} S{me.Episode.AppropriateSeasonNumber} E{me.Episode.AppropriateEpNum}: with file {matchedFiles[0]?.FullName} as there are multiple shows that match for that file");
                        me.AddComment(
                            $"Ignoring potential match with file {matchedFiles[0]?.FullName} as there are multiple shows for that file");
                    }
                }
                else
                {
                    LOGGER.Warn($"Ignoring potential match for {me.Episode.Show.ShowName} S{me.Episode.AppropriateSeasonNumber} E{me.Episode.AppropriateEpNum}: with file {matchedFiles[0]?.FullName} as there are multiple actions for that file");
                    me.AddComment(
                        $"Ignoring potential match with file {matchedFiles[0]?.FullName} as there are multiple actions for that file");
                }
            }

            if (matchedFiles.Count > 1)
            {
                List <FileInfo> bestMatchedFiles = IdentifyBestMatches(matchedFiles);

                if (bestMatchedFiles.Count == 1)
                {
                    //We have one file that is better, lets use it
                    toRemove.Add(me);
                    newList.AddRange(thisRound);
                }
                else
                {
                    foreach (FileInfo matchedFile in matchedFiles)
                    {
                        LOGGER.Warn(
                            $"Ignoring potential match for {me.Episode.Show.ShowName} S{me.Episode.AppropriateSeasonNumber} E{me.Episode.AppropriateEpNum}: with file {matchedFile?.FullName} as there are multiple files for that action");

                        me.AddComment(
                            $"Ignoring potential match with file {matchedFile?.FullName} as there are multiple files for that action");
                    }
                }
            }
        }
예제 #24
0
        private List <FileInfo> FindMatchedFiles(TVDoc.ScanSettings settings, [NotNull] DirCache dirCache, ItemMissing me, ItemList thisRound)
        {
            List <FileInfo> matchedFiles = new List <FileInfo>();

            foreach (DirCacheEntry dce in dirCache)
            {
                if (!ReviewFile(me, thisRound, dce.TheFile, settings, TVSettings.Instance.AutoMergeDownloadEpisodes, TVSettings.Instance.PreventMove, true, TVSettings.Instance.UseFullPathNameToMatchSearchFolders))
                {
                    continue;
                }

                matchedFiles.Add(dce.TheFile);
            }

            return(matchedFiles);
        }
예제 #25
0
        protected override void DoCheck(SetProgressDelegate prog, ICollection <ShowItem> shows, TVDoc.ScanSettings settings)
        {
            returnActions   = new ItemList();
            showList        = MDoc.Library.GetShowItems(); //We ignore the current set of shows being scanned to be secrure that no files are deleted for unscanned shows
            currentSettings = 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

            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) || currentSettings.Token.IsCancellationRequested)
                {
                    continue;
                }

                filesThatMayBeNeeded = new List <FileInfo>();

                ReviewFilesInDownloadDirectory(dirPath);
                ReviewDirsInDownloadDirectory(dirPath);
            }

            ItemList removeActions = new ItemList();

            //Remove any missing items we are planning to resolve
            foreach (ActionCopyMoveRename acmr in returnActions.OfType <ActionCopyMoveRename>())
            {
                foreach (ItemMissing missingItem in MDoc.TheActionList.MissingItems())
                {
                    if (missingItem.Episode == acmr.Episode)
                    {
                        removeActions.Add(missingItem);
                    }
                }
            }

            MDoc.TheActionList.Replace(removeActions, returnActions);
        }
예제 #26
0
        protected override void Check(MovieConfiguration si, DirFilesCache dfc, TVDoc.ScanSettings settings)
        {
            List <string> allFolders = si.Locations.ToList();

            if (allFolders.Count == 0) // no folders defined for this show
            {
                return;                // so, nothing to do.
            }

            // process each folder for show...
            foreach (string folder in allFolders)
            {
                if (settings.Token.IsCancellationRequested)
                {
                    return;
                }

                CheckMovieFolder(si, dfc, settings, folder);
            }
        }
예제 #27
0
        private void CheckSeason([NotNull] ShowConfiguration si, DirFilesCache dfc, TVDoc.ScanSettings settings, int snum, [NotNull] SafeList <string> folders, bool timeForBannerUpdate)
        {
            bool folderNotDefined = folders.Count == 0;

            if (folderNotDefined && TVSettings.Instance.MissingCheck && !si.AutoAddNewSeasons())
            {
                return;
            }

            // base folder:
            if (!string.IsNullOrEmpty(si.AutoAddFolderBase) && si.AutoAddType != ShowConfiguration.AutomaticFolderType.none)
            {
                // main image for the folder itself
                Doc.TheActionList.Add(downloadIdentifiers.ProcessShow(si));
            }

            foreach (string folder in folders)
            {
                CheckSeasonFolder(si, dfc, settings, snum, timeForBannerUpdate, folder);
            } // for each folder for this season of this show
        }
예제 #28
0
        private bool OtherActionsMatch(FileInfo matchedFile, Item me, TVDoc.ScanSettings settings, bool useFullPath)
        //This is used to check whether the selected file may match any other files we are looking for
        {
            foreach (ItemMissing testMissingAction in ActionList.MissingItems().ToList())
            {
                if (testMissingAction.SameAs(me))
                {
                    continue;
                }

                if (ReviewFile(testMissingAction, new ItemList(), matchedFile, settings, false, false, false, useFullPath))
                {
                    //We have 2 options that match  me and testAction - See whether one is subset of the other
                    if (me.Episode.Show.ShowName.Contains(testMissingAction.Episode.Show.ShowName))
                    {
                        continue; //'me' is a better match, so don't worry about the new one
                    }

                    return(true);
                }
            }
            return(false);
        }
        protected override void Check(MovieConfiguration movie, DirFilesCache dfc, TVDoc.ScanSettings settings)
        {
            if (!movie.DoMissingCheck && !movie.DoRename)
            {
                return; // skip
            }

            if (TVSettings.Instance.IgnorePreviouslySeenMovies)
            {
                if (TVSettings.Instance.PreviouslySeenMovies.Includes(movie))
                {
                    return;
                }
            }

            List <string> folders = movie.Locations.ToList();

            List <string> ignoredLocations = new List <string>();

            foreach (string folderExists in folders)
            {
                CreateFolder(movie, ignoredLocations, folderExists, settings.Owner);
            } // for each folder
        }
예제 #30
0
        protected override void Check(ShowItem si, DirFilesCache dfc, TVDoc.ScanSettings settings)
        {
            if (settings.Token.IsCancellationRequested)
            {
                throw new TVRenameOperationInterruptedException();
            }

            if (!Active())
            {
                return;
            }

            Dictionary <int, List <string> > allFolders = si.AllExistngFolderLocations();

            if (allFolders.Count == 0) // no folders defined for this show
            {
                return;                // so, nothing to do.
            }

            // process each folder for each season...
            foreach (int snum in si.GetSeasonKeys())
            {
                if (settings.Token.IsCancellationRequested)
                {
                    throw new TVRenameOperationInterruptedException();
                }

                if (si.IgnoreSeasons.Contains(snum) || !allFolders.ContainsKey(snum))
                {
                    continue;
                }

                // all the folders for this particular season
                MergeShowEpisodes(si, dfc, settings.Token, snum, allFolders[snum]);
            } // for each season of this show
        }