public void DoAllActions() { PreventAutoScan("Do all actions"); ItemList theList = new ItemList(); theList.AddRange(TheActionList.Actions()); DoActions(theList); AllowAutoScan(); }
protected override void DoCheck(SetProgressDelegate prog, TVDoc.ScanSettings settings) { returnActions.Clear(); showList = MDoc.TvLibrary.GetSortedShowItems(); //We ignore the current set of shows being scanned to be secrure that no files are deleted for unscanned shows movieList = MDoc.FilmLibrary.GetSortedMovies(); 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, settings.Owner); ReviewDirsInDownloadDirectory(dirPath); } ItemList removeActions = new ItemList(); //Remove any missing items we are planning to resolve foreach (ActionCopyMoveRename acmr in returnActions.OfType <ActionCopyMoveRename>()) { removeActions.AddRange(MDoc.TheActionList.MissingEpisodes.Where(missingItem => missingItem.Episode == acmr.Episode)); removeActions.AddRange(MDoc.TheActionList.MissingMovies.Where(missingItem => missingItem.Movie == acmr.Movie)); } MDoc.TheActionList.Replace(removeActions, returnActions); }
public override void Check(SetProgressDelegate prog, int startpct, int totPct) { prog.Invoke(startpct); ItemList newList = new ItemList(); ItemList toRemove = new ItemList(); int fileCount = 0; foreach (string s in TVSettings.Instance.DownloadFolders) { fileCount += DirCache.CountFiles(s, true); } DirCache dirCache = new DirCache(); foreach (string s in TVSettings.Instance.DownloadFolders) { if (ActionCancel) { return; } dirCache.AddFolder(prog, 0, fileCount, s, true); } int currentItem = 0; int totalN = ActionList.Count; foreach (ItemMissing me in ActionList.MissingItems()) { if (ActionCancel) { return; } prog.Invoke(startpct + ((totPct - startpct) * (++currentItem) / (totalN + 1))); ItemList thisRound = new ItemList(); List <DirCacheEntry> matchedFiles = new List <DirCacheEntry>(); foreach (DirCacheEntry dce in dirCache) { if (!ReviewFile(me, thisRound, dce)) { continue; } matchedFiles.Add(dce); } if (matchedFiles.Count == 1) { if (!OtherActionsMatch(matchedFiles[0], me)) { 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]?.TheFile.FullName} as there are multiple actions for that file"); me.AddComment( $"Ignoring potential match with file {matchedFiles[0]?.TheFile.FullName} as there are multiple actions for that file"); } } else if (matchedFiles.Count > 1) { List <DirCacheEntry> 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 (DirCacheEntry matchedFile in matchedFiles) { LOGGER.Warn( $"Ignoring potential match for {me.Episode.Show.ShowName} S{me.Episode.AppropriateSeasonNumber} E{me.Episode.AppropriateEpNum}: with file {matchedFile?.TheFile.FullName} as there are multiple files for that action"); me.AddComment( $"Ignoring potential match with file {matchedFile?.TheFile.FullName} as there are multiple files for that action"); } } } } if (TVSettings.Instance.KeepTogether) { KeepTogether(newList); } prog.Invoke(totPct); if (!TVSettings.Instance.LeaveOriginals) { // go through and change last of each operation on a given source file to a 'Move' // ideally do that move within same filesystem // sort based on source file, and destination drive, putting last if destdrive == sourcedrive newList.Sort(new ActionItemSorter()); // sort puts all the CopyMoveRenames together // then set the last of each source file to be a move for (int i = 0; i < newList.Count; i++) { ActionCopyMoveRename cmr1 = newList[i] as ActionCopyMoveRename; bool ok1 = cmr1 != null; if (!ok1) { continue; } bool last = i == (newList.Count - 1); ActionCopyMoveRename cmr2 = !last ? newList[i + 1] as ActionCopyMoveRename : null; bool ok2 = cmr2 != null; if (ok2) { ActionCopyMoveRename a1 = cmr1; ActionCopyMoveRename a2 = cmr2; if (!FileHelper.Same(a1.From, a2.From)) { a1.Operation = ActionCopyMoveRename.Op.move; } } else { // last item, or last copymoverename item in the list ActionCopyMoveRename a1 = cmr1; a1.Operation = ActionCopyMoveRename.Op.move; } } } foreach (Item i in toRemove) { ActionList.Remove(i); } foreach (Item i in newList) { ActionList.Add(i); } }
private void CopyFutureDatedFile(FileInfo fi, [NotNull] ProcessedEpisode pep, TVDoc d) { ShowItem si = pep.Show; int seasF = pep.AppropriateSeasonNumber; int epF = pep.AppropriateEpNum; //This episode may be a future dated one - process it now if the settings request that we do and it wont be picked up in a full scan if (!TVSettings.Instance.CopyFutureDatedEpsFromSearchFolders || si.ForceCheckFuture || !si.DoMissingCheck || !TVSettings.Instance.MissingCheck || TVSettings.Instance.PreventMove) { return; } if (!pep.IsInFuture(true)) { return; } Dictionary <int, List <string> > foldersLocations = si.AllProposedFolderLocations(); if (!foldersLocations.ContainsKey(seasF)) { LOGGER.Info( $"Identified that {fi.FullName} matches S{seasF}E{epF} of show {si.ShowName}, but can't tell where to copy it. Not copying across."); return; } LOGGER.Info( $"Identified that {fi.FullName} matches S{seasF}E{epF} of show {si.ShowName}, that it's not already present and airs in the future. Copying across."); List <string> folders = si.AllProposedFolderLocations()[seasF]; foreach (string folder in folders) { if (!Directory.Exists(folder)) { if (TVSettings.Instance.AutoCreateFolders) // Also check || Doc.Args.MissingFolder == CommandLineArgs.MissingFolderBehavior.create { LOGGER.Info($"Want to copy {fi.FullName} to {folder}, but it doesn't exist yet, so creating it"); Directory.CreateDirectory(folder); } else { LOGGER.Warn($"Want to copy {fi.FullName} to {folder}, but it doesn't exist yet"); continue; } } string filename = TVSettings.Instance.FilenameFriendly(TVSettings.Instance.NamingStyle.NameFor(pep, fi.Extension, folder.Length)); FileInfo targetFile = new FileInfo(folder.EnsureEndsWithSeparator() + filename); if (fi.FullName == targetFile.FullName) { continue; } returnActions.Add(new ActionCopyMoveRename(fi, targetFile, pep, d)); // if we're copying/moving a file across, we might also want to make a thumbnail or NFO for it returnActions.AddRange(new DownloadIdentifiersController().ProcessEpisode(pep, targetFile)); } }