Esempio n. 1
0
        private static (int seas, int ep, int maxEp) IdentifyEpisode(ShowConfiguration?si, [NotNull] Match m, TVSettings.FilenameProcessorRE re)
        {
            if (!int.TryParse(m.Groups["s"].ToString(), out int seas))
            {
                if (!re.RegExpression.Contains("<s>") && (si?.AppropriateSeasons().Count ?? 0) == 1)
                {
                    seas = 1;
                }
                else
                {
                    seas = -1;
                }
            }

            if (!int.TryParse(m.Groups["e"].ToString(), out int ep))
            {
                ep = -1;
            }

            if (!int.TryParse(m.Groups["f"].ToString(), out int maxEp))
            {
                maxEp = -1;
            }

            return(seas, ep, maxEp);
        }
Esempio n. 2
0
        private List <ProcessedEpisode>?MatchEpisodes(FileInfo droppedFile)
        {
            ShowConfiguration?bestShow = FinderHelper.FindBestMatchingShow(droppedFile, MDoc.TvLibrary.Shows);

            if (bestShow is null)
            {
                return(null);
            }

            if (!FinderHelper.FindSeasEp(droppedFile, out int seasonNum, out int episodeNum, out int _, bestShow,
                                         out TVSettings.FilenameProcessorRE _))
            {
                return(null);
            }

            try
            {
                ProcessedEpisode episode = bestShow.GetEpisode(seasonNum, episodeNum);

                return(new List <ProcessedEpisode> {
                    episode
                });
            }
            catch (ShowConfiguration.EpisodeNotFoundException)
            {
                return(null);
            }
        }
Esempio n. 3
0
        public static bool FindSeasEpNameCheck(FileInfo?fi, ShowConfiguration?si, out int seas, out int ep)
        {
            ep   = -1;
            seas = -1;

            if (fi is null || si is null)
            {
                return(false);
            }

            CachedSeriesInfo?ser = si.CachedShow;

            if (ser is null)
            {
                return(false);
            }

            string simplifiedFilename = fi.Name.CompareName();

            foreach (Episode epi in si.EpisodesToUse())
            {
                string simplifiedEpName = epi.Name.CompareName();

                if (simplifiedFilename.Contains(simplifiedEpName))
                {
                    seas = epi.GetSeasonNumber(si.Order);
                    ep   = epi.GetEpisodeNumber(si.Order);
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 4
0
        private static void TvdbFor(ShowConfiguration?si)
        {
            if (si?.WebsiteUrl is null)
            {
                return;
            }

            Helpers.OpenUrl(si.WebsiteUrl);
        }
Esempio n. 5
0
 private static void TvSourceFor(ShowConfiguration?si)
 {
     if (si != null)
     {
         if (si.WebsiteUrl.HasValue())
         {
             Helpers.OpenUrl(si.WebsiteUrl !);
         }
         else if (si.CachedShow?.WebUrl.HasValue() ?? false)
         {
             Helpers.OpenUrl(si.CachedShow?.WebUrl !);
         }
     }
 }
Esempio n. 6
0
        public static bool FindSeasEp(string directory, string filename, out int seas, out int ep, out int maxEp,
                                      ShowConfiguration?si, IEnumerable <TVSettings.FilenameProcessorRE> rexps, out TVSettings.FilenameProcessorRE?rex)
        {
            string showNameHint = si != null ? si.ShowName : string.Empty;

            maxEp = -1;
            seas  = -1;
            ep    = -1;
            rex   = null;

            filename = SimplifyFilename(filename, showNameHint);

            string fullPath = directory.HasValue()
                ? directory + Path.DirectorySeparatorChar + filename
                : filename; // construct full path with sanitised filename

            fullPath = fullPath.ToLower() + " ";

            foreach (TVSettings.FilenameProcessorRE re in rexps.Where(re => re.Enabled))
            {
                try
                {
                    string pathToTest = re.UseFullPath ? fullPath : filename.ToLower() + " ";

                    Match m = Regex.Match(pathToTest, re.RegExpression, RegexOptions.IgnoreCase);

                    if (m.Success)
                    {
                        (seas, ep, maxEp) = IdentifyEpisode(si, m, re);

                        rex = re;
                        if (seas != -1 && ep != -1)
                        {
                            return(true);
                        }
                    }
                }
                catch (FormatException fe)
                {
                    Logger.Warn($"Please check for the regex {re.RegExpression} as it's causing an FormatException error {fe.Message}");
                }
                catch (ArgumentException ae)
                {
                    Logger.Warn($"Please check for the regex {re.RegExpression} as it's causing an ArgumentException error {ae.Message}");
                }
            }

            return(seas != -1 && ep != -1);
        }
Esempio n. 7
0
        public ItemList ProcessShow(ShowConfiguration?si)
        {
            ItemList theActionList = new ItemList();

            if (si is null)
            {
                return(theActionList);
            }

            foreach (DownloadIdentifier di in identifiers)
            {
                theActionList.Add(di.ProcessShow(si));
            }
            return(theActionList);
        }
Esempio n. 8
0
        public ItemList ProcessSeason(ShowConfiguration?si, string folder, int snum)
        {
            ItemList theActionList = new ItemList();

            if (si is null)
            {
                return(theActionList);
            }

            foreach (DownloadIdentifier di in identifiers)
            {
                theActionList.Add(di.ProcessSeason(si, folder, snum));
            }
            return(theActionList);
        }
        private void GotoEpGuide(ShowConfiguration?si, PossibleMergedEpisode?mlastSelected)
        {
            if (mlastSelected != null)
            {
                mainUi.GotoEpguideFor(mlastSelected.Episode, true);
            }
            else
            {
                if (si != null)
                {
                    mainUi.GotoEpguideFor(si, true);
                }
            }

            Close();
        }
Esempio n. 10
0
        public ItemList ForceUpdateSeason(DownloadIdentifier.DownloadType dt, ShowConfiguration?si, string folder, int snum)
        {
            ItemList theActionList = new ItemList();

            if (si is null)
            {
                return(theActionList);
            }

            foreach (DownloadIdentifier di in identifiers)
            {
                if (dt == di.GetDownloadType())
                {
                    theActionList.Add(di.ProcessSeason(si, folder, snum, true));
                }
            }
            return(theActionList);
        }
Esempio n. 11
0
        public static bool FileNeeded(DirectoryInfo?di, ShowConfiguration?si, DirFilesCache dfc)
        {
            if (di is null)
            {
                throw new ArgumentNullException(nameof(di));
            }

            if (si is null)
            {
                throw new ArgumentNullException(nameof(si));
            }

            if (FindSeasEp(di, out int seasF, out int epF, si, out _))
            {
                return(EpisodeNeeded(si, dfc, seasF, epF, di));
            }

            //We may need the file
            return(true);
        }
Esempio n. 12
0
        private void lvDuplicates_MouseClick(object sender, [NotNull] MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Right)
            {
                return;
            }

            if (lvMergedEpisodes.SelectedItems.Count == 0)
            {
                return;
            }

            PossibleMergedEpisode?mlastSelected = (PossibleMergedEpisode)lvMergedEpisodes.SelectedItems[0].Tag;
            ListViewItem?         mlastClicked  = lvMergedEpisodes.SelectedItems[0];
            ShowConfiguration?    si            = mlastSelected?.ShowConfiguration;

            if (si == null)
            {
                return;
            }

            Point pt = lvMergedEpisodes.PointToScreen(new Point(e.X, e.Y));

            possibleMergedEpisodeRightClickMenu.Items.Clear();

            AddRcMenuItem("Episode Guide", (o, args) => GotoEpGuide(si, mlastSelected));
            AddRcMenuItem("Force Refresh", (o, args) => mainUi.ForceRefresh(si, false));
            AddRcMenuItem("Edit Show", (o, args) => mainUi.EditShow(si));

            AddRcMenuItem("Edit " + ProcessedSeason.UIFullSeasonWord(mlastSelected.SeasonNumber),
                          (o, args) => mainUi.EditSeason(si, mlastSelected.SeasonNumber));

            possibleMergedEpisodeRightClickMenu.Items.Add(new ToolStripSeparator());
            AddRcMenuItem("Add Rule", (o, args) => AddRule(mlastSelected, si, mlastClicked));

            possibleMergedEpisodeRightClickMenu.Show(pt);
        }
Esempio n. 13
0
        protected readonly ShowConfiguration?SelectedShow;  // if for an entire show, rather than specific episode

        protected ActionWriteMetadata(FileInfo where, ShowConfiguration sI)
        {
            Where        = where;
            SelectedShow = sI;
        }
Esempio n. 14
0
        private void ProcessFile([NotNull] FileInfo droppedFile, IDialogParent owner)
        {
            if ((droppedFile.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
            {
                Logger.Error($"{droppedFile.FullName} is a directory, ignoring.");
                return;
            }

            if (!droppedFile.IsMovieFile())
            {
                Logger.Info($"{droppedFile.FullName} is not a movie file, ignoring.");
                return;
            }

            // Note that the extension of the file may not be fi.extension as users can put ".mkv.t" for example as an extension
            string otherExtension = TVSettings.Instance.FileHasUsefulExtensionDetails(droppedFile, true);

            ShowConfiguration?bestShow = (string)cbShowList.SelectedItem == "<Auto>"
                ? FinderHelper.FindBestMatchingShow(droppedFile.FullName, mDoc.TvLibrary.Shows)
                : mDoc.TvLibrary.Shows.FirstOrDefault(item => item.ShowName == (string)cbShowList.SelectedItem);

            if (bestShow is null)
            {
                if (TVSettings.Instance.AutoAddAsPartOfQuickRename)
                {
                    List <MediaConfiguration> addedShows = FinderHelper.FindMedia(new List <FileInfo> {
                        droppedFile
                    }, mDoc, owner);
                    bestShow = addedShows.OfType <ShowConfiguration>().FirstOrDefault();

                    if (bestShow != null)
                    {
                        mDoc.Add(bestShow);
                        mDoc.TvAddedOrEdited(true, false, false, parent, bestShow);

                        Logger.Info($"Added new show called: {bestShow.ShowName}");
                    }
                }

                if (bestShow is null)
                {
                    Logger.Info($"Cannot find show for {droppedFile.FullName}, ignoring this file.");
                    return;
                }
            }

            if (!FinderHelper.FindSeasEp(droppedFile, out int seasonNum, out int episodeNum, out int _, bestShow,
                                         out TVSettings.FilenameProcessorRE _))
            {
                Logger.Info($"Cannot find episode for {bestShow.ShowName} for {droppedFile.FullName}, ignoring this file.");
                return;
            }

            try
            {
                ProcessedEpisode episode = bestShow.GetEpisode(seasonNum, episodeNum);

                string filename = TVSettings.Instance.FilenameFriendly(
                    TVSettings.Instance.NamingStyle.NameFor(episode, otherExtension,
                                                            droppedFile.DirectoryName.Length));

                FileInfo targetFile =
                    new FileInfo(droppedFile.DirectoryName.EnsureEndsWithSeparator() + filename);

                if (droppedFile.FullName == targetFile.FullName)
                {
                    Logger.Info(
                        $"Can't rename file for {bestShow.ShowName} for {droppedFile.FullName}, as it already has the appropriate name.");

                    return;
                }

                mDoc.TheActionList.Add(new ActionCopyMoveRename(droppedFile, targetFile, episode, mDoc));

                // if we're copying/moving a file across, we might also want to make a thumbnail or NFO for it
                mDoc.TheActionList.AddNullableRange(new DownloadIdentifiersController().ProcessEpisode(episode, targetFile));

                //If keep together is active then we may want to copy over related files too
                if (TVSettings.Instance.KeepTogether)
                {
                    FileFinder.KeepTogether(mDoc.TheActionList, false, true, mDoc);
                }
            }
            catch (ShowConfiguration.EpisodeNotFoundException)
            {
                Logger.Info(
                    $"Can't rename file for {bestShow.ShowName} for {droppedFile.FullName}, as it does not have Episode {episodeNum} for Season {seasonNum}.");
            }
        }
Esempio n. 15
0
        public AddEditSeasEpFinders(List <TVSettings.FilenameProcessorRE> rex, List <ShowConfiguration> sil, ShowConfiguration?initialShow,
                                    string initialFolder)
        {
            OutputRegularExpressions = rex;
            shows = sil;

            InitializeComponent();

            SetupGrid();
            FillGrid(OutputRegularExpressions);

            foreach (ShowConfiguration si in shows)
            {
                cbShowList.Items.Add(si.ShowName);
                if (si == initialShow)
                {
                    cbShowList.SelectedIndex = cbShowList.Items.Count - 1;
                }
            }

            txtFolder.Text = initialFolder;
        }
Esempio n. 16
0
        public static bool FindSeasEp(FileInfo?fi, out int seas, out int ep, out int maxEp, ShowConfiguration?si,
                                      IEnumerable <TVSettings.FilenameProcessorRE> rexps, out TVSettings.FilenameProcessorRE?re)
        {
            if (fi is null)
            {
                re    = null;
                seas  = -1;
                ep    = -1;
                maxEp = -1;
                return(false);
            }

            return(FindSeasEp(fi.Directory.FullName, fi.RemoveExtension(), out seas, out ep, out maxEp, si, rexps, out re));
        }
Esempio n. 17
0
 public static bool FindSeasEp(string itemName, out int seas, out int ep, out int maxEp, ShowConfiguration?si, IEnumerable <TVSettings.FilenameProcessorRE> rexps, out TVSettings.FilenameProcessorRE?re)
 {
     return(FindSeasEp(string.Empty, itemName, out seas, out ep, out maxEp, si, rexps, out re));
 }
Esempio n. 18
0
 public static bool FindSeasEp(FileInfo fi, out int seas, out int ep, out int maxEp, ShowConfiguration?si, out TVSettings.FilenameProcessorRE?re)
 {
     return(FindSeasEp(fi, out seas, out ep, out maxEp, si, TVSettings.Instance.FNPRegexs, out re));
 }
Esempio n. 19
0
 public static bool FindSeasEp(FileInfo theFile, out int seasF, out int epF, out int maxEp, ShowConfiguration?sI)
 {
     return(FindSeasEp(theFile, out seasF, out epF, out maxEp, sI, out TVSettings.FilenameProcessorRE _));
 }
Esempio n. 20
0
 public static bool FindSeasEp(string itemName, out int seas, out int ep, out int maxEp, ShowConfiguration?show)
 {
     return(FindSeasEp(string.Empty, itemName, out seas, out ep, out maxEp, show, TVSettings.Instance.FNPRegexs, out TVSettings.FilenameProcessorRE _));
 }
Esempio n. 21
0
        public static bool FindSeasEpDateCheck(string?filename, out int seas, out int ep, ShowConfiguration?si)
        {
            ep   = -1;
            seas = -1;

            if (filename is null || si is null)
            {
                return(false);
            }

            // look for a valid airdate in the filename
            // check for YMD, DMY, and MDY
            // only check against airdates we expect for the given show
            CachedSeriesInfo ser = si.CachedShow;

            if (ser is null)
            {
                return(false);
            }

            string[] dateFormats = { "yyyy-MM-dd", "dd-MM-yyyy", "MM-dd-yyyy", "yy-MM-dd", "dd-MM-yy", "MM-dd-yy" };

            // force possible date separators to a dash
            filename = filename.Replace("/", "-");
            filename = filename.Replace(".", "-");
            filename = filename.Replace(",", "-");
            filename = filename.Replace(" ", "-");

            foreach (Episode epi in si.EpisodesToUse())
            {
                LocalDateTime?dt = epi.GetAirDateDt();  // file will have local timezone date, not ours
                if (dt is null)
                {
                    continue;
                }

                TimeSpan closestDate = TimeSpan.MaxValue;

                foreach (string dateFormat in dateFormats)
                {
                    string datestr = dt.Value.ToString(dateFormat, CultureInfo.CurrentCulture);

                    if (filename.Contains(datestr) && DateTime.TryParseExact(datestr, dateFormat,
                                                                             new CultureInfo("en-GB"), DateTimeStyles.None, out DateTime dtInFilename))
                    {
                        TimeSpan timeAgo = DateTime.Now.Subtract(dtInFilename);

                        if (timeAgo < closestDate)
                        {
                            seas        = epi.GetSeasonNumber(si.Order);
                            ep          = epi.GetEpisodeNumber(si.Order);
                            closestDate = timeAgo;
                        }
                    }
                }
            }

            return(ep != -1 && seas != -1);
        }
Esempio n. 22
0
        private static void UpdateEpisodeFields([NotNull] Episode episode, ShowConfiguration?show, [NotNull] XElement root, bool isMultiPart)
        {
            root.UpdateElement("title", episode.Name, true);
            root.UpdateElement("id", episode.EpisodeId, true);
            root.UpdateElement("plot", episode.Overview, true);
            UpdateAmongstElements(root, "studio", episode.TheCachedSeries.Network);

            UpdateId(root, "tvdb", "true", episode.EpisodeId);
            UpdateId(root, "imdb", "false", episode.ImdbCode);

            string showRating = episode.EpisodeRating;

            if (showRating != null)
            {
                UpdateRatings(root, showRating, episode.SiteRatingCount ?? 0);
            }

            if (!(show is null))
            {
                root.UpdateElement("originaltitle", show.ShowName, true);
                root.UpdateElement("showtitle", show.ShowName, true);
                root.UpdateElement("season", episode.GetSeasonNumber(show.Order), true);
                root.UpdateElement("episode", episode.GetEpisodeNumber(show.Order), true);
                root.UpdateElement("mpaa", show.CachedShow?.ContentRating, true);

                //actor(s) and guest actor(s)
                CachedSeriesInfo s = show.CachedShow;
                if (s != null)
                {
                    ReplaceActors(root, episode.AllActors(s));
                }
            }

            if (episode.FirstAired.HasValue)
            {
                root.UpdateElement("aired", episode.FirstAired.Value.ToString("yyyy-MM-dd"), true);
            }

            //Director(s)
            string?epDirector = episode.EpisodeDirector;

            if (!string.IsNullOrEmpty(epDirector))
            {
                string[] dirs = epDirector.Split('|');
                if (dirs.Any())
                {
                    root.ReplaceElements("director", dirs);
                }
            }

            //Writers(s)
            string?epWriter = episode.Writer;

            if (!string.IsNullOrEmpty(epWriter))
            {
                string[] writers = epWriter.Split('|');
                if (writers.Any())
                {
                    root.ReplaceElements("credits", writers);
                }
            }

            if (isMultiPart && show != null)
            {
                XElement resumeElement = root.GetOrCreateElement("resume");

                //we have to put 0 as we don't know where the multipart episode starts/ends
                resumeElement.UpdateElement("position", 0);
                resumeElement.UpdateElement("total", 0);

                //For now we only put art in for multipart episodes. Kodi finds the art appropriately
                //without our help for the others

                string filename = TVSettings.Instance.FilenameFriendly(show, episode);

                string thumbFilename = filename + ".jpg";
                UpdateAmongstElements(root, "thumb", thumbFilename);
                //Should be able to do this using the local filename, but only seems to work if you provide a URL
                //XMLHelper.WriteElementToXML(writer, "thumb", LocalCache.Instance.GetTVDBDownloadURL(episode.GetFilename()))
            }
        }