示例#1
0
        private static string GetEpisodeXml(SeriesBase series, Episode episode, IEnumerable <string> bannerImages)
        {
            var metadata = new EpisodeMetadata();

            var m = new Movie
            {
                Title       = episode.EpisodeName,
                Season      = episode.SeasonNumber.Value,
                Episode     = episode.EpisodeNumber.Value,
                Year        = episode.FirstAired.Year,
                Rating      = episode.Rating,
                Plot        = series.Overview,
                EpisodePlot = episode.Overview,
                MPAA        = series.ContentRating,
                Runtime     = series.Runtime.Value,
                genres      = SeriesIOHelper.ToArray(series.Genre),
                Director    = episode.Director,
                Credits     = episode.Writer
            };
            var cast = series.Actors.Length > 0
                ? series.Actors
                : episode.GuestStars;

            m.cast  = SeriesIOHelper.ToArray(cast);
            m.image = bannerImages.ToArray();

            metadata.Movie = m;
            return(metadata.AsXml());
        }
示例#2
0
        /// <summary>
        /// Take the raw episode data row and create a nicely typed struct.
        /// </summary>
        private EpisodeMetadata ExtractEpisodeMetadata(DataRow episodeData, int episodeId)
        {
            EpisodeMetadata metadata = new EpisodeMetadata();

            metadata.Title            = (string)episodeData["TV_Episode_Title"];
            metadata.Summary          = (string)episodeData["TV_Episode_Description"];
            metadata.GalleryImagePath = (string)episodeData["TV_Episode_Gallery_Image"];
            metadata.DetailImagePath  = (string)episodeData["TV_Episode_Detail_Image"];
            metadata.Length           = (int)episodeData["TV_Episode_Length"];
            metadata.Season           = (int)episodeData["TV_Episode_Season"];
            metadata.ReleaseDate      = (DateTime)episodeData["TV_Episode_Release_Date"];

            metadata.Id     = (int)episodeData["TV_Episode_ID"];
            metadata.ShowId = (int)episodeData["TV_Show_ID"];


            //
            // Rating
            //

            DataRow rating = Z.DataSetHelpers.GetIDMappedDataRow(episodeData, "TV_Rating_ID",
                                                                 dataSet.Tables["tbl_TV_Rating"], "TV_Rating_ID");

            metadata.Rating = (string)rating["TV_Rating"];


            return(metadata);
        }
 protected override async Task SaveInternal()
 {
     Title.Save();
     SeasonNumber.Save();
     EpisodeNumber.Save();
     EpisodeMetadata metadata = CreateMetadata();
     await _metadataService.Save(Path, metadata);
 }
示例#4
0
        public Tuple <EpisodeMetadata, int> GetFallbackMetadata(Episode episode)
        {
            string path     = episode.MediaVersions.Head().MediaFiles.Head().Path;
            string fileName = Path.GetFileName(path);
            var    metadata = new EpisodeMetadata
            {
                MetadataKind = MetadataKind.Fallback, Title = fileName ?? path, DateAdded = DateTime.UtcNow
            };

            return(fileName != null?GetEpisodeMetadata(fileName, metadata) : Tuple(metadata, 0));
        }
示例#5
0
        private async Task <Either <BaseError, PlexEpisode> > UpdateArtwork(PlexEpisode existing, PlexEpisode incoming)
        {
            EpisodeMetadata existingMetadata = existing.EpisodeMetadata.Head();
            EpisodeMetadata incomingMetadata = incoming.EpisodeMetadata.Head();

            if (incomingMetadata.DateUpdated > existingMetadata.DateUpdated)
            {
                await UpdateArtworkIfNeeded(existingMetadata, incomingMetadata, ArtworkKind.Thumbnail);
            }

            return(existing);
        }
示例#6
0
        /// <summary>
        /// Create a details page for an episode.
        /// NOTE: This is public to enable debug markup access.
        /// </summary>
        public DetailsPage CreateEpisodeDetailsPage(int episodeId)
        {
            DetailsPage page = new DetailsPage();

            //
            // Get the full metadata on the episode.
            //

            DataRow         episodeData     = GetEpisodeData(episodeId);
            EpisodeMetadata episodeMetadata = ExtractEpisodeMetadata(episodeData, episodeId);


            //
            // Get the full metadata on the show.
            //

            DataRow      showData     = GetShowData(episodeMetadata.ShowId);
            ShowMetadata showMetadata = ExtractShowMetadata(showData, episodeMetadata.ShowId);


            //
            // Fill in the page's easy properties.
            //

            page.Title      = episodeMetadata.Title;
            page.Summary    = episodeMetadata.Summary;
            page.Background = LoadImage(episodeMetadata.DetailImagePath);


            //
            // Metadata
            //
            // Now that we have all the little pieces, we can put together our
            // final metadata string.
            //

            page.Metadata = String.Format(Z.Resources.TV_Details_Metadata,
                                          showMetadata.Provider,
                                          episodeMetadata.Season,
                                          showMetadata.Genre,
                                          episodeMetadata.Length,
                                          showMetadata.CountryShortName,
                                          episodeMetadata.ReleaseDate.Year);


            //
            // Actions
            //

            CreateEpisodeDetailsCommands(page, episodeData, episodeId);

            return(page);
        }
        public async Task Refresh_Always_RefreshesTvShowProperties()
        {
            // Arrange
            EpisodeMetadata metadata = CreateEpisodeMetadata();

            _metadataService.Get(_path)
            .Returns(Task.FromResult(metadata));

            // Act
            await _viewModel.Refresh();

            // Assert
            AssertMetadataEqualsViewModel(metadata);
        }
        public async Task Update_WhenMetadataAlreadyExists_DoesNothing()
        {
            // Arrange
            EpisodeMetadata metadata = CreateEpisodeMetadata();

            _metadataService.Get(_path)
            .Returns(Task.FromResult(metadata));
            _tvShowMetadata.Id
            .Returns("123");

            // Act
            await _viewModel.Update();

            // Assert
            _metadataService.DidNotReceiveWithAnyArgs()
            .Update(_path, "123").Async();
        }
        private async Task <Either <BaseError, Episode> > UpdateThumbnail(Episode episode)
        {
            try
            {
                await LocateThumbnail(episode).IfSomeAsync(
                    async posterFile =>
                {
                    EpisodeMetadata metadata = episode.EpisodeMetadata.Head();
                    await RefreshArtwork(posterFile, metadata, ArtworkKind.Thumbnail);
                });

                return(episode);
            }
            catch (Exception ex)
            {
                return(BaseError.New(ex.ToString()));
            }
        }
 private bool AssertMetadataEqualsViewModel(EpisodeMetadata metadata)
 {
     Assert.Equal(metadata.AiredDate, _viewModel.AiredDate);
     Assert.Equal(metadata.Credits, _viewModel.Credits.Collection);
     Assert.Equal(metadata.Director, _viewModel.Directors.Collection);
     Assert.Equal(metadata.DisplayEpisode, _viewModel.DisplayEpisode);
     Assert.Equal(metadata.DisplaySeason, _viewModel.DisplaySeason);
     Assert.Equal(metadata.EpisodeBookmarks, _viewModel.EpisodeBookmarks);
     Assert.Equal(metadata.EpisodeNumber, _viewModel.EpisodeNumber.Value);
     Assert.Equal(metadata.ImageUrl, _viewModel.ImageUrl);
     Assert.Equal(metadata.LastPlayed, _viewModel.LastPlayed);
     Assert.Equal(metadata.PlayCount, _viewModel.PlayCount);
     Assert.Equal(metadata.Plot, _viewModel.Plot);
     Assert.Equal(metadata.Rating, _viewModel.Rating);
     Assert.Equal(metadata.SeasonNumber, _viewModel.SeasonNumber.Value);
     Assert.Equal(metadata.Title, _viewModel.Title.Value);
     return(true);
 }
示例#11
0
        private Tuple <EpisodeMetadata, int> GetEpisodeMetadata(string fileName, EpisodeMetadata metadata)
        {
            try
            {
                const string PATTERN = @"^(.*?)[.\s-]+[sS](\d+)[eE](\d+).*\.\w+$";
                Match        match   = Regex.Match(fileName, PATTERN);
                if (match.Success)
                {
                    metadata.Title       = match.Groups[1].Value;
                    metadata.DateUpdated = DateTime.UtcNow;
                    return(Tuple(metadata, int.Parse(match.Groups[3].Value)));
                }
            }
            catch (Exception)
            {
                // ignored
            }

            return(Tuple(metadata, 0));
        }
示例#12
0
    private async Task <Either <BaseError, MediaItemScanResult <PlexEpisode> > > UpdateArtwork(
        MediaItemScanResult <PlexEpisode> result,
        PlexEpisode incoming)
    {
        PlexEpisode existing = result.Item;

        foreach (EpisodeMetadata incomingMetadata in incoming.EpisodeMetadata)
        {
            Option <EpisodeMetadata> maybeExistingMetadata = existing.EpisodeMetadata
                                                             .Find(em => em.EpisodeNumber == incomingMetadata.EpisodeNumber);
            if (maybeExistingMetadata.IsSome)
            {
                EpisodeMetadata existingMetadata = maybeExistingMetadata.ValueUnsafe();
                await UpdateArtworkIfNeeded(existingMetadata, incomingMetadata, ArtworkKind.Thumbnail);

                await _metadataRepository.MarkAsUpdated(existingMetadata, incomingMetadata.DateUpdated);
            }
        }

        return(result);
    }
        public async Task Update_WhenNoMetadataAlreadyExists_RetrievesFreshMetadata()
        {
            // Arrange
            EpisodeMetadata metadata = CreateEpisodeMetadata();

            _metadataService.Get(_path)
            .Returns(new EpisodeMetadata().ToTask(), metadata.ToTask());
            _tvShowMetadata.Id
            .Returns("123");

            // Act
            IEnumerable <ProgressItem> items = await _viewModel.Update();

            ProgressItem item = items.First();
            await item.Execute();

            // Assert
            _metadataService.Received()
            .Update(_path, "123").Async();
            AssertMetadataEqualsViewModel(metadata);
        }
        private void RefreshFromMetadata(EpisodeMetadata metadata)
        {
            Title.Value = metadata.Title;
            Title.Save();
            Rating             = metadata.Rating;
            SeasonNumber.Value = metadata.SeasonNumber;
            SeasonNumber.Save();
            EpisodeNumber.Value = metadata.EpisodeNumber;
            EpisodeNumber.Save();
            Plot = metadata.Plot;
            ImagePath.RefreshImage(metadata.ImagePath);
            ImageUrl         = metadata.ImageUrl;
            PlayCount        = metadata.PlayCount;
            LastPlayed       = metadata.LastPlayed;
            AiredDate        = metadata.AiredDate;
            DisplaySeason    = metadata.DisplaySeason;
            DisplayEpisode   = metadata.DisplayEpisode;
            EpisodeBookmarks = metadata.EpisodeBookmarks;

            Credits.ReplaceWith(metadata.Credits);
            Directors.ReplaceWith(metadata.Director);

            _localMetadataExists = metadata.FileInformation != null;
        }
示例#15
0
 public Task <Unit> RemoveMetadata(Episode episode, EpisodeMetadata metadata) =>
 throw new NotSupportedException();
示例#16
0
 public Task <bool> AddActor(EpisodeMetadata metadata, Actor actor) => throw new NotSupportedException();
示例#17
0
        /// <summary>
        /// Called when one of the custom actions on a details page is clicked.
        /// </summary>
        private void OnEpisodeDetailsActionInvoked(DetailsCommand command)
        {
            TVEpisodeDetailsActionType actionType = (TVEpisodeDetailsActionType)command.Type;
            string value     = command.Value;
            int    episodeId = command.ItemId;

            //
            // Interpret the action.
            //

            switch (actionType)
            {
            case TVEpisodeDetailsActionType.WatchNow:
            {
                // Placeholder...
                break;
            }

            case TVEpisodeDetailsActionType.Record:
            {
                //
                // TODO: Grab the xml from the database
                //
                // As is this code schedules a manual 30 minute recording to
                // occur 1 hour from now on channel 4.
                //

                string   xmlRecordingInfoFormat = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<clickToRecord xmlns=\"urn:schemas-microsoft-com:ehome:clicktorecord\">\n\t<body>\n\t\t<programRecord programDuration=\"30\">\n\t\t\t<service>\n\t\t\t\t<key field=\"urn:schemas-microsoft-com:ehome:epg:service#mappedChannelNumber\" match=\"exact\">{0}</key>\n\t\t\t</service>\n\t\t\t<airing>\n\t\t\t\t<key field=\"urn:schemas-microsoft-com:ehome:epg:airing#starttime\">{1}</key>\n\t\t\t</airing>\n\t\t</programRecord>\n\t</body>\n</clickToRecord>";
                int      channelNumber          = 4;
                DateTime time             = DateTime.UtcNow.AddHours(1);
                string   xmlRecordingInfo = String.Format(xmlRecordingInfoFormat, channelNumber, time.ToString("o"));

                XmlReader reader = XmlReader.Create(new StringReader(xmlRecordingInfo));


                CreateScheduleRequestResult scheduleResult = CreateScheduleRequestResult.NoConfiguredResource;
                try
                {
                    //
                    // Create EventSchedule object and create ScheduleRequest from XML.
                    //

                    EventSchedule   scheduler = new EventSchedule();
                    ScheduleRequest request   = null;
                    scheduleResult = scheduler.CreateScheduleRequest(reader, ConflictResolutionPolicy.AllowConflict, "example", out request);

                    Debug.WriteLine("DetailsAction: Record: " + scheduleResult);
                }
                catch (EventScheduleException)
                {
                    // TV may not be configured - handle that exception.
                    Application.Current.MessageBox(Z.Resources.TV_NotSetUpDialog_Text, Z.Resources.TV_NotSetUpDialog_Caption);
                }


                //
                // Display a dialog to notify the user.
                //

                if ((scheduleResult != CreateScheduleRequestResult.NoConfiguredResource) &&
                    (Application.Current.MediaCenterEnvironment != null))
                {
                    EpisodeMetadata metadata = ExtractEpisodeMetadata(GetEpisodeData(episodeId), episodeId);

                    // Two options: "View Scheduled" or "OK"
                    IEnumerable buttons = new object[] {
                        Z.Resources.TV_RecordDialog_ViewScheduled,
                        (int)DialogButtons.Ok
                    };

                    // Use the gallery image in the dialog.
                    // Note that the Dialog API requires a standard Uri, so we
                    // need to specificy the system drive letter.
                    string systemDrive = Environment.GetEnvironmentVariable("SystemDrive");
                    string imagePath   = "file://" + systemDrive + ImagesDirectory + metadata.GalleryImagePath;

                    Application.Current.MediaCenterEnvironment.Dialog(
                        Z.Resources.TV_RecordDialog_Text,
                        metadata.Title,
                        buttons,
                        0, true,
                        imagePath,
                        delegate(DialogResult dialogResult)
                        {
                            // Custom button #1 = 100 = "View Scheduled"
                            // Navigate to the scheduled recordings page
                            if ((int)dialogResult == 100)
                            {
                                Application.Current.MediaCenterEnvironment.NavigateToPage(PageId.ScheduledTVRecordings, null);
                            }

                            Debug.WriteLine("Dialog closed:" + dialogResult);
                        }
                        );
                }
                break;
            }

            case TVEpisodeDetailsActionType.Related:
            {
                //
                // Go to this episode's show gallery.
                //

                EpisodeMetadata metadata = ExtractEpisodeMetadata(GetEpisodeData(episodeId), episodeId);
                GalleryPage     page     = CreateEpisodeGalleryPage(metadata.ShowId);
                Application.Current.GoToGallery(page);
                break;
            }


            default:
                Debug.WriteLine(String.Format("DetailsAction: {0}({1}): NOT YET IMPLEMENTED", actionType, value));
                break;
            }
        }
示例#18
0
        public string GetEpisodeMetadata()
        {
            var metadata = new EpisodeMetadata();

            return(metadata.AsXml());
        }
示例#19
0
 public Task <bool> AddDirector(EpisodeMetadata metadata, Director director) => throw new NotSupportedException();
示例#20
0
 public Task <bool> AddWriter(EpisodeMetadata metadata, Writer writer) => throw new NotSupportedException();
        protected override async Task RefreshInternal()
        {
            EpisodeMetadata metadata = await _metadataService.Get(Path);

            RefreshFromMetadata(metadata);
        }