コード例 #1
0
        public static void SetMp4FileMetadata(this ConsoleClient item, TvEpisode episode, string input, string output)
        {
            var seasonNumArg  = (episode.SeasonNumber == Helpers.InvalidSeasonNumber) ? String.Empty : $"--TVSeasonNum {episode.SeasonNumber}";
            var episodeNumArg = (episode.EpisodeNumber == Helpers.InvalidEpisodeNumber) ? String.Empty : $"--TVEpisodeNum {episode.EpisodeNumber}";
            var artworkArg    = (episode.ThumbnailFile == null) ? String.Empty : $"--artwork \"{episode.ThumbnailFile}\"";
            var aired         = episode.AiredTime.ToString(Helpers.UtcDateTimeFormat);

            var args = new string[]
            {
                $"\"{input}\"",
                $"--title \"{episode.Title}\"",
                "--stik \"TV Show\"",
                $"--year \"{aired}\"",
                $"--genre \"{episode.Genre}\"",
                $"--TVNetwork \"{episode.Channel}\"",
                $"--TVShowName \"{episode.ShowName}\"",
                seasonNumArg,
                episodeNumArg,
                $"--description \"{episode.Description}\"",
                $"--comment \"{episode.Credits}\"",
                artworkArg,
                $"--output \"{output}\""
            };

            item.Run(args);
        }
コード例 #2
0
        public static TvEpisode MapShowName(this TvEpisode result, ShowNameMapEntry[] map)
        {
            var name = result.ShowName;

            if (map != null && map.Any() && String.IsNullOrWhiteSpace(name) == false)
            {
                foreach (var correction in map)
                {
                    var match = Regex.Match(name, correction.Regex, RegexOptions.IgnoreCase);
                    if (match.Success)
                    {
                        if (String.IsNullOrWhiteSpace(correction.Name) == false)
                        {
                            result.ShowName = correction.Name;
                        }
                        if (String.IsNullOrWhiteSpace(correction.KodiUrl) == false)
                        {
                            result.KodiUrl = correction.KodiUrl;
                        }
                        break;
                    }
                }
            }

            return(result);
        }
コード例 #3
0
        public static void SaveNfoFile(this TvEpisode item, string path)
        {
            var episode = new XElement("episodedetails");

            if (item.SeasonNumber != Helpers.InvalidSeasonNumber && item.EpisodeNumber != Helpers.InvalidEpisodeNumber)
            {
                episode.Add(
                    new XElement("season", item.SeasonNumber),
                    new XElement("episode", item.EpisodeNumber)
                    );
            }
            if (String.IsNullOrWhiteSpace(item.ShowName) == false)
            {
                episode.Add(new XElement("showtitle", item.ShowName));
            }
            episode.Add(new XElement("originaltitle", item.OriginalTitle));
            episode.Add(new XElement("title", item.Title));
            if (String.IsNullOrWhiteSpace(item.Description) == false)
            {
                episode.Add(new XElement("plot", item.Description));
            }
            if (item.AiredTime != DateTime.MinValue)
            {
                episode.Add(new XElement("aired", item.AiredTime));
            }
            if (String.IsNullOrWhiteSpace(item.Genre) == false)
            {
                episode.Add(new XElement("genre", item.Genre));
            }
            if (String.IsNullOrWhiteSpace(item.Channel) == false)
            {
                episode.Add(new XElement("studio", item.Channel));
            }
            if (String.IsNullOrWhiteSpace(item.Credits) == false)
            {
                episode.Add(new XElement("credits", item.Credits));
            }
            if (item.OriginalAirDate != DateTime.MinValue)
            {
                episode.Add(new XElement("premiered", item.OriginalAirDate.Date));
            }

            if (String.IsNullOrWhiteSpace(item.ThumbnailFile) == false)
            {
                var thumb = Path.GetFileName(item.ThumbnailFile);
                episode.Add(new XElement("thumb", thumb));
            }

            var xml = new XDocument(
                new XDeclaration("1.0", "utf-8", "yes"),
                episode
                );

            xml.Save(path);
        }
コード例 #4
0
        public static TvEpisode FromFileName(this TvEpisode result, string fileName)
        {
            if (TrySetFromTvheadendFileName(result, fileName) == false)
            {
                if (TrySetFromMediaCenterFileName(result, fileName) == false)
                {
                    _ = TrySetFromKodiCompatibleFileName(result, fileName);
                }
            }

            return(result);
        }
コード例 #5
0
        public static TvEpisode FromJsonMetadata(this TvEpisode result, JsonPayload json)
        {
            if (json.TryGetValue <string>("format.tags.DATE_BROADCASTED", out string broadcastDateStr) == false)
            {
                _ = json.TryGetValue <string>("format.tags.date", out broadcastDateStr);
            }
            if (String.IsNullOrWhiteSpace(broadcastDateStr) == false)
            {
                if (DateTime.TryParse(broadcastDateStr, CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal, out DateTime date))
                {
                    result.AiredTime = date;
                }
            }
            if (json.TryGetValue <string>("format.tags.title", out string title))
            {
                result.OriginalTitle = title;
                result.Title         = title;
                result.ShowName      = title;
            }
            if (json.TryGetValue <string>("format.tags.show", out string show))
            {
                result.ShowName = show;
            }
            if (json.TryGetValue <string>("format.tags.SUMMARY", out string description) == false)
            {
                _ = json.TryGetValue <string>("format.tags.description", out description);
            }
            if (String.IsNullOrWhiteSpace(description) == false)
            {
                result.Description = description.FixBBCEncoding();
            }
            if (json.TryGetValue <double>("format.duration", out double duration))
            {
                result.Duration = TimeSpan.FromSeconds(duration);
            }
            if (json.TryGetValue <string>("format.tags.TVCHANNEL", out string channel) == false)
            {
                if (json.TryGetValue <string>("format.tags.network", out channel) == false)
                {
                    _ = json.TryGetValue <string>("programs.tags.service_name", out channel);
                }
            }
            if (String.IsNullOrWhiteSpace(channel) == false)
            {
                result.Channel = channel;
            }
            if (json.TryGetValue <string>("format.tags.CONTENT_TYPE", out string contentType))
            {
                result.Genre = contentType;
            }

            return(result);
        }
コード例 #6
0
        private static bool TrySetFromKodiCompatibleFileName(TvEpisode item, string fileName)
        {
            var  match  = Regex.Match(fileName, @"^(.+)s(\d+)e(\d+)", RegexOptions.IgnoreCase);
            bool result = match.Success && match.Groups.Count == 4;

            if (result)
            {
                item.ShowName      = match.Groups[1].Value.Trim();
                item.SeasonNumber  = int.Parse(match.Groups[2].Value);
                item.EpisodeNumber = int.Parse(match.Groups[3].Value);
            }

            return(result);
        }
コード例 #7
0
 public static void TrySetEpisodeNumber(this TvEpisode item, string s)
 {
     if (String.IsNullOrEmpty(s) == false)
     {
         var match = Regex.Match(s, Helpers.EpisodeNumberPatternBBC);
         if (match.Success && match.Groups.Count == 2)
         {
             if (int.TryParse(match.Groups[1].Value, out int episodeNumber))
             {
                 item.EpisodeNumber = episodeNumber;
             }
         }
     }
 }
コード例 #8
0
        public static void TrySetEpisodeName(this TvEpisode item, string s)
        {
            if (String.IsNullOrEmpty(s) == false)
            {
                var match = Regex.Match(s, @"^(.+):(.*)$");
                if (match.Success && match.Groups.Count == 3)
                {
                    var episodeTitle = match.Groups[1].Value.Trim();
                    var plot         = match.Groups[2].Value.Trim();

                    item.Title = episodeTitle;
                }
            }
        }
コード例 #9
0
        public static TvEpisode FromMediaCenterAttributes(this TvEpisode result, IDictionary <string, object> attributes)
        {
            if (attributes.TryGetValueAs <string>(StreamBufferRecording.Title, out string title))
            {
                result.ShowName = title;
            }
            if (attributes.TryGetValueAs <string>(StreamBufferRecording.Subtitle, out string subtitle))
            {
                result.OriginalTitle = subtitle;
                result.Title         = subtitle;
            }
            if (attributes.TryGetValueAs <string>(StreamBufferRecording.SubtitleDescription, out string description))
            {
                result.Description = description;
            }
            if (attributes.TryGetValueAs <long>(StreamBufferRecording.EncodeTime, out long encodeTime))
            {
                result.AiredTime = new DateTime(encodeTime, DateTimeKind.Utc).ToLocalTime();
            }
            if (attributes.TryGetValueAs <string>(StreamBufferRecording.BroadcastDateTime, out string dateStr))
            {
                var date = DateTime.Parse(dateStr);
                if (date != DateTime.MinValue)
                {
                    result.OriginalAirDate = date.ToLocalTime();
                }
            }
            if (attributes.TryGetValueAs <string>(StreamBufferRecording.StationCallSign, out string channel))
            {
                result.Channel = channel;
            }
            if (attributes.TryGetValueAs <string>(StreamBufferRecording.MediaCredits, out string credits))
            {
                if (String.IsNullOrWhiteSpace(credits) == false)
                {
                    string[] parts = credits.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    result.Credits = String.Join(";", parts);
                }
            }
            if (attributes.TryGetValueAs <long>(StreamBufferRecording.Duration, out long duration))
            {
                result.Duration = new TimeSpan(duration);
            }
            if (attributes.TryGetValueAs <string>(StreamBufferRecording.Genre, out string genre))
            {
                result.Genre = genre;
            }

            return(result);
        }
コード例 #10
0
 public static void TrySetSeriesAndEpisodeNumbers(this TvEpisode item, string s)
 {
     if (String.IsNullOrEmpty(s) == false)
     {
         var match = Regex.Match(s, @"s(\d+)[ ,]+ep[\s\. ]?(\d+)", RegexOptions.IgnoreCase);
         if (match.Success && match.Groups.Count == 3)
         {
             if (int.TryParse(match.Groups[1].Value, out int seriesNumber) &&
                 int.TryParse(match.Groups[2].Value, out int episodeNumber))
             {
                 item.SeasonNumber  = seriesNumber;
                 item.EpisodeNumber = episodeNumber;
             }
         }
     }
 }
コード例 #11
0
        /// <summary>
        /// Tries to extract the TV show name and broadcast date from the file name
        /// </summary>
        /// <example>
        /// Baptiste 2019-02-24 21-00
        /// </example>
        private static bool TrySetFromTvheadendFileName(TvEpisode item, string fileName)
        {
            var  match  = Regex.Match(fileName, @"^(.+)[\s-]+(\d{4}-\d{2}-\d{2}[\s-]+\d{2}-\d{2})");
            bool result = match.Success && match.Groups.Count == 3;

            if (result)
            {
                item.ShowName = match.Groups[1].Value.Trim();

                var recordTime = match.Groups[2].Value.Trim();
                if (DateTime.TryParseExact(recordTime, _dateTimeFormats, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out DateTime broadcastDate))
                {
                    item.AiredTime = broadcastDate;
                }
            }

            return(result);
        }
コード例 #12
0
        public static string GetOutputFileName(this TvEpisode item)
        {
            var result = item.SafeShowName;

            if (item.EpisodeNumber != Helpers.InvalidEpisodeNumber &&
                item.SeasonNumber != Helpers.InvalidSeasonNumber)
            {
                result = $"{item.SafeShowName} s{item.SeasonNumber:D2}e{item.EpisodeNumber:D2}";
            }
            else
            {
                if (item.AiredTime != DateTime.MinValue)
                {
                    string aired = item.AiredTime.ToString("yyyy-MM-dd HH:mm");
                    result = $"{item.SafeShowName} {aired}";
                }
            }

            return(Helpers.MakeFileNameSafe(result, '-'));
        }
コード例 #13
0
        public static void SaveShowNfoFile(this TvEpisode item, string path)
        {
            var show = new XElement("tvshow");

            show.Add(new XElement("title", item.ShowName));
            show.Add(new XElement("uniqueid",
                                  new XAttribute("type", "unknown"),
                                  new XAttribute("default", "true")));

            var xml = new XDocument(
                new XDeclaration("1.0", "utf-8", "yes"),
                show
                );

            xml.Save(path);

            if (String.IsNullOrWhiteSpace(item.KodiUrl) == false)
            {
                File.AppendAllText(path, Environment.NewLine + item.KodiUrl);
            }
        }
コード例 #14
0
        public static TvEpisode FixTitleAndShowName(this TvEpisode result)
        {
            const string Prefix      = "New_";
            const string Replacement = "New:";

            // Order is important - don't change
            if (String.IsNullOrEmpty(result.Title))
            {
                result.Title = result.ShowName;
            }
            if (String.IsNullOrEmpty(result.OriginalTitle))
            {
                result.OriginalTitle = result.ShowName;
            }
            if (String.IsNullOrEmpty(result.Title) == false)
            {
                if (result.Title.StartsWith(Prefix, StringComparison.CurrentCultureIgnoreCase))
                {
                    result.Title = Replacement + result.Title.Substring(Prefix.Length);
                }
            }
            if (string.IsNullOrEmpty(result.ShowName) == false)
            {
                result.ShowName = result.ShowName.RemoveOptionalPrefix(Prefix).Trim();
                result.ShowName = result.ShowName.RemoveOptionalPrefix(Replacement).Trim();

                result.ShowName = result.ShowName.RemoveOptionalPostfix("...").Trim();
                result.ShowName = result.ShowName.TrimEnd(':').Trim();
            }
            if (result.AiredTime != DateTime.MinValue)
            {
                string aired = result.AiredTime.ToString("yyyy-MM-dd HH:mm");
                result.Title = $"{result.Title} {aired}";
            }

            return(result);
        }
コード例 #15
0
        public static TvEpisode FromDescription(this TvEpisode result)
        {
            result.TrySetSeriesAndEpisodeNumbers(result.Description);

            return(result);
        }
コード例 #16
0
        public static TvEpisode SetSafeShowName(this TvEpisode result)
        {
            result.SafeShowName = Helpers.MakeFileNameSafe(result.ShowName);

            return(result);
        }