diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs index c83028bb2d..29848cfc04 100644 --- a/MediaBrowser.Api/ConfigurationService.cs +++ b/MediaBrowser.Api/ConfigurationService.cs @@ -122,42 +122,44 @@ namespace MediaBrowser.Api return ToOptimizedResult(result); } + const string XbmcMetadata = "Xbmc Nfo"; + const string MediaBrowserMetadata = "Media Browser Xml"; + public void Post(AutoSetMetadataOptions request) { var service = AutoDetectMetadataService(); Logger.Info("Setting preferred metadata format to " + service); - _configurationManager.SetPreferredMetadataService(service); + var serviceToDisable = string.Equals(service, XbmcMetadata) ? + MediaBrowserMetadata : + XbmcMetadata; + + _configurationManager.DisableMetadataService(serviceToDisable); _configurationManager.SaveConfiguration(); } private string AutoDetectMetadataService() { - const string xbmc = "Xbmc Nfo"; - const string mb = "Media Browser Xml"; - var paths = _libraryManager.GetDefaultVirtualFolders() .SelectMany(i => i.Locations) .Distinct(StringComparer.OrdinalIgnoreCase) .Select(i => new DirectoryInfo(i)) .ToList(); - if (paths.Select(i => i.EnumerateFiles("*.xml", SearchOption.AllDirectories)) - .SelectMany(i => i) + if (paths.SelectMany(i => i.EnumerateFiles("*.xml", SearchOption.AllDirectories)) .Any()) { - return xbmc; + return XbmcMetadata; } - if (paths.Select(i => i.EnumerateFiles("*.xml", SearchOption.AllDirectories)) - .SelectMany(i => i) + if (paths.SelectMany(i => i.EnumerateFiles("*.xml", SearchOption.AllDirectories)) .Any(i => string.Equals(i.Name, "series.xml", StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, "movie.xml", StringComparison.OrdinalIgnoreCase))) { - return mb; + return MediaBrowserMetadata; } - return xbmc; + return XbmcMetadata; } /// diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index db6c6ce53e..1fa1a5509d 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -65,6 +65,11 @@ namespace MediaBrowser.Api } } + private DateTime NormalizeDateTime(DateTime val) + { + return DateTime.SpecifyKind(val, DateTimeKind.Utc); + } + private void UpdateItem(BaseItemDto request, BaseItem item) { item.Name = request.Name; @@ -140,11 +145,11 @@ namespace MediaBrowser.Api if (request.DateCreated.HasValue) { - item.DateCreated = request.DateCreated.Value.ToUniversalTime(); + item.DateCreated = NormalizeDateTime(request.DateCreated.Value); } - item.EndDate = request.EndDate.HasValue ? request.EndDate.Value.ToUniversalTime() : (DateTime?)null; - item.PremiereDate = request.PremiereDate.HasValue ? request.PremiereDate.Value.ToUniversalTime() : (DateTime?)null; + item.EndDate = request.EndDate.HasValue ? NormalizeDateTime(request.EndDate.Value) : (DateTime?)null; + item.PremiereDate = request.PremiereDate.HasValue ? NormalizeDateTime(request.PremiereDate.Value) : (DateTime?)null; item.ProductionYear = request.ProductionYear; item.OfficialRating = request.OfficialRating; item.CustomRating = request.CustomRating; diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index 178199b220..df4bc06bab 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Library; @@ -11,6 +12,7 @@ using ServiceStack.Text.Controller; using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Threading.Tasks; namespace MediaBrowser.Api @@ -168,6 +170,7 @@ namespace MediaBrowser.Api private readonly IDtoService _dtoService; private readonly ISessionManager _sessionMananger; private readonly IServerConfigurationManager _config; + private readonly INetworkManager _networkManager; public IAuthorizationContext AuthorizationContext { get; set; } @@ -178,12 +181,13 @@ namespace MediaBrowser.Api /// The dto service. /// The session mananger. /// xmlSerializer - public UserService(IUserManager userManager, IDtoService dtoService, ISessionManager sessionMananger, IServerConfigurationManager config) + public UserService(IUserManager userManager, IDtoService dtoService, ISessionManager sessionMananger, IServerConfigurationManager config, INetworkManager networkManager) { _userManager = userManager; _dtoService = dtoService; _sessionMananger = sessionMananger; _config = config; + _networkManager = networkManager; } public object Get(GetPublicUsers request) @@ -200,18 +204,65 @@ namespace MediaBrowser.Api }); } - // TODO: Add or is authenticated - if (_sessionMananger.IsInLocalNetwork(Request.RemoteIp)) + // TODO: Uncomment this once all clients can handle an empty user list. + return Get(new GetUsers { - return Get(new GetUsers - { - IsHidden = false, - IsDisabled = false - }); + IsHidden = false, + IsDisabled = false + }); + + //// TODO: Add or is authenticated + //if (Request.IsLocal || IsInLocalNetwork(Request.RemoteIp)) + //{ + // return Get(new GetUsers + // { + // IsHidden = false, + // IsDisabled = false + // }); + //} + + //// Return empty when external + //return ToOptimizedResult(new List()); + } + + private bool IsInLocalNetwork(string remoteEndpoint) + { + if (string.IsNullOrWhiteSpace(remoteEndpoint)) + { + throw new ArgumentNullException("remoteEndpoint"); } - // Return empty when external - return ToOptimizedResult(new List()); + IPAddress address; + if (!IPAddress.TryParse(remoteEndpoint, out address)) + { + return true; + } + + const int lengthMatch = 4; + + if (remoteEndpoint.Length >= lengthMatch) + { + var prefix = remoteEndpoint.Substring(0, lengthMatch); + + if (_networkManager.GetLocalIpAddresses() + .Any(i => i.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))) + { + return true; + } + } + + // Private address space: + // http://en.wikipedia.org/wiki/Private_network + + return + + // If url was requested with computer name, we may see this + remoteEndpoint.IndexOf("::", StringComparison.OrdinalIgnoreCase) != -1 || + + remoteEndpoint.StartsWith("10.", StringComparison.OrdinalIgnoreCase) || + remoteEndpoint.StartsWith("192.", StringComparison.OrdinalIgnoreCase) || + remoteEndpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase) || + remoteEndpoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase); } /// @@ -307,7 +358,7 @@ namespace MediaBrowser.Api var auth = AuthorizationContext.GetAuthorizationInfo(Request); var result = _sessionMananger.AuthenticateNewSession(request.Username, request.Password, auth.Client, auth.Version, - auth.DeviceId, auth.Device, Request.RemoteIp).Result; + auth.DeviceId, auth.Device, Request.RemoteIp, Request.IsLocal).Result; return ToOptimizedResult(result); } diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs index 751ff55a57..e4c88e6568 100644 --- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs +++ b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs @@ -177,17 +177,27 @@ namespace MediaBrowser.Common.Implementations.Updates { if (_lastPackageListResult != null) { - // Let dev users get results more often for testing purposes - var cacheLength = _config.CommonConfiguration.SystemUpdateLevel == PackageVersionClass.Dev - ? TimeSpan.FromMinutes(3) - : TimeSpan.FromHours(6); + TimeSpan cacheLength; + + switch (_config.CommonConfiguration.SystemUpdateLevel) + { + case PackageVersionClass.Beta: + cacheLength = TimeSpan.FromMinutes(30); + break; + case PackageVersionClass.Dev: + cacheLength = TimeSpan.FromMinutes(3); + break; + default: + cacheLength = TimeSpan.FromHours(6); + break; + } if ((DateTime.UtcNow - _lastPackageListResult.Item2) < cacheLength) { return _lastPackageListResult.Item1; } } - + using (var json = await _httpClient.Get(Constants.Constants.MbAdminUrl + "service/MB3Packages.json", cancellationToken).ConfigureAwait(false)) { cancellationToken.ThrowIfCancellationRequested(); @@ -274,7 +284,7 @@ namespace MediaBrowser.Common.Implementations.Updates { var packages = await GetAvailablePackages(CancellationToken.None).ConfigureAwait(false); - var package = packages.FirstOrDefault(p => string.Equals(p.guid, guid ?? "none", StringComparison.OrdinalIgnoreCase)) + var package = packages.FirstOrDefault(p => string.Equals(p.guid, guid ?? "none", StringComparison.OrdinalIgnoreCase)) ?? packages.FirstOrDefault(p => p.name.Equals(name, StringComparison.OrdinalIgnoreCase)); if (package == null) @@ -310,7 +320,7 @@ namespace MediaBrowser.Common.Implementations.Updates /// PackageVersionInfo. public PackageVersionInfo GetLatestCompatibleVersion(IEnumerable availablePackages, string name, string guid, Version currentServerVersion, PackageVersionClass classification = PackageVersionClass.Release) { - var package = availablePackages.FirstOrDefault(p => string.Equals(p.guid, guid ?? "none", StringComparison.OrdinalIgnoreCase)) + var package = availablePackages.FirstOrDefault(p => string.Equals(p.guid, guid ?? "none", StringComparison.OrdinalIgnoreCase)) ?? availablePackages.FirstOrDefault(p => p.name.Equals(name, StringComparison.OrdinalIgnoreCase)); if (package == null) diff --git a/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs b/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs index c3d1796f99..aac8cda2eb 100644 --- a/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs +++ b/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs @@ -31,6 +31,6 @@ namespace MediaBrowser.Controller.Configuration /// Sets the preferred metadata service. /// /// The service. - void SetPreferredMetadataService(string service); + void DisableMetadataService(string service); } } diff --git a/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs b/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs index 42178c44c1..ff94ceff36 100644 --- a/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs +++ b/MediaBrowser.Controller/Resolvers/EntityResolutionHelper.cs @@ -14,6 +14,21 @@ namespace MediaBrowser.Controller.Resolvers /// public static class EntityResolutionHelper { + /// + /// Any folder named in this list will be ignored - can be added to at runtime for extensibility + /// + public static readonly List IgnoreFolders = new List + { + "metadata", + "ps3_update", + "ps3_vprm", + "extrafanart", + "extrathumbs", + ".actors", + ".wd_tv" + + }; + /// /// Any extension in this list is considered a video file - can be added to at runtime for extensibility /// diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index c8ae0e6a75..e37a139233 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -218,6 +218,7 @@ namespace MediaBrowser.Controller.Session /// The device identifier. /// Name of the device. /// The remote end point. + /// if set to true [is local]. /// Task{SessionInfo}. Task AuthenticateNewSession(string username, string password, @@ -225,7 +226,8 @@ namespace MediaBrowser.Controller.Session string appVersion, string deviceId, string deviceName, - string remoteEndPoint); + string remoteEndPoint, + bool isLocal); /// /// Reports the capabilities. @@ -282,12 +284,5 @@ namespace MediaBrowser.Controller.Session /// The identifier. /// Task. Task RevokeToken(string id); - - /// - /// Determines whether the specified remote endpoint is local. - /// - /// The remote endpoint. - /// true if the specified remote endpoint is local; otherwise, false. - bool IsInLocalNetwork(string remoteEndpoint); } } \ No newline at end of file diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index bb919edb82..baa9f933d3 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -57,14 +57,30 @@ + + + ..\packages\Microsoft.Bcl.Async.1.0.168\lib\portable-net40+sl4+win8+wp71+wpa81\Microsoft.Threading.Tasks.dll + + + ..\packages\Microsoft.Bcl.Async.1.0.168\lib\portable-net40+sl4+win8+wp71+wpa81\Microsoft.Threading.Tasks.Extensions.dll + ..\packages\PropertyChanged.Fody.1.41.0.0\Lib\portable-net4+sl4+wp7+win8+MonoAndroid16+MonoTouch40\PropertyChanged.dll False + + ..\packages\Microsoft.Bcl.1.1.8\lib\portable-net40+sl5+win8+wp8+wpa81\System.IO.dll + + + ..\packages\Microsoft.Bcl.1.1.8\lib\portable-net40+sl5+win8+wp8+wpa81\System.Runtime.dll + + + ..\packages\Microsoft.Bcl.1.1.8\lib\portable-net40+sl5+win8+wp8+wpa81\System.Threading.Tasks.dll + @@ -914,6 +930,11 @@ xcopy "$(TargetPath)" "$(SolutionDir)\Nuget\dlls\portable\" /y /d /r /i + + + + +