Пример #1
0
        public void CheckFolders(CancellationToken token, [NotNull] SetProgressDelegate prog, bool detailedLogging, bool showErrorMsgBox)
        {
            // Check the  folder list, and build up a new "AddItems" list.
            // guessing what the shows actually are isn't done here.  That is done by
            // calls to "GuessShowItem"
            Logger.Info("*********************************************************************");
            Logger.Info("*Starting to find folders that contain files, but are not in library*");

            AddItems = new FolderMonitorEntryList();

            int c = TVSettings.Instance.LibraryFolders.Count;

            int c2 = 0;

            foreach (string folder in TVSettings.Instance.LibraryFolders)
            {
                prog.Invoke(100 * c2++ / c, folder);
                DirectoryInfo di = new DirectoryInfo(folder);

                CheckFolderForShows(di, token, detailedLogging, showErrorMsgBox);

                if (token.IsCancellationRequested)
                {
                    break;
                }
            }
            prog.Invoke(100, string.Empty);
        }
Пример #2
0
        private void Check(SetProgressDelegate?progress, int startpct, int totPct)
        {
            startPosition    = startpct;
            endPosition      = totPct;
            progressDelegate = progress;
            progressDelegate?.Invoke(startpct, string.Empty);
            try
            {
                if (!Active())
                {
                    return;
                }

                DoCheck(progress);
                LogActionListSummary();
            }
            catch (TVRenameOperationInterruptedException)
            {
                throw;
            }
            catch (Exception e)
            {
                LOGGER.Fatal(e, $"Failed to run Scan for {ActivityName()}");
            }
            finally
            {
                progressDelegate?.Invoke(totPct, string.Empty);
            }
        }
Пример #3
0
        public override void Check(SetProgressDelegate prog, int startpct, int totPct)
        {
            int c = this.TheActionList.Count + 2;
            int n = 1;

            prog.Invoke(100 * n / c);
            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 Action1 in this.TheActionList)
            {
                if (this.ActionCancel)
                {
                    return;
                }

                n++;
                prog.Invoke(100 * n / c);

                if (!(Action1 is ItemMissing))
                {
                    continue;
                }

                ItemMissing Action = (ItemMissing)(Action1);

                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))) && (rss.Season == pe.SeasonNumber) && (rss.Episode == pe.EpNum))
                    {
                        newItems.Add(new ActionRSS(rss, Action.TheFileNoExt, pe));
                        toRemove.Add(Action1);
                    }
                }
            }
            foreach (Item i in toRemove)
            {
                this.TheActionList.Remove(i);
            }

            foreach (Item Action in newItems)
            {
                this.TheActionList.Add(Action);
            }

            prog.Invoke(100);
        }
Пример #4
0
        protected void SearchForAppropriateDownloads(SetProgressDelegate prog, int startpct, int totPct, List <TorrentEntry> downloading, DownloadApp tApp)
        {
            ItemList newList  = new ItemList();
            ItemList toRemove = new ItemList();
            int      c        = ActionList.Count + 2;
            int      n        = 1;

            prog.Invoke(startpct);
            foreach (ItemMissing action in ActionList.MissingItems())
            {
                if (ActionCancel)
                {
                    return;
                }

                prog.Invoke(startpct + ((totPct - startpct) * (++n) / (c)));

                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?
                    bool matched = (action.Episode.Show.GetSimplifiedPossibleShowNames().Any(name => FileHelper.SimplifyAndCheckFilename(file.FullName, name)));

                    if (!matched)
                    {
                        continue;
                    }

                    if (TVDoc.FindSeasEp(file, out int seasF, out int epF, out int _, action.Episode.Show) && (seasF == action.Episode.AppropriateSeasonNumber) && (epF == action.Episode.AppropriateEpNum))
                    {
                        toRemove.Add(action);
                        newList.Add(new ItemDownloading(te, action.Episode, action.TheFileNoExt, tApp));
                        break;
                    }
                }
            }

            foreach (Item i in toRemove)
            {
                ActionList.Remove(i);
            }

            foreach (Item action in newList)
            {
                ActionList.Add(action);
            }

            prog.Invoke(totPct);
        }
Пример #5
0
        private int BuildDirCache(SetProgressDelegate prog, int count, int totalFiles, string folder, bool subFolders)
        {
            if (!Directory.Exists(folder))
            {
                logger.Error("The search folder \"" + folder + " does not exist.");
                return(count);
            }

            try
            {
                /*
                 * if (folder.Length >= 248)
                 *
                 * {
                 *  logger.Error ("Skipping folder that has a name longer than the Windows permitted 247 characters: " + folder);
                 *  return count;
                 * }
                 *
                 */
                DirectoryInfo di = new DirectoryInfo(folder);
                if (!di.Exists)
                {
                    return(count);
                }

                //                DirectorySecurity ^ds = di->GetAccessControl();

                FileInfo[] f2 = di.GetFiles();
                foreach (FileInfo ff in f2)
                {
                    count++;
//                    if ((ff.Name.Length + folder.Length) >= 260)
//                        logger.Error("Skipping file that has a path+name longer than the Windows permitted 259 characters: " + ff.Name + " in " + folder);
//                    else
                    this.Add(new DirCacheEntry(ff));
                    if ((prog != null) && (totalFiles != 0))
                    {
                        prog.Invoke(100 * (count) / totalFiles);
                    }
                }

                if (subFolders)
                {
                    DirectoryInfo[] dirs = di.GetDirectories();
                    foreach (DirectoryInfo di2 in dirs)
                    {
                        count = this.BuildDirCache(prog, count, totalFiles, di2.FullName, subFolders);
                    }
                }
            }
            catch (UnauthorizedAccessException e)
            {
                logger.Info(e);
            }
            catch (Exception exception)
            {
                logger.Error(exception);
            }
            return(count);
        }
Пример #6
0
        private int BuildDirCache(SetProgressDelegate prog, int count, int totalFiles, string folder, bool subFolders)
        {
            if (!Directory.Exists(folder))
            {
                MessageBox.Show("The search folder \"" + folder + " does not exist.\n", "Folder does not exist", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return(count);
            }

            try
            {
                if (folder.Length >= 248)
                {
                    MessageBox.Show("Skipping folder that has a name longer than the Windows permitted 247 characters: " + folder, "Path name too long", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return(count);
                }

                DirectoryInfo di = new DirectoryInfo(folder);
                if (!di.Exists)
                {
                    return(count);
                }

                //                DirectorySecurity ^ds = di->GetAccessControl();

                FileInfo[] f2 = di.GetFiles();
                foreach (FileInfo ff in f2)
                {
                    count++;
                    if ((ff.Name.Length + folder.Length) >= 260)
                    {
                        MessageBox.Show("Skipping file that has a path+name longer than the Windows permitted 259 characters: " + ff.Name + " in " + folder, "File+Path name too long", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                    else
                    {
                        this.Add(new DirCacheEntry(ff));
                    }
                    if ((prog != null) && (totalFiles != 0))
                    {
                        prog.Invoke(100 * (count) / totalFiles);
                    }
                }

                if (subFolders)
                {
                    DirectoryInfo[] dirs = di.GetDirectories();
                    foreach (DirectoryInfo di2 in dirs)
                    {
                        count = this.BuildDirCache(prog, count, totalFiles, di2.FullName, subFolders);
                    }
                }
            }
            catch (UnauthorizedAccessException)
            {
            }
            catch
            {
            }
            return(count);
        }
Пример #7
0
        private int BuildDirCache(SetProgressDelegate prog, int count, int totalFiles, string folder, bool subFolders)
        {
            if (!Directory.Exists(folder))
            {
                Logger.Error("The search folder \"" + folder + " does not exist.");
                return(count);
            }

            try
            {
                DirectoryInfo di = new DirectoryInfo(folder);
                if (!di.Exists)
                {
                    return(count);
                }

                FileInfo[] f2 = di.GetFiles();
                foreach (FileInfo ff in f2)
                {
                    count++;
                    Add(new DirCacheEntry(ff));
                    if ((prog != null) && (totalFiles != 0))
                    {
                        prog.Invoke(100 * (count) / totalFiles);
                    }
                }

                if (subFolders)
                {
                    DirectoryInfo[] dirs = di.GetDirectories();
                    foreach (DirectoryInfo di2 in dirs)
                    {
                        count += BuildDirCache(prog, count, totalFiles, di2.FullName, true);
                    }
                }
            }
            catch (UnauthorizedAccessException e)
            {
                Logger.Info(e);
            }
            catch (Exception exception)
            {
                Logger.Error(exception);
            }
            return(count);
        }
Пример #8
0
        private int BuildDirCache(SetProgressDelegate prog, int count, int totalFiles, string folder, bool subFolders)
        {
            if (!Directory.Exists(folder))
            {
                Logger.Warn("The search folder \"" + folder + " does not exist.");
                return(count);
            }

            try
            {
                DirectoryInfo di = new DirectoryInfo(folder);
                if (!di.Exists)
                {
                    return(count);
                }

                foreach (FileInfo ff in GetFiles(di))
                {
                    count++;
                    Add(new DirCacheEntry(ff));
                    if (prog != null && totalFiles != 0)
                    {
                        prog.Invoke(100 * count / totalFiles, string.Empty);
                    }
                }

                if (subFolders)
                {
                    foreach (DirectoryInfo di2 in GetDirectoryInfo(di))
                    {
                        count += BuildDirCache(prog, count, totalFiles, di2.FullName, true);
                    }
                }
            }
            catch (Exception exception)
            {
                Logger.Error(exception);
            }
            return(count);
        }
Пример #9
0
        public void CheckAgainstSABnzbd(SetProgressDelegate prog, int startpct, int totPct)
        {
            if (String.IsNullOrEmpty(Settings.SABAPIKey) || String.IsNullOrEmpty(Settings.SABHostPort))
            {
                prog.Invoke(startpct + totPct);
                return;
            }

            // get list of files being downloaded by SABnzbd

            // Something like:
            // http://localhost:8080/sabnzbd/api?mode=queue&apikey=xxx&start=0&limit=8888&output=xml
            String theURL = "http://" + Settings.SABHostPort +
                            "/sabnzbd/api?mode=queue&start=0&limit=8888&output=xml&apikey=" + Settings.SABAPIKey;

            WebClient wc = new WebClient();
            byte[] r = null;
            try
            {
                r = wc.DownloadData(theURL);
            }
            catch (WebException)
            {
            }

            if (r == null)
            {
                prog.Invoke(startpct + totPct);
                return;
            }

            try
            {
                SAB.result res = SAB.result.Deserialize(r);
                if (res.status == "False")
                {
                    MessageBox.Show(res.error, "SABnzbd Queue Check", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    prog.Invoke(startpct + totPct);
                    return;
                }
            }
            catch
            {
                // wasn't a result/error combo.  this is good!
            }

            SAB.queue sq = null;
            try
            {
                sq = SAB.queue.Deserialize(r);
            }
            catch (Exception)
            {
                MessageBox.Show("Error processing data from SABnzbd", "SABnzbd Queue Check", MessageBoxButtons.OK, MessageBoxIcon.Error);
                prog.Invoke(startpct + totPct);
                return;
            }

            System.Diagnostics.Debug.Assert(sq != null); // shouldn't happen
            if (sq == null || sq.slots==null || sq.slots.Length == 0) // empty queue
                return;

            ItemList newList = new ItemList();
            ItemList toRemove = new ItemList();
            int c = this.TheActionList.Count + 2;
            int n = 1;

            foreach (Item Action1 in this.TheActionList)
            {
                if (this.ActionCancel)
                    return;

                n++;
                prog.Invoke(startpct + totPct * n / c);

                if (!(Action1 is ItemMissing))
                    continue;

                ItemMissing Action = (ItemMissing) (Action1);

                string showname = Helpers.SimplifyName(Action.Episode.SI.ShowName);

                foreach (SAB.queueSlotsSlot te  in sq.slots)
                {
                    //foreach (queueSlotsSlot te in qs)
                    {
                        FileInfo file = new FileInfo(te.filename);
                        //if (!this.Settings.UsefulExtension(file.Extension, false)) // not a usefile file extension
                        //    continue;

                        if (this.SimplifyAndCheckFilename(file.FullName, showname, true, false))
                            // if (Regex::Match(simplifiedfname,"\\b"+showname+"\\b",RegexOptions::IgnoreCase)->Success)
                        {
                            int seasF;
                            int epF;
                            if (this.FindSeasEp(file, out seasF, out epF, Action.Episode.SI) &&
                                (seasF == Action.Episode.SeasonNumber) && (epF == Action.Episode.EpNum))
                            {
                                toRemove.Add(Action1);
                                newList.Add(new ItemSABnzbd(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);
        }
Пример #10
0
        public void RSSSearch(SetProgressDelegate prog)
        {
            int c = this.TheActionList.Count + 2;
            int n = 1;
            prog.Invoke(100 * n / c);
            this.RSSList = new RSSItemList();
            foreach (string s in this.Settings.RSSURLs)
                this.RSSList.DownloadRSS(s, this.Settings.FNPRegexs);

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

            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);

                ProcessedEpisode pe = Action.Episode;
                string simpleShowName = Helpers.SimplifyName(pe.SI.ShowName);
                string simpleSeriesName = Helpers.SimplifyName(pe.TheSeries.Name);

                foreach (RSSItem rss in this.RSSList)
                {
                    if ((this.SimplifyAndCheckFilename(rss.ShowName, simpleShowName, true, false) || (string.IsNullOrEmpty(rss.ShowName) && this.SimplifyAndCheckFilename(rss.Title, simpleSeriesName, true, false))) && (rss.Season == pe.SeasonNumber) && (rss.Episode == pe.EpNum))
                    {
                        newItems.Add(new ActionRSS(rss, Action.TheFileNoExt, pe));
                        toRemove.Add(Action1);
                    }
                }
            }
            foreach (Item i in toRemove)
                this.TheActionList.Remove(i);
            foreach (Item Action in newItems)
                this.TheActionList.Add(Action);

            prog.Invoke(100);
        }
Пример #11
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 (this.Settings.RenameCheck)
                this.Stats().RenameChecksDone++;

            if (this.Settings.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;

            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(this.Settings).Count == 0) // no folders defined for this show
                    continue; // so, nothing to do.

                // for each tv show, optionally write a tvshow.nfo file

                if (this.Settings.NFOs && !string.IsNullOrEmpty(si.AutoAdd_FolderBase) && (si.AllFolderLocations(this.Settings).Count > 0))
                {
                    FileInfo tvshownfo = Helpers.FileInFolder(si.AutoAdd_FolderBase, "tvshow.nfo");

                    bool needUpdate = !tvshownfo.Exists || (si.TheSeries().Srv_LastUpdated > TimeZone.Epoch(tvshownfo.LastWriteTime));
                    // was it written before we fixed the bug in <episodeguideurl> ?
                    needUpdate = needUpdate || (tvshownfo.LastWriteTime.ToUniversalTime().CompareTo(new DateTime(2009, 9, 13, 7, 30, 0, 0, DateTimeKind.Utc)) < 0);
                    if (needUpdate)
                        this.TheActionList.Add(new ActionNFO(tvshownfo, si));
                }

                // 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(this.Settings);

                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 && (this.Settings.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;
                    }

                    List<string> doneFolderJPG = new List<String>();
                    if (this.Settings.FolderJpg)
                    {
                        // main image for the folder itself

                        // base folder:
                        if (!string.IsNullOrEmpty(si.AutoAdd_FolderBase) && (si.AllFolderLocations(this.Settings, false).Count > 0))
                        {
                            FileInfo fi = Helpers.FileInFolder(si.AutoAdd_FolderBase, "folder.jpg");
                            if (!fi.Exists)
                            {
                                string bannerPath = si.TheSeries().GetItem(this.Settings.ItemForFolderJpg());
                                if (!string.IsNullOrEmpty(bannerPath))
                                    this.TheActionList.Add(new ActionDownload(si, null, fi, bannerPath));
                            }
                            doneFolderJPG.Add(si.AutoAdd_FolderBase);
                        }
                    }

                    foreach (string folder in folders)
                    {
                        if (this.ActionCancel)
                            return;

                        // generate new filename info
                        DirectoryInfo di;
                        try
                        {
                            di = new DirectoryInfo(folder);
                        }
                        catch
                        {
                            continue;
                        }

                        bool renCheck = this.Settings.RenameCheck && si.DoRename && di.Exists; // renaming check needs the folder to exist
                        bool missCheck = this.Settings.MissingCheck && si.DoMissingCheck;

                        if (this.Settings.FolderJpg)
                        {
                            // season folders JPGs

                            if (!doneFolderJPG.Contains(folder)) // some folders may come up multiple times
                            {
                                doneFolderJPG.Add(folder);

                                FileInfo fi = Helpers.FileInFolder(folder, "folder.jpg");
                                if (!fi.Exists)
                                {
                                    string bannerPath = si.TheSeries().GetItem(this.Settings.ItemForFolderJpg());
                                    if (!string.IsNullOrEmpty(bannerPath))
                                        this.TheActionList.Add(new ActionDownload(si, null, fi, bannerPath));
                                }
                            }
                        }

                        FileInfo[] files = di.GetFiles(); // all the files in the folder
                        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 (!this.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 && this.Settings.UsefulExtension(fi.Extension, true)) // == RENAMING CHECK ==
                            {
                                string newname = this.Settings.FilenameFriendly(this.Settings.NamingStyle.NameForExt(ep, fi.Extension, folder.Length));

                                if (newname != actualFile.Name)
                                {
                                    actualFile = Helpers.FileInFolder(folder, newname); // rename updates the filename
                                      this.TheActionList.Add(new ActionCopyMoveRename(ActionCopyMoveRename.Op.Rename, fi, actualFile, ep));
                                }
                            }
                            if (missCheck && this.Settings.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 db = this.GetTVDB(true, "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 + this.Settings.FilenameFriendly(this.Settings.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.ThumbnailAndNFOCheck(dbep, filo, this.TheActionList);
                                }
                            } // up to date check, for each episode in thetvdb
                            db.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();
        }
Пример #12
0
        public void LookForMissingEps(SetProgressDelegate prog)
        {
            // for each ep we have noticed as being missing
            // look through the monitored folders for it

            this.Stats().FindAndOrganisesDone++;

            prog.Invoke(0);

            ItemList newList = new ItemList();
            ItemList toRemove = new ItemList();

            int fileCount = 0;
            foreach (string s in this.SearchFolders)
                fileCount += DirCache.CountFiles(s, true);

            int c = 0;

            DirCache dirCache = new DirCache();
            foreach (String s in this.SearchFolders)
            {
                if (this.ActionCancel)
                    return;

                c = dirCache.AddFolder(prog, c, fileCount, s, true, this.Settings);
            }

            c = 0;
            int totalN = this.TheActionList.Count;
            foreach (Item action1 in this.TheActionList)
            {
                if (this.ActionCancel)
                    return;

                prog.Invoke(50 + 50 * (++c) / (totalN + 1)); // second 50% of progress bar

                if (action1 is ItemMissing)
                {
                    if (this.FindMissingEp(dirCache, (ItemMissing) (action1), newList, ActionCopyMoveRename.Op.Copy))
                        toRemove.Add(action1);
                }
            }

            if (this.Settings.KeepTogether)
                this.KeepTogether(newList);

            prog.Invoke(100);

            if (!this.Settings.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 (!Helpers.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)
                this.TheActionList.Remove(i);

            foreach (Item i in newList)
                this.TheActionList.Add(i);

            //                 if (Settings->ExportFOXML)
            //				ExportFOXML(Settings->ExportFOXMLTo);
        }
Пример #13
0
        protected void UpdateStatus(int recordNumber, int totalRecords, string message)
        {
            int position = (endPosition - startPosition) * recordNumber / (totalRecords + 1);

            progressDelegate?.Invoke(startPosition + position, message);
        }
Пример #14
0
        public override void Check(SetProgressDelegate prog, int startpct, int totPct)
        {
            if (string.IsNullOrEmpty(TVSettings.Instance.SABAPIKey) || string.IsNullOrEmpty(TVSettings.Instance.SABHostPort))
            {
                prog.Invoke(totPct);
                return;
            }

            // get list of files being downloaded by SABnzbd

            // Something like:
            // http://localhost:8080/sabnzbd/api?mode=queue&apikey=xxx&start=0&limit=8888&output=xml
            string theUrl = "http://" + TVSettings.Instance.SABHostPort +
                            "/sabnzbd/api?mode=queue&start=0&limit=8888&output=xml&apikey=" + TVSettings.Instance.SABAPIKey;

            byte[] r = DownloadPage(theUrl);

            if (r == null)
            {
                prog.Invoke(totPct);
                return;
            }

            try
            {
                SAB.Result res = SAB.Result.Deserialize(r);
                if (res != null && res.status == "False")
                {
                    LOGGER.Error("Error processing data from SABnzbd (Queue Check): {0}", res.error);
                    prog.Invoke(totPct);
                    return;
                }
            }
            catch
            {
                // wasn't a result/error combo.  this is good!
            }

            SAB.Queue sq;
            try
            {
                sq = SAB.Queue.Deserialize(r);
            }
            catch (Exception e)
            {
                LOGGER.Error(e, "Error processing data from SABnzbd (Queue Check)");
                prog.Invoke(totPct);
                return;
            }

            System.Diagnostics.Debug.Assert(sq != null);  // shouldn't happen
            if (sq.slots == null || sq.slots.Length == 0) // empty queue
            {
                return;
            }

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

            foreach (ItemMissing action in ActionList.MissingItems())
            {
                if (ActionCancel)
                {
                    return;
                }

                prog.Invoke(startpct + ((totPct - startpct) * (++n) / (c)));

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

                foreach (SAB.QueueSlotsSlot te in sq.slots)
                {
                    FileInfo file = new FileInfo(te.filename);

                    if (!FileHelper.SimplifyAndCheckFilename(file.FullName, showname, true, false))
                    {
                        continue;
                    }
                    if (!TVDoc.FindSeasEp(file, out int seasF, out int epF, out int _, action.Episode.Show) ||
                        (seasF != action.Episode.AppropriateSeasonNumber) || (epF != action.Episode.AppropriateEpNum))
                    {
                        continue;
                    }
                    toRemove.Add(action);
                    newList.Add(new ItemDownloading(te, action.Episode, action.TheFileNoExt, DownloadApp.SABnzbd));
                    break;
                }
            }

            foreach (Item i in toRemove)
            {
                ActionList.Remove(i);
            }

            foreach (Item action in newList)
            {
                ActionList.Add(action);
            }

            prog.Invoke(totPct);
        }
Пример #15
0
        public override void Check(SetProgressDelegate prog, int startpct, int totPct)
        {
            if (String.IsNullOrEmpty(TVSettings.Instance.SABAPIKey) || String.IsNullOrEmpty(TVSettings.Instance.SABHostPort))
            {
                prog.Invoke(startpct + totPct);
                return;
            }

            // get list of files being downloaded by SABnzbd

            // Something like:
            // http://localhost:8080/sabnzbd/api?mode=queue&apikey=xxx&start=0&limit=8888&output=xml
            String theURL = "http://" + TVSettings.Instance.SABHostPort +
                            "/sabnzbd/api?mode=queue&start=0&limit=8888&output=xml&apikey=" + TVSettings.Instance.SABAPIKey;

            WebClient wc = new WebClient();

            byte[] r = null;
            try
            {
                r = wc.DownloadData(theURL);
            }
            catch (WebException)
            {
            }

            if (r == null)
            {
                prog.Invoke(startpct + totPct);
                return;
            }

            try
            {
                SAB.result res = SAB.result.Deserialize(r);
                if (res.status == "False")
                {
                    MessageBox.Show(res.error, "SABnzbd Queue Check", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    prog.Invoke(startpct + totPct);
                    return;
                }
            }
            catch
            {
                // wasn't a result/error combo.  this is good!
            }

            SAB.queue sq = null;
            try
            {
                sq = SAB.queue.Deserialize(r);
            }
            catch (Exception)
            {
                MessageBox.Show("Error processing data from SABnzbd", "SABnzbd Queue Check", MessageBoxButtons.OK, MessageBoxIcon.Error);
                prog.Invoke(startpct + totPct);
                return;
            }

            System.Diagnostics.Debug.Assert(sq != null);                // shouldn't happen
            if (sq == null || sq.slots == null || sq.slots.Length == 0) // empty queue
            {
                return;
            }

            ItemList newList  = new ItemList();
            ItemList toRemove = new ItemList();
            int      c        = this.TheActionList.Count + 2;
            int      n        = 1;

            foreach (Item Action1 in this.TheActionList)
            {
                if (this.ActionCancel)
                {
                    return;
                }

                n++;
                prog.Invoke(startpct + totPct * n / c);

                if (!(Action1 is ItemMissing))
                {
                    continue;
                }

                ItemMissing Action = (ItemMissing)(Action1);

                string showname = Helpers.SimplifyName(Action.Episode.SI.ShowName);

                foreach (SAB.queueSlotsSlot te in sq.slots)
                {
                    //foreach (queueSlotsSlot te in qs)
                    {
                        FileInfo file = new FileInfo(te.filename);
                        //if (!TVSettings.Instance.UsefulExtension(file.Extension, false)) // not a usefile file extension
                        //    continue;

                        if (FileHelper.SimplifyAndCheckFilename(file.FullName, showname, true, false))
                        // if (Regex::Match(simplifiedfname,"\\b"+showname+"\\b",RegexOptions::IgnoreCase)->Success)
                        {
                            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 ItemSABnzbd(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);
        }
Пример #16
0
        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);

                string showname = Helpers.SimplifyName(Action.Episode.SI.ShowName);

                foreach (TorrentEntry te in downloading)
                {
                    FileInfo file = new FileInfo(te.DownloadingTo);
                    if (!TVSettings.Instance.UsefulExtension(file.Extension, false)) // not a usefile file extension
                    {
                        continue;
                    }

                    if (FileHelper.SimplifyAndCheckFilename(file.FullName, showname, true, false)) // if (Regex::Match(simplifiedfname,"\\b"+showname+"\\b",RegexOptions::IgnoreCase)->Success)
                    {
                        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);
        }
Пример #17
0
        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);
        }
Пример #18
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();
        }
Пример #19
0
        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.ActionList.Count + 2;
            int      n        = 1;

            prog.Invoke(startpct);
            foreach (Item action1 in this.ActionList)
            {
                if (this.ActionCancel)
                {
                    return;
                }

                prog.Invoke(startpct + (totPct - startpct) * (++n) / (c));


                if (!(action1 is ItemMissing action))
                {
                    continue;
                }

                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?
                    bool matched = (action.Episode.SI.getSimplifiedPossibleShowNames().Any(name => FileHelper.SimplifyAndCheckFilename(file.FullName, name)));

                    if (!matched)
                    {
                        continue;
                    }

                    if (TVDoc.FindSeasEp(file, out int seasF, out int epF, out int maxEp, action.Episode.SI) && (seasF == action.Episode.AppropriateSeasonNumber) && (epF == action.Episode.AppropriateEpNum))
                    {
                        toRemove.Add(action1);
                        newList.Add(new ItemuTorrenting(te, action.Episode, action.TheFileNoExt));
                        break;
                    }
                }
            }

            foreach (Item i in toRemove)
            {
                this.ActionList.Remove(i);
            }

            foreach (Item action in newList)
            {
                this.ActionList.Add(action);
            }

            prog.Invoke(totPct);
        }
Пример #20
0
        public override void Check(SetProgressDelegate prog, int startpct, int totPct)
        {
            prog.Invoke(0);

            ItemList newList  = new ItemList();
            ItemList toRemove = new ItemList();

            int fileCount = 0;

            foreach (string s in this.mDoc.SearchFolders)
            {
                fileCount += DirCache.CountFiles(s, true);
            }

            int c = 0;

            DirCache dirCache = new DirCache();

            foreach (String s in this.mDoc.SearchFolders)
            {
                if (this.ActionCancel)
                {
                    return;
                }

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

            c = 0;
            int totalN = this.TheActionList.Count;

            foreach (Item action1 in this.TheActionList)
            {
                if (this.ActionCancel)
                {
                    return;
                }

                prog.Invoke(50 + 50 * (++c) / (totalN + 1)); // second 50% of progress bar

                if (action1 is ItemMissing)
                {
                    if (this.FindMissingEp(dirCache, (ItemMissing)(action1), newList, ActionCopyMoveRename.Op.Copy))
                    {
                        toRemove.Add(action1);
                    }
                }
            }

            if (TVSettings.Instance.KeepTogether)
            {
                this.KeepTogether(newList);
            }

            prog.Invoke(100);

            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)
            {
                this.TheActionList.Remove(i);
            }

            foreach (Item i in newList)
            {
                this.TheActionList.Add(i);
            }

            //                 if (Settings->ExportFOXML)
            //				ExportFOXML(Settings->ExportFOXMLTo);
        }
Пример #21
0
        public void CheckAgainstuTorrent(SetProgressDelegate prog, int startpct, int totPct)
        {
            // get list of files being downloaded by uTorrent
            string resDatFile = this.Settings.ResumeDatPath;
            if (string.IsNullOrEmpty(resDatFile) || !File.Exists(resDatFile))
                return;

            BTResume btr = new BTResume(prog, resDatFile);
            if (!btr.LoadResumeDat(Args))
                return;

            List<TorrentEntry> downloading = btr.AllFilesBeingDownloaded(this.Settings, Args);

            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);

                string showname = Helpers.SimplifyName(Action.Episode.SI.ShowName);

                foreach (TorrentEntry te in downloading)
                {
                    FileInfo file = new FileInfo(te.DownloadingTo);
                    if (!this.Settings.UsefulExtension(file.Extension, false)) // not a usefile file extension
                        continue;

                    if (this.SimplifyAndCheckFilename(file.FullName, showname, true, false)) // if (Regex::Match(simplifiedfname,"\\b"+showname+"\\b",RegexOptions::IgnoreCase)->Success)
                    {
                        int seasF;
                        int epF;
                        if (this.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);
        }
Пример #22
0
        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);
        }
Пример #23
0
        public override void Check(SetProgressDelegate prog, int startpct, int totPct)
        {
            if (string.IsNullOrEmpty(TVSettings.Instance.SABAPIKey) || String.IsNullOrEmpty(TVSettings.Instance.SABHostPort))
            {
                prog.Invoke(totPct);
                return;
            }

            // get list of files being downloaded by SABnzbd

            // Something like:
            // http://localhost:8080/sabnzbd/api?mode=queue&apikey=xxx&start=0&limit=8888&output=xml
            string theURL = "http://" + TVSettings.Instance.SABHostPort +
                            "/sabnzbd/api?mode=queue&start=0&limit=8888&output=xml&apikey=" + TVSettings.Instance.SABAPIKey;

            WebClient wc = new WebClient();

            byte[] r = null;
            try
            {
                r = wc.DownloadData(theURL);
            }
            catch (WebException)
            {
                logger.Warn("Failed to obtain SABnzbd, please recheck settings: " + theURL);
            }

            if (r == null)
            {
                prog.Invoke(totPct);
                return;
            }

            try
            {
                SAB.result res = SAB.result.Deserialize(r);
                if (res != null && res.status == "False")
                {
                    logger.Error("Error processing data from SABnzbd (Queue Check): {0}", res.error);
                    prog.Invoke(totPct);
                    return;
                }
            }
            catch
            {
                // wasn't a result/error combo.  this is good!
            }

            SAB.queue sq = null;
            try
            {
                sq = SAB.queue.Deserialize(r);
            }
            catch (Exception e)
            {
                logger.Error(e, "Error processing data from SABnzbd (Queue Check)");
                prog.Invoke(totPct);
                return;
            }

            System.Diagnostics.Debug.Assert(sq != null);   // shouldn't happen
            if (sq?.slots == null || sq.slots.Length == 0) // empty queue
            {
                return;
            }

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

            foreach (Item Action1 in this.ActionList)
            {
                if (this.ActionCancel)
                {
                    return;
                }

                prog.Invoke(startpct + (totPct - startpct) * (++n) / (c));


                if (!(Action1 is ItemMissing))
                {
                    continue;
                }

                ItemMissing Action = (ItemMissing)(Action1);

                string showname = Helpers.SimplifyName(Action.Episode.SI.ShowName);

                foreach (SAB.queueSlotsSlot te in sq.slots)
                {
                    //foreach (queueSlotsSlot te in qs)
                    {
                        FileInfo file = new FileInfo(te.filename);
                        //if (!TVSettings.Instance.UsefulExtension(file.Extension, false)) // not a usefile file extension
                        //    continue;

                        if (!FileHelper.SimplifyAndCheckFilename(file.FullName, showname, true, false))
                        {
                            continue;
                        }
                        if (!TVDoc.FindSeasEp(file, out int seasF, out int epF, out int maxEp, Action.Episode.SI) ||
                            (seasF != Action.Episode.AppropriateSeasonNumber) || (epF != Action.Episode.AppropriateEpNum))
                        {
                            continue;
                        }
                        toRemove.Add(Action1);
                        newList.Add(new ItemSABnzbd(te, Action.Episode, Action.TheFileNoExt));
                        break;
                    }
                }
            }

            foreach (Item i in toRemove)
            {
                this.ActionList.Remove(i);
            }

            foreach (Item Action in newList)
            {
                this.ActionList.Add(Action);
            }

            prog.Invoke(totPct);
        }
Пример #24
0
 protected void Prog(int percent, string message) => SetProg?.Invoke(percent, message);
Пример #25
0
        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);
            }
        }
Пример #26
0
        public override void Check(SetProgressDelegate prog, int startpct, int totPct)
        {
            int c = 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 (ItemMissing action in ActionList.MissingItems())
            {
                if (ActionCancel)
                {
                    return;
                }

                prog.Invoke(startpct + ((totPct - startpct) * (++n) / (c)));

                ProcessedEpisode pe               = action.Episode;
                string           simpleShowName   = Helpers.SimplifyName(pe.Show.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 {action.Episode.Show.ShowName} S{action.Episode.AppropriateSeasonNumber}E{action.Episode.AppropriateEpNum}");
                    newItems.Add(new ActionTDownload(rss, action.TheFileNoExt, pe));
                    toRemove.Add(action);
                }
            }

            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);
        }