示例#1
0
        public AddModifyRule(ShowRule rule)
        {
            this.mRule = rule;
            this.InitializeComponent();

            this.FillDialog();
        }
示例#2
0
        public AddModifyRule(ShowRule rule)
        {
            this.mRule = rule;
            this.InitializeComponent();

            this.FillDialog();
        }
示例#3
0
 public ShowRule(ShowRule O)
 {
     this.DoWhatNow        = O.DoWhatNow;
     this.First            = O.First;
     this.Second           = O.Second;
     this.UserSuppliedText = O.UserSuppliedText;
 }
示例#4
0
        private static ShowItemMissing UpdateMissingItem([NotNull] ShowItemMissing me, [NotNull] FileInfo dce, int epF, int maxEp, int seasF)
        {
            ShowRule sr = new ShowRule
            {
                DoWhatNow = RuleAction.kMerge,
                First     = epF,
                Second    = maxEp
            };

            me.MissingEpisode.Show.AddSeasonRule(seasF, sr);

            LOGGER.Info(
                $"Looking at {me.MissingEpisode.Show.ShowName} and have identified that episode {epF} and {maxEp} of season {seasF} have been merged into one file {dce.FullName}");

            LOGGER.Info($"Added new rule automatically for {sr}");

            //Regenerate the episodes with the new rule added
            ShowLibrary.GenerateEpisodeDict(me.MissingEpisode.Show);

            //Get the newly created processed episode we are after
            // ReSharper disable once InconsistentNaming
            ProcessedEpisode newPE = me.MissingEpisode;

            foreach (ProcessedEpisode pe in me.MissingEpisode.Show.SeasonEpisodes[seasF])
            {
                if (pe.AppropriateEpNum == epF && pe.EpNum2 == maxEp)
                {
                    newPE = pe;
                }
            }

            return(new ShowItemMissing(newPE, me.TargetFolder));
        }
示例#5
0
 public ShowRule(ShowRule O)
 {
     this.DoWhatNow = O.DoWhatNow;
     this.First = O.First;
     this.Second = O.Second;
     this.UserSuppliedText = O.UserSuppliedText;
 }
示例#6
0
        public void AddSeasonRule(int snum, ShowRule sr)
        {
            if (!SeasonRules.ContainsKey(snum))
            {
                SeasonRules[snum] = new List <ShowRule>();
            }

            SeasonRules[snum].Add(sr);
        }
示例#7
0
        public AddModifyRule(ShowRule rule, Season season, bool dvdOrder)
        {
            this.mRule     = rule;
            this.mSeason   = season;
            this.mdvdOrder = dvdOrder;

            this.InitializeComponent();

            this.FillDialog();
        }
示例#8
0
        public AddModifyRule(ShowRule rule, Season season, bool dvdOrder)
        {
            mRule     = rule;
            mSeason   = season;
            mdvdOrder = dvdOrder;

            InitializeComponent();

            FillDialog();
        }
示例#9
0
        public AddModifyRule(ShowRule rule, ShowConfiguration show, IEnumerable <ProcessedEpisode> s)
        {
            mRule  = rule;
            eps    = s;
            mOrder = show.Order;

            InitializeComponent();

            FillDialog();
        }
示例#10
0
        public AddModifyRule(ShowRule rule, [NotNull] ShowItem show, int seasonNumber)
        {
            mRule   = rule;
            mSeason = show.GetSeason(seasonNumber);
            mOrder  = show.Order;

            InitializeComponent();

            FillDialog();
        }
示例#11
0
        private void bnDelRule_Click(object sender, System.EventArgs e)
        {
            if (this.lvRuleList.SelectedItems.Count == 0)
            {
                return;
            }
            ShowRule sr = (ShowRule)(this.lvRuleList.SelectedItems[0].Tag);

            this.WorkingRuleSet.Remove(sr);
            this.FillRuleList(false, 0);
        }
示例#12
0
        private void bnAddRule_Click(object sender, System.EventArgs e)
        {
            ShowRule sr = new ShowRule();
            AddModifyRule ar = new AddModifyRule(sr);

            bool res = ar.ShowDialog() == System.Windows.Forms.DialogResult.OK;
            if (res)
                this.WorkingRuleSet.Add(sr);

            this.FillRuleList(false, 0);
        }
示例#13
0
        private void bnEdit_Click(object sender, System.EventArgs e)
        {
            if (this.lvRuleList.SelectedItems.Count == 0)
            {
                return;
            }
            ShowRule      sr = (ShowRule)(this.lvRuleList.SelectedItems[0].Tag);
            AddModifyRule ar = new AddModifyRule(sr, this.mSI.GetSeason(this.mSeasonNumber), this.mSI.DVDOrder);

            ar.ShowDialog(); // modifies rule in-place if OK'd
            this.FillRuleList(false, 0);
        }
示例#14
0
        private void EditSelectedRule()
        {
            if (lvRuleList.SelectedItems.Count == 0)
            {
                return;
            }

            ShowRule      sr = (ShowRule)lvRuleList.SelectedItems[0].Tag;
            AddModifyRule ar = new AddModifyRule(sr, show, ProcessedEpisodes());

            ar.ShowDialog(this); // modifies rule in-place if OK'd
            FillRuleList(false, 0);
        }
示例#15
0
        private void bnEdit_Click(object sender, System.EventArgs e)
        {
            if (lvRuleList.SelectedItems.Count == 0)
            {
                return;
            }

            ShowRule      sr = (ShowRule)lvRuleList.SelectedItems[0].Tag;
            AddModifyRule ar = new AddModifyRule(sr, show, mSeasonNumber);

            ar.ShowDialog(); // modifies rule in-place if OK'd
            FillRuleList(false, 0);
        }
示例#16
0
        private static void RemoveEpisode(List <ProcessedEpisode> eis, ShowItem si, ShowRule sr, int n1, int n2, string txt, int ec)
        {
            if ((n1 != -1) && (n2 != -1) && (n1 < ec) && (n2 < ec) && (n1 < n2))
            {
                ProcessedEpisode oldFirstEi   = eis[n1];
                List <string>    episodeNames = new List <string> {
                    eis[n1].Name
                };
                string         defaultCombinedName = eis[n1].Name + " + ";
                string         combinedSummary     = eis[n1].Overview + "<br/><br/>";
                List <Episode> alleps = new List <Episode>();
                alleps.Add(eis[n1]);
                for (int i = n1 + 1; i <= n2; i++)
                {
                    episodeNames.Add(eis[i].Name);
                    defaultCombinedName += eis[i].Name;
                    combinedSummary     += eis[i].Overview;
                    alleps.Add(eis[i]);
                    if (i != n2)
                    {
                        defaultCombinedName += " + ";
                        combinedSummary     += "<br/><br/>";
                    }
                }

                eis.RemoveRange(n1, n2 - n1);

                eis.RemoveAt(n1);

                string combinedName = GetBestNameFor(episodeNames, defaultCombinedName);

                ProcessedEpisode pe2 = new ProcessedEpisode(oldFirstEi, si, alleps)
                {
                    Name       = ((string.IsNullOrEmpty(txt)) ? combinedName : txt),
                    AiredEpNum = -2,
                    DvdEpNum   = -2
                };

                if (sr.DoWhatNow == RuleAction.kMerge)
                {
                    pe2.EpNum2 = -2 + n2 - n1;
                }
                else
                {
                    pe2.EpNum2 = -2;
                }

                pe2.Overview = combinedSummary;
                eis.Insert(n1, pe2);
            }
        }
示例#17
0
        private void bnAddRule_Click(object sender, System.EventArgs e)
        {
            ShowRule      sr = new ShowRule();
            AddModifyRule ar = new AddModifyRule(sr, show, mSeasonNumber);

            bool res = ar.ShowDialog() == DialogResult.OK;

            if (res)
            {
                workingRuleSet.Add(sr);
            }

            FillRuleList(false, 0);
        }
示例#18
0
        private void bnAddRule_Click(object sender, System.EventArgs e)
        {
            ShowRule      sr = new ShowRule();
            AddModifyRule ar = new AddModifyRule(sr, this.mSI.GetSeason(this.mSeasonNumber), this.mSI.DVDOrder);

            bool res = ar.ShowDialog() == System.Windows.Forms.DialogResult.OK;

            if (res)
            {
                this.WorkingRuleSet.Add(sr);
            }

            this.FillRuleList(false, 0);
        }
示例#19
0
        private void bnRuleDown_Click(object sender, System.EventArgs e)
        {
            if (this.lvRuleList.SelectedIndices.Count != 1)
            {
                return;
            }
            int p = this.lvRuleList.SelectedIndices[0];

            if (p >= (this.lvRuleList.Items.Count - 1))
            {
                return;
            }

            ShowRule sr = this.WorkingRuleSet[p];

            this.WorkingRuleSet.RemoveAt(p);
            this.WorkingRuleSet.Insert(p + 1, sr);
            this.FillRuleList(true, +1);
        }
示例#20
0
        private void bnRuleUp_Click(object sender, System.EventArgs e)
        {
            if (lvRuleList.SelectedIndices.Count != 1)
            {
                return;
            }
            int p = lvRuleList.SelectedIndices[0];

            if (p <= 0)
            {
                return;
            }

            ShowRule sr = workingRuleSet[p];

            workingRuleSet.RemoveAt(p);
            workingRuleSet.Insert(p - 1, sr);

            FillRuleList(true, -1);
        }
示例#21
0
        private static void ApplyRule([NotNull] List <ProcessedEpisode> episodes, ShowConfiguration show, [NotNull] ShowRule sr)
        {
            try
            {
                // turn nn1 and nn2 from ep number into position in array
                int n1 = FindIndex(episodes, sr.First);
                int n2 = FindIndex(episodes, sr.Second);

                switch (sr.DoWhatNow)
                {
                case RuleAction.kRename:
                    RenameEpisode(episodes, n1, sr.UserSuppliedText);
                    break;

                case RuleAction.kRemove:
                    RemoveEpisode(episodes, n1, n2);
                    break;

                case RuleAction.kIgnoreEp:
                    IgnoreEpisodes(episodes, n1, n2);
                    break;

                case RuleAction.kSplit:
                    SplitEpisode(episodes, show, sr.Second, n1);
                    break;

                case RuleAction.kMerge:
                case RuleAction.kCollapse:
                    MergeEpisodes(episodes, show, sr.DoWhatNow, n1, n2, sr.UserSuppliedText);
                    break;

                case RuleAction.kSwap:
                    SwapEpisode(episodes, n1, n2);
                    break;

                case RuleAction.kInsert:
                    InsertEpisode(episodes, show, n1, sr.UserSuppliedText, sr);
                    break;
                }

                if (sr.RenumberAfter)
                {
                    Renumber(episodes);
                }
            }
            catch (Exception e)
            {
                Logger.Warn(
                    $"Please review rules for {show.ShowName} season {episodes.FirstOrDefault()?.AppropriateSeasonNumber}");

                Logger.Warn(e,
                            $"Could not process rule for {show.ShowName}, {sr.DoWhatNow}:{sr.First}:{sr.Second}:{sr.UserSuppliedText}");
            }
        }
示例#22
0
        protected override void Check(ShowItem si, DirFilesCache dfc, TVDoc.ScanSettings settings)
        {
            if (settings.Token.IsCancellationRequested)
            {
                throw new TVRenameOperationInterruptedException();
            }

            if (!TVSettings.Instance.AutoMergeLibraryEpisodes)
            {
                return;
            }

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

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

            int[] numbers = new int[si.SeasonEpisodes.Keys.Count];
            si.SeasonEpisodes.Keys.CopyTo(numbers, 0);

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

                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
                }

                if ((snum == 0) && TVSettings.Instance.IgnoreAllSpecials)
                {
                    continue;
                }

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

                List <ProcessedEpisode> eps = si.SeasonEpisodes[snum];

                List <ShowRule> rulesToAdd = new List <ShowRule>();

                foreach (string folder in folders)
                {
                    if (settings.Token.IsCancellationRequested)
                    {
                        throw new TVRenameOperationInterruptedException();
                    }

                    FileInfo[] files = dfc.GetFiles(folder);
                    if (files is null)
                    {
                        continue;
                    }

                    foreach (FileInfo fi in files)
                    {
                        if (settings.Token.IsCancellationRequested)
                        {
                            throw new TVRenameOperationInterruptedException();
                        }

                        if (!fi.IsMovieFile())
                        {
                            continue; //not a video file, so ignore
                        }

                        if (!FinderHelper.FindSeasEp(fi, out int seasNum, out int epNum, out int maxEp, si,
                                                     out TVSettings.FilenameProcessorRE _))
                        {
                            continue; // can't find season & episode, so this file is of no interest to us
                        }

                        if (seasNum == -1)
                        {
                            seasNum = snum;
                        }

                        int epIdx = eps.FindIndex(x =>
                                                  ((x.AppropriateEpNum == epNum) && (x.AppropriateSeasonNumber == seasNum)));

                        if (epIdx == -1)
                        {
                            continue; // season+episode number don't correspond to any episode we know of from thetvdb
                        }

                        ProcessedEpisode ep = eps[epIdx];

                        if (ep.Type != ProcessedEpisode.ProcessedEpisodeType.merged && maxEp != -1)
                        {
                            LOGGER.Info(
                                $"Looking at {ep.Show.ShowName} and have identified that episode {epNum} and {maxEp} of season {seasNum} should be merged into one file {fi.FullName}");

                            ShowRule sr = new ShowRule
                            {
                                DoWhatNow = RuleAction.kMerge,
                                First     = epNum,
                                Second    = maxEp
                            };

                            rulesToAdd.Add(sr);
                        }
                    } // foreach file in folder
                }     // for each folder for this season of this show

                foreach (ShowRule sr in rulesToAdd)
                {
                    si.AddSeasonRule(snum, sr);
                    LOGGER.Info($"Added new rule automatically for {sr}");

                    //Regenerate the episodes with the new rule added
                    ShowLibrary.GenerateEpisodeDict(si);
                }
            } // for each season of this show
        }
示例#23
0
        private static void MergeEpisodes([NotNull] List <ProcessedEpisode> eis, ShowItem si, ShowRule sr, int fromIndex, int toIndex, [CanBeNull] string newName)
        {
            int ec = eis.Count;

            if (ValidIndex(fromIndex, ec) && ValidIndex(toIndex, ec) && (fromIndex < toIndex))
            {
                ProcessedEpisode oldFirstEi   = eis[fromIndex];
                List <string>    episodeNames = new List <string> {
                    eis[fromIndex].Name
                };
                string         defaultCombinedName = eis[fromIndex].Name + " + ";
                string         combinedSummary     = eis[fromIndex].Overview + "<br/><br/>";
                List <Episode> alleps = new List <Episode> {
                    eis[fromIndex]
                };
                for (int i = fromIndex + 1; i <= toIndex; i++)
                {
                    episodeNames.Add(eis[i].Name);
                    defaultCombinedName += eis[i].Name;
                    combinedSummary     += eis[i].Overview;
                    alleps.Add(eis[i]);
                    if (i != toIndex)
                    {
                        defaultCombinedName += " + ";
                        combinedSummary     += "<br/><br/>";
                    }
                }

                eis.RemoveRange(fromIndex, toIndex - fromIndex);

                eis.RemoveAt(fromIndex);

                string combinedName = GetBestNameFor(episodeNames, defaultCombinedName);

                ProcessedEpisode pe2 = new ProcessedEpisode(oldFirstEi, si, alleps)
                {
                    Name       = ((string.IsNullOrEmpty(newName)) ? combinedName : newName),
                    AiredEpNum = -2,
                    DvdEpNum   = -2,
                    EpNum2     = sr.DoWhatNow == RuleAction.kMerge ? -2 + toIndex - fromIndex : -2,
                    Overview   = combinedSummary
                };

                eis.Insert(fromIndex, pe2);
            }
        }
示例#24
0
        private static void MergeShowEpisodes([NotNull] ShowItem si, DirFilesCache dfc, CancellationToken token, int snum, IEnumerable <string> folders)
        {
            if (snum == 0 && si.CountSpecials)
            {
                return;
            }

            if (snum == 0 && TVSettings.Instance.IgnoreAllSpecials)
            {
                return;
            }

            List <ProcessedEpisode> eps = si.SeasonEpisodes[snum];

            List <ShowRule> rulesToAdd = new List <ShowRule>();

            foreach (string folder in folders)
            {
                if (token.IsCancellationRequested)
                {
                    throw new TVRenameOperationInterruptedException();
                }

                FileInfo[] files = dfc.GetFiles(folder);
                if (files is null)
                {
                    continue;
                }

                foreach (FileInfo fi in files)
                {
                    if (token.IsCancellationRequested)
                    {
                        throw new TVRenameOperationInterruptedException();
                    }

                    if (!fi.IsMovieFile())
                    {
                        continue; //not a video file, so ignore
                    }

                    if (!FinderHelper.FindSeasEp(fi, out int seasNum, out int epNum, out int maxEp, si,
                                                 out TVSettings.FilenameProcessorRE _))
                    {
                        continue; // can't find season & episode, so this file is of no interest to us
                    }

                    if (seasNum == -1)
                    {
                        seasNum = snum;
                    }

                    int epIdx = eps.FindIndex(x =>
                                              x.AppropriateEpNum == epNum && x.AppropriateSeasonNumber == seasNum);

                    if (epIdx == -1)
                    {
                        continue; // season+episode number don't correspond to any episode we know of from thetvdb
                    }

                    ProcessedEpisode ep = eps[epIdx];

                    if (ep.Type == ProcessedEpisode.ProcessedEpisodeType.merged || maxEp == -1)
                    {
                        continue;
                    }

                    LOGGER.Info(
                        $"Looking at {ep.Show.ShowName} and have identified that episode {epNum} and {maxEp} of season {seasNum} should be merged into one file {fi.FullName}");

                    ShowRule sr = new ShowRule
                    {
                        DoWhatNow = RuleAction.kMerge,
                        First     = epNum,
                        Second    = maxEp
                    };

                    rulesToAdd.Add(sr);
                } // foreach file in folder
            }     // for each folder for this season of this show

            foreach (ShowRule sr in rulesToAdd)
            {
                si.AddSeasonRule(snum, sr);
                LOGGER.Info($"Added new rule automatically for {sr}");
            }

            if (rulesToAdd.Any())
            {
                //Regenerate the episodes with the new rule added
                ShowLibrary.GenerateEpisodeDict(si);
            }
        }
示例#25
0
        private bool ReviewFile(ItemMissing me, ItemList addTo, DirCacheEntry dce)
        {
            if (ActionCancel)
            {
                return(true);
            }

            int  season  = me.Episode.AppropriateSeasonNumber;
            int  epnum   = me.Episode.AppropriateEpNum;
            bool matched = false;

            try
            {
                if (FileHelper.IgnoreFile(dce.TheFile))
                {
                    return(false);
                }

                //do any of the possible names for the series match the filename?
                matched = (me.Episode.Show.GetSimplifiedPossibleShowNames()
                           .Any(name => FileHelper.SimplifyAndCheckFilename(dce.SimplifiedFullName, name)));

                if (matched)
                {
                    bool regularMatch = TVDoc.FindSeasEp(dce.TheFile, out int seasF, out int epF, out int maxEp, me.Episode.Show) &&
                                        seasF == season &&
                                        epF == epnum;

                    bool sequentialMatch = me.Episode.Show.UseSequentialMatch &&
                                           TVDoc.MatchesSequentialNumber(dce.TheFile.Name, ref seasF, ref epF, me.Episode) &&
                                           seasF == season &&
                                           epF == epnum;

                    if (regularMatch || sequentialMatch)
                    {
                        if (maxEp != -1 && TVSettings.Instance.AutoMergeDownloadEpisodes)
                        {
                            ShowRule sr = new ShowRule
                            {
                                DoWhatNow = RuleAction.kMerge,
                                First     = epF,
                                Second    = maxEp
                            };
                            me.Episode.Show?.AddSeasonRule(seasF, sr);

                            LOGGER.Info(
                                $"Looking at {me.Episode.Show.ShowName} and have identified that episode {epF} and {maxEp} of season {seasF} have been merged into one file {dce.TheFile.FullName}");
                            LOGGER.Info($"Added new rule automatically for {sr}");

                            //Regenerate the episodes with the new rule added
                            ShowLibrary.GenerateEpisodeDict(me.Episode.Show);

                            //Get the newly created processed episode we are after
                            // ReSharper disable once InconsistentNaming
                            ProcessedEpisode newPE = me.Episode;
                            foreach (ProcessedEpisode pe in me.Episode.Show.SeasonEpisodes[seasF])
                            {
                                if (pe.AppropriateEpNum == epF && pe.EpNum2 == maxEp)
                                {
                                    newPE = pe;
                                }
                            }

                            me = new ItemMissing(newPE, me.TargetFolder,
                                                 TVSettings.Instance.FilenameFriendly(TVSettings.Instance.NamingStyle.NameFor(newPE)));
                        }
                        FileInfo fi = new FileInfo(me.TheFileNoExt + dce.TheFile.Extension);

                        if (TVSettings.Instance.PreventMove)
                        {
                            //We do not want to move the file, just rename it
                            fi = new FileInfo(dce.TheFile.DirectoryName + System.IO.Path.DirectorySeparatorChar + me.Filename +
                                              dce.TheFile.Extension);
                        }

                        // don't remove the base search folders
                        bool doTidyup = true;
                        foreach (string folder in TVSettings.Instance.DownloadFolders)
                        {
                            if (folder.SameDirectoryLocation(fi.Directory.FullName))
                            {
                                doTidyup = false;
                                break;
                            }
                        }

                        if (dce.TheFile.FullName != fi.FullName)
                        {
                            addTo.Add(new ActionCopyMoveRename(ActionCopyMoveRename.Op.copy, dce.TheFile, fi, me.Episode,
                                                               doTidyup ? TVSettings.Instance.Tidyup : null, me));
                        }

                        DownloadIdentifiersController di = new DownloadIdentifiersController();

                        // if we're copying/moving a file across, we might also want to make a thumbnail or NFO for it
                        addTo.Add(di.ProcessEpisode(me.Episode, fi));

                        return(true);
                    }
                }
            }
            catch (System.IO.PathTooLongException e)
            {
                string t = "Path too long. " + dce.TheFile.FullName + ", " + e.Message;
                LOGGER.Warn(e, "Path too long. " + dce.TheFile.FullName);

                t += ".  More information is available in the log file";
                if ((!Doc.Args.Unattended) && (!Doc.Args.Hide))
                {
                    MessageBox.Show(t, "Path too long", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }

                t  = "DirectoryName " + dce.TheFile.DirectoryName + ", File name: " + dce.TheFile.Name;
                t += matched ? ", matched.  " : ", no match.  ";
                if (matched)
                {
                    t += "Show: " + me.Episode.TheSeries.Name + ", Season " + season + ", Ep " + epnum + ".  ";
                    t += "To: " + me.TheFileNoExt;
                }
                LOGGER.Warn(t);
            }
            return(false);
        }
示例#26
0
        private static void InsertEpisode([NotNull] IList <ProcessedEpisode> eis, ShowConfiguration si, int index, string txt, [NotNull] ShowRule sr)
        {
            // this only applies for inserting an episode, at the end of the list
            if (sr.First == eis[eis.Count - 1].AppropriateEpNum + 1) // after the last episode
            {
                index = eis.Count;
            }

            int ec = eis.Count;

            if (ValidIndex(index, ec))
            {
                ProcessedEpisode t = eis[index];
                ProcessedEpisode n = new ProcessedEpisode(t, si, txt, t.AiredEpNum + 1, t.DvdEpNum + 1, t.EpNum2 + 1);
                eis.Insert(index, n);
            }
            else if (index == ec)
            {
                ProcessedEpisode t = eis[index - 1];
                ProcessedEpisode n = new ProcessedEpisode(t, si, txt, t.AiredEpNum + 1, t.DvdEpNum + 1, t.EpNum2 + 1);
                eis.Add(n);
            }
            else
            {
                //Parameters are invalid, so we'll do nothing
            }
        }