protected void SearchForAppropriateDownloads(List <TorrentEntry> downloading, DownloadApp tApp, TVDoc.ScanSettings settings) { ItemList newList = new ItemList(); ItemList toRemove = new ItemList(); int c = ActionList.Missing.Count + 2; int n = 1; UpdateStatus(n, c, "Searching torrent queue..."); foreach (ItemMissing?action in ActionList.Missing.ToList()) { if (settings.Token.IsCancellationRequested) { return; } UpdateStatus(n++, c, action.Filename); foreach (TorrentEntry te in downloading) { FileInfo file = new FileInfo(te.DownloadingTo); if (!file.IsMovieFile() && file.Extension != ".rar") // not a usefile file extension { continue; } if (action is ShowItemMissing showMissingAction) { //do any of the possible names for the cachedSeries match the filename? ProcessedEpisode episode = showMissingAction.MissingEpisode; bool matched = episode.Show.NameMatch(file, true); if (!matched) { continue; } if (FinderHelper.FindSeasEp(file, out int seasF, out int epF, out int _, episode.Show) && seasF == episode.AppropriateSeasonNumber && epF == episode.AppropriateEpNum) { toRemove.Add(action); newList.Add(new ItemDownloading(te, episode, action.TheFileNoExt, tApp, action)); break; } } if (action is MovieItemMissing movieMissingAction) { //do any of the possible names for the cachedSeries match the filename? MovieConfiguration movie = movieMissingAction.MovieConfig; bool matched = movie.NameMatch(file, true); if (!matched) { continue; } toRemove.Add(action); newList.Add(new ItemDownloading(te, movie, action.TheFileNoExt, tApp, action)); break; } } } ActionList.Replace(toRemove, newList); }
public void DoActions(ItemList theList) { actionManager.DoActions(theList, !Args.Hide && Environment.UserInteractive); new CleanUpEmptyLibraryFolders(this).Check(null); }
public override void Check(SetProgressDelegate prog, int startpct, int totPct) { int c = this.ActionList.Count + 2; int n = 1; prog.Invoke(startpct); // ReSharper disable once InconsistentNaming RSSItemList RSSList = new RSSItemList(); foreach (string s in TVSettings.Instance.RSSURLs) { RSSList.DownloadRSS(s, TVSettings.Instance.FNPRegexs); } ItemList newItems = new ItemList(); ItemList toRemove = new ItemList(); foreach (Item testItem in this.ActionList) { if (this.ActionCancel) { return; } prog.Invoke(startpct + ((totPct - startpct) * (++n) / (c))); if (!(testItem is ItemMissing action)) { continue; } ProcessedEpisode pe = action.Episode; string simpleShowName = Helpers.SimplifyName(pe.SI.ShowName); string simpleSeriesName = Helpers.SimplifyName(pe.TheSeries.Name); foreach (RSSItem rss in RSSList) { if ( !FileHelper.SimplifyAndCheckFilename(rss.ShowName, simpleShowName, true, false) && !( string.IsNullOrEmpty(rss.ShowName) && FileHelper.SimplifyAndCheckFilename(rss.Title, simpleSeriesName, true, false) ) ) { continue; } if (rss.Season != pe.AppropriateSeasonNumber) { continue; } if (rss.Episode != pe.AppropriateEpNum) { continue; } Logger.Info($"Adding {rss.URL} as it appears to be match for {testItem.Episode.SI.ShowName} S{testItem.Episode.AppropriateSeasonNumber}E{testItem.Episode.AppropriateEpNum}"); newItems.Add(new ActionRSS(rss, action.TheFileNoExt, pe)); toRemove.Add(testItem); } } //We now want to rationlise the newItems - just in case we've added duplicates List <ActionRSS> duplicateActionRSS = new List <ActionRSS>(); foreach (Item x in newItems) { if (!(x is ActionRSS testActionRSSOne)) { continue; } foreach (Item y in newItems) { if (!(y is ActionRSS testActionRSSTwo)) { continue; } if (x.Equals(y)) { continue; } string[] preferredTerms = TVSettings.Instance.PreferredRSSSearchTerms(); if (testActionRSSOne.RSS.ShowName.ContainsOneOf(preferredTerms) && !testActionRSSTwo.RSS.ShowName.ContainsOneOf(preferredTerms)) { duplicateActionRSS.Add(testActionRSSTwo); Logger.Info($"Removing {testActionRSSTwo.RSS.URL} as it is not as good a match as {testActionRSSOne.RSS.URL }"); } if (testActionRSSOne.RSS.Title.ContainsOneOf(preferredTerms) && !testActionRSSTwo.RSS.Title.ContainsOneOf(preferredTerms)) { duplicateActionRSS.Add(testActionRSSTwo); Logger.Info( $"Removing {testActionRSSTwo.RSS.URL} as it is not as good a match as {testActionRSSOne.RSS.URL}"); } } } foreach (ActionRSS x in duplicateActionRSS) { newItems.Remove(x); } foreach (Item i in toRemove) { this.ActionList.Remove(i); } foreach (Item action in newItems) { this.ActionList.Add(action); } prog.Invoke(totPct); }
public override void Check(SetProgressDelegate prog, int startpct, int totPct) { int c = ActionList.Count + 2; int n = 1; prog.Invoke(startpct); ItemList newItems = new ItemList(); ItemList toRemove = new ItemList(); try { foreach (ItemMissing action in ActionList.MissingItems()) { if (ActionCancel) { return; } prog.Invoke(startpct + ((totPct - startpct) * (++n) / (c))); ProcessedEpisode pe = action.Episode; string simpleShowName = Helpers.SimplifyName(action.Episode.Show.ShowName); string simpleSeriesName = Helpers.SimplifyName(action.Episode.TheSeries.Name); string imdbId = action.Episode.TheSeries.GetImdbNumber(); if (string.IsNullOrWhiteSpace(imdbId)) { continue; } WebClient client = new WebClient(); client.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"); string response = client.DownloadString($"{TVSettings.Instance.SearchJSONURL}{imdbId}"); JObject jsonResponse = JObject.Parse(response); if (jsonResponse.ContainsKey(TVSettings.Instance.SearchJSONRootNode)) { foreach (JToken item in jsonResponse[TVSettings.Instance.SearchJSONRootNode]) { if (item != null && item is JObject episodeResponse) { if (episodeResponse.ContainsKey(TVSettings.Instance.SearchJSONFilenameToken) && episodeResponse.ContainsKey(TVSettings.Instance.SearchJSONURLToken)) { string itemName = (string)item[TVSettings.Instance.SearchJSONFilenameToken]; string itemUrl = (string)item[TVSettings.Instance.SearchJSONURLToken]; if (TVSettings.Instance.DetailedRSSJSONLogging) { LOGGER.Info("Processing JSON Item"); LOGGER.Info(episodeResponse.ToString); LOGGER.Info("Extracted"); LOGGER.Info($"Name: {itemName}"); LOGGER.Info($"URL: {itemUrl}"); } if (!FileHelper.SimplifyAndCheckFilename(itemName, simpleShowName, true, false) && !FileHelper.SimplifyAndCheckFilename(itemName, simpleSeriesName, true, false)) { continue; } if (!TVDoc.FindSeasEp(itemName, out int seas, out int ep, out int _, action.Episode.Show)) { continue; } if (TVSettings.Instance.DetailedRSSJSONLogging) { LOGGER.Info($"Season: {seas}"); LOGGER.Info($"Episode: {ep}"); } if (seas != pe.AppropriateSeasonNumber) { continue; } if (ep != pe.AppropriateEpNum) { continue; } LOGGER.Info( $"Adding {itemUrl} as it appears to be match for {pe.Show.ShowName} S{pe.AppropriateSeasonNumber}E{pe.AppropriateEpNum}"); newItems.Add(new ActionTDownload(itemName, itemUrl, action.TheFileNoExt, pe)); toRemove.Add(action); } else { LOGGER.Info( $"{TVSettings.Instance.SearchJSONFilenameToken} or {TVSettings.Instance.SearchJSONURLToken} not found in {TVSettings.Instance.SearchJSONURL}{imdbId} for {action.Episode.TheSeries.Name}"); } } } } else { LOGGER.Info( $"{TVSettings.Instance.SearchJSONRootNode} not found in {TVSettings.Instance.SearchJSONURL}{imdbId} for {action.Episode.TheSeries.Name}"); } } } catch (WebException ex) { LOGGER.Info(ex, $"Failed to Access {TVSettings.Instance.SearchJSONURL}"); } foreach (ActionTDownload x in FindDuplicates(newItems)) { newItems.Remove(x); } foreach (Item i in toRemove) { ActionList.Remove(i); } foreach (Item action in newItems) { ActionList.Add(action); } prog.Invoke(totPct); }
private static void FindMissingEpisode([NotNull] ShowItemMissing action, ItemList toRemove, ItemList newItems, UrlCache cache) { ProcessedEpisode pe = action.MissingEpisode; string imdbId = pe.TheCachedSeries.GetImdbNumber(); if (string.IsNullOrWhiteSpace(imdbId)) { return; } string simpleShowName = Helpers.SimplifyName(pe.Show.ShowName); string simpleSeriesName = Helpers.SimplifyName(pe.TheCachedSeries.Name); ItemList newItemsForThisMissingEpisode = new ItemList(); string response = cache.GetUrl($"{TVSettings.Instance.SearchJSONURL}{imdbId}", TVSettings.Instance.SearchJSONUseCloudflare); if (string.IsNullOrWhiteSpace(response)) { LOGGER.Warn( $"Got no response from {TVSettings.Instance.SearchJSONURL}{imdbId} for {action.MissingEpisode.TheCachedSeries.Name}"); return; } JObject jsonResponse = JObject.Parse(response); if (jsonResponse.ContainsKey(TVSettings.Instance.SearchJSONRootNode)) { JToken?x = jsonResponse[TVSettings.Instance.SearchJSONRootNode]; if (x is null) { LOGGER.Warn($"Could not find {TVSettings.Instance.SearchJSONRootNode} in JSON Repsonse {jsonResponse}"); return; } foreach (JToken item in x) { if (item is null || !(item is JObject episodeResponse)) { continue; } if (episodeResponse.ContainsKey(TVSettings.Instance.SearchJSONFilenameToken) && episodeResponse.ContainsKey(TVSettings.Instance.SearchJSONURLToken)) { string itemName = (string)item[TVSettings.Instance.SearchJSONFilenameToken]; string itemUrl = (string)item[TVSettings.Instance.SearchJSONURLToken]; int seeders = (int)item[TVSettings.Instance.SearchJSONSeedersToken]; long itemSizeBytes = CalculateItemSizeBytes(item); if (TVSettings.Instance.DetailedRSSJSONLogging) { LOGGER.Info("Processing JSON Item"); LOGGER.Info(episodeResponse.ToString); LOGGER.Info("Extracted"); LOGGER.Info($"Name: {itemName}"); LOGGER.Info($"URL: {itemUrl}"); LOGGER.Info($"Size: {itemSizeBytes}"); LOGGER.Info($"Seeds: {seeders}"); } if (itemName is null || itemUrl is null) { continue; } if (!FileHelper.SimplifyAndCheckFilename(itemName, simpleShowName, true, false) && !FileHelper.SimplifyAndCheckFilename(itemName, simpleSeriesName, true, false)) { continue; } if (!FinderHelper.FindSeasEp(itemName, out int seas, out int ep, out int _, pe.Show)) { continue; } if (TVSettings.Instance.DetailedRSSJSONLogging) { LOGGER.Info($"Season: {seas}"); LOGGER.Info($"Episode: {ep}"); } if (seas != pe.AppropriateSeasonNumber) { continue; } if (ep != pe.AppropriateEpNum) { continue; } LOGGER.Info( $"Adding {itemUrl} from JSON page as it appears to be match for {pe.Show.ShowName} S{pe.AppropriateSeasonNumber}E{pe.AppropriateEpNum}"); newItemsForThisMissingEpisode.Add(new ActionTDownload(itemName, itemSizeBytes, seeders, itemUrl, action.TheFileNoExt, pe, action, $"JSON WebPage: {TVSettings.Instance.SearchJSONURL}{imdbId}")); toRemove.Add(action); } else { LOGGER.Info( $"{TVSettings.Instance.SearchJSONFilenameToken} or {TVSettings.Instance.SearchJSONURLToken} not found in {TVSettings.Instance.SearchJSONURL}{imdbId} for {action.MissingEpisode.TheCachedSeries.Name}"); } } } else { LOGGER.Info( $"{TVSettings.Instance.SearchJSONRootNode} not found in {TVSettings.Instance.SearchJSONURL}{imdbId} for {action.MissingEpisode.TheCachedSeries.Name}"); } RemoveDuplicates(newItemsForThisMissingEpisode); newItems.AddNullableRange(newItemsForThisMissingEpisode); }
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); }
public void DoActions(ItemList theList) { actionManager.DoActions(theList, !Args.Hide && Environment.UserInteractive); }
public override void Check(SetProgressDelegate prog, int startpct, int totPct) { // get list of files being downloaded by uTorrent string resDatFile = TVSettings.Instance.ResumeDatPath; if (string.IsNullOrEmpty(resDatFile) || !File.Exists(resDatFile)) { return; } BTResume btr = new BTResume(prog, resDatFile); if (!btr.LoadResumeDat()) { return; } List <TorrentEntry> downloading = btr.AllFilesBeingDownloaded(); ItemList newList = new ItemList(); ItemList toRemove = new ItemList(); int c = this.TheActionList.Count + 2; int n = 1; prog.Invoke(startpct + totPct * n / c); foreach (Item Action1 in this.TheActionList) { if (this.ActionCancel) { return; } n++; prog.Invoke(100 * n / c); if (!(Action1 is ItemMissing)) { continue; } ItemMissing Action = (ItemMissing)(Action1); foreach (TorrentEntry te in downloading) { FileInfo file = new FileInfo(te.DownloadingTo); if (!TVSettings.Instance.UsefulExtension(file.Extension, false)) // not a usefile file extension { continue; } //do any of the possible names for the series match the filename? Boolean matched = (Action.Episode.SI.getSimplifiedPossibleShowNames().Any(name => FileHelper.SimplifyAndCheckFilename(file.FullName, name))); if (matched) { int seasF; int epF; if (TVDoc.FindSeasEp(file, out seasF, out epF, Action.Episode.SI) && (seasF == Action.Episode.SeasonNumber) && (epF == Action.Episode.EpNum)) { toRemove.Add(Action1); newList.Add(new ItemuTorrenting(te, Action.Episode, Action.TheFileNoExt)); break; } } } } foreach (Item i in toRemove) { this.TheActionList.Remove(i); } foreach (Item Action in newList) { this.TheActionList.Add(Action); } prog.Invoke(startpct + totPct); }
private static bool ActionListContains([NotNull] ItemList actionlist, ActionCopyMoveRename newitem) { return(actionlist.CopyMoveItems().Any(cmAction => cmAction.SameSource(newitem))); }
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"); } } } }
// 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); } int season = me.Episode.AppropriateSeasonNumber; int epnum = me.Episode.AppropriateEpNum; 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 regularMatch = FinderHelper.FindSeasEp(dce, 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.Name, ref seasF, ref epF, me.Episode) && seasF == season && epF == epnum; if (!regularMatch && !sequentialMatch) { 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)); } 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, season, epnum); } return(false); }
private static void KeepTogetherForItem(ItemList actionlist, bool fromLibrary, [NotNull] ActionCopyMoveRename action, ItemList extras, bool showErrors) { try { DirectoryInfo sfdi = action.From.Directory; string basename = action.From.Name; int l = basename.Length; basename = basename.Substring(0, l - action.From.Extension.Length); string toname = action.To.Name; int l2 = toname.Length; toname = toname.Substring(0, l2 - action.To.Extension.Length); try { FileInfo[] flist = sfdi.GetFiles(basename + ".*"); foreach (FileInfo fi in flist) { //check to see whether the file is one of the types we do/don't want to include //If we are copying from outside the library we use the 'Keep Together' Logic if (!fromLibrary && !TVSettings.Instance.KeepTogetherFilesWithType(fi.Extension)) { continue; } //If we are with in the library we use the 'Other Extensions' if (fromLibrary && !TVSettings.Instance.FileHasUsefulExtension(fi, true)) { continue; } string newName = GetFilename(fi.Name, basename, toname); ActionCopyMoveRename newitem = new ActionCopyMoveRename(action.Operation, fi, FileHelper.FileInFolder(action.To.Directory, newName), action.Episode, false, null); // tidy up on main action, not this // check this item isn't already in our to-do list if (ActionListContains(actionlist, newitem)) { continue; } if (!newitem.SameAs(action)) // don't re-add ourself { extras.Add(newitem); } } } catch (UnauthorizedAccessException) { LOGGER.Warn("Could not access: " + action.From.FullName); } catch (DirectoryNotFoundException) { LOGGER.Warn("Could not find: " + action.From.FullName); } } catch (PathTooLongException e) { string t = "Path or filename too long. " + action.From.FullName + ", " + e.Message; LOGGER.Warn(e, "Path or filename too long. " + action.From.FullName); if (showErrors && Environment.UserInteractive) { MessageBox.Show(t, "Path or filename too long", MessageBoxButton.OK, MessageBoxImage.Exclamation); } } }
protected void KeepTogether([NotNull] ItemList actionlist, bool fromLibrary) { KeepTogether(actionlist, fromLibrary, (!MDoc.Args.Unattended) && (!MDoc.Args.Hide)); }
protected ActionListXml(ItemList theActionList) : base(theActionList) { }
public RenamingXML(ItemList theActionList) : base(theActionList) { }
public CopyMoveXml(ItemList theActionList) : base(theActionList) { }
private void FindEpisode(TVDoc.ScanSettings settings, ShowItemMissing me, DirFilesCache dfc, ItemList newList, ItemList toRemove) { ItemList thisRound = new ItemList(); 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); }
protected override void DoCheck(SetProgressDelegate prog, ICollection <ShowItem> showList, 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.MissingItems().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.FNPRegexs); } ItemList newItems = new ItemList(); ItemList toRemove = new ItemList(); foreach (ItemMissing action in ActionList.MissingItems().ToList()) { if (settings.Token.IsCancellationRequested) { return; } UpdateStatus(n++, c, action.Filename); ProcessedEpisode pe = action.Episode; string simpleShowName = Helpers.SimplifyName(pe.Show.ShowName); string simpleSeriesName = Helpers.SimplifyName(pe.TheSeries.Name); ItemList newItemsForThisMissingEpisode = new ItemList(); foreach (RSSItem rss in RSSList) { if ( !FileHelper.SimplifyAndCheckFilename(rss.ShowName, simpleShowName, true, false) && !( string.IsNullOrEmpty(rss.ShowName) && FileHelper.SimplifyAndCheckFilename(rss.Title, simpleSeriesName, true, false) ) ) { continue; } if (rss.Season != pe.AppropriateSeasonNumber) { continue; } if (rss.Episode != pe.AppropriateEpNum) { continue; } LOGGER.Info($"Adding {rss.URL} from RSS feed as it appears to be match for {action.Episode.Show.ShowName} S{action.Episode.AppropriateSeasonNumber}E{action.Episode.AppropriateEpNum}"); newItemsForThisMissingEpisode.Add(new ActionTDownload(rss, action.TheFileNoExt, pe, action)); toRemove.Add(action); } foreach (ActionTDownload x in FindDuplicates(newItemsForThisMissingEpisode)) { newItemsForThisMissingEpisode.Remove(x); } newItems.AddNullableRange(newItemsForThisMissingEpisode); } ActionList.Replace(toRemove, newItems); }
private void FindMovie(TVDoc.ScanSettings settings, MovieItemMissing mim, DirFilesCache dfc, ItemList newList, ItemList toRemove) { if (!mim.MovieConfig.UseAutomaticFolders) { return; } (string targetFolder, string targetFolderEarlier, string targetFolderLater) = mim.MovieConfig.NeighbouringFolderNames(); TestShouldMove(targetFolderEarlier, targetFolder, dfc, newList, toRemove, mim); TestShouldMove(targetFolderLater, targetFolder, dfc, newList, toRemove, mim); }
private static void FindMissingEpisode([NotNull] ShowItemMissing action, ItemList toRemove, ItemList newItems) { ProcessedEpisode processedEpisode = action.MissingEpisode; string url = TVSettings.Instance.UseJackettTextSearch ? TextJackettUrl(processedEpisode) : NormalJackettUrl(processedEpisode); RssItemList rssList = new RssItemList(); rssList.DownloadRSS(url, false, "Jackett"); ItemList newItemsForThisMissingEpisode = new ItemList(); foreach (RSSItem rss in rssList.Where(rss => RssMatch(rss, processedEpisode))) { if (TVSettings.Instance.DetailedRSSJSONLogging) { LOGGER.Info( $"Adding {rss.URL} from RSS feed as it appears to be match for {processedEpisode.Show.ShowName} S{processedEpisode.AppropriateSeasonNumber}E{processedEpisode.AppropriateEpNum}"); } ItemDownloading becomes = new ItemDownloading(new FutureTorrentEntry(rss.URL, action.TheFileNoExt), action.MissingEpisode, action.TheFileNoExt, DownloadingFinder.DownloadApp.qBitTorrent, action); newItemsForThisMissingEpisode.Add(new ActionTDownload(rss, action, becomes)); toRemove.Add(action); } foreach (ActionTDownload x in FindDuplicates(newItemsForThisMissingEpisode)) { newItemsForThisMissingEpisode.Remove(x); } newItems.AddNullableRange(newItemsForThisMissingEpisode); }
private void TestShouldMove(string sourceFolder, string targetFolder, DirFilesCache dfc, ItemList newList, ItemList toRemove, MovieItemMissing mim) { if (sourceFolder == targetFolder) { return; } if (dfc.GetFiles(targetFolder).Length > 0) { //do not want to copy any files over new location return; } if (!Directory.Exists(sourceFolder) || dfc.GetFiles(sourceFolder).Length == 0) { return; } LOGGER.Info($"Have identified that {sourceFolder} can be copied to {targetFolder}"); toRemove.Add(mim); newList.Add(new ActionMoveRenameDirectory(sourceFolder, targetFolder, mim.MovieConfig)); }
public MissingCSV(ItemList theActionList) : base(theActionList) { }
public MissingMovieXml(ItemList theActionList) : base(theActionList) { }