From 1b4dbe88948f9b7103bbdd51427c4a93b102037e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Feb 2016 13:45:11 -0500 Subject: [PATCH 1/8] update channel ids --- MediaBrowser.Model/LiveTv/LiveTvOptions.cs | 2 -- .../TunerHosts/HdHomerun/HdHomerunHost.cs | 26 ++++++++++++------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs index 50c41fd21..095fa95e1 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs @@ -31,7 +31,6 @@ namespace MediaBrowser.Model.LiveTv public string Type { get; set; } public bool ImportFavoritesOnly { get; set; } public bool IsEnabled { get; set; } - public string GuideGroup { get; set; } public TunerHostInfo() { @@ -49,6 +48,5 @@ namespace MediaBrowser.Model.LiveTv public string ZipCode { get; set; } public string Country { get; set; } public string Path { get; set; } - public string GuideGroup { get; set; } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 013dabe26..ca7d0e119 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -14,6 +14,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dlna; @@ -64,7 +65,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { Name = i.GuideName, Number = i.GuideNumber.ToString(CultureInfo.InvariantCulture), - Id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture), + Id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture) + '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N"), IsFavorite = i.Favorite }); @@ -347,6 +348,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun return Config.GetConfiguration("encoding"); } + private string GetHdHrIdFromChannelId(string channelId) + { + return channelId.Split('_')[1]; + } + protected override async Task> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) { var list = new List(); @@ -355,9 +361,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { return list; } - channelId = channelId.Substring(ChannelIdPrefix.Length); + var hdhrId = GetHdHrIdFromChannelId(channelId); - list.Add(GetMediaSource(info, channelId, "native")); + list.Add(GetMediaSource(info, hdhrId, "native")); try { @@ -366,12 +372,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun if (model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1) { - list.Insert(0, GetMediaSource(info, channelId, "heavy")); + list.Insert(0, GetMediaSource(info, hdhrId, "heavy")); - list.Add(GetMediaSource(info, channelId, "internet480")); - list.Add(GetMediaSource(info, channelId, "internet360")); - list.Add(GetMediaSource(info, channelId, "internet240")); - list.Add(GetMediaSource(info, channelId, "mobile")); + list.Add(GetMediaSource(info, hdhrId, "internet480")); + list.Add(GetMediaSource(info, hdhrId, "internet360")); + list.Add(GetMediaSource(info, hdhrId, "internet240")); + list.Add(GetMediaSource(info, hdhrId, "mobile")); } } catch (Exception ex) @@ -400,9 +406,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { throw new ArgumentException("Channel not found"); } - channelId = channelId.Substring(ChannelIdPrefix.Length); + var hdhrId = GetHdHrIdFromChannelId(channelId); - return GetMediaSource(info, channelId, streamId); + return GetMediaSource(info, hdhrId, streamId); } public async Task Validate(TunerHostInfo info) From 10d4ad98d9fe2e11cc6de78eb0f68307162974fe Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Feb 2016 13:45:20 -0500 Subject: [PATCH 2/8] create notion of locked path --- MediaBrowser.Controller/Library/ILibraryMonitor.cs | 7 +++++++ .../FileOrganization/EpisodeFileOrganizer.cs | 7 +++++++ MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/MediaBrowser.Controller/Library/ILibraryMonitor.cs b/MediaBrowser.Controller/Library/ILibraryMonitor.cs index 918382f04..e965e47d6 100644 --- a/MediaBrowser.Controller/Library/ILibraryMonitor.cs +++ b/MediaBrowser.Controller/Library/ILibraryMonitor.cs @@ -32,5 +32,12 @@ namespace MediaBrowser.Controller.Library /// /// The path. void ReportFileSystemChanged(string path); + + /// + /// Determines whether [is path locked] [the specified path]. + /// + /// The path. + /// true if [is path locked] [the specified path]; otherwise, false. + bool IsPathLocked(string path); } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 2d3c203a2..42f88a5c0 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -64,6 +64,13 @@ namespace MediaBrowser.Server.Implementations.FileOrganization FileSize = new FileInfo(path).Length }; + if (_libraryMonitor.IsPathLocked(path)) + { + result.Status = FileSortingStatus.Failure; + result.StatusMessage = "Path is locked by other processes. Please try again later."; + return result; + } + var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(); var resolver = new Naming.TV.EpisodeResolver(namingOptions, new PatternsLogger()); diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 764eb7c68..25fda3ac1 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -78,6 +78,12 @@ namespace MediaBrowser.Server.Implementations.IO TemporarilyIgnore(path); } + public bool IsPathLocked(string path) + { + var lockedPaths = _tempIgnoredPaths.Keys.ToList(); + return lockedPaths.Any(i => string.Equals(i, path, StringComparison.OrdinalIgnoreCase) || _fileSystem.ContainsSubPath(i, path)); + } + public async void ReportFileSystemChangeComplete(string path, bool refreshPath) { if (string.IsNullOrEmpty(path)) From ae859fd56f569217458e438a357f432bb35e9f0c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Feb 2016 14:06:26 -0500 Subject: [PATCH 3/8] update listing providers --- MediaBrowser.Controller/LiveTv/ChannelInfo.cs | 6 ++++++ MediaBrowser.Model/LiveTv/LiveTvOptions.cs | 11 ++++++++++- .../LiveTv/EmbyTV/EmbyTV.cs | 19 +++++++++++++++++-- .../TunerHosts/HdHomerun/HdHomerunHost.cs | 3 ++- .../LiveTv/TunerHosts/M3UTunerHost.cs | 2 +- .../LiveTv/TunerHosts/M3uParser.cs | 15 ++++++++------- .../LiveTv/TunerHosts/SatIp/SatIpHost.cs | 2 +- 7 files changed, 45 insertions(+), 13 deletions(-) diff --git a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs index 32b8abdc5..7d8df96ed 100644 --- a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs @@ -25,6 +25,12 @@ namespace MediaBrowser.Controller.LiveTv /// The id of the channel. public string Id { get; set; } + /// + /// Gets or sets the tuner host identifier. + /// + /// The tuner host identifier. + public string TunerHostId { get; set; } + /// /// Gets or sets the type of the channel. /// diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs index 095fa95e1..14bcfe342 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Model.LiveTv public int PrePaddingSeconds { get; set; } public int PostPaddingSeconds { get; set; } - + public LiveTvOptions() { EnableMovieProviders = true; @@ -48,5 +48,14 @@ namespace MediaBrowser.Model.LiveTv public string ZipCode { get; set; } public string Country { get; set; } public string Path { get; set; } + + public string[] EnabledTuners { get; set; } + public bool EnableAllTuners { get; set; } + + public ListingsProviderInfo() + { + EnabledTuners = new string[] { }; + EnableAllTuners = true; + } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 6071fd18b..29cb1e70d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -210,9 +210,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } - if (list.Count > 0) + foreach (var provider in GetListingProviders()) { - foreach (var provider in GetListingProviders()) + var enabledChannels = list + .Where(i => IsListingProviderEnabledForTuner(provider.Item2, i.TunerHostId)) + .ToList(); + + if (enabledChannels.Count > 0) { try { @@ -228,6 +232,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } } + _channelCache = list; return list; } @@ -489,6 +494,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } + private bool IsListingProviderEnabledForTuner(ListingsProviderInfo info, string tunerHostId) + { + return info.EnableAllTuners || info.EnabledTuners.Contains(tunerHostId ?? string.Empty, StringComparer.OrdinalIgnoreCase); + } + private async Task> GetProgramsAsyncInternal(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { var channels = await GetChannelsAsync(true, cancellationToken).ConfigureAwait(false); @@ -496,6 +506,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV foreach (var provider in GetListingProviders()) { + if (!IsListingProviderEnabledForTuner(provider.Item2, channel.TunerHostId)) + { + continue; + } + var programs = await provider.Item1.GetProgramsAsync(provider.Item2, channel.Number, channel.Name, startDateUtc, endDateUtc, cancellationToken) .ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index ca7d0e119..f59abe1d5 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -66,7 +66,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun Name = i.GuideName, Number = i.GuideNumber.ToString(CultureInfo.InvariantCulture), Id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture) + '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N"), - IsFavorite = i.Favorite + IsFavorite = i.Favorite, + TunerHostId = info.Id }); diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 17e52fb8e..523f14dfc 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -44,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts protected override async Task> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) { - return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(info.Url, ChannelIdPrefix, cancellationToken).ConfigureAwait(false); + return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(info.Url, ChannelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false); } public Task> GetTunerInfos(CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index 51c35caf4..f8f003fa1 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -25,14 +25,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts _httpClient = httpClient; } - public async Task> Parse(string url, string channelIdPrefix, CancellationToken cancellationToken) + public async Task> Parse(string url, string channelIdPrefix, string tunerHostId, CancellationToken cancellationToken) { var urlHash = url.GetMD5().ToString("N"); // Read the file and display it line by line. using (var reader = new StreamReader(await GetListingsStream(url, cancellationToken).ConfigureAwait(false))) { - return GetChannels(reader, urlHash, channelIdPrefix); + return GetChannels(reader, urlHash, channelIdPrefix, tunerHostId); } } @@ -45,7 +45,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return Task.FromResult(_fileSystem.OpenRead(url)); } - private List GetChannels(StreamReader reader, string urlHash, string channelIdPrefix) + private List GetChannels(StreamReader reader, string urlHash, string channelIdPrefix, string tunerHostId) { var channels = new List(); string line; @@ -69,8 +69,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts _logger.Info("Found m3u channel: {0}", extInf); } else if (!string.IsNullOrWhiteSpace(extInf)) - { - var channel = GetChannelnfo(extInf); + { + var channel = GetChannelnfo(extInf, tunerHostId); channel.Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N"); channel.Path = line; channels.Add(channel); @@ -79,10 +79,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts } return channels; } - public M3UChannel GetChannelnfo(string extInf) + private M3UChannel GetChannelnfo(string extInf, string tunerHostId) { var titleIndex = extInf.LastIndexOf(','); var channel = new M3UChannel(); + channel.TunerHostId = tunerHostId; channel.Number = extInf.Trim().Split(' ')[0] ?? "0"; channel.Name = extInf.Substring(titleIndex + 1); @@ -108,7 +109,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return channel; } - public string FindProperty(string property, string properties, string defaultResult = "") + private string FindProperty(string property, string properties, string defaultResult = "") { var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase); var matches = reg.Matches(properties); diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs index 976041bcc..181169e9a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp { var satInfo = (SatIpTunerHostInfo) tuner; - return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(satInfo.M3UUrl, ChannelIdPrefix, cancellationToken).ConfigureAwait(false); + return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(satInfo.M3UUrl, ChannelIdPrefix, tuner.Id, cancellationToken).ConfigureAwait(false); } public static string DeviceType From b52e9091bbfe3294d92ae56b67a1bb2f0ebeb4c0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Feb 2016 14:29:49 -0500 Subject: [PATCH 4/8] improve support for embedded mp4 info --- .../Probing/ProbeResultNormalizer.cs | 49 +++++++++++++------ MediaBrowser.Model/MediaInfo/MediaInfo.cs | 5 ++ .../MediaInfo/FFProbeVideoInfo.cs | 5 ++ 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 7936a824a..fb0253f0b 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -57,7 +57,7 @@ namespace MediaBrowser.MediaEncoding.Probing } var tags = new Dictionary(StringComparer.OrdinalIgnoreCase); - var tagStreamType = isAudio ? "audio" : "video"; + var tagStreamType = isAudio ? "info" : "video"; if (data.streams != null) { @@ -81,12 +81,29 @@ namespace MediaBrowser.MediaEncoding.Probing } FetchGenres(info, tags); - var overview = FFProbeHelpers.GetDictionaryValue(tags, "description"); + var shortOverview = FFProbeHelpers.GetDictionaryValue(tags, "description"); + var overview = FFProbeHelpers.GetDictionaryValue(tags, "synopsis"); + + if (string.IsNullOrWhiteSpace(overview)) + { + overview = shortOverview; + shortOverview = null; + } + if (string.IsNullOrWhiteSpace(overview)) + { + overview = FFProbeHelpers.GetDictionaryValue(tags, "desc"); + } + if (!string.IsNullOrWhiteSpace(overview)) { info.Overview = overview; } + if (!string.IsNullOrWhiteSpace(shortOverview)) + { + info.ShortOverview = shortOverview; + } + var title = FFProbeHelpers.GetDictionaryValue(tags, "title"); if (!string.IsNullOrWhiteSpace(title)) { @@ -105,13 +122,15 @@ namespace MediaBrowser.MediaEncoding.Probing { SetAudioRuntimeTicks(data, info); - // tags are normally located under data.format, but we've seen some cases with ogg where they're part of the audio stream + // tags are normally located under data.format, but we've seen some cases with ogg where they're part of the info stream // so let's create a combined list of both SetAudioInfoFromTags(info, tags); } else { + FetchStudios(info, tags, "copyright"); + var iTunEXTC = FFProbeHelpers.GetDictionaryValue(tags, "iTunEXTC"); if (!string.IsNullOrWhiteSpace(iTunEXTC)) { @@ -124,13 +143,13 @@ namespace MediaBrowser.MediaEncoding.Probing info.OfficialRatingDescription = parts[3]; } } - + var itunesXml = FFProbeHelpers.GetDictionaryValue(tags, "iTunMOVI"); if (!string.IsNullOrWhiteSpace(itunesXml)) { FetchFromItunesInfo(itunesXml, info); } - + if (data.format != null && !string.IsNullOrEmpty(data.format.duration)) { info.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration, _usCulture)).Ticks; @@ -157,7 +176,7 @@ namespace MediaBrowser.MediaEncoding.Probing /// /// Converts ffprobe stream info to our MediaStream class /// - /// if set to true [is audio]. + /// if set to true [is info]. /// The stream info. /// The format info. /// MediaStream. @@ -190,7 +209,7 @@ namespace MediaBrowser.MediaEncoding.Probing stream.Comment = GetDictionaryValue(streamInfo.tags, "comment"); } - if (string.Equals(streamInfo.codec_type, "audio", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(streamInfo.codec_type, "info", StringComparison.OrdinalIgnoreCase)) { stream.Type = MediaStreamType.Audio; @@ -438,8 +457,8 @@ namespace MediaBrowser.MediaEncoding.Probing { if (result.streams != null) { - // Get the first audio stream - var stream = result.streams.FirstOrDefault(s => string.Equals(s.codec_type, "audio", StringComparison.OrdinalIgnoreCase)); + // Get the first info stream + var stream = result.streams.FirstOrDefault(s => string.Equals(s.codec_type, "info", StringComparison.OrdinalIgnoreCase)); if (stream != null) { @@ -703,10 +722,10 @@ namespace MediaBrowser.MediaEncoding.Probing /// /// Gets the studios from the tags collection /// - /// The audio. + /// The info. /// The tags. /// Name of the tag. - private void FetchStudios(Model.MediaInfo.MediaInfo audio, Dictionary tags, string tagName) + private void FetchStudios(MediaInfo info, Dictionary tags, string tagName) { var val = FFProbeHelpers.GetDictionaryValue(tags, tagName); @@ -717,19 +736,19 @@ namespace MediaBrowser.MediaEncoding.Probing foreach (var studio in studios) { // Sometimes the artist name is listed here, account for that - if (audio.Artists.Contains(studio, StringComparer.OrdinalIgnoreCase)) + if (info.Artists.Contains(studio, StringComparer.OrdinalIgnoreCase)) { continue; } - if (audio.AlbumArtists.Contains(studio, StringComparer.OrdinalIgnoreCase)) + if (info.AlbumArtists.Contains(studio, StringComparer.OrdinalIgnoreCase)) { continue; } - audio.Studios.Add(studio); + info.Studios.Add(studio); } - audio.Studios = audio.Studios + info.Studios = info.Studios .Where(i => !string.IsNullOrWhiteSpace(i)) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); diff --git a/MediaBrowser.Model/MediaInfo/MediaInfo.cs b/MediaBrowser.Model/MediaInfo/MediaInfo.cs index 126710197..de082635d 100644 --- a/MediaBrowser.Model/MediaInfo/MediaInfo.cs +++ b/MediaBrowser.Model/MediaInfo/MediaInfo.cs @@ -51,6 +51,11 @@ namespace MediaBrowser.Model.MediaInfo /// /// The overview. public string Overview { get; set; } + /// + /// Gets or sets the short overview. + /// + /// The short overview. + public string ShortOverview { get; set; } public MediaInfo() { diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index fb8e25892..ee05a89a8 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -463,6 +463,11 @@ namespace MediaBrowser.Providers.MediaInfo video.Overview = data.Overview; } } + + if (string.IsNullOrWhiteSpace(video.ShortOverview) || isFullRefresh) + { + video.ShortOverview = data.ShortOverview; + } } private async Task FetchPeople(Video video, Model.MediaInfo.MediaInfo data, MetadataRefreshOptions options) From 5ca2ae6395acc88d0f322a041afd9a25437938af Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Feb 2016 15:20:22 -0500 Subject: [PATCH 5/8] support parsing itunes info --- .../Probing/ProbeResultNormalizer.cs | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index fb0253f0b..bfc86b10e 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -7,7 +7,10 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Text; +using System.Xml; using CommonIO; +using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; @@ -170,7 +173,215 @@ namespace MediaBrowser.MediaEncoding.Probing private void FetchFromItunesInfo(string xml, MediaInfo info) { + // Make things simpler and strip out the dtd + xml = xml.Substring(xml.IndexOf("" + xml; + // \n\n\n\n\tcast\n\t\n\t\t\n\t\t\tname\n\t\t\tBlender Foundation\n\t\t\n\t\t\n\t\t\tname\n\t\t\tJanus Bager Kristensen\n\t\t\n\t\n\tdirectors\n\t\n\t\t\n\t\t\tname\n\t\t\tSacha Goedegebure\n\t\t\n\t\n\tstudio\n\tBlender Foundation\n\n\n + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml))) + { + using (var streamReader = new StreamReader(stream)) + { + // Use XmlReader for best performance + using (var reader = XmlReader.Create(streamReader)) + { + reader.MoveToContent(); + + // Loop through each element + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "dict": + using (var subtree = reader.ReadSubtree()) + { + ReadFromDictNode(subtree, info); + } + break; + default: + reader.Skip(); + break; + } + } + } + } + } + } + } + + private void ReadFromDictNode(XmlReader reader, MediaInfo info) + { + reader.MoveToContent(); + + string currentKey = null; + List pairs = new List(); + + // Loop through each element + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "key": + if (!string.IsNullOrWhiteSpace(currentKey)) + { + ProcessPairs(currentKey, pairs, info); + } + currentKey = reader.ReadElementContentAsString(); + pairs = new List(); + break; + case "string": + var value = reader.ReadElementContentAsString(); + if (!string.IsNullOrWhiteSpace(value)) + { + pairs.Add(new NameValuePair + { + Name = value, + Value = value + }); + } + break; + case "array": + if (!string.IsNullOrWhiteSpace(currentKey)) + { + using (var subtree = reader.ReadSubtree()) + { + pairs.AddRange(ReadValueArray(subtree)); + } + } + break; + default: + reader.Skip(); + break; + } + } + } + } + + private List ReadValueArray(XmlReader reader) + { + reader.MoveToContent(); + + List pairs = new List(); + + // Loop through each element + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "dict": + using (var subtree = reader.ReadSubtree()) + { + var dict = GetNameValuePair(subtree); + if (dict != null) + { + pairs.Add(dict); + } + } + break; + default: + reader.Skip(); + break; + } + } + } + + return pairs; + } + + private void ProcessPairs(string key, List pairs, MediaInfo info) + { + if (string.Equals(key, "studio", StringComparison.OrdinalIgnoreCase)) + { + foreach (var pair in pairs) + { + info.Studios.Add(pair.Value); + } + + info.Studios = info.Studios + .Where(i => !string.IsNullOrWhiteSpace(i)) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + + } + else if (string.Equals(key, "screenwriters", StringComparison.OrdinalIgnoreCase)) + { + foreach (var pair in pairs) + { + info.People.Add(new BaseItemPerson + { + Name = pair.Value, + Type = PersonType.Writer + }); + } + } + else if (string.Equals(key, "producers", StringComparison.OrdinalIgnoreCase)) + { + foreach (var pair in pairs) + { + info.People.Add(new BaseItemPerson + { + Name = pair.Value, + Type = PersonType.Producer + }); + } + } + else if (string.Equals(key, "directors", StringComparison.OrdinalIgnoreCase)) + { + foreach (var pair in pairs) + { + info.People.Add(new BaseItemPerson + { + Name = pair.Value, + Type = PersonType.Director + }); + } + } + } + + private NameValuePair GetNameValuePair(XmlReader reader) + { + reader.MoveToContent(); + + string name = null; + string value = null; + + // Loop through each element + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "key": + name = reader.ReadElementContentAsString(); + break; + case "string": + value = reader.ReadElementContentAsString(); + break; + default: + reader.Skip(); + break; + } + } + } + + if (string.IsNullOrWhiteSpace(name) || + string.IsNullOrWhiteSpace(value)) + { + return null; + } + + return new NameValuePair + { + Name = name, + Value = value + }; } /// From 355a4eea4e9592ac7a288e883f30a284a519e4f8 Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 24 Feb 2016 16:59:34 -0500 Subject: [PATCH 6/8] update mac release --- .../Emby.Server.Mac.csproj | 567 ++++-------------- 1 file changed, 123 insertions(+), 444 deletions(-) diff --git a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj index 0b4dce140..dde4c544e 100644 --- a/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj +++ b/MediaBrowser.Server.Mac/Emby.Server.Mac.csproj @@ -476,6 +476,9 @@ Resources\dashboard-ui\photos.html + + Resources\dashboard-ui\pin.html + Resources\dashboard-ui\playbackconfiguration.html @@ -1316,6 +1319,18 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\visibleinviewport.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\actionsheet\actionsheet.css + + + Resources\dashboard-ui\bower_components\emby-webcomponents\actionsheet\actionsheet.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\confirm\confirm.js + + + Resources\dashboard-ui\bower_components\emby-webcomponents\confirm\nativeconfirm.js + Resources\dashboard-ui\bower_components\emby-webcomponents\images\basicimagefetcher.js @@ -1325,6 +1340,12 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\images\persistentimagefetcher.js + + Resources\dashboard-ui\bower_components\emby-webcomponents\loading\loading.css + + + Resources\dashboard-ui\bower_components\emby-webcomponents\loading\loading.js + Resources\dashboard-ui\bower_components\emby-webcomponents\paperdialoghelper\paperdialoghelper.css @@ -1352,6 +1373,9 @@ Resources\dashboard-ui\bower_components\emby-webcomponents\slideshow\style.css + + Resources\dashboard-ui\bower_components\emby-webcomponents\toast\toast.js + Resources\dashboard-ui\bower_components\fastclick\.bower.json @@ -1868,6 +1892,9 @@ Resources\dashboard-ui\bower_components\iron-demo-helpers\.gitignore + + Resources\dashboard-ui\bower_components\iron-demo-helpers\.travis.yml + Resources\dashboard-ui\bower_components\iron-demo-helpers\CONTRIBUTING.md @@ -2003,6 +2030,9 @@ Resources\dashboard-ui\bower_components\iron-flex-layout\index.html + + Resources\dashboard-ui\bower_components\iron-flex-layout\iron-flex-layout-classes.html + Resources\dashboard-ui\bower_components\iron-flex-layout\iron-flex-layout.html @@ -2012,12 +2042,18 @@ Resources\dashboard-ui\bower_components\iron-flex-layout\classes\iron-shadow-flex-layout.html - - Resources\dashboard-ui\bower_components\iron-flex-layout\demo\demo-snippet.html - Resources\dashboard-ui\bower_components\iron-flex-layout\demo\index.html + + Resources\dashboard-ui\bower_components\iron-flex-layout\test\index.html + + + Resources\dashboard-ui\bower_components\iron-flex-layout\test\iron-flex-layout-classes.html + + + Resources\dashboard-ui\bower_components\iron-flex-layout\test\iron-flex-layout.html + Resources\dashboard-ui\bower_components\iron-form-element-behavior\.bower.json @@ -2486,6 +2522,12 @@ Resources\dashboard-ui\bower_components\iron-resizable-behavior\.gitignore + + Resources\dashboard-ui\bower_components\iron-resizable-behavior\.travis.yml + + + Resources\dashboard-ui\bower_components\iron-resizable-behavior\CONTRIBUTING.md + Resources\dashboard-ui\bower_components\iron-resizable-behavior\README.md @@ -2642,50 +2684,17 @@ Resources\dashboard-ui\bower_components\jquery\.bower.json - - Resources\dashboard-ui\bower_components\jquery\.editorconfig - - - Resources\dashboard-ui\bower_components\jquery\.gitattributes - - - Resources\dashboard-ui\bower_components\jquery\.gitignore - - - Resources\dashboard-ui\bower_components\jquery\.jscsrc - - - Resources\dashboard-ui\bower_components\jquery\.jshintignore - - - Resources\dashboard-ui\bower_components\jquery\.jshintrc - - - Resources\dashboard-ui\bower_components\jquery\.mailmap - - - Resources\dashboard-ui\bower_components\jquery\.npmignore - - - Resources\dashboard-ui\bower_components\jquery\.travis.yml - Resources\dashboard-ui\bower_components\jquery\AUTHORS.txt - - Resources\dashboard-ui\bower_components\jquery\CONTRIBUTING.md - - - Resources\dashboard-ui\bower_components\jquery\Gruntfile.js - Resources\dashboard-ui\bower_components\jquery\LICENSE.txt Resources\dashboard-ui\bower_components\jquery\README.md - - Resources\dashboard-ui\bower_components\jquery\package.json + + Resources\dashboard-ui\bower_components\jquery\bower.json Resources\dashboard-ui\bower_components\jquery\dist\jquery.js @@ -2696,44 +2705,14 @@ Resources\dashboard-ui\bower_components\jquery\dist\jquery.min.map - - Resources\dashboard-ui\bower_components\jquery\external\npo\npo.js + + Resources\dashboard-ui\bower_components\jquery\dist\jquery.slim.js - - Resources\dashboard-ui\bower_components\jquery\external\qunit\LICENSE.txt + + Resources\dashboard-ui\bower_components\jquery\dist\jquery.slim.min.js - - Resources\dashboard-ui\bower_components\jquery\external\qunit\MIT-LICENSE.txt - - - Resources\dashboard-ui\bower_components\jquery\external\qunit\qunit.css - - - Resources\dashboard-ui\bower_components\jquery\external\qunit\qunit.js - - - Resources\dashboard-ui\bower_components\jquery\external\qunit-assert-step\MIT-LICENSE.txt - - - Resources\dashboard-ui\bower_components\jquery\external\qunit-assert-step\qunit-assert-step.js - - - Resources\dashboard-ui\bower_components\jquery\external\requirejs\require.js - - - Resources\dashboard-ui\bower_components\jquery\external\sinon\sinon-1.14.1.js - - - Resources\dashboard-ui\bower_components\jquery\external\sizzle\LICENSE.txt - - - Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.js - - - Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.js - - - Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.map + + Resources\dashboard-ui\bower_components\jquery\dist\jquery.slim.min.map Resources\dashboard-ui\bower_components\jquery\src\.jshintrc @@ -2801,6 +2780,9 @@ Resources\dashboard-ui\bower_components\jquery\src\serialize.js + + Resources\dashboard-ui\bower_components\jquery\src\support.js + Resources\dashboard-ui\bower_components\jquery\src\traversing.js @@ -2840,6 +2822,9 @@ Resources\dashboard-ui\bower_components\jquery\src\attributes\val.js + + Resources\dashboard-ui\bower_components\jquery\src\core\DOMEval.js + Resources\dashboard-ui\bower_components\jquery\src\core\access.js @@ -2879,12 +2864,24 @@ Resources\dashboard-ui\bower_components\jquery\src\data\Data.js + + Resources\dashboard-ui\bower_components\jquery\src\data\accepts.js + + + Resources\dashboard-ui\bower_components\jquery\src\data\support.js + + + Resources\dashboard-ui\bower_components\jquery\src\deferred\exceptionHook.js + Resources\dashboard-ui\bower_components\jquery\src\effects\Tween.js Resources\dashboard-ui\bower_components\jquery\src\effects\animatedSelector.js + + Resources\dashboard-ui\bower_components\jquery\src\effects\support.js + Resources\dashboard-ui\bower_components\jquery\src\event\ajax.js @@ -2912,6 +2909,9 @@ Resources\dashboard-ui\bower_components\jquery\src\manipulation\buildFragment.js + + Resources\dashboard-ui\bower_components\jquery\src\manipulation\createSafeFragment.js + Resources\dashboard-ui\bower_components\jquery\src\manipulation\getAll.js @@ -2930,366 +2930,6 @@ Resources\dashboard-ui\bower_components\jquery\src\traversing\findFilter.js - - Resources\dashboard-ui\bower_components\jquery\test\.jshintrc - - - Resources\dashboard-ui\bower_components\jquery\test\delegatetest.html - - - Resources\dashboard-ui\bower_components\jquery\test\hovertest.html - - - Resources\dashboard-ui\bower_components\jquery\test\index.html - - - Resources\dashboard-ui\bower_components\jquery\test\jquery.js - - - Resources\dashboard-ui\bower_components\jquery\test\localfile.html - - - Resources\dashboard-ui\bower_components\jquery\test\networkerror.html - - - Resources\dashboard-ui\bower_components\jquery\test\promises_aplus_adapter.js - - - Resources\dashboard-ui\bower_components\jquery\test\readywait.html - - - Resources\dashboard-ui\bower_components\jquery\test\xhtml.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\1x1.jpg - - - Resources\dashboard-ui\bower_components\jquery\test\data\atom+xml.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\badcall.js - - - Resources\dashboard-ui\bower_components\jquery\test\data\badjson.js - - - Resources\dashboard-ui\bower_components\jquery\test\data\cleanScript.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\dashboard.xml - - - Resources\dashboard-ui\bower_components\jquery\test\data\echoData.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\echoQuery.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\errorWithJSON.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\errorWithText.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\etag.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\headers.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\if_modified_since.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\iframe.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\jquery-1.9.1.js - - - Resources\dashboard-ui\bower_components\jquery\test\data\json.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\json_obj.js - - - Resources\dashboard-ui\bower_components\jquery\test\data\jsonp.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\name.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\name.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\nocontent.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\params_html.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\readywaitasset.js - - - Resources\dashboard-ui\bower_components\jquery\test\data\readywaitloader.js - - - Resources\dashboard-ui\bower_components\jquery\test\data\script.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\statusText.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\test.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\test.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\test2.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\test3.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\testbar.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\testinit.js - - - Resources\dashboard-ui\bower_components\jquery\test\data\testrunner.js - - - Resources\dashboard-ui\bower_components\jquery\test\data\testsuite.css - - - Resources\dashboard-ui\bower_components\jquery\test\data\text.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\with_fries.xml - - - Resources\dashboard-ui\bower_components\jquery\test\data\with_fries_over_jsonp.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\ajax\content-type.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\ajax\evalScript.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\ajax\method.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\ajax\onunload.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\ajax\unreleasedXHR.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\core\aliased.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\core\cc_on.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\core\dont_return.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\core\dynamic_ready.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\core\onready.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\css\cssWidthBeforeDocReady.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\data\dataAttrs.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\dimensions\documentLarge.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\event\focusElem.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\event\focusinCrossFrame.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\event\interactiveReady.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\event\longLoadScript.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\event\onbeforeunload.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\event\promiseReady.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\event\syncReady.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\event\triggerunload.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\manipulation\iframe-denied.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\offset\absolute.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\offset\body.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\offset\fixed.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\offset\relative.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\offset\scroll.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\offset\static.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\offset\table.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\selector\html5_selector.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\selector\sizzle_cache.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\support\bodyBackground.html - - - Resources\dashboard-ui\bower_components\jquery\test\data\support\csp-clean.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\support\csp-log.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\support\csp.js - - - Resources\dashboard-ui\bower_components\jquery\test\data\support\csp.php - - - Resources\dashboard-ui\bower_components\jquery\test\data\support\getComputedSupport.js - - - Resources\dashboard-ui\bower_components\jquery\test\integration\gh-1764-fullscreen.html - - - Resources\dashboard-ui\bower_components\jquery\test\integration\gh-2343-ie-radio-click.html - - - Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.css - - - Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.html - - - Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen.js - - - Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\.jshintrc - - - Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_missing.js - - - Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_passed.js - - - Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_present_originally.js - - - Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_native_symbol.js - - - Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_symbol_polyfill.js - - - Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_global_not_created.js - - - Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_iterability_es6.js - - - Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_jquery.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\ajax.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\attributes.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\basic.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\callbacks.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\core.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\css.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\data.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\deferred.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\deprecated.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\dimensions.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\effects.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\event.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\exports.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\manipulation.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\offset.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\queue.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\ready.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\selector.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\serialize.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\support.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\traversing.js - - - Resources\dashboard-ui\bower_components\jquery\test\unit\wrap.js - Resources\dashboard-ui\bower_components\jstree\.bower.json @@ -8279,6 +7919,9 @@ Resources\dashboard-ui\components\filterdialog\filterdialog.template.html + + Resources\dashboard-ui\components\filterdialog\style.css + Resources\dashboard-ui\components\guestinviter\guestinviter.js @@ -8762,21 +8405,21 @@ Resources\dashboard-ui\devices\ios\ios.css + + Resources\dashboard-ui\devices\windowsphone\wp.css + Resources\dashboard-ui\files\dummy.mp4 Resources\dashboard-ui\legacy\buttonenabled.js - - Resources\dashboard-ui\legacy\deferred.js + + Resources\dashboard-ui\legacy\dashboard.js Resources\dashboard-ui\scripts\aboutpage.js - - Resources\dashboard-ui\scripts\actionsheet.js - Resources\dashboard-ui\scripts\addpluginpage.js @@ -9104,6 +8747,9 @@ Resources\dashboard-ui\scripts\photos.js + + Resources\dashboard-ui\scripts\pin.js + Resources\dashboard-ui\scripts\playbackconfiguration.js @@ -9122,9 +8768,6 @@ Resources\dashboard-ui\scripts\pluginspage.js - - Resources\dashboard-ui\scripts\queryfilters.js - Resources\dashboard-ui\scripts\ratingdialog.js @@ -9920,8 +9563,11 @@ Resources\dashboard-ui\thirdparty\social-share-kit-1.0.4\dist\js\social-share-kit.min.js - - Resources\dashboard-ui\voice\textprocessor-en-us.js + + Resources\dashboard-ui\voice\Readme.md + + + Resources\dashboard-ui\voice\grammarprocessor.js Resources\dashboard-ui\voice\voice.css @@ -9929,5 +9575,38 @@ Resources\dashboard-ui\voice\voice.js + + Resources\dashboard-ui\voice\voicecommands.js + + + Resources\dashboard-ui\voice\voicedialog.js + + + Resources\dashboard-ui\voice\commands\controlcommands.js + + + Resources\dashboard-ui\voice\commands\disablecommands.js + + + Resources\dashboard-ui\voice\commands\enablecommands.js + + + Resources\dashboard-ui\voice\commands\playcommands.js + + + Resources\dashboard-ui\voice\commands\searchcommands.js + + + Resources\dashboard-ui\voice\commands\showcommands.js + + + Resources\dashboard-ui\voice\commands\togglecommands.js + + + Resources\dashboard-ui\voice\grammar\en-US.json + + + Resources\dashboard-ui\voice\grammar\grammar.json + \ No newline at end of file From b1e35d248b8676e60d7d25c48e91a051b4ed0ee1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Feb 2016 22:15:07 -0500 Subject: [PATCH 7/8] update login --- MediaBrowser.Api/MediaBrowser.Api.csproj | 1 - MediaBrowser.Api/PinLoginService.cs | 243 ------------------ .../MediaBrowser.WebDashboard.csproj | 6 - 3 files changed, 250 deletions(-) delete mode 100644 MediaBrowser.Api/PinLoginService.cs diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index f711c69e6..7e55446ae 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -80,7 +80,6 @@ - diff --git a/MediaBrowser.Api/PinLoginService.cs b/MediaBrowser.Api/PinLoginService.cs deleted file mode 100644 index a4957651f..000000000 --- a/MediaBrowser.Api/PinLoginService.cs +++ /dev/null @@ -1,243 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Globalization; -using System.Threading.Tasks; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Session; -using MediaBrowser.Model.Connect; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Session; -using ServiceStack; - -namespace MediaBrowser.Api -{ - [Route("/Auth/Pin", "POST", Summary = "Creates a pin request")] - public class CreatePinRequest : IReturn - { - [ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] - public string DeviceId { get; set; } - [ApiMember(Name = "AppName", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] - public string AppName { get; set; } - } - - [Route("/Auth/Pin", "GET", Summary = "Gets pin status")] - public class GetPinStatusRequest : IReturn - { - [ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] - public string DeviceId { get; set; } - [ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] - public string Pin { get; set; } - } - - [Route("/Auth/Pin/Exchange", "POST", Summary = "Exchanges a pin")] - public class ExchangePinRequest : IReturn - { - [ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] - public string DeviceId { get; set; } - [ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] - public string Pin { get; set; } - } - - [Route("/Auth/Pin/Validate", "POST", Summary = "Validates a pin")] - [Authenticated] - public class ValidatePinRequest : IReturn - { - [ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] - public string Pin { get; set; } - } - - public class PinLoginService : BaseApiService - { - private static readonly ConcurrentDictionary _activeRequests = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - private readonly ISessionManager _sessionManager; - private readonly IUserManager _userManager; - - public PinLoginService(ISessionManager sessionManager, IUserManager userManager) - { - _sessionManager = sessionManager; - _userManager = userManager; - } - - public object Post(CreatePinRequest request) - { - if (string.IsNullOrWhiteSpace(request.DeviceId)) - { - throw new ArgumentNullException("DeviceId"); - } - if (string.IsNullOrWhiteSpace(request.AppName)) - { - throw new ArgumentNullException("AppName"); - } - - var pin = GetNewPin(); - - var value = new MyPinStatus - { - CreationTimeUtc = DateTime.UtcNow, - IsConfirmed = false, - IsExpired = false, - Pin = pin, - DeviceId = request.DeviceId, - AppName = request.AppName - }; - - _activeRequests.AddOrUpdate(pin, value, (k, v) => value); - - return ToOptimizedResult(new PinCreationResult - { - DeviceId = request.DeviceId, - IsConfirmed = false, - IsExpired = false, - Pin = pin - }); - } - - public object Get(GetPinStatusRequest request) - { - MyPinStatus status; - - if (!_activeRequests.TryGetValue(request.Pin, out status)) - { - Logger.Debug("Pin {0} not found.", request.Pin); - throw new ResourceNotFoundException(); - } - - EnsureValid(request.DeviceId, status); - - return ToOptimizedResult(new PinStatusResult - { - Pin = status.Pin, - IsConfirmed = status.IsConfirmed, - IsExpired = status.IsExpired - }); - } - - public async Task Post(ExchangePinRequest request) - { - MyPinStatus status; - - if (!_activeRequests.TryGetValue(request.Pin, out status)) - { - Logger.Debug("Pin {0} not found.", request.Pin); - throw new ResourceNotFoundException(); - } - - EnsureValid(request.DeviceId, status); - - if (!status.IsConfirmed) - { - throw new ResourceNotFoundException(); - } - - var auth = AuthorizationContext.GetAuthorizationInfo(Request); - var user = _userManager.GetUserById(status.UserId); - - var result = await _sessionManager.CreateNewSession(new AuthenticationRequest - { - App = auth.Client, - AppVersion = auth.Version, - DeviceId = auth.DeviceId, - DeviceName = auth.Device, - RemoteEndPoint = Request.RemoteIp, - Username = user.Name - - }).ConfigureAwait(false); - - return ToOptimizedResult(result); - } - - public object Post(ValidatePinRequest request) - { - MyPinStatus status; - - if (!_activeRequests.TryGetValue(request.Pin, out status)) - { - throw new ResourceNotFoundException(); - } - - EnsureValid(status); - - status.IsConfirmed = true; - status.UserId = AuthorizationContext.GetAuthorizationInfo(Request).UserId; - - return ToOptimizedResult(new ValidatePinResult - { - AppName = status.AppName - }); - } - - private void EnsureValid(string requestedDeviceId, MyPinStatus status) - { - if (!string.Equals(requestedDeviceId, status.DeviceId, StringComparison.OrdinalIgnoreCase)) - { - Logger.Debug("Pin device Id's do not match. requestedDeviceId: {0}, status.DeviceId: {1}", requestedDeviceId, status.DeviceId); - throw new ResourceNotFoundException(); - } - - EnsureValid(status); - } - - private void EnsureValid(MyPinStatus status) - { - if ((DateTime.UtcNow - status.CreationTimeUtc).TotalMinutes > 10) - { - status.IsExpired = true; - } - - if (status.IsExpired) - { - Logger.Debug("Pin {0} is expired", status.Pin); - throw new ResourceNotFoundException(); - } - } - - private string GetNewPin() - { - var pin = GetNewPinInternal(); - - while (IsPinActive(pin)) - { - pin = GetNewPinInternal(); - } - - return pin; - } - - private string GetNewPinInternal() - { - return new Random().Next(10000, 99999).ToString(CultureInfo.InvariantCulture); - } - - private bool IsPinActive(string pin) - { - MyPinStatus status; - - if (!_activeRequests.TryGetValue(pin, out status)) - { - return false; - } - - if (status.IsExpired) - { - return false; - } - - return true; - } - - public class MyPinStatus : PinStatusResult - { - public DateTime CreationTimeUtc { get; set; } - public string DeviceId { get; set; } - public string UserId { get; set; } - public string AppName { get; set; } - } - } - - public class ValidatePinResult - { - public string AppName { get; set; } - } -} diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index fb99e5f9d..59c9efa69 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -278,9 +278,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -320,9 +317,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest From d4dd1cbf7fdb5db561039a7cf1a4c4707f6273bc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 25 Feb 2016 01:09:10 -0500 Subject: [PATCH 8/8] fix audio tracks --- .../Probing/ProbeResultNormalizer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index bfc86b10e..57c2f75cc 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -60,7 +60,7 @@ namespace MediaBrowser.MediaEncoding.Probing } var tags = new Dictionary(StringComparer.OrdinalIgnoreCase); - var tagStreamType = isAudio ? "info" : "video"; + var tagStreamType = isAudio ? "audio" : "video"; if (data.streams != null) { @@ -420,7 +420,7 @@ namespace MediaBrowser.MediaEncoding.Probing stream.Comment = GetDictionaryValue(streamInfo.tags, "comment"); } - if (string.Equals(streamInfo.codec_type, "info", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(streamInfo.codec_type, "audio", StringComparison.OrdinalIgnoreCase)) { stream.Type = MediaStreamType.Audio; @@ -664,12 +664,12 @@ namespace MediaBrowser.MediaEncoding.Probing return null; } - private void SetAudioRuntimeTicks(InternalMediaInfoResult result, Model.MediaInfo.MediaInfo data) + private void SetAudioRuntimeTicks(InternalMediaInfoResult result, MediaInfo data) { if (result.streams != null) { // Get the first info stream - var stream = result.streams.FirstOrDefault(s => string.Equals(s.codec_type, "info", StringComparison.OrdinalIgnoreCase)); + var stream = result.streams.FirstOrDefault(s => string.Equals(s.codec_type, "audio", StringComparison.OrdinalIgnoreCase)); if (stream != null) {