public TVDoc([CanBeNull] FileInfo settingsFile, CommandLineArgs args) { Args = args; Library = new ShowLibrary(); CurrentStats = new TVRenameStats(); actionManager = new ActionEngine(CurrentStats); cacheManager = new CacheUpdater(); localFinders = new FindMissingEpisodesLocally(this); downloadFinders = new FindMissingEpisodesDownloading(this); searchFinders = new FindMissingEpisodesSearch(this); mDirty = false; TheActionList = new ItemList(); scanProgDlg = null; downloadIdentifiers = new DownloadIdentifiersController(); LoadOk = (settingsFile is null || LoadXMLSettings(settingsFile)) && TheTVDB.Instance.LoadOk; }
public RenameAndMissingMovieCheck(TVDoc doc) : base(doc) { downloadIdentifiers = new DownloadIdentifiersController(); }
private bool ReviewFile(ItemMissing me, ItemList addTo, DirCacheEntry dce) { if (ActionCancel) { return(true); } int season = me.Episode.AppropriateSeasonNumber; int epnum = me.Episode.AppropriateEpNum; bool matched = false; try { if (FileHelper.IgnoreFile(dce.TheFile)) { return(false); } //do any of the possible names for the series match the filename? matched = (me.Episode.Show.GetSimplifiedPossibleShowNames() .Any(name => FileHelper.SimplifyAndCheckFilename(dce.SimplifiedFullName, name))); if (matched) { bool regularMatch = TVDoc.FindSeasEp(dce.TheFile, out int seasF, out int epF, out int maxEp, me.Episode.Show) && seasF == season && epF == epnum; bool sequentialMatch = me.Episode.Show.UseSequentialMatch && TVDoc.MatchesSequentialNumber(dce.TheFile.Name, ref seasF, ref epF, me.Episode) && seasF == season && epF == epnum; if (regularMatch || sequentialMatch) { if (maxEp != -1 && TVSettings.Instance.AutoMergeDownloadEpisodes) { ShowRule sr = new ShowRule { DoWhatNow = RuleAction.kMerge, First = epF, Second = maxEp }; me.Episode.Show?.AddSeasonRule(seasF, sr); LOGGER.Info( $"Looking at {me.Episode.Show.ShowName} and have identified that episode {epF} and {maxEp} of season {seasF} have been merged into one file {dce.TheFile.FullName}"); LOGGER.Info($"Added new rule automatically for {sr}"); //Regenerate the episodes with the new rule added ShowLibrary.GenerateEpisodeDict(me.Episode.Show); //Get the newly created processed episode we are after // ReSharper disable once InconsistentNaming ProcessedEpisode newPE = me.Episode; foreach (ProcessedEpisode pe in me.Episode.Show.SeasonEpisodes[seasF]) { if (pe.AppropriateEpNum == epF && pe.EpNum2 == maxEp) { newPE = pe; } } me = new ItemMissing(newPE, me.TargetFolder, TVSettings.Instance.FilenameFriendly(TVSettings.Instance.NamingStyle.NameFor(newPE))); } FileInfo fi = new FileInfo(me.TheFileNoExt + dce.TheFile.Extension); if (TVSettings.Instance.PreventMove) { //We do not want to move the file, just rename it fi = new FileInfo(dce.TheFile.DirectoryName + System.IO.Path.DirectorySeparatorChar + me.Filename + dce.TheFile.Extension); } // don't remove the base search folders bool doTidyup = true; foreach (string folder in TVSettings.Instance.DownloadFolders) { if (folder.SameDirectoryLocation(fi.Directory.FullName)) { doTidyup = false; break; } } if (dce.TheFile.FullName != fi.FullName) { addTo.Add(new ActionCopyMoveRename(ActionCopyMoveRename.Op.copy, dce.TheFile, fi, me.Episode, doTidyup ? TVSettings.Instance.Tidyup : null, me)); } DownloadIdentifiersController di = new DownloadIdentifiersController(); // if we're copying/moving a file across, we might also want to make a thumbnail or NFO for it addTo.Add(di.ProcessEpisode(me.Episode, fi)); return(true); } } } catch (System.IO.PathTooLongException e) { string t = "Path too long. " + dce.TheFile.FullName + ", " + e.Message; LOGGER.Warn(e, "Path too long. " + dce.TheFile.FullName); t += ". More information is available in the log file"; if ((!Doc.Args.Unattended) && (!Doc.Args.Hide)) { MessageBox.Show(t, "Path too long", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } t = "DirectoryName " + dce.TheFile.DirectoryName + ", File name: " + dce.TheFile.Name; t += matched ? ", matched. " : ", no match. "; if (matched) { t += "Show: " + me.Episode.TheSeries.Name + ", Season " + season + ", Ep " + epnum + ". "; t += "To: " + me.TheFileNoExt; } LOGGER.Warn(t); } return(false); }
// ReSharper disable once FunctionComplexityOverflow protected bool ReviewFile(ItemMissing me, ItemList addTo, FileInfo dce, TVDoc.ScanSettings settings, bool addMergeRules, bool preventMove, bool doExtraFiles, bool useFullPath) { if (settings.Token.IsCancellationRequested) { return(false); } bool matched = false; try { if (dce.IgnoreFile()) { return(false); } //do any of the possible names for the series match the filename? matched = me.Episode.Show.NameMatch(dce, useFullPath); if (!matched) { return(false); } (bool identifySuccess, int seasF, int epF, int maxEp) = IdentifyFile(me, dce); if (!identifySuccess) { return(false); } if (maxEp != -1 && addMergeRules) { me = UpdateMissingItem(me, dce, epF, maxEp, seasF); } FileInfo fi = new FileInfo(me.TheFileNoExt + dce.Extension); if (preventMove) { //We do not want to move the file, just rename it fi = new FileInfo(dce.DirectoryName + Path.DirectorySeparatorChar + me.Filename + dce.Extension); } if (dce.FullName != fi.FullName && !FindExistingActionFor(addTo, dce)) { // don't remove the base search folders bool doTidyup = !TVSettings.Instance.DownloadFolders.Any(folder => folder.SameDirectoryLocation(fi.Directory.FullName)); addTo.Add(new ActionCopyMoveRename(ActionCopyMoveRename.Op.copy, dce, fi, me.Episode, doTidyup, me, MDoc)); } if (doExtraFiles) { DownloadIdentifiersController di = new DownloadIdentifiersController(); // if we're copying/moving a file across, we might also want to make a thumbnail or NFO for it addTo.Add(di.ProcessEpisode(me.Episode, fi)); } return(true); } catch (PathTooLongException e) { WarnPathTooLong(me, dce, e, matched); } return(false); }
}; // TODO: move into settings, and allow user to edit these public TVDoc(FileInfo settingsFile, CommandLineArgs args) { this.Args = args; this.Ignore = new List<IgnoreItem>(); this.Workers = null; this.WorkerSemaphore = null; this.mStats = new TVRenameStats(); this.mDirty = false; this.TheActionList = new ItemList(); this.MonitorFolders = new List<String>(); this.IgnoreFolders = new List<String>(); this.SearchFolders = new List<String>(); ShowItems = new List<ShowItem>(); this.AddItems = new FolderMonitorEntryList(); this.DownloadDone = true; this.DownloadOK = true; this.ActionCancel = false; this.ScanProgDlg = null; this.Finders = new List<Finder> (); this.Finders.Add(new FileFinder(this)); this.Finders.Add(new RSSFinder(this)); this.Finders.Add(new uTorrentFinder(this)); this.Finders.Add(new SABnzbdFinder(this)); this.LoadOK = ((settingsFile == null) || this.LoadXMLSettings(settingsFile)) && TheTVDB.Instance.LoadOK; this.DownloadIdentifiers = new DownloadIdentifiersController(); UpdateTVDBLanguage(); // StartServer(); }
// consider each of the files, see if it is suitable for series "ser" and episode "epi" // if so, add a rcitem for copy to "fi" public bool FindMissingEp(DirCache dirCache, ItemMissing me, ItemList addTo, ActionCopyMoveRename.Op whichOp) { int season = me.Episode.SeasonNumber; //String ^toName = FilenameFriendly(Settings->NamingStyle->NameFor(me->PE)); int epnum = me.Episode.EpNum; // TODO: find a 'best match', or use first ? foreach (DirCacheEntry dce in dirCache) { if (this.ActionCancel) { return(true); } bool matched = false; try { if (!dce.HasUsefulExtension_NotOthersToo) // not a usefile file extension { continue; } if (TVSettings.Instance.IgnoreSamples && dce.LowerName.Contains("sample") && ((dce.Length / (1024 * 1024)) < TVSettings.Instance.SampleFileMaxSizeMB)) { continue; } //do any of the possible names for the series match the filename? matched = (me.Episode.SI.getSimplifiedPossibleShowNames().Any(name => FileHelper.SimplifyAndCheckFilename(dce.SimplifiedFullName, name))); if (matched) { int seasF; int epF; if ((TVDoc.FindSeasEp(dce.TheFile, out seasF, out epF, me.Episode.SI) && (seasF == season) && (epF == epnum)) || (me.Episode.SI.UseSequentialMatch && TVDoc.MatchesSequentialNumber(dce.TheFile.Name, ref seasF, ref epF, me.Episode) && (seasF == season) && (epF == epnum))) { FileInfo fi = new FileInfo(me.TheFileNoExt + dce.TheFile.Extension); // don't remove the base search folders bool doTidyup = true; foreach (String folder in this.mDoc.SearchFolders) { // http://stackoverflow.com/questions/1794025/how-to-check-whether-2-directoryinfo-objects-are-pointing-to-the-same-directory if (String.Compare(folder.ToLower().TrimEnd('\\'), fi.Directory.FullName.ToLower().TrimEnd('\\'), StringComparison.InvariantCultureIgnoreCase) == 0) { doTidyup = false; break; } } addTo.Add(new ActionCopyMoveRename(whichOp, dce.TheFile, fi, me.Episode, doTidyup ? TVSettings.Instance.Tidyup : null)); DownloadIdentifiersController di = new DownloadIdentifiersController(); // if we're copying/moving a file across, we might also want to make a thumbnail or NFO for it addTo.Add(di.ProcessEpisode(me.Episode, fi)); return(true); } } } catch (System.IO.PathTooLongException e) { string t = "Path too long. " + dce.TheFile.FullName + ", " + e.Message; logger.Warn(e, "Path too long. " + dce.TheFile.FullName); t += ". More information is available in the log file"; if ((!this.mDoc.Args.Unattended) && (!this.mDoc.Args.Hide)) { MessageBox.Show(t, "Path too long", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } t = "DirectoryName " + dce.TheFile.DirectoryName + ", File name: " + dce.TheFile.Name; t += matched ? ", matched. " : ", no match. "; if (matched) { t += "Show: " + me.Episode.TheSeries.Name + ", Season " + season + ", Ep " + epnum + ". "; t += "To: " + me.TheFileNoExt; } logger.Warn(t); } } return(false); }
protected bool ReviewFile(MovieItemMissing me, ItemList addTo, FileInfo dce, TVDoc.ScanSettings settings, bool preventMove, bool doExtraFiles, bool useFullPath) { if (settings.Token.IsCancellationRequested) { return(false); } bool matched = false; try { if (dce.IgnoreFile() || me.Movie is null) { return(false); } //do any of the possible names for the cachedSeries match the filename? matched = me.Show.NameMatch(dce, useFullPath); if (!matched) { return(false); } if (me.Show.LengthNameMatch(dce, useFullPath) != MDoc.FilmLibrary.Movies.MaxOrDefault(m => m.LengthNameMatch(dce, useFullPath), 0)) { int c = 1; return(false); } FileInfo fi = FinderHelper.GenerateTargetName(me, dce); if (preventMove) { //We do not want to move the file, just rename it fi = new FileInfo(dce.DirectoryName.EnsureEndsWithSeparator() + me.Filename + dce.Extension); } if (dce.FullName != fi.FullName && !FindExistingActionFor(addTo, dce)) { // don't remove the base search folders bool doTidyup = !TVSettings.Instance.DownloadFolders.Any(folder => folder.SameDirectoryLocation(fi.Directory.FullName)); addTo.Add(new ActionCopyMoveRename(ActionCopyMoveRename.Op.copy, dce, fi, me.Movie, doTidyup, me, MDoc)); } if (doExtraFiles) { DownloadIdentifiersController di = new DownloadIdentifiersController(); // if we're copying/moving a file across, we might also want to make a thumbnail or NFO for it addTo.Add(di.ProcessMovie(me.MovieConfig, fi)); } return(true); } catch (PathTooLongException e) { WarnPathTooLong(me, dce, e, matched); } return(false); }
// consider each of the files, see if it is suitable for series "ser" and episode "epi" // if so, add a rcitem for copy to "fi" public bool FindMissingEp(DirCache dirCache, ItemMissing me, ItemList addTo, ActionCopyMoveRename.Op whichOp) { string showname = me.Episode.SI.ShowName; int season = me.Episode.SeasonNumber; //String ^toName = FilenameFriendly(Settings->NamingStyle->NameFor(me->PE)); int epnum = me.Episode.EpNum; // TODO: find a 'best match', or use first ? showname = Helpers.SimplifyName(showname); foreach (DirCacheEntry dce in dirCache) { if (this.ActionCancel) return true; bool matched = false; try { if (!dce.HasUsefulExtension_NotOthersToo) // not a usefile file extension continue; if (TVSettings.Instance.IgnoreSamples && dce.LowerName.Contains("sample") && ((dce.Length / (1024 * 1024)) < TVSettings.Instance.SampleFileMaxSizeMB)) continue; matched = Regex.Match(dce.SimplifiedFullName, "\\b" + showname + "\\b", RegexOptions.IgnoreCase).Success; // if we don't match the main name, then test the aliases if (!matched) { foreach (string alias in me.Episode.SI.AliasNames) { string aliasName = Helpers.SimplifyName(alias); matched = Regex.Match(dce.SimplifiedFullName, "\\b" + aliasName + "\\b", RegexOptions.IgnoreCase).Success; if (matched) break; } } if (matched) { int seasF; int epF; if ((TVDoc.FindSeasEp(dce.TheFile, out seasF, out epF, me.Episode.SI) && (seasF == season) && (epF == epnum)) || (me.Episode.SI.UseSequentialMatch && TVDoc.MatchesSequentialNumber(dce.TheFile.Name, ref seasF, ref epF, me.Episode) && (seasF == season) && (epF == epnum))) { FileInfo fi = new FileInfo(me.TheFileNoExt + dce.TheFile.Extension); // don't remove the base search folders bool doTidyup = true; foreach (String folder in this.mDoc.SearchFolders) { // http://stackoverflow.com/questions/1794025/how-to-check-whether-2-directoryinfo-objects-are-pointing-to-the-same-directory if (String.Compare(folder.ToLower().TrimEnd('\\'), fi.Directory.FullName.ToLower().TrimEnd('\\'), StringComparison.InvariantCultureIgnoreCase) == 0) { doTidyup = false; break; } } addTo.Add(new ActionCopyMoveRename(whichOp, dce.TheFile, fi, me.Episode, doTidyup ? TVSettings.Instance.Tidyup : null)); DownloadIdentifiersController di = new DownloadIdentifiersController(); // if we're copying/moving a file across, we might also want to make a thumbnail or NFO for it addTo.Add(di.ProcessEpisode(me.Episode, fi)); return true; } } } catch (System.IO.PathTooLongException e) { string t = "Path too long. " + dce.TheFile.FullName + ", " + e.Message; t += ". Try to display more info?"; DialogResult dr = MessageBox.Show(t, "Path too long", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); if (dr == DialogResult.Yes) { t = "DirectoryName " + dce.TheFile.DirectoryName + ", File name: " + dce.TheFile.Name; t += matched ? ", matched. " : ", no match. "; if (matched) { t += "Show: " + me.Episode.TheSeries.Name + ", Season " + season + ", Ep " + epnum + ". "; t += "To: " + me.TheFileNoExt; } MessageBox.Show(t, "Path too long", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } return false; }