Example #1
0
        public override bool BeforeMetadataRefresh()
        {
            var hasChanges = base.BeforeMetadataRefresh();

            var locationType = LocationType;

            if (locationType == LocationType.FileSystem || locationType == LocationType.Offline)
            {
                if (!IndexNumber.HasValue && !string.IsNullOrEmpty(Path))
                {
                    IndexNumber = TVUtils.GetEpisodeNumberFromFile(Path, Parent is Season);

                    // If a change was made record it
                    if (IndexNumber.HasValue)
                    {
                        hasChanges = true;
                    }
                }

                if (!IndexNumberEnd.HasValue && !string.IsNullOrEmpty(Path))
                {
                    IndexNumberEnd = TVUtils.GetEndingEpisodeNumberFromFile(Path);

                    // If a change was made record it
                    if (IndexNumberEnd.HasValue)
                    {
                        hasChanges = true;
                    }
                }
            }

            if (!ParentIndexNumber.HasValue)
            {
                var season = Season;

                if (season != null)
                {
                    ParentIndexNumber = season.IndexNumber;
                }

                if (!ParentIndexNumber.HasValue && !string.IsNullOrEmpty(Path))
                {
                    ParentIndexNumber = TVUtils.GetSeasonNumberFromPath(Path);

                    // If a change was made record it
                    if (ParentIndexNumber.HasValue)
                    {
                        hasChanges = true;
                    }
                }

                // If a change was made record it
                if (ParentIndexNumber.HasValue)
                {
                    hasChanges = true;
                }
            }

            return(hasChanges);
        }
        public void TestEpisodeNumberFromFile()
        {
            Assert.AreEqual("02", TVUtils.EpisodeNumberFromFile(@"c:\somefolder\Season 1\1x02 BFOD.avi"));
            Assert.AreEqual("02", TVUtils.EpisodeNumberFromFile(@"c:\somefolder\1x02 BFOD.avi"));
            Assert.AreEqual("02", TVUtils.EpisodeNumberFromFile(@"c:\somefolder\South.Park.s01e02 BFOD.avi"));
            Assert.AreEqual("02", TVUtils.EpisodeNumberFromFile(@"c:\somefolder\South.Park.s01.e02 BFOD.avi"));
            Assert.AreEqual("05", TVUtils.EpisodeNumberFromFile(@"c:\somefolder\South.Park.01x05 BFOD.avi"));
            Assert.AreEqual("02", TVUtils.EpisodeNumberFromFile(@"c:\seriesname\season1\South.Park.s01e02 BFOD.avi"));
            Assert.AreEqual("02", TVUtils.EpisodeNumberFromFile(@"c:\seriesname\season1\South.Park.S01E02 BFOD.avi"));
            Assert.AreEqual("05", TVUtils.EpisodeNumberFromFile(@"c:\seriesname\season 1\South.Park.01x05 BFOD.avi"));
            Assert.AreEqual("2", TVUtils.EpisodeNumberFromFile(@"c:\someseries\Season 1\2 - 22 Balloon.avi"));
            Assert.AreEqual("2", TVUtils.EpisodeNumberFromFile(@"c:\someseries\Saison 1\2 - 22 Balloon.avi"));
            Assert.AreEqual("2", TVUtils.EpisodeNumberFromFile(@"c:\someseries\Temporada 1\2 - 22 Balloon.avi"));
            Assert.AreEqual("2", TVUtils.EpisodeNumberFromFile(@"c:\someseries\Sæson 1\2 - 22 Balloon.avi"));
            Assert.AreEqual("03", TVUtils.EpisodeNumberFromFile(@"c:\someseries\Season1\103 BFOD.avi"));
            Assert.AreEqual("01", TVUtils.EpisodeNumberFromFile(@"c:\Flight.of.the.Conchords.S01E01....dfdfdf..avi"));
            Assert.AreEqual("02", TVUtils.EpisodeNumberFromFile(@"c:\Flight.of.the.Conchords.S01E02.avi"));
            Assert.AreEqual("03", TVUtils.EpisodeNumberFromFile(@"c:\Flight.of.the.Conchords.S01E03.sdad.avi"));
            Assert.AreEqual("04", TVUtils.EpisodeNumberFromFile(@"c:\Flight.of.the.Conchords.S01E04.dfg.avi"));
            Assert.AreEqual("05", TVUtils.EpisodeNumberFromFile(@"c:\Flight.of.the.Conchords.S01E05.dfgfd.avi"));
            Assert.AreEqual("06", TVUtils.EpisodeNumberFromFile(@"c:\Flight.of.the.Conchords.S01E06.dsfdsf 119223 sdfd.avi"));
            Assert.AreEqual("07", TVUtils.EpisodeNumberFromFile(@"c:\Flight.of.the.Conchords.S01E07.sfddsfsf2.avi"));
            Assert.AreEqual("08", TVUtils.EpisodeNumberFromFile(@"c:\Flight.of.the.Conchords.S01E08.dsfsdf.avi"));
            Assert.AreEqual("09", TVUtils.EpisodeNumberFromFile(@"c:\Flight.of.the.Conchords.S01E09.sdfsdfdff.avi"));
            Assert.AreEqual("10", TVUtils.EpisodeNumberFromFile(@"c:\Flight.of.the.Conchords.S01E10.sdfsdfs.avi"));
            Assert.AreEqual("11", TVUtils.EpisodeNumberFromFile(@"c:\Flight.of.the.Conchords.S01E11.sfdsdf.avi"));
            Assert.AreEqual("12", TVUtils.EpisodeNumberFromFile(@"c:\Flight.of.the.Conchords.S01E12.sdfsdf.avi"));

            // Test network share
            Assert.AreEqual("11", TVUtils.EpisodeNumberFromFile(@"\\10.0.0.4\videos\TV\Mister TV\Season 12\Mister.Tv.S12E11.NONSE.avi"));
        }
Example #3
0
        private void MapSeriesToResult(MetadataResult <Series> result, TvDbSharper.Dto.Series tvdbSeries, string metadataLanguage)
        {
            Series series = result.Item;

            series.SetProviderId(MetadataProviders.Tvdb, tvdbSeries.Id.ToString());
            series.Name           = tvdbSeries.SeriesName;
            series.Overview       = (tvdbSeries.Overview ?? string.Empty).Trim();
            result.ResultLanguage = metadataLanguage;
            series.AirDays        = TVUtils.GetAirDays(tvdbSeries.AirsDayOfWeek);
            series.AirTime        = tvdbSeries.AirsTime;

            series.CommunityRating = (float?)tvdbSeries.SiteRating;
            series.SetProviderId(MetadataProviders.Imdb, tvdbSeries.ImdbId);
            series.SetProviderId(MetadataProviders.Zap2It, tvdbSeries.Zap2itId);
            if (Enum.TryParse(tvdbSeries.Status, true, out SeriesStatus seriesStatus))
            {
                series.Status = seriesStatus;
            }

            if (DateTime.TryParse(tvdbSeries.FirstAired, out var date))
            {
                // dates from tvdb are UTC but without offset or Z
                series.PremiereDate   = date;
                series.ProductionYear = date.Year;
            }

            series.RunTimeTicks = TimeSpan.FromMinutes(Convert.ToDouble(tvdbSeries.Runtime)).Ticks;
            foreach (var genre in tvdbSeries.Genre)
            {
                series.AddGenre(genre);
            }

            series.AddStudio(tvdbSeries.Network);

            if (result.Item.Status.HasValue && result.Item.Status.Value == SeriesStatus.Ended)
            {
                try
                {
                    var episodeSummary = _tvDbClientManager
                                         .GetSeriesEpisodeSummaryAsync(tvdbSeries.Id, metadataLanguage, CancellationToken.None).Result.Data;
                    var maxSeasonNumber = episodeSummary.AiredSeasons.Select(s => Convert.ToInt32(s)).Max();
                    var episodeQuery    = new EpisodeQuery
                    {
                        AiredSeason = maxSeasonNumber
                    };
                    var episodesPage =
                        _tvDbClientManager.GetEpisodesPageAsync(tvdbSeries.Id, episodeQuery, metadataLanguage, CancellationToken.None).Result.Data;
                    result.Item.EndDate = episodesPage.Select(e =>
                    {
                        DateTime.TryParse(e.FirstAired, out var firstAired);
                        return(firstAired);
                    }).Max();
                }
                catch (TvDbServerException e)
                {
                    _logger.LogError(e, "Failed to find series end date for series {TvdbId}", tvdbSeries.Id);
                }
            }
        }
        public override void ResolveEntity(IMediaLocation location,
                                           out BaseItemFactory factory,
                                           out IEnumerable <InitializationParameter> setup)
        {
            factory = null;
            setup   = null;

            if (!location.IsHidden())
            {
                bool isFolder = !Path.HasExtension(location.Path);

                bool containsIfo = false;
                bool isDvd       = isFolder ? IsDvd(location, out containsIfo) : false;
                bool isIso       = isFolder ? false : Helper.IsIso(location.Path);
                bool isBD        = isFolder ? Helper.IsBluRayFolder(location.Path, null) : false;

                bool isVideo = !(location is IFolderMediaLocation) &&
                               (isIso || isBD || Helper.IsVideo(location.Path) || location.IsVob());

                if ((isDvd || isBD || isVideo) &&
                    TVUtils.IsEpisode(location.Path))
                {
                    if (isBD)
                    {
                        setup = new List <InitializationParameter>()
                        {
                            new MediaTypeInitializationParameter()
                            {
                                MediaType = MediaType.BluRay
                            }
                        };
                    }
                    else if (containsIfo || isIso)
                    {
                        MediaType mt = isIso ? MediaType.ISO : MediaType.DVD;
                        setup = new List <InitializationParameter>()
                        {
                            new MediaTypeInitializationParameter()
                            {
                                MediaType = mt
                            }
                        };
                    }
                    else if (isVideo)
                    {
                        MediaType mt = location.GetVideoMediaType();
                        setup = new List <InitializationParameter>()
                        {
                            new MediaTypeInitializationParameter()
                            {
                                MediaType = mt
                            }
                        };
                    }

                    factory = BaseItemFactory <Episode> .Instance;
                }
            }
        }
Example #5
0
        public void TestGetEndingEpisodeNumberFromFile()
        {
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\4x01 – 20 Hours in America (1).mkv"));

            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\01x02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\S01x02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\S01E02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\S01xE02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\seriesname 01x02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\seriesname S01x02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\seriesname S01E02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\seriesname S01xE02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2\02x03 - 04 Ep Name.ext"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2\My show name 02x03 - 04 Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2\Elementary - 02x03 - 02x04 - 02x15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2\02x03 - 02x04 - 02x15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2\02x03-04-15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2\Elementary - 02x03-04-15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 02\02x03-E15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 02\Elementary - 02x03-E15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 02\02x03 - x04 - x15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 02\Elementary - 02x03 - x04 - x15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 02\02x03x04x15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 02\Elementary - 02x03x04x15 - Ep Name.ext"));
            Assert.AreEqual(26, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\Elementary - S01E23-E24-E26 - The Woman.mp4"));
            Assert.AreEqual(26, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\S01E23-E24-E26 - The Woman.mp4"));


            //Four Digits seasons
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\2009x02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\S2009x02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\S2009E02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\S2009xE02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\seriesname 2009x02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\seriesname S2009x02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\seriesname S2009E02 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\seriesname S2009xE02 blah.avi"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03 - 2009x04 - 2009x15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\2009x03 - 2009x04 - 2009x15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\2009x03-04-15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03-04-15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\2009x03-E15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03-E15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\2009x03 - x04 - x15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03 - x04 - x15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\2009x03x04x15 - Ep Name.ext"));
            Assert.AreEqual(15, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03x04x15 - Ep Name.ext"));
            Assert.AreEqual(26, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\Elementary - S2009E23-E24-E26 - The Woman.mp4"));
            Assert.AreEqual(26, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2009\S2009E23-E24-E26 - The Woman.mp4"));

            //Without season number
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\02 - blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2\02 - blah 14 blah.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 1\02 - blah-02 a.avi"));
            Assert.AreEqual(null, TVUtils.GetEndingEpisodeNumberFromFile(@"Season 2\02.avi"));
        }
Example #6
0
        /// <summary>
        /// Fetches metadata and returns true or false indicating if any work that requires persistence was done
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="force">if set to <c>true</c> [force].</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task{System.Boolean}.</returns>
        public override Task <bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
        {
            var episode = (Episode)item;

            episode.IndexNumber    = TVUtils.GetEpisodeNumberFromFile(item.Path, item.Parent is Season);
            episode.IndexNumberEnd = TVUtils.GetEndingEpisodeNumberFromFile(item.Path);

            SetLastRefreshed(item, DateTime.UtcNow);

            return(TrueTaskResult);
        }
        /// <summary>
        /// Resolves the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Season.</returns>
        protected override Season Resolve(ItemResolveArgs args)
        {
            if (args.Parent is Series && args.IsDirectory)
            {
                return(new Season
                {
                    IndexNumber = TVUtils.GetSeasonNumberFromPath(args.Path)
                });
            }

            return(null);
        }
        public override void ResolveEntity(IMediaLocation location,
                                           out BaseItemFactory factory,
                                           out IEnumerable <InitializationParameter> setup)
        {
            factory = null;
            setup   = null;

            if (location is IFolderMediaLocation && !location.IsHidden() && TVUtils.IsSeasonFolder(location.Path))
            {
                factory = BaseItemFactory <Season> .Instance;
            }
        }
Example #9
0
        public void TestGetEpisodeNumberFromFile()
        {
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\01x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\S01x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\S01E02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\S01xE02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\seriesname 01x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\seriesname S01x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\seriesname S01E02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\seriesname S01xE02 blah.avi", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2\Elementary - 02x03 - 02x04 - 02x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2\02x03 - 02x04 - 02x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2\02x03-04-15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2\Elementary - 02x03-04-15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 02\02x03-E15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 02\Elementary - 02x03-E15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 02\02x03 - x04 - x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 02\Elementary - 02x03 - x04 - x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 02\02x03x04x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 02\Elementary - 02x03x04x15 - Ep Name.ext", true));
            Assert.AreEqual(23, TVUtils.GetEpisodeNumberFromFile(@"Season 1\Elementary - S01E23-E24-E26 - The Woman.mp4", true));
            Assert.AreEqual(23, TVUtils.GetEpisodeNumberFromFile(@"Season 1\S01E23-E24-E26 - The Woman.mp4", true));
            Assert.AreEqual(9, TVUtils.GetEpisodeNumberFromFile(@"Season 25\The Simpsons.S25E09.Steal this episode.mp4", true));
            Assert.AreEqual(8, TVUtils.GetEpisodeNumberFromFile(@"The Simpsons\The Simpsons.S25E08.Steal this episode.mp4", false));

            //Four Digits seasons
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\2009x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\S2009x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\S2009E02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\S2009xE02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\seriesname 2009x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\seriesname S2009x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\seriesname S2009E02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\seriesname S2009xE02 blah.avi", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03 - 2009x04 - 2009x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\2009x03 - 2009x04 - 2009x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\2009x03-04-15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03-04-15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\2009x03-E15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03-E15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\2009x03 - x04 - x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03 - x04 - x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\2009x03x04x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03x04x15 - Ep Name.ext", true));
            Assert.AreEqual(23, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\Elementary - S2009E23-E24-E26 - The Woman.mp4", true));
            Assert.AreEqual(23, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\S2009E23-E24-E26 - The Woman.mp4", true));

            //Without season number
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\02 - blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2\02 - blah 14 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\02 - blah-02 a.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2\02.avi", true));
        }
Example #10
0
        /// <summary>
        /// Resolves the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Episode.</returns>
        protected override Episode Resolve(ItemResolveArgs args)
        {
            var season = args.Parent as Season;

            // If the parent is a Season or Series, then this is an Episode if the VideoResolver returns something
            if (season != null || args.Parent is Series)
            {
                Episode episode = null;

                if (args.IsDirectory)
                {
                    if (args.ContainsFileSystemEntryByName("video_ts"))
                    {
                        episode = new Episode
                        {
                            Path      = args.Path,
                            VideoType = VideoType.Dvd
                        };
                    }
                    if (args.ContainsFileSystemEntryByName("bdmv"))
                    {
                        episode = new Episode
                        {
                            Path      = args.Path,
                            VideoType = VideoType.BluRay
                        };
                    }
                }

                if (episode == null)
                {
                    episode = base.Resolve(args);
                }

                if (episode != null)
                {
                    if (season != null)
                    {
                        episode.ParentIndexNumber = season.IndexNumber;
                    }

                    if (episode.ParentIndexNumber == null)
                    {
                        episode.ParentIndexNumber = TVUtils.GetSeasonNumberFromEpisodeFile(args.Path);
                    }
                }

                return(episode);
            }

            return(null);
        }
Example #11
0
        public void TestGetSeasonNumberFromPath()
        {
            Assert.AreEqual(02, TVUtils.GetSeasonNumberFromEpisodeFile(@"\Show\Season 02\S02E03 blah.avi"));

            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 02"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 02"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 02"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 02"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 02"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 02"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));

            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Seinfeld\S02"));

            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Seinfeld\2"));

            //Four Digits seasons
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
        }
Example #12
0
        public void TestGetSeasonNumberFromEpisodeFile()
        {
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 1\01x02 blah.avi"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 1\S01x02 blah.avi"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 1\S01E02 blah.avi"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 1\S01xE02 blah.avi"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 1\seriesname 01x02 blah.avi"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 1\seriesname S01x02 blah.avi"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 1\seriesname S01E02 blah.avi"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 1\seriesname S01xE02 blah.avi"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2\Elementary - 02x03 - 02x04 - 02x15 - Ep Name.ext"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2\02x03 - 02x04 - 02x15 - Ep Name.ext"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2\02x03-04-15 - Ep Name.ext"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2\Elementary - 02x03-04-15 - Ep Name.ext"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 02\02x03-E15 - Ep Name.ext"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 02\Elementary - 02x03-E15 - Ep Name.ext"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 02\02x03 - x04 - x15 - Ep Name.ext"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 02\Elementary - 02x03 - x04 - x15 - Ep Name.ext"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 02\02x03x04x15 - Ep Name.ext"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 02\Elementary - 02x03x04x15 - Ep Name.ext"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 1\Elementary - S01E23-E24-E26 - The Woman.mp4"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 1\S01E23-E24-E26 - The Woman.mp4"));

            //Four Digits seasons
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\2009x02 blah.avi"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\S2009x02 blah.avi"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\S2009E02 blah.avi"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\S2009xE02 blah.avi"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\seriesname 2009x02 blah.avi"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\seriesname S2009x02 blah.avi"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\seriesname S2009E02 blah.avi"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\seriesname S2009xE02 blah.avi"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\Elementary - 2009x03 - 2009x04 - 2009x15 - Ep Name.ext"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\2009x03 - 2009x04 - 2009x15 - Ep Name.ext"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\2009x03-04-15 - Ep Name.ext"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\Elementary - 2009x03-04-15 - Ep Name.ext"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\2009x03-E15 - Ep Name.ext"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\Elementary - 2009x03-E15 - Ep Name.ext"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\2009x03 - x04 - x15 - Ep Name.ext"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\Elementary - 2009x03 - x04 - x15 - Ep Name.ext"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\2009x03x04x15 - Ep Name.ext"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\Elementary - 2009x03x04x15 - Ep Name.ext"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\Elementary - S2009E23-E24-E26 - The Woman.mp4"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 2009\S2009E23-E24-E26 - The Woman.mp4"));
            Assert.AreEqual(25, TVUtils.GetSeasonNumberFromEpisodeFile(@"Season 25\The Simpsons.S25E09.Steal this episode.mp4"));
            Assert.AreEqual(25, TVUtils.GetSeasonNumberFromEpisodeFile(@"The Simpsons\The Simpsons.S25E09.Steal this episode.mp4"));
        }
Example #13
0
        public void TestGetSeasonNumberFromPath()
        {
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 02"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 02"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 02"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 02"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 02"));
            Assert.AreEqual(2, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 02"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));
            Assert.AreEqual(1, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 1"));

            //Four Digits seasons
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
            Assert.AreEqual(2009, TVUtils.GetSeasonNumberFromPath(@"\Drive\Season 2009"));
        }
Example #14
0
        public void TestGetEpisodeNumberFromFile()
        {
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\01x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\S01x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\S01E02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\S01xE02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\seriesname 01x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\seriesname S01x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\seriesname S01E02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 1\seriesname S01xE02 blah.avi", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2\Elementary - 02x03 - 02x04 - 02x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2\02x03 - 02x04 - 02x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2\02x03-04-15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2\Elementary - 02x03-04-15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 02\02x03-E15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 02\Elementary - 02x03-E15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 02\02x03 - x04 - x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 02\Elementary - 02x03 - x04 - x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 02\02x03x04x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 02\Elementary - 02x03x04x15 - Ep Name.ext", true));
            Assert.AreEqual(23, TVUtils.GetEpisodeNumberFromFile(@"Season 1\Elementary - S01E23-E24-E26 - The Woman.mp4", true));
            Assert.AreEqual(23, TVUtils.GetEpisodeNumberFromFile(@"Season 1\S01E23-E24-E26 - The Woman.mp4", true));

            //Four Digits seasons
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\2009x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\S2009x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\S2009E02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\S2009xE02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\seriesname 2009x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\seriesname S2009x02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\seriesname S2009E02 blah.avi", true));
            Assert.AreEqual(02, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\seriesname S2009xE02 blah.avi", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03 - 2009x04 - 2009x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\2009x03 - 2009x04 - 2009x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\2009x03-04-15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03-04-15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\2009x03-E15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03-E15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\2009x03 - x04 - x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03 - x04 - x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\2009x03x04x15 - Ep Name.ext", true));
            Assert.AreEqual(03, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\Elementary - 2009x03x04x15 - Ep Name.ext", true));
            Assert.AreEqual(23, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\Elementary - S2009E23-E24-E26 - The Woman.mp4", true));
            Assert.AreEqual(23, TVUtils.GetEpisodeNumberFromFile(@"Season 2009\S2009E23-E24-E26 - The Woman.mp4", true));
        }
Example #15
0
        /// <summary>
        /// Resolves the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Season.</returns>
        protected override Season Resolve(ItemResolveArgs args)
        {
            if (args.Parent is Series && args.IsDirectory)
            {
                var season = new Season
                {
                    IndexNumber = TVUtils.GetSeasonNumberFromPath(args.Path)
                };

                if (season.IndexNumber.HasValue && season.IndexNumber.Value == 0)
                {
                    season.Name = _config.Configuration.SeasonZeroDisplayName;
                }

                return(season);
            }

            return(null);
        }
        public static bool IsSeriesFolder(this IMediaLocation location)
        {
            IFolderMediaLocation folder = location as IFolderMediaLocation;

            if (folder != null)
            {
                if (TVUtils.IsSeasonFolder(folder.Path))
                {
                    return(false);
                }

                int i = 0;

                foreach (IMediaLocation child in folder.Children)
                {
                    if (child is IFolderMediaLocation &&
                        TVUtils.IsSeasonFolder(child.Path))
                    {
                        return(true); // we have found at least one season folder
                    }
                    else
                    {
                        i++;
                    }
                    if (i >= 3)
                    {
                        return(false); // a folder with more than 3 non-season folders in will not be counted as a series
                    }
                }

                foreach (IMediaLocation child in folder.Children)
                {
                    if (!(child is IFolderMediaLocation) &&
                        child.IsVideo() &&
                        TVUtils.EpisodeNumberFromFile(child.Path, false) != null)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Example #17
0
        /// <summary>
        /// This is called before any metadata refresh and returns true or false indicating if changes were made
        /// </summary>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public override bool BeforeMetadataRefresh()
        {
            var hasChanges = base.BeforeMetadataRefresh();

            var locationType = LocationType;

            if (locationType == LocationType.FileSystem || locationType == LocationType.Offline)
            {
                if (!IndexNumber.HasValue && !string.IsNullOrEmpty(Path))
                {
                    IndexNumber = IndexNumber ?? TVUtils.GetSeasonNumberFromPath(Path);

                    // If a change was made record it
                    if (IndexNumber.HasValue)
                    {
                        hasChanges = true;
                    }
                }
            }

            return(hasChanges);
        }
Example #18
0
        /// <summary>
        /// Resolves the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Series.</returns>
        protected override Series Resolve(ItemResolveArgs args)
        {
            if (args.IsDirectory)
            {
                // Avoid expensive tests against VF's and all their children by not allowing this
                if (args.Parent == null || args.Parent.IsRoot)
                {
                    return(null);
                }

                // Optimization to avoid running these tests against Seasons
                if (args.Parent is Series || args.Parent is Season || args.Parent is MusicArtist || args.Parent is MusicAlbum)
                {
                    return(null);
                }

                var collectionType = args.GetCollectionType();

                var isTvShowsFolder = string.Equals(collectionType, CollectionType.TvShows,
                                                    StringComparison.OrdinalIgnoreCase);

                // If there's a collection type and it's not tv, it can't be a series
                if (!string.IsNullOrEmpty(collectionType) &&
                    !isTvShowsFolder &&
                    !string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
                {
                    return(null);
                }

                if (TVUtils.IsSeriesFolder(args.Path, isTvShowsFolder, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger))
                {
                    return(new Series());
                }
            }

            return(null);
        }
Example #19
0
        private void FetchDataFromSeriesNode(Series item, XmlReader reader, CancellationToken cancellationToken)
        {
            reader.MoveToContent();

            // Loop through each element
            while (reader.Read())
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (reader.NodeType == XmlNodeType.Element)
                {
                    switch (reader.Name)
                    {
                    case "SeriesName":
                    {
                        item.Name = (reader.ReadElementContentAsString() ?? string.Empty).Trim();
                        break;
                    }

                    case "Overview":
                    {
                        item.Overview = (reader.ReadElementContentAsString() ?? string.Empty).Trim();
                        break;
                    }

                    case "Airs_DayOfWeek":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            item.AirDays = TVUtils.GetAirDays(val);
                        }
                        break;
                    }

                    case "Airs_Time":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            item.AirTime = val;
                        }
                        break;
                    }

                    case "ContentRating":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            item.OfficialRating = val;
                        }
                        break;
                    }

                    case "Rating":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            // Only fill this if it doesn't already have a value, since we get it from imdb which has better data
                            if (!item.CommunityRating.HasValue || string.IsNullOrWhiteSpace(item.GetProviderId(MetadataProviders.Imdb)))
                            {
                                float rval;

                                // float.TryParse is local aware, so it can be probamatic, force us culture
                                if (float.TryParse(val, NumberStyles.AllowDecimalPoint, _usCulture, out rval))
                                {
                                    item.CommunityRating = rval;
                                }
                            }
                        }
                        break;
                    }

                    case "RatingCount":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            int rval;

                            // int.TryParse is local aware, so it can be probamatic, force us culture
                            if (int.TryParse(val, NumberStyles.Integer, _usCulture, out rval))
                            {
                                item.VoteCount = rval;
                            }
                        }

                        break;
                    }

                    case "IMDB_ID":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            item.SetProviderId(MetadataProviders.Imdb, val);
                        }

                        break;
                    }

                    case "zap2it_id":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            item.SetProviderId(MetadataProviders.Zap2It, val);
                        }

                        break;
                    }

                    case "Status":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            SeriesStatus seriesStatus;

                            if (Enum.TryParse(val, true, out seriesStatus))
                            {
                                item.Status = seriesStatus;
                            }
                        }

                        break;
                    }

                    case "FirstAired":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            DateTime date;
                            if (DateTime.TryParse(val, out date))
                            {
                                date = date.ToUniversalTime();

                                item.PremiereDate   = date;
                                item.ProductionYear = date.Year;
                            }
                        }

                        break;
                    }

                    case "Runtime":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            int rval;

                            // int.TryParse is local aware, so it can be probamatic, force us culture
                            if (int.TryParse(val, NumberStyles.Integer, _usCulture, out rval))
                            {
                                item.RunTimeTicks = TimeSpan.FromMinutes(rval).Ticks;
                            }
                        }

                        break;
                    }

                    case "Genre":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            var vals = val
                                       .Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
                                       .Select(i => i.Trim())
                                       .Where(i => !string.IsNullOrWhiteSpace(i))
                                       .ToList();

                            if (vals.Count > 0)
                            {
                                item.Genres.Clear();

                                foreach (var genre in vals)
                                {
                                    item.AddGenre(genre);
                                }
                            }
                        }

                        break;
                    }

                    case "Network":
                    {
                        var val = reader.ReadElementContentAsString();

                        if (!string.IsNullOrWhiteSpace(val))
                        {
                            var vals = val
                                       .Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
                                       .Select(i => i.Trim())
                                       .Where(i => !string.IsNullOrWhiteSpace(i))
                                       .ToList();

                            if (vals.Count > 0)
                            {
                                item.Studios.Clear();

                                foreach (var genre in vals)
                                {
                                    item.AddStudio(genre);
                                }
                            }
                        }

                        break;
                    }

                    default:
                        reader.Skip();
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Fetches the main info.
        /// </summary>
        /// <param name="series">The series.</param>
        /// <param name="doc">The doc.</param>
        private void FetchMainInfo(Series series, XmlDocument doc)
        {
            if (!series.LockedFields.Contains(MetadataFields.Name))
            {
                series.Name = doc.SafeGetString("//SeriesName");
            }
            if (!series.LockedFields.Contains(MetadataFields.Overview))
            {
                series.Overview = doc.SafeGetString("//Overview");
            }
            series.CommunityRating = doc.SafeGetSingle("//Rating", 0, 10);
            series.AirDays         = TVUtils.GetAirDays(doc.SafeGetString("//Airs_DayOfWeek"));
            series.AirTime         = doc.SafeGetString("//Airs_Time");
            SeriesStatus seriesStatus;

            if (Enum.TryParse(doc.SafeGetString("//Status"), true, out seriesStatus))
            {
                series.Status = seriesStatus;
            }
            series.PremiereDate = doc.SafeGetDateTime("//FirstAired");
            if (series.PremiereDate.HasValue)
            {
                series.ProductionYear = series.PremiereDate.Value.Year;
            }

            series.RunTimeTicks = TimeSpan.FromMinutes(doc.SafeGetInt32("//Runtime")).Ticks;

            if (!series.LockedFields.Contains(MetadataFields.Studios))
            {
                string s = doc.SafeGetString("//Network");

                if (!string.IsNullOrWhiteSpace(s))
                {
                    series.Studios.Clear();

                    foreach (var studio in s.Trim().Split('|'))
                    {
                        series.AddStudio(studio);
                    }
                }
            }
            series.OfficialRating = doc.SafeGetString("//ContentRating");
            if (!series.LockedFields.Contains(MetadataFields.Genres))
            {
                string g = doc.SafeGetString("//Genre");

                if (g != null)
                {
                    string[] genres = g.Trim('|').Split('|');
                    if (g.Length > 0)
                    {
                        series.Genres.Clear();

                        foreach (var genre in genres)
                        {
                            series.AddGenre(genre);
                        }
                    }
                }
            }
            if (series.Status == SeriesStatus.Ended)
            {
                var document = XDocument.Load(new XmlNodeReader(doc));
                var dates    = document.Descendants("Episode").Where(x => {
                    var seasonNumber = x.Element("SeasonNumber");
                    var firstAired   = x.Element("FirstAired");
                    return(firstAired != null && seasonNumber != null && (!string.IsNullOrEmpty(seasonNumber.Value) && seasonNumber.Value != "0") && !string.IsNullOrEmpty(firstAired.Value));
                }).Select(x => {
                    DateTime?date = null;
                    DateTime tempDate;
                    var firstAired = x.Element("FirstAired");
                    if (firstAired != null && DateTime.TryParse(firstAired.Value, out tempDate))
                    {
                        date = tempDate;
                    }
                    return(date);
                }).ToList();
                if (dates.Any(x => x.HasValue))
                {
                    series.EndDate = dates.Where(x => x.HasValue).Max();
                }
            }
        }
Example #21
0
        /// <summary>
        /// Fetches the data from XML node.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="itemResult">The item result.</param>
        protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult <Series> itemResult)
        {
            var item = itemResult.Item;

            switch (reader.Name)
            {
            case "id":
            {
                string imdbId = reader.GetAttribute("IMDB");
                string tmdbId = reader.GetAttribute("TMDB");
                string tvdbId = reader.GetAttribute("TVDB");

                if (string.IsNullOrWhiteSpace(tvdbId))
                {
                    tvdbId = reader.ReadElementContentAsString();
                }
                if (!string.IsNullOrWhiteSpace(imdbId))
                {
                    item.SetProviderId(MetadataProviders.Imdb, imdbId);
                }
                if (!string.IsNullOrWhiteSpace(tmdbId))
                {
                    item.SetProviderId(MetadataProviders.Tmdb, tmdbId);
                }
                if (!string.IsNullOrWhiteSpace(tvdbId))
                {
                    item.SetProviderId(MetadataProviders.Tvdb, tvdbId);
                }
                break;
            }

            case "airs_dayofweek":
            {
                item.AirDays = TVUtils.GetAirDays(reader.ReadElementContentAsString());
                break;
            }

            case "airs_time":
            {
                var val = reader.ReadElementContentAsString();

                if (!string.IsNullOrWhiteSpace(val))
                {
                    item.AirTime = val;
                }
                break;
            }

            case "status":
            {
                var status = reader.ReadElementContentAsString();

                if (!string.IsNullOrWhiteSpace(status))
                {
                    if (Enum.TryParse(status, true, out SeriesStatus seriesStatus))
                    {
                        item.Status = seriesStatus;
                    }
                    else
                    {
                        Logger.LogInformation("Unrecognized series status: " + status);
                    }
                }

                break;
            }

            default:
                base.FetchDataFromXmlNode(reader, itemResult);
                break;
            }
        }
        /// <summary>
        /// Fetches the season data.
        /// </summary>
        /// <param name="season">The season.</param>
        /// <param name="seriesId">The series id.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task{System.Boolean}.</returns>
        private async Task <bool> FetchSeasonData(Season season, string seriesId, CancellationToken cancellationToken)
        {
            string name = season.Name;

            Logger.Debug("TvDbProvider: Fetching season data: " + name);
            var seasonNumber = TVUtils.GetSeasonNumberFromPath(season.Path) ?? -1;

            season.IndexNumber = seasonNumber;

            if (seasonNumber == 0)
            {
                season.Name = "Specials";
            }

            if (!string.IsNullOrEmpty(seriesId))
            {
                if ((season.PrimaryImagePath == null) || (!season.HasImage(ImageType.Banner)) || (season.BackdropImagePaths == null))
                {
                    var images = new XmlDocument();
                    var url    = string.Format("http://www.thetvdb.com/api/" + TVUtils.TVDBApiKey + "/series/{0}/banners.xml", seriesId);

                    try
                    {
                        using (var imgs = await HttpClient.Get(url, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false))
                        {
                            images.Load(imgs);
                        }
                    }
                    catch (HttpException)
                    {
                    }

                    if (images.HasChildNodes)
                    {
                        if (ConfigurationManager.Configuration.RefreshItemImages || !season.HasLocalImage("folder"))
                        {
                            var n = images.SelectSingleNode("//Banner[BannerType='season'][BannerType2='season'][Season='" + seasonNumber + "']");
                            if (n != null)
                            {
                                n = n.SelectSingleNode("./BannerPath");

                                try
                                {
                                    if (n != null)
                                    {
                                        season.PrimaryImagePath = await _providerManager.DownloadAndSaveImage(season, TVUtils.BannerUrl + n.InnerText, "folder" + Path.GetExtension(n.InnerText), RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false);
                                    }
                                }
                                catch (HttpException)
                                {
                                }
                                catch (IOException)
                                {
                                }
                            }
                        }

                        if (ConfigurationManager.Configuration.DownloadSeasonImages.Banner && (ConfigurationManager.Configuration.RefreshItemImages || !season.HasLocalImage("banner")))
                        {
                            var n = images.SelectSingleNode("//Banner[BannerType='season'][BannerType2='seasonwide'][Season='" + seasonNumber + "']");
                            if (n != null)
                            {
                                n = n.SelectSingleNode("./BannerPath");
                                if (n != null)
                                {
                                    try
                                    {
                                        var bannerImagePath =
                                            await _providerManager.DownloadAndSaveImage(season,
                                                                                        TVUtils.BannerUrl + n.InnerText,
                                                                                        "banner" +
                                                                                        Path.GetExtension(n.InnerText),
                                                                                        RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).
                                            ConfigureAwait(false);

                                        season.SetImage(ImageType.Banner, bannerImagePath);
                                    }
                                    catch (HttpException)
                                    {
                                    }
                                    catch (IOException)
                                    {
                                    }
                                }
                            }
                        }

                        if (ConfigurationManager.Configuration.DownloadSeasonImages.Backdrops && (ConfigurationManager.Configuration.RefreshItemImages || !season.HasLocalImage("backdrop")))
                        {
                            var n = images.SelectSingleNode("//Banner[BannerType='fanart'][Season='" + seasonNumber + "']");
                            if (n != null)
                            {
                                n = n.SelectSingleNode("./BannerPath");
                                if (n != null)
                                {
                                    try
                                    {
                                        if (season.BackdropImagePaths == null)
                                        {
                                            season.BackdropImagePaths = new List <string>();
                                        }
                                        season.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(season, TVUtils.BannerUrl + n.InnerText, "backdrop" + Path.GetExtension(n.InnerText), RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false));
                                    }
                                    catch (HttpException)
                                    {
                                    }
                                    catch (IOException)
                                    {
                                    }
                                }
                            }
                            else if (!ConfigurationManager.Configuration.SaveLocalMeta) //if saving local - season will inherit from series
                            {
                                // not necessarily accurate but will give a different bit of art to each season
                                var lst = images.SelectNodes("//Banner[BannerType='fanart']");
                                if (lst != null && lst.Count > 0)
                                {
                                    var num = seasonNumber % lst.Count;
                                    n = lst[num];
                                    n = n.SelectSingleNode("./BannerPath");
                                    if (n != null)
                                    {
                                        if (season.BackdropImagePaths == null)
                                        {
                                            season.BackdropImagePaths = new List <string>();
                                        }

                                        try
                                        {
                                            season.BackdropImagePaths.Add(
                                                await _providerManager.DownloadAndSaveImage(season,
                                                                                            TVUtils.BannerUrl +
                                                                                            n.InnerText,
                                                                                            "backdrop" +
                                                                                            Path.GetExtension(
                                                                                                n.InnerText),
                                                                                            RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken)
                                                .ConfigureAwait(false));
                                        }
                                        catch (HttpException)
                                        {
                                        }
                                        catch (IOException)
                                        {
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                return(true);
            }

            return(false);
        }
Example #23
0
        /// <summary>
        /// Fetches the series data.
        /// </summary>
        /// <param name="series">The series.</param>
        /// <param name="seriesId">The series id.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task{System.Boolean}.</returns>
        private async Task <bool> FetchSeriesData(Series series, string seriesId, CancellationToken cancellationToken)
        {
            var success = false;

            var name = series.Name;

            Logger.Debug("TvDbProvider: Fetching series data: " + name);

            if (!string.IsNullOrEmpty(seriesId))
            {
                string url = string.Format(seriesGet, TVUtils.TVDBApiKey, seriesId, ConfigurationManager.Configuration.PreferredMetadataLanguage);
                var    doc = new XmlDocument();

                try
                {
                    using (var xml = await HttpClient.Get(url, TvDbResourcePool, cancellationToken).ConfigureAwait(false))
                    {
                        doc.Load(xml);
                    }
                }
                catch (HttpException)
                {
                }

                if (doc.HasChildNodes)
                {
                    //kick off the actor and image fetch simultaneously
                    var actorTask = FetchActors(series, seriesId, doc, cancellationToken);
                    var imageTask = FetchImages(series, seriesId, cancellationToken);

                    success = true;

                    series.Name            = doc.SafeGetString("//SeriesName");
                    series.Overview        = doc.SafeGetString("//Overview");
                    series.CommunityRating = doc.SafeGetSingle("//Rating", 0, 10);
                    series.AirDays         = TVUtils.GetAirDays(doc.SafeGetString("//Airs_DayOfWeek"));
                    series.AirTime         = doc.SafeGetString("//Airs_Time");

                    string n = doc.SafeGetString("//banner");
                    if (!string.IsNullOrWhiteSpace(n))
                    {
                        series.SetImage(ImageType.Banner, await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + n, "banner" + Path.GetExtension(n), TvDbResourcePool, cancellationToken).ConfigureAwait(false));
                    }

                    string s = doc.SafeGetString("//Network");
                    if (!string.IsNullOrWhiteSpace(s))
                    {
                        series.AddStudios(new List <string>(s.Trim().Split('|')));
                    }

                    series.OfficialRating = doc.SafeGetString("//ContentRating");

                    string g = doc.SafeGetString("//Genre");

                    if (g != null)
                    {
                        string[] genres = g.Trim('|').Split('|');
                        if (g.Length > 0)
                        {
                            series.AddGenres(genres);
                        }
                    }

                    //wait for other tasks
                    await Task.WhenAll(actorTask, imageTask).ConfigureAwait(false);

                    if (ConfigurationManager.Configuration.SaveLocalMeta)
                    {
                        var ms = new MemoryStream();
                        doc.Save(ms);

                        await _providerManager.SaveToLibraryFilesystem(series, Path.Combine(series.MetaLocation, LOCAL_META_FILE_NAME), ms, cancellationToken).ConfigureAwait(false);
                    }
                }
            }



            return(success);
        }
        public async Task <FileOrganizationResult> OrganizeEpisodeFile(string path, TvFileOrganizationOptions options, bool overwriteExisting, CancellationToken cancellationToken)
        {
            _logger.Info("Sorting file {0}", path);

            var result = new FileOrganizationResult
            {
                Date             = DateTime.UtcNow,
                OriginalPath     = path,
                OriginalFileName = Path.GetFileName(path),
                Type             = FileOrganizerType.Episode,
                FileSize         = new FileInfo(path).Length
            };

            var seriesName = TVUtils.GetSeriesNameFromEpisodeFile(path);

            if (!string.IsNullOrEmpty(seriesName))
            {
                var season = TVUtils.GetSeasonNumberFromEpisodeFile(path);

                result.ExtractedSeasonNumber = season;

                if (season.HasValue)
                {
                    // Passing in true will include a few extra regex's
                    var episode = TVUtils.GetEpisodeNumberFromFile(path, true);

                    result.ExtractedEpisodeNumber = episode;

                    if (episode.HasValue)
                    {
                        _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, season, episode);

                        var endingEpisodeNumber = TVUtils.GetEndingEpisodeNumberFromFile(path);

                        result.ExtractedEndingEpisodeNumber = endingEpisodeNumber;

                        await OrganizeEpisode(path, seriesName, season.Value, episode.Value, endingEpisodeNumber, options, overwriteExisting, result, cancellationToken).ConfigureAwait(false);
                    }
                    else
                    {
                        var msg = string.Format("Unable to determine episode number from {0}", path);
                        result.Status        = FileSortingStatus.Failure;
                        result.StatusMessage = msg;
                        _logger.Warn(msg);
                    }
                }
                else
                {
                    var msg = string.Format("Unable to determine season number from {0}", path);
                    result.Status        = FileSortingStatus.Failure;
                    result.StatusMessage = msg;
                    _logger.Warn(msg);
                }
            }
            else
            {
                var msg = string.Format("Unable to determine series name from {0}", path);
                result.Status        = FileSortingStatus.Failure;
                result.StatusMessage = msg;
                _logger.Warn(msg);
            }

            var previousResult = _organizationService.GetResultBySourcePath(path);

            if (previousResult != null)
            {
                // Don't keep saving the same result over and over if nothing has changed
                if (previousResult.Status == result.Status && result.Status != FileSortingStatus.Success)
                {
                    return(previousResult);
                }
            }

            await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);

            return(result);
        }
Example #25
0
        /// <summary>
        /// Fetches the data from XML node.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="result">The result.</param>
        protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult <Series> result)
        {
            var item = result.Item;

            switch (reader.Name)
            {
            case "Series":
                //MB generated metadata is within a "Series" node
                using (var subTree = reader.ReadSubtree())
                {
                    subTree.MoveToContent();

                    // Loop through each element
                    while (subTree.Read())
                    {
                        if (subTree.NodeType == XmlNodeType.Element)
                        {
                            FetchDataFromXmlNode(subTree, result);
                        }
                    }
                }
                break;

            case "id":
                string id = reader.ReadElementContentAsString();
                if (!string.IsNullOrWhiteSpace(id))
                {
                    item.SetProviderId(MetadataProviders.Tvdb, id);
                }
                break;

            case "Airs_DayOfWeek":
            {
                item.AirDays = TVUtils.GetAirDays(reader.ReadElementContentAsString());
                break;
            }

            case "Airs_Time":
            {
                var val = reader.ReadElementContentAsString();

                if (!string.IsNullOrWhiteSpace(val))
                {
                    item.AirTime = val;
                }
                break;
            }

            case "AnimeSeriesIndex":
            {
                var number = reader.ReadElementContentAsString();

                if (!string.IsNullOrWhiteSpace(number))
                {
                    int num;

                    if (int.TryParse(number, out num))
                    {
                        item.AnimeSeriesIndex = num;
                    }
                }
                break;
            }

            case "Status":
            {
                var status = reader.ReadElementContentAsString();

                if (!string.IsNullOrWhiteSpace(status))
                {
                    SeriesStatus seriesStatus;
                    if (Enum.TryParse(status, true, out seriesStatus))
                    {
                        item.Status = seriesStatus;
                    }
                    else
                    {
                        Logger.Info("Unrecognized series status: " + status);
                    }
                }

                break;
            }

            default:
                base.FetchDataFromXmlNode(reader, result);
                break;
            }
        }
Example #26
0
        /// <summary>
        /// Resolves the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Series.</returns>
        protected override Series Resolve(ItemResolveArgs args)
        {
            if (args.IsDirectory)
            {
                // Avoid expensive tests against VF's and all their children by not allowing this
                if (args.Parent == null || args.Parent.IsRoot)
                {
                    return(null);
                }

                // Optimization to avoid running these tests against Seasons
                if (args.Parent is Series || args.Parent is Season || args.Parent is MusicArtist || args.Parent is MusicAlbum)
                {
                    return(null);
                }

                var collectionType = args.GetCollectionType();

                // If there's a collection type and it's not tv, it can't be a series
                if (!string.IsNullOrEmpty(collectionType) &&
                    !string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase) &&
                    !string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
                {
                    return(null);
                }

                // It's a Series if any of the following conditions are met:
                // series.xml exists
                // [tvdbid= is present in the path
                // TVUtils.IsSeriesFolder returns true
                var filename = Path.GetFileName(args.Path);

                if (string.IsNullOrEmpty(filename))
                {
                    return(null);
                }

                // Without these movies that have the name season in them could cause the parent folder to be resolved as a series
                if (filename.IndexOf("[tmdbid=", StringComparison.OrdinalIgnoreCase) != -1)
                {
                    return(null);
                }

                if (args.ContainsMetaFileByName("series.xml") || filename.IndexOf("[tvdbid=", StringComparison.OrdinalIgnoreCase) != -1 || TVUtils.IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService))
                {
                    return(new Series());
                }
            }

            return(null);
        }
        /// <summary>
        /// Resolves the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Episode.</returns>
        protected override Episode Resolve(ItemResolveArgs args)
        {
            var parent = args.Parent;

            if (parent == null)
            {
                return(null);
            }

            var season = parent as Season;

            // Just in case the user decided to nest episodes.
            // Not officially supported but in some cases we can handle it.
            if (season == null)
            {
                season = parent.Parents.OfType <Season>().FirstOrDefault();
            }

            // If the parent is a Season or Series, then this is an Episode if the VideoResolver returns something
            if (season != null || parent is Series || parent.Parents.OfType <Series>().Any())
            {
                Episode episode = null;

                if (args.IsDirectory)
                {
                    if (args.ContainsFileSystemEntryByName("video_ts"))
                    {
                        episode = new Episode
                        {
                            Path      = args.Path,
                            VideoType = VideoType.Dvd
                        };
                    }
                    if (args.ContainsFileSystemEntryByName("bdmv"))
                    {
                        episode = new Episode
                        {
                            Path      = args.Path,
                            VideoType = VideoType.BluRay
                        };
                    }
                }

                if (episode == null)
                {
                    episode = base.Resolve(args);
                }

                if (episode != null)
                {
                    if (season != null)
                    {
                        episode.ParentIndexNumber = season.IndexNumber;
                    }

                    if (episode.ParentIndexNumber == null)
                    {
                        episode.ParentIndexNumber = TVUtils.GetSeasonNumberFromEpisodeFile(args.Path);
                    }
                }

                return(episode);
            }

            return(null);
        }
Example #28
0
        /// <summary>
        /// Fetches the episode data.
        /// </summary>
        /// <param name="seriesXml">The series XML.</param>
        /// <param name="episode">The episode.</param>
        /// <param name="seriesId">The series id.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task{System.Boolean}.</returns>
        private async Task <ProviderRefreshStatus> FetchEpisodeData(XmlDocument seriesXml, Episode episode, string seriesId, CancellationToken cancellationToken)
        {
            var status = ProviderRefreshStatus.Success;

            if (episode.IndexNumber == null)
            {
                return(status);
            }

            var seasonNumber = episode.ParentIndexNumber ?? TVUtils.GetSeasonNumberFromEpisodeFile(episode.Path);

            if (seasonNumber == null)
            {
                return(status);
            }

            var usingAbsoluteData = false;

            var episodeNode = seriesXml.SelectSingleNode("//Episode[EpisodeNumber='" + episode.IndexNumber.Value + "'][SeasonNumber='" + seasonNumber.Value + "']");

            if (episodeNode == null)
            {
                if (seasonNumber.Value == 1)
                {
                    episodeNode       = seriesXml.SelectSingleNode("//Episode[absolute_number='" + episode.IndexNumber.Value + "']");
                    usingAbsoluteData = true;
                }
            }

            // If still null, nothing we can do
            if (episodeNode == null)
            {
                return(status);
            }
            IEnumerable <XmlDocument> extraEpisodesNode = new XmlDocument[] { };

            if (episode.IndexNumberEnd.HasValue)
            {
                var seriesXDocument = XDocument.Load(new XmlNodeReader(seriesXml));
                if (usingAbsoluteData)
                {
                    extraEpisodesNode =
                        seriesXDocument.Descendants("Episode")
                        .Where(
                            x =>
                            int.Parse(x.Element("absolute_number").Value) > episode.IndexNumber &&
                            int.Parse(x.Element("absolute_number").Value) <= episode.IndexNumberEnd.Value).OrderBy(x => x.Element("absolute_number").Value).Select(x => x.ToXmlDocument());
                }
                else
                {
                    var all =
                        seriesXDocument.Descendants("Episode").Where(x => int.Parse(x.Element("SeasonNumber").Value) == seasonNumber.Value);

                    var xElements = all.Where(x => int.Parse(x.Element("EpisodeNumber").Value) > episode.IndexNumber && int.Parse(x.Element("EpisodeNumber").Value) <= episode.IndexNumberEnd.Value);
                    extraEpisodesNode = xElements.OrderBy(x => x.Element("EpisodeNumber").Value).Select(x => x.ToXmlDocument());
                }
            }
            var doc = new XmlDocument();

            doc.LoadXml(episodeNode.OuterXml);

            if (!episode.HasImage(ImageType.Primary))
            {
                var p = doc.SafeGetString("//filename");
                if (p != null)
                {
                    if (!Directory.Exists(episode.MetaLocation))
                    {
                        Directory.CreateDirectory(episode.MetaLocation);
                    }

                    try
                    {
                        var url = TVUtils.BannerUrl + p;

                        await _providerManager.SaveImage(episode, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Primary, null, cancellationToken)
                        .ConfigureAwait(false);
                    }
                    catch (HttpException)
                    {
                        status = ProviderRefreshStatus.CompletedWithErrors;
                    }
                }
            }
            if (!episode.LockedFields.Contains(MetadataFields.Overview))
            {
                var extraOverview = extraEpisodesNode.Aggregate("", (current, xmlDocument) => current + ("\r\n\r\n" + xmlDocument.SafeGetString("//Overview")));
                episode.Overview = doc.SafeGetString("//Overview") + extraOverview;
            }
            if (usingAbsoluteData)
            {
                episode.IndexNumber = doc.SafeGetInt32("//absolute_number", -1);
            }
            if (episode.IndexNumber < 0)
            {
                episode.IndexNumber = doc.SafeGetInt32("//EpisodeNumber");
            }
            if (!episode.LockedFields.Contains(MetadataFields.Name))
            {
                var extraNames = extraEpisodesNode.Aggregate("", (current, xmlDocument) => current + (", " + xmlDocument.SafeGetString("//EpisodeName")));
                episode.Name = doc.SafeGetString("//EpisodeName") + extraNames;
            }
            episode.CommunityRating = doc.SafeGetSingle("//Rating", -1, 10);
            var      firstAired = doc.SafeGetString("//FirstAired");
            DateTime airDate;

            if (DateTime.TryParse(firstAired, out airDate) && airDate.Year > 1850)
            {
                episode.PremiereDate   = airDate.ToUniversalTime();
                episode.ProductionYear = airDate.Year;
            }
            if (!episode.LockedFields.Contains(MetadataFields.Cast))
            {
                episode.People.Clear();

                var actors = doc.SafeGetString("//GuestStars");
                if (actors != null)
                {
                    // Sometimes tvdb actors have leading spaces
                    //Regex Info:
                    //The first block are the posible delimitators (open-parentheses should be there cause if dont the next block will fail)
                    //The second block Allow the delimitators to be part of the text if they're inside parentheses
                    var persons = Regex.Matches(actors, @"(?<delimitators>([^|,(])|(?<ignoreinParentheses>\([^)]*\)*))+")
                                  .Cast <Match>()
                                  .Select(m => m.Value)
                                  .Where(i => !string.IsNullOrWhiteSpace(i) && !string.IsNullOrEmpty(i));

                    foreach (var person in persons.Select(str =>
                    {
                        var nameGroup = str.Split(new[] { '(' }, 2, StringSplitOptions.RemoveEmptyEntries);
                        var name = nameGroup[0].Trim();
                        var roles = nameGroup.Count() > 1 ? nameGroup[1].Trim() : null;
                        if (roles != null)
                        {
                            roles = roles.EndsWith(")") ? roles.Substring(0, roles.Length - 1) : roles;
                        }
                        return(new PersonInfo {
                            Type = PersonType.GuestStar, Name = name, Role = roles
                        });
                    }))
                    {
                        episode.AddPerson(person);
                    }
                }
                foreach (var xmlDocument in extraEpisodesNode)
                {
                    var extraActors = xmlDocument.SafeGetString("//GuestStars");
                    if (extraActors == null)
                    {
                        continue;
                    }
                    // Sometimes tvdb actors have leading spaces
                    var persons = Regex.Matches(extraActors, @"(?<delimitators>([^|,(])|(?<ignoreinParentheses>\([^)]*\)*))+")
                                  .Cast <Match>()
                                  .Select(m => m.Value)
                                  .Where(i => !string.IsNullOrWhiteSpace(i) && !string.IsNullOrEmpty(i));

                    foreach (var person in persons.Select(str =>
                    {
                        var nameGroup = str.Split(new[] { '(' }, 2, StringSplitOptions.RemoveEmptyEntries);
                        var name = nameGroup[0].Trim();
                        var roles = nameGroup.Count() > 1 ? nameGroup[1].Trim() : null;
                        if (roles != null)
                        {
                            roles = roles.EndsWith(")") ? roles.Substring(0, roles.Length - 1) : roles;
                        }
                        return(new PersonInfo {
                            Type = PersonType.GuestStar, Name = name, Role = roles
                        });
                    }))
                    {
                        episode.AddPerson(person);
                    }
                }

                var directors = doc.SafeGetString("//Director");
                if (directors != null)
                {
                    // Sometimes tvdb actors have leading spaces
                    foreach (var person in directors.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries)
                             .Where(i => !string.IsNullOrWhiteSpace(i))
                             .Select(str => new PersonInfo {
                        Type = PersonType.Director, Name = str.Trim()
                    }))
                    {
                        episode.AddPerson(person);
                    }
                }


                var writers = doc.SafeGetString("//Writer");
                if (writers != null)
                {
                    // Sometimes tvdb actors have leading spaces
                    foreach (var person in writers.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries)
                             .Where(i => !string.IsNullOrWhiteSpace(i))
                             .Select(str => new PersonInfo {
                        Type = PersonType.Writer, Name = str.Trim()
                    }))
                    {
                        episode.AddPerson(person);
                    }
                }
            }

            return(status);
        }
Example #29
0
        public override void ResolveEntity(IMediaLocation location,
                                           out BaseItemFactory factory,
                                           out IEnumerable <InitializationParameter> setup)
        {
            factory = null;
            setup   = null;

            if (!(location is IFolderMediaLocation) && Helper.IsVideo(location.Path) && TVUtils.IsEpisode(location.Path))
            {
                factory = BaseItemFactory <Episode> .Instance;
            }
        }
Example #30
0
        /// <summary>
        /// Fetches the data from XML node.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="item">The item.</param>
        protected override void FetchDataFromXmlNode(XmlReader reader, Series item)
        {
            switch (reader.Name)
            {
            case "id":
                string id = reader.ReadElementContentAsString();
                if (!string.IsNullOrWhiteSpace(id))
                {
                    item.SetProviderId(MetadataProviders.Tvdb, id);
                }
                break;

            case "airs_dayofweek":
            {
                item.AirDays = TVUtils.GetAirDays(reader.ReadElementContentAsString());
                break;
            }

            case "airs_time":
            {
                var val = reader.ReadElementContentAsString();

                if (!string.IsNullOrWhiteSpace(val))
                {
                    item.AirTime = val;
                }
                break;
            }

            case "animeseriesindex":
            {
                var number = reader.ReadElementContentAsString();

                if (!string.IsNullOrWhiteSpace(number))
                {
                    int num;

                    if (int.TryParse(number, out num))
                    {
                        item.AnimeSeriesIndex = num;
                    }
                }
                break;
            }

            case "status":
            {
                var status = reader.ReadElementContentAsString();

                if (!string.IsNullOrWhiteSpace(status))
                {
                    SeriesStatus seriesStatus;
                    if (Enum.TryParse(status, true, out seriesStatus))
                    {
                        item.Status = seriesStatus;
                    }
                    else
                    {
                        Logger.Info("Unrecognized series status: " + status);
                    }
                }

                break;
            }

            default:
                base.FetchDataFromXmlNode(reader, item);
                break;
            }
        }