diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 276aba365c..ffbb5229b0 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -341,7 +341,7 @@ namespace MediaBrowser.Api.Images ImageIndex = imageIndex, ImageType = info.Type, ImageTag = _imageProcessor.GetImageCacheTag(item, info), - Size = fileInfo.Length, + Size = info.Length ?? fileInfo.Length, Width = Convert.ToInt32(size.Width), Height = Convert.ToInt32(size.Height) }; diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index fdffa60d0a..34056c240d 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1309,7 +1309,8 @@ namespace MediaBrowser.Controller.Entities { Path = file.FullName, Type = type, - DateModified = FileSystem.GetLastWriteTimeUtc(file) + DateModified = FileSystem.GetLastWriteTimeUtc(file), + Length = ((FileInfo)file).Length }); } else @@ -1420,11 +1421,14 @@ namespace MediaBrowser.Controller.Entities return null; } + var info = new FileInfo(path); + return new ItemImageInfo { Path = path, - DateModified = FileSystem.GetLastWriteTimeUtc(path), - Type = imageType + DateModified = FileSystem.GetLastWriteTimeUtc(info), + Type = imageType, + Length = info.Length }; } diff --git a/MediaBrowser.Controller/Entities/ItemImageInfo.cs b/MediaBrowser.Controller/Entities/ItemImageInfo.cs index 80aec64824..fe8193c5fe 100644 --- a/MediaBrowser.Controller/Entities/ItemImageInfo.cs +++ b/MediaBrowser.Controller/Entities/ItemImageInfo.cs @@ -10,5 +10,7 @@ namespace MediaBrowser.Controller.Entities public ImageType Type { get; set; } public DateTime DateModified { get; set; } + + public long? Length { get; set; } } } diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 5ea535f4d5..a2335b4bc3 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Playlists public IEnumerable GetManageableItems() { - return GetLinkedChildren(); + return GetPlaylistItems(MediaType, GetLinkedChildren(), null); } private IEnumerable GetPlayableItems(User user) @@ -40,8 +40,12 @@ namespace MediaBrowser.Controller.Playlists if (folder != null) { - var items = folder.GetRecursiveChildren(user, true) - .Where(m => !m.IsFolder && string.Equals(m.MediaType, playlistMediaType, StringComparison.OrdinalIgnoreCase)); + var items = user == null + ? folder.GetRecursiveChildren() + : folder.GetRecursiveChildren(user, true); + + items = items + .Where(m => !m.IsFolder); if (!folder.IsPreSorted) { @@ -52,7 +56,8 @@ namespace MediaBrowser.Controller.Playlists } return new[] { i }; - }); + + }).Where(m => string.Equals(m.MediaType, playlistMediaType, StringComparison.OrdinalIgnoreCase)); } [IgnoreDataMember] diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index 05d822185f..866f87776c 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -7,6 +7,7 @@ using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Playlists; using MediaBrowser.Dlna.Didl; using MediaBrowser.Dlna.Server; using MediaBrowser.Dlna.Service; @@ -339,7 +340,7 @@ namespace MediaBrowser.Dlna.ContentDirectory } else if (search.SearchType == SearchType.Playlist) { - + items = items.OfType(); } items = SortItems(items, user, sort); @@ -495,7 +496,7 @@ namespace MediaBrowser.Dlna.ContentDirectory return items.Where(i => { // Unplayable - if (i.LocationType == LocationType.Virtual) + if (i.LocationType == LocationType.Virtual && !i.IsFolder) { return false; } @@ -507,7 +508,6 @@ namespace MediaBrowser.Dlna.ContentDirectory return false; } - // Upnp renderers won't understand these if (i is Game || i is Book) { return false; diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs index a5a97567a9..595e0e00d9 100644 --- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs +++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs @@ -148,14 +148,37 @@ namespace MediaBrowser.Dlna.Didl private void AddSubtitleElement(XmlElement container, SubtitleStreamInfo info) { - var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL); + var subtitleProfile = _profile.SubtitleProfiles + .FirstOrDefault(i => string.Equals(info.Format, i.Format, StringComparison.OrdinalIgnoreCase) && i.Method == SubtitleDeliveryMethod.External); + + if (subtitleProfile == null) + { + return; + } + + var subtitleMode = subtitleProfile.DidlMode; - res.InnerText = info.Url; + if (string.Equals(subtitleMode, "CaptionInfoEx", StringComparison.OrdinalIgnoreCase)) + { + var res = container.OwnerDocument.CreateElement("SEC", "CaptionInfoEx"); - // TODO: Remove this hard-coding - res.SetAttribute("protocolInfo", "http-get:*:text/srt:*"); + res.InnerText = info.Url; - container.AppendChild(res); + // TODO: attribute needs SEC: + res.SetAttribute("type", info.Format.ToLower()); + container.AppendChild(res); + } + else + { + var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL); + + res.InnerText = info.Url; + + var protocolInfo = string.Format("http-get:*:text/{0}:*", info.Format.ToLower()); + res.SetAttribute("protocolInfo", protocolInfo); + + container.AppendChild(res); + } } private void AddVideoResource(XmlElement container, Video video, string deviceId, Filter filter, string contentFeatures, StreamInfo streamInfo) @@ -496,7 +519,7 @@ namespace MediaBrowser.Dlna.Didl } else { - throw new NotSupportedException(); + objectClass.InnerText = "object.item"; } return objectClass; @@ -611,7 +634,7 @@ namespace MediaBrowser.Dlna.Didl icon.InnerText = iconUrlInfo.Url; element.AppendChild(icon); - if (!_profile.EnableAlbumArtInDidl && !(item is Photo)) + if (!_profile.EnableAlbumArtInDidl) { return; } @@ -656,8 +679,8 @@ namespace MediaBrowser.Dlna.Didl if (imageInfo.IsDirectStream) { - // TODO: Add file size - //res.SetAttribute("size", imageInfo.Size.Value.ToString(_usCulture)); + var length = imageInfo.ItemImageInfo.Length ?? new FileInfo(imageInfo.File).Length; + res.SetAttribute("size", length.ToString(_usCulture)); } if (width.HasValue && height.HasValue) @@ -735,7 +758,8 @@ namespace MediaBrowser.Dlna.Didl ImageTag = tag, Width = width, Height = height, - File = imageInfo.Path + File = imageInfo.Path, + ItemImageInfo = imageInfo }; } @@ -751,6 +775,8 @@ namespace MediaBrowser.Dlna.Didl internal bool IsDirectStream; internal string File; + + internal ItemImageInfo ItemImageInfo; } class ImageUrlInfo diff --git a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs index 3dc1967dd9..b0eef109d6 100644 --- a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs +++ b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs @@ -344,7 +344,14 @@ namespace MediaBrowser.Dlna.Profiles new SubtitleProfile { Format = "smi", - Method = SubtitleDeliveryMethod.External + Method = SubtitleDeliveryMethod.External, + DidlMode = "CaptionInfoEx" + }, + new SubtitleProfile + { + Format = "srt", + Method = SubtitleDeliveryMethod.External, + DidlMode = "CaptionInfoEx" } }; } diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml index b8edd8ff51..1ce80339cb 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml @@ -107,6 +107,7 @@ - + + \ No newline at end of file diff --git a/MediaBrowser.Model/ApiClient/ApiClientExtensions.cs b/MediaBrowser.Model/ApiClient/ApiClientExtensions.cs index 98e99b1ccb..4b0effa55d 100644 --- a/MediaBrowser.Model/ApiClient/ApiClientExtensions.cs +++ b/MediaBrowser.Model/ApiClient/ApiClientExtensions.cs @@ -1,4 +1,5 @@ using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Querying; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -25,5 +26,10 @@ namespace MediaBrowser.Model.ApiClient { return apiClient.GetPublicUsersAsync(CancellationToken.None); } + + public static Task GetItemsAsync(this IApiClient apiClient, ItemQuery query) + { + return apiClient.GetItemsAsync(query, CancellationToken.None); + } } } diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs index c25e93c388..b89d8b73b6 100644 --- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs +++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs @@ -24,8 +24,9 @@ namespace MediaBrowser.Model.Dlna DlnaFlags flagValue = DlnaFlags.StreamingTransferMode | DlnaFlags.BackgroundTransferMode | + DlnaFlags.InteractiveTransferMode | DlnaFlags.DlnaV15; - + string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", DlnaMaps.FlagsToString(flagValue)); @@ -62,16 +63,17 @@ namespace MediaBrowser.Model.Dlna DlnaFlags flagValue = DlnaFlags.StreamingTransferMode | DlnaFlags.BackgroundTransferMode | + DlnaFlags.InteractiveTransferMode | DlnaFlags.DlnaV15; if (isDirectStream) { - //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_BYTE_BASED_SEEK; - } - else if (runtimeTicks.HasValue) - { - //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK; + flagValue = flagValue | DlnaFlags.ByteBasedSeek; } + //else if (runtimeTicks.HasValue) + //{ + // flagValue = flagValue | DlnaFlags.TimeBasedSeek; + //} string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", DlnaMaps.FlagsToString(flagValue)); @@ -120,16 +122,17 @@ namespace MediaBrowser.Model.Dlna DlnaFlags flagValue = DlnaFlags.StreamingTransferMode | DlnaFlags.BackgroundTransferMode | + DlnaFlags.InteractiveTransferMode | DlnaFlags.DlnaV15; if (isDirectStream) { - //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_BYTE_BASED_SEEK; - } - else if (runtimeTicks.HasValue) - { - //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK; + flagValue = flagValue | DlnaFlags.ByteBasedSeek; } + //else if (runtimeTicks.HasValue) + //{ + // flagValue = flagValue | DlnaFlags.TimeBasedSeek; + //} string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", DlnaMaps.FlagsToString(flagValue)); diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 5366a538c0..ff9e1d6a32 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -99,7 +99,8 @@ namespace MediaBrowser.Model.Dlna ResponseProfiles = new ResponseProfile[] { }; CodecProfiles = new CodecProfile[] { }; ContainerProfiles = new ContainerProfile[] { }; - + SubtitleProfiles = new SubtitleProfile[] { }; + XmlRootAttributes = new XmlAttribute[] { }; SupportedMediaTypes = "Audio,Photo,Video"; diff --git a/MediaBrowser.Model/Dlna/DlnaFlags.cs b/MediaBrowser.Model/Dlna/DlnaFlags.cs index 23859312dc..7c7fe8d8f5 100644 --- a/MediaBrowser.Model/Dlna/DlnaFlags.cs +++ b/MediaBrowser.Model/Dlna/DlnaFlags.cs @@ -5,17 +5,44 @@ namespace MediaBrowser.Model.Dlna [Flags] public enum DlnaFlags : ulong { + /*! Background transfer mode. + For use with upload and download transfers to and from the server. + The primary difference between \ref DH_TransferMode_Interactive and + \ref DH_TransferMode_Bulk is that the latter assumes that the user + is not relying on the transfer for immediately rendering the content + and there are no issues with causing a buffer overflow if the + receiver uses TCP flow control to reduce total throughput. + */ BackgroundTransferMode = (1 << 22), + ByteBasedSeek = (1 << 29), ConnectionStall = (1 << 21), + DlnaV15 = (1 << 20), + + /*! Interactive transfer mode. + For best effort transfer of images and non-real-time transfers. + URIs with image content usually support \ref DH_TransferMode_Bulk too. + The primary difference between \ref DH_TransferMode_Interactive and + \ref DH_TransferMode_Bulk is that the former assumes that the + transfer is intended for immediate rendering. + */ InteractiveTransferMode = (1 << 23), + PlayContainer = (1 << 28), RtspPause = (1 << 25), S0Increase = (1 << 27), SenderPaced = (1L << 31), SnIncrease = (1 << 26), + + /*! Streaming transfer mode. + The server transmits at a throughput sufficient for real-time playback of + audio or video. URIs with audio or video often support the + \ref DH_TransferMode_Interactive and \ref DH_TransferMode_Bulk transfer modes. + The most well-known exception to this general claim is for live streams. + */ StreamingTransferMode = (1 << 24), + TimeBasedSeek = (1 << 30) } } \ No newline at end of file diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 72bf88b70d..ad82cdc137 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -537,16 +537,6 @@ namespace MediaBrowser.Model.Dlna return SubtitleDeliveryMethod.Encode; } - private string NormalizeSubtitleFormat(string codec) - { - if (StringHelper.EqualsIgnoreCase(codec, "subrip")) - { - return SubtitleFormat.SRT; - } - - return codec; - } - private bool ContainsSubtitleFormat(SubtitleProfile[] profiles, SubtitleDeliveryMethod method, string[] formats) { foreach (SubtitleProfile profile in profiles) diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 563a2f19af..eb686864bf 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -172,7 +172,8 @@ namespace MediaBrowser.Model.Dlna Url = url, IsForced = stream.IsForced, Language = stream.Language, - Name = stream.Language ?? "Unknown" + Name = stream.Language ?? "Unknown", + Format = SubtitleFormat }); } } @@ -512,5 +513,6 @@ namespace MediaBrowser.Model.Dlna public string Language { get; set; } public string Name { get; set; } public bool IsForced { get; set; } + public string Format { get; set; } } } diff --git a/MediaBrowser.Model/Dlna/SubtitleProfile.cs b/MediaBrowser.Model/Dlna/SubtitleProfile.cs index 1895158357..d3989829ca 100644 --- a/MediaBrowser.Model/Dlna/SubtitleProfile.cs +++ b/MediaBrowser.Model/Dlna/SubtitleProfile.cs @@ -7,10 +7,11 @@ namespace MediaBrowser.Model.Dlna [XmlAttribute("format")] public string Format { get; set; } - [XmlAttribute("protocol")] - public string Protocol { get; set; } - [XmlAttribute("method")] public SubtitleDeliveryMethod Method { get; set; } + + [XmlAttribute("didlMode")] + public string DidlMode { get; set; } + } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 1c207b0a2c..b3ddcee79d 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -135,7 +135,7 @@ "HeaderSelectTranscodingPath": "Select Transcoding Temporary Path", "HeaderSelectImagesByNamePath": "Select Images By Name Path", "HeaderSelectMetadataPath": "Select Metadata Path", - "HeaderSelectServerCachePathHelp": "Browse or enter the path to use for server cache files. The folder must be writeable. The location of this folder will directly impact server performance and should ideally be placed on a solid state drive.", + "HeaderSelectServerCachePathHelp": "Browse or enter the path to use for server cache files. The folder must be writeable.", "HeaderSelectTranscodingPathHelp": "Browse or enter the path to use for transcoding temporary files. The folder must be writeable.", "HeaderSelectImagesByNamePathHelp": "Browse or enter the path to your items by name folder. The folder must be writeable.", "HeaderSelectMetadataPathHelp": "Browse or enter the path you'd like to store metadata within. The folder must be writeable.", diff --git a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs index 6ab306c0ba..d461773522 100644 --- a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs +++ b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs @@ -147,11 +147,11 @@ namespace MediaBrowser.Server.Implementations.Playlists return path; } - private IEnumerable GetPlaylistItems(IEnumerable itemIds, string playlistMediaType, User user) + private IEnumerable GetPlaylistItems(IEnumerable itemIds, string playlistMediaType) { var items = itemIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null); - return Playlist.GetPlaylistItems(playlistMediaType, items, user); + return Playlist.GetPlaylistItems(playlistMediaType, items, null); } public async Task AddToPlaylist(string playlistId, IEnumerable itemIds) @@ -166,17 +166,11 @@ namespace MediaBrowser.Server.Implementations.Playlists var list = new List(); var itemList = new List(); - foreach (var itemId in itemIds) - { - var item = _libraryManager.GetItemById(itemId); - - if (item == null) - { - throw new ArgumentException("No item exists with the supplied Id"); - } + var items = GetPlaylistItems(itemIds, playlist.MediaType).ToList(); + foreach (var item in items) + { itemList.Add(item); - list.Add(LinkedChild.Create(item)); } diff --git a/MediaBrowser.Server.Implementations/Security/EncryptionManager.cs b/MediaBrowser.Server.Implementations/Security/EncryptionManager.cs index 33818dcea9..cd9b9651ec 100644 --- a/MediaBrowser.Server.Implementations/Security/EncryptionManager.cs +++ b/MediaBrowser.Server.Implementations/Security/EncryptionManager.cs @@ -1,6 +1,5 @@ using MediaBrowser.Controller.Security; using System; -using System.Security.Cryptography; using System.Text; namespace MediaBrowser.Server.Implementations.Security @@ -17,11 +16,7 @@ namespace MediaBrowser.Server.Implementations.Security { if (value == null) throw new ArgumentNullException("value"); -#if __MonoCS__ return EncryptStringUniversal(value); -#endif - - return Encoding.Default.GetString(ProtectedData.Protect(Encoding.Default.GetBytes(value), null, DataProtectionScope.LocalMachine)); } /// @@ -34,11 +29,7 @@ namespace MediaBrowser.Server.Implementations.Security { if (value == null) throw new ArgumentNullException("value"); -#if __MonoCS__ return DecryptStringUniversal(value); -#endif - - return Encoding.Default.GetString(ProtectedData.Unprotect(Encoding.Default.GetBytes(value), null, DataProtectionScope.LocalMachine)); } private string EncryptStringUniversal(string value) diff --git a/MediaBrowser.Server.Mono/Native/NativeApp.cs b/MediaBrowser.Server.Mono/Native/NativeApp.cs index 1cf2179101..23b91f1497 100644 --- a/MediaBrowser.Server.Mono/Native/NativeApp.cs +++ b/MediaBrowser.Server.Mono/Native/NativeApp.cs @@ -1,4 +1,11 @@ using MediaBrowser.Server.Mono; +using System; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.Updates; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Updates; namespace MediaBrowser.ServerApplication.Native { @@ -56,5 +63,16 @@ namespace MediaBrowser.ServerApplication.Native { } + + public async Task CheckForApplicationUpdate(Version currentVersion, + PackageVersionClass updateLevel, + IInstallationManager installationManager, + CancellationToken cancellationToken, + IProgress progress) + { + var result = new CheckForUpdateResult { AvailableVersion = currentVersion.ToString(), IsUpdateAvailable = false }; + + return Task.FromResult(result); + } } } diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index a4ac7e0ba1..d44ac250de 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -1183,24 +1183,18 @@ namespace MediaBrowser.ServerApplication /// Task{CheckForUpdateResult}. public override async Task CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress progress) { - var availablePackages = await InstallationManager.GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); + var result = await NativeApp.CheckForApplicationUpdate(ApplicationVersion, + ConfigurationManager.CommonConfiguration.SystemUpdateLevel, InstallationManager, + cancellationToken, progress).ConfigureAwait(false); - var version = InstallationManager.GetLatestCompatibleVersion(availablePackages, "MBServer", null, ApplicationVersion, - ConfigurationManager.CommonConfiguration.SystemUpdateLevel); + HasUpdateAvailable = result.IsUpdateAvailable; - var versionObject = version == null || string.IsNullOrWhiteSpace(version.versionStr) ? null : new Version(version.versionStr); - - var isUpdateAvailable = versionObject != null && versionObject > ApplicationVersion; - HasUpdateAvailable = isUpdateAvailable; - - if (isUpdateAvailable) + if (result.IsUpdateAvailable) { - Logger.Info("New application version is available: {0}", versionObject); + Logger.Info("New application version is available: {0}", result.AvailableVersion); } - return versionObject != null ? - new CheckForUpdateResult { AvailableVersion = versionObject.ToString(), IsUpdateAvailable = isUpdateAvailable, Package = version } : - new CheckForUpdateResult { AvailableVersion = ApplicationVersion.ToString(), IsUpdateAvailable = false }; + return result; } /// diff --git a/MediaBrowser.ServerApplication/Native/NativeApp.cs b/MediaBrowser.ServerApplication/Native/NativeApp.cs index 2388b610b7..0e7dc50a9f 100644 --- a/MediaBrowser.ServerApplication/Native/NativeApp.cs +++ b/MediaBrowser.ServerApplication/Native/NativeApp.cs @@ -1,4 +1,10 @@ -using System.Runtime.InteropServices; +using System; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.Updates; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Updates; namespace MediaBrowser.ServerApplication.Native { @@ -84,5 +90,24 @@ namespace MediaBrowser.ServerApplication.Native EXECUTION_STATE es = SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED); } } + + public static async Task CheckForApplicationUpdate(Version currentVersion, + PackageVersionClass updateLevel, + IInstallationManager installationManager, + CancellationToken cancellationToken, + IProgress progress) + { + var availablePackages = await installationManager.GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); + + var version = installationManager.GetLatestCompatibleVersion(availablePackages, "MBServer", null, currentVersion, updateLevel); + + var versionObject = version == null || string.IsNullOrWhiteSpace(version.versionStr) ? null : new Version(version.versionStr); + + var isUpdateAvailable = versionObject != null && versionObject > currentVersion; + + return versionObject != null ? + new CheckForUpdateResult { AvailableVersion = versionObject.ToString(), IsUpdateAvailable = isUpdateAvailable, Package = version } : + new CheckForUpdateResult { AvailableVersion = currentVersion.ToString(), IsUpdateAvailable = false }; + } } } diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index c058193612..7bc124eb59 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -221,6 +221,16 @@ namespace MediaBrowser.WebDashboard.Api var contentType = MimeTypes.GetMimeType(path); var isHtml = IsHtml(path); + + if (isHtml && !_serverConfigurationManager.Configuration.IsStartupWizardCompleted) + { + if (path.IndexOf("wizard", StringComparison.OrdinalIgnoreCase) == -1) + { + Request.Response.Redirect("wizardstart.html"); + return null; + } + } + var localizationCulture = GetLocalizationCulture(); // Don't cache if not configured to do so diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 78218d9ce7..a3343b7e63 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.423 + 3.0.424 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 2a0fbc9af9..398f74d6a1 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.423 + 3.0.424 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index 2724c2088f..016fbc4251 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.423 + 3.0.424 MediaBrowser.Model - Signed Edition Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 0f48a19769..703103ed38 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.423 + 3.0.424 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - + diff --git a/README.md b/README.md index 601f9395eb..84b097997f 100644 --- a/README.md +++ b/README.md @@ -9,14 +9,15 @@ We have several client apps released and in production: - [Android](https://play.google.com/store/apps/details?id=com.mb.android "Android") - Html5 -- [iOS](https://itunes.apple.com/us/app/media-browser-for-ios/id705058087 "iOS") +- [iPad](https://itunes.apple.com/us/app/media-browser-client/id879475585 "iPad") +- [iPhone](https://itunes.apple.com/us/app/media-browser-for-ios/id705058087?mt=8 "iPhone") - [Media Portal](http://www.team-mediaportal.com/ "Media Portal") - [Roku](http://www.roku.com/channels/#!details/34503/media-browser "Roku") - Windows 7/8 Desktop - Windows Media Center - [Windows Phone](http://www.windowsphone.com/s?appid=f4971ed9-f651-4bf6-84bb-94fd98613b86 "Windows Phone") - [Windows 8](http://apps.microsoft.com/windows/en-us/app/media-browser/ad55a2f0-9897-47bd-8944-bed3aefd5d06 "Windows 8.1") -- [Xbmc](http://addons.xbmc.org/show/plugin.video.xbmb3c "Xbmc") +- [Xbmc](http://mediabrowser.tv/download/ "Xbmc") ## New Users ##