Просмотр исходного кода

Merge pull request #1681 from MediaBrowser/dev

Dev
Luke 9 лет назад
Родитель
Сommit
e02b3f479e
46 измененных файлов с 273 добавлено и 188 удалено
  1. 2 1
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  2. 6 4
      MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
  3. 3 3
      MediaBrowser.Common.Implementations/packages.config
  4. 21 3
      MediaBrowser.Controller/Entities/TV/Series.cs
  5. 3 1
      MediaBrowser.Controller/IServerApplicationHost.cs
  6. 1 1
      MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs
  7. 19 22
      MediaBrowser.Providers/Manager/ProviderManager.cs
  8. 1 1
      MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs
  9. 1 1
      MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
  10. 1 1
      MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
  11. 3 3
      MediaBrowser.Providers/Movies/MovieDbProvider.cs
  12. 1 1
      MediaBrowser.Providers/Movies/MovieDbSearch.cs
  13. 5 5
      MediaBrowser.Providers/Movies/MovieExternalIds.cs
  14. 1 1
      MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs
  15. 1 1
      MediaBrowser.Providers/Music/FanArtArtistProvider.cs
  16. 1 1
      MediaBrowser.Providers/Music/FanArtUpdatesPostScanTask.cs
  17. 9 9
      MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs
  18. 4 4
      MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs
  19. 6 6
      MediaBrowser.Providers/Music/MusicExternalIds.cs
  20. 1 1
      MediaBrowser.Providers/Omdb/OmdbImageProvider.cs
  21. 4 9
      MediaBrowser.Providers/Omdb/OmdbItemProvider.cs
  22. 1 1
      MediaBrowser.Providers/Omdb/OmdbProvider.cs
  23. 3 3
      MediaBrowser.Providers/People/MovieDbPersonProvider.cs
  24. 1 1
      MediaBrowser.Providers/TV/FanArt/FanArtTvUpdatesPostScanTask.cs
  25. 1 1
      MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs
  26. 1 1
      MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs
  27. 1 1
      MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs
  28. 2 2
      MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs
  29. 2 2
      MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs
  30. 4 4
      MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs
  31. 1 1
      MediaBrowser.Providers/TV/TvExternalIds.cs
  32. 7 3
      MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
  33. 2 1
      MediaBrowser.Server.Implementations/packages.config
  34. 10 0
      MediaBrowser.Server.Mono/Native/BaseMonoApp.cs
  35. 6 1
      MediaBrowser.Server.Startup.Common/ApplicationHost.cs
  36. 15 44
      MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs
  37. 15 16
      MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs
  38. 1 1
      MediaBrowser.Server.Startup.Common/EntryPoints/StartupWizard.cs
  39. 4 0
      MediaBrowser.Server.Startup.Common/INativeApp.cs
  40. 6 1
      MediaBrowser.ServerApplication/MainStartup.cs
  41. 26 14
      MediaBrowser.ServerApplication/Native/Standby.cs
  42. 47 2
      MediaBrowser.ServerApplication/Native/WindowsApp.cs
  43. 10 5
      MediaBrowser.ServerApplication/ServerNotifyIcon.cs
  44. 9 0
      MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
  45. 2 2
      Nuget/MediaBrowser.Common.Internal.nuspec
  46. 2 2
      OpenSubtitlesHandler/Utilities.cs

+ 2 - 1
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -2222,9 +2222,10 @@ namespace MediaBrowser.Api.Playback
 
             if (state.VideoRequest != null)
             {
+                // Important: If this is ever re-enabled, make sure not to use it with wtv because it breaks seeking
                 if (string.Equals(state.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase) && state.VideoRequest.CopyTimestamps)
                 {
-                    inputModifier += " -noaccurate_seek";
+                    //inputModifier += " -noaccurate_seek";
                 }
             }
 

+ 6 - 4
MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj

@@ -54,8 +54,9 @@
     <Reference Include="MoreLinq">
       <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
     </Reference>
-    <Reference Include="NLog">
-      <HintPath>..\packages\NLog.4.2.3\lib\net45\NLog.dll</HintPath>
+    <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+      <HintPath>..\packages\NLog.4.3.1\lib\net45\NLog.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="Patterns.Logging">
       <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
@@ -64,8 +65,9 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\ThirdParty\SharpCompress\SharpCompress.dll</HintPath>
     </Reference>
-    <Reference Include="SimpleInjector">
-      <HintPath>..\packages\SimpleInjector.3.1.2\lib\net45\SimpleInjector.dll</HintPath>
+    <Reference Include="SimpleInjector, Version=3.1.3.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
+      <HintPath>..\packages\SimpleInjector.3.1.3\lib\net45\SimpleInjector.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Configuration" />

+ 3 - 3
MediaBrowser.Common.Implementations/packages.config

@@ -2,7 +2,7 @@
 <packages>
   <package id="CommonIO" version="1.0.0.9" targetFramework="net45" />
   <package id="morelinq" version="1.4.0" targetFramework="net45" />
-  <package id="NLog" version="4.2.3" targetFramework="net45" />
+  <package id="NLog" version="4.3.1" targetFramework="net45" />
   <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
-  <package id="SimpleInjector" version="3.1.2" targetFramework="net45" />
-</packages>
+  <package id="SimpleInjector" version="3.1.3" targetFramework="net45" />
+</packages>

+ 21 - 3
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -255,7 +255,7 @@ namespace MediaBrowser.Controller.Entities.TV
             // Refresh current item
             await RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
 
-            // Refresh TV
+            // Refresh seasons
             foreach (var item in seasons)
             {
                 cancellationToken.ThrowIfCancellationRequested();
@@ -268,12 +268,30 @@ namespace MediaBrowser.Controller.Entities.TV
                 progress.Report(percent * 100);
             }
 
-            // Refresh all non-songs
+            // Refresh episodes and other children
             foreach (var item in otherItems)
             {
                 cancellationToken.ThrowIfCancellationRequested();
 
-                await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+                var skipItem = false;
+
+                var episode = item as Episode;
+
+                if (episode != null
+                    && refreshOptions.MetadataRefreshMode != MetadataRefreshMode.FullRefresh
+                    && !refreshOptions.ReplaceAllMetadata
+                    && episode.IsMissingEpisode 
+                    && episode.LocationType == Model.Entities.LocationType.Virtual 
+                    && episode.PremiereDate.HasValue 
+                    && (DateTime.UtcNow - episode.PremiereDate.Value).TotalDays > 30)
+                {
+                    skipItem = true;
+                }
+
+                if (!skipItem)
+                {
+                    await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+                }
 
                 numComplete++;
                 double percent = numComplete;

+ 3 - 1
MediaBrowser.Controller/IServerApplicationHost.cs

@@ -12,7 +12,7 @@ namespace MediaBrowser.Controller
     public interface IServerApplicationHost : IApplicationHost
     {
         event EventHandler HasUpdateAvailableChanged;
-        
+
         /// <summary>
         /// Gets the system info.
         /// </summary>
@@ -86,5 +86,7 @@ namespace MediaBrowser.Controller
         /// <param name="ipAddress">The ip address.</param>
         /// <returns>System.String.</returns>
         string GetLocalApiUrl(IPAddress ipAddress);
+
+        void LaunchUrl(string url);
     }
 }

+ 1 - 1
MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs

@@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.BoxSets
 {
     public class MovieDbBoxSetProvider : IRemoteMetadataProvider<BoxSet, BoxSetInfo>
     {
-        private const string GetCollectionInfo3 = @"http://api.themoviedb.org/3/collection/{0}?api_key={1}&append_to_response=images";
+        private const string GetCollectionInfo3 = @"https://api.themoviedb.org/3/collection/{0}?api_key={1}&append_to_response=images";
 
         internal static MovieDbBoxSetProvider Current;
 

+ 19 - 22
MediaBrowser.Providers/Manager/ProviderManager.cs

@@ -20,6 +20,7 @@ using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
+using MediaBrowser.Model.Serialization;
 
 namespace MediaBrowser.Providers.Manager
 {
@@ -60,6 +61,7 @@ namespace MediaBrowser.Providers.Manager
         private IEnumerable<IMetadataSaver> _savers;
         private IImageSaver[] _imageSavers;
         private readonly IServerApplicationPaths _appPaths;
+        private readonly IJsonSerializer _json;
 
         private IExternalId[] _externalIds;
 
@@ -73,7 +75,7 @@ namespace MediaBrowser.Providers.Manager
         /// <param name="libraryMonitor">The directory watchers.</param>
         /// <param name="logManager">The log manager.</param>
         /// <param name="fileSystem">The file system.</param>
-        public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func<ILibraryManager> libraryManagerFactory)
+        public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func<ILibraryManager> libraryManagerFactory, IJsonSerializer json)
         {
             _logger = logManager.GetLogger("ProviderManager");
             _httpClient = httpClient;
@@ -82,6 +84,7 @@ namespace MediaBrowser.Providers.Manager
             _fileSystem = fileSystem;
             _appPaths = appPaths;
             _libraryManagerFactory = libraryManagerFactory;
+            _json = json;
         }
 
         /// <summary>
@@ -730,8 +733,6 @@ namespace MediaBrowser.Providers.Manager
             where TItemType : BaseItem, new()
             where TLookupType : ItemLookupInfo
         {
-            const int maxResults = 10;
-
             // Give it a dummy path just so that it looks like a file system item
             var dummy = new TItemType
             {
@@ -761,7 +762,6 @@ namespace MediaBrowser.Providers.Manager
             }
 
             var resultList = new List<RemoteSearchResult>();
-            var foundProviderIds = new Dictionary<Tuple<string, string>, RemoteSearchResult>();
 
             foreach (var provider in providers)
             {
@@ -771,31 +771,26 @@ namespace MediaBrowser.Providers.Manager
 
                     foreach (var result in results)
                     {
-                        var bFound = false;
+                        var existingMatch = resultList.FirstOrDefault(i => i.ProviderIds.Any(p => string.Equals(result.GetProviderId(p.Key), p.Value, StringComparison.OrdinalIgnoreCase)));
 
-                        // This check prevents duplicate search results by comparing provider ids
-                        foreach (var providerId in result.ProviderIds)
+                        if (existingMatch == null)
                         {
-                            var idTuple = new Tuple<string, string>(providerId.Key.ToLower(), providerId.Value.ToLower());
-
-                            if (!foundProviderIds.ContainsKey(idTuple))
-                            {
-                                foundProviderIds.Add(idTuple, result);
-                            }
-                            else
+                            resultList.Add(result);
+                        }
+                        else
+                        {
+                            foreach (var providerId in result.ProviderIds)
                             {
-                                bFound = true;
-                                var existingResult = foundProviderIds[idTuple];
-                                if (string.IsNullOrEmpty(existingResult.ImageUrl) && !string.IsNullOrEmpty(result.ImageUrl))
+                                if (!existingMatch.ProviderIds.ContainsKey(providerId.Key))
                                 {
-                                    existingResult.ImageUrl = result.ImageUrl;
+                                    existingMatch.ProviderIds.Add(providerId.Key, providerId.Value);
                                 }
                             }
-                        }
 
-                        if (!bFound && resultList.Count < maxResults)
-                        {
-                            resultList.Add(result);
+                            if (string.IsNullOrWhiteSpace(existingMatch.ImageUrl))
+                            {
+                                existingMatch.ImageUrl = result.ImageUrl;
+                            }
                         }
                     }
                 }
@@ -805,6 +800,8 @@ namespace MediaBrowser.Providers.Manager
                 }
             }
 
+            //_logger.Debug("Returning search results {0}", _json.SerializeToString(resultList));
+
             return resultList;
         }
 

+ 1 - 1
MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs

@@ -20,7 +20,7 @@ namespace MediaBrowser.Providers.Movies
 {
     class FanartMovieUpdatesPostScanTask : ILibraryPostScanTask
     {
-        private const string UpdatesUrl = "http://webservice.fanart.tv/v3/movies/latest?api_key={0}&date={1}";
+        private const string UpdatesUrl = "https://webservice.fanart.tv/v3/movies/latest?api_key={0}&date={1}";
 
         /// <summary>
         /// The _HTTP client

+ 1 - 1
MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs

@@ -31,7 +31,7 @@ namespace MediaBrowser.Providers.Movies
         private readonly IFileSystem _fileSystem;
         private readonly IJsonSerializer _json;
 
-        private const string FanArtBaseUrl = "http://webservice.fanart.tv/v3/movies/{1}?api_key={0}";
+        private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3/movies/{1}?api_key={0}";
         // &client_key=52c813aa7b8c8b3bb87f4797532a2f8c
 
         internal static FanartMovieImageProvider Current;

+ 1 - 1
MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs

@@ -329,7 +329,7 @@ namespace MediaBrowser.Providers.Movies
                 {
                     hasTrailers.RemoteTrailers = movieData.trailers.youtube.Select(i => new MediaUrl
                     {
-                        Url = string.Format("http://www.youtube.com/watch?v={0}", i.source),
+                        Url = string.Format("https://www.youtube.com/watch?v={0}", i.source),
                         Name = i.name,
                         VideoSize = string.Equals("hd", i.size, StringComparison.OrdinalIgnoreCase) ? VideoSize.HighDefinition : VideoSize.StandardDefinition
 

+ 3 - 3
MediaBrowser.Providers/Movies/MovieDbProvider.cs

@@ -172,8 +172,8 @@ namespace MediaBrowser.Providers.Movies
             }
         }
 
-        private const string TmdbConfigUrl = "http://api.themoviedb.org/3/configuration?api_key={0}";
-        private const string GetMovieInfo3 = @"http://api.themoviedb.org/3/movie/{0}?api_key={1}&append_to_response=casts,releases,images,keywords,trailers";
+        private const string TmdbConfigUrl = "https://api.themoviedb.org/3/configuration?api_key={0}";
+        private const string GetMovieInfo3 = @"https://api.themoviedb.org/3/movie/{0}?api_key={1}&append_to_response=casts,releases,images,keywords,trailers";
 
         internal static string ApiKey = "f6bd687ffa63cd282b6ff2c6877f2669";
         internal static string AcceptHeader = "application/json,image/*";
@@ -281,7 +281,7 @@ namespace MediaBrowser.Providers.Movies
         public static string NormalizeLanguage(string language)
         {
             // They require this to be uppercase
-            // http://emby.media/community/index.php?/topic/32454-fr-follow-tmdbs-new-language-api-update/?p=311148
+            // https://emby.media/community/index.php?/topic/32454-fr-follow-tmdbs-new-language-api-update/?p=311148
             var parts = language.Split('-');
 
             if (parts.Length == 2)

+ 1 - 1
MediaBrowser.Providers/Movies/MovieDbSearch.cs

@@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.Movies
     public class MovieDbSearch
     {
         private static readonly CultureInfo EnUs = new CultureInfo("en-US");
-        private const string Search3 = @"http://api.themoviedb.org/3/search/{3}?api_key={1}&query={0}&language={2}";
+        private const string Search3 = @"https://api.themoviedb.org/3/search/{3}?api_key={1}&query={0}&language={2}";
 
         internal static string ApiKey = "f6bd687ffa63cd282b6ff2c6877f2669";
         internal static string AcceptHeader = "application/json,image/*";

+ 5 - 5
MediaBrowser.Providers/Movies/MovieExternalIds.cs

@@ -21,7 +21,7 @@ namespace MediaBrowser.Providers.Movies
 
         public string UrlFormatString
         {
-            get { return "http://www.themoviedb.org/movie/{0}"; }
+            get { return "https://www.themoviedb.org/movie/{0}"; }
         }
 
         public bool Supports(IHasProviderIds item)
@@ -51,7 +51,7 @@ namespace MediaBrowser.Providers.Movies
 
         public string UrlFormatString
         {
-            get { return "http://www.themoviedb.org/tv/{0}"; }
+            get { return "https://www.themoviedb.org/tv/{0}"; }
         }
 
         public bool Supports(IHasProviderIds item)
@@ -74,7 +74,7 @@ namespace MediaBrowser.Providers.Movies
 
         public string UrlFormatString
         {
-            get { return "http://www.themoviedb.org/collection/{0}"; }
+            get { return "https://www.themoviedb.org/collection/{0}"; }
         }
 
         public bool Supports(IHasProviderIds item)
@@ -97,7 +97,7 @@ namespace MediaBrowser.Providers.Movies
 
         public string UrlFormatString
         {
-            get { return "http://www.themoviedb.org/person/{0}"; }
+            get { return "https://www.themoviedb.org/person/{0}"; }
         }
 
         public bool Supports(IHasProviderIds item)
@@ -120,7 +120,7 @@ namespace MediaBrowser.Providers.Movies
 
         public string UrlFormatString
         {
-            get { return "http://www.themoviedb.org/collection/{0}"; }
+            get { return "https://www.themoviedb.org/collection/{0}"; }
         }
 
         public bool Supports(IHasProviderIds item)

+ 1 - 1
MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Movies
         /// <summary>
         /// The updates URL
         /// </summary>
-        private const string UpdatesUrl = "http://api.themoviedb.org/3/movie/changes?start_date={0}&api_key={1}&page={2}";
+        private const string UpdatesUrl = "https://api.themoviedb.org/3/movie/changes?start_date={0}&api_key={1}&page={2}";
 
         /// <summary>
         /// The _HTTP client

+ 1 - 1
MediaBrowser.Providers/Music/FanArtArtistProvider.cs

@@ -26,7 +26,7 @@ namespace MediaBrowser.Providers.Music
     {
         internal readonly SemaphoreSlim FanArtResourcePool = new SemaphoreSlim(3, 3);
         internal const string ApiKey = "5c6b04c68e904cfed1e6cbc9a9e683d4";
-        private const string FanArtBaseUrl = "http://webservice.fanart.tv/v3.1/music/{1}?api_key={0}";
+        private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3.1/music/{1}?api_key={0}";
 
         private readonly CultureInfo _usCulture = new CultureInfo("en-US");
         private readonly IServerConfigurationManager _config;

+ 1 - 1
MediaBrowser.Providers/Music/FanArtUpdatesPostScanTask.cs

@@ -19,7 +19,7 @@ namespace MediaBrowser.Providers.Music
 {
     class FanartUpdatesPostScanTask : ILibraryPostScanTask
     {
-        private const string UpdatesUrl = "http://api.fanart.tv/webservice/newmusic/{0}/{1}/";
+        private const string UpdatesUrl = "https://api.fanart.tv/webservice/newmusic/{0}/{1}/";
 
         /// <summary>
         /// The _HTTP client

+ 9 - 9
MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs

@@ -42,7 +42,7 @@ namespace MediaBrowser.Providers.Music
 
             if (!string.IsNullOrEmpty(releaseId))
             {
-                url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=reid:{0}", releaseId);
+                url = string.Format("https://www.musicbrainz.org/ws/2/release/?query=reid:{0}", releaseId);
             }
             else
             {
@@ -50,7 +50,7 @@ namespace MediaBrowser.Providers.Music
 
                 if (!string.IsNullOrWhiteSpace(artistMusicBrainzId))
                 {
-                    url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND arid:{1}",
+                    url = string.Format("https://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND arid:{1}",
                         WebUtility.UrlEncode(searchInfo.Name),
                         artistMusicBrainzId);
                 }
@@ -58,7 +58,7 @@ namespace MediaBrowser.Providers.Music
                 {
                     isNameSearch = true;
 
-                    url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"",
+                    url = string.Format("https://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"",
                        WebUtility.UrlEncode(searchInfo.Name),
                        WebUtility.UrlEncode(searchInfo.GetAlbumArtist()));
                 }
@@ -77,7 +77,7 @@ namespace MediaBrowser.Providers.Music
         private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlDocument doc)
         {
             var ns = new XmlNamespaceManager(doc.NameTable);
-            ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#");
+            ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#");
 
             var list = new List<RemoteSearchResult>();
 
@@ -197,7 +197,7 @@ namespace MediaBrowser.Providers.Music
 
         private async Task<ReleaseResult> GetReleaseResult(string albumName, string artistId, CancellationToken cancellationToken)
         {
-            var url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND arid:{1}",
+            var url = string.Format("https://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND arid:{1}",
                 WebUtility.UrlEncode(albumName),
                 artistId);
 
@@ -208,7 +208,7 @@ namespace MediaBrowser.Providers.Music
 
         private async Task<ReleaseResult> GetReleaseResultByArtistName(string albumName, string artistName, CancellationToken cancellationToken)
         {
-            var url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"",
+            var url = string.Format("https://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"",
                 WebUtility.UrlEncode(albumName),
                 WebUtility.UrlEncode(artistName));
 
@@ -220,7 +220,7 @@ namespace MediaBrowser.Providers.Music
         private ReleaseResult GetReleaseResult(XmlDocument doc)
         {
             var ns = new XmlNamespaceManager(doc.NameTable);
-            ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#");
+            ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#");
 
             var result = new ReleaseResult
             {
@@ -258,12 +258,12 @@ namespace MediaBrowser.Providers.Music
         /// <returns>Task{System.String}.</returns>
         private async Task<string> GetReleaseGroupId(string releaseEntryId, CancellationToken cancellationToken)
         {
-            var url = string.Format("http://www.musicbrainz.org/ws/2/release-group/?query=reid:{0}", releaseEntryId);
+            var url = string.Format("https://www.musicbrainz.org/ws/2/release-group/?query=reid:{0}", releaseEntryId);
 
             var doc = await GetMusicBrainzResponse(url, false, cancellationToken).ConfigureAwait(false);
 
             var ns = new XmlNamespaceManager(doc.NameTable);
-            ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#");
+            ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#");
             var node = doc.SelectSingleNode("//mb:release-group-list/mb:release-group/@id", ns);
 
             return node != null ? node.Value : null;

+ 4 - 4
MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs

@@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.Music
 
             if (!string.IsNullOrWhiteSpace(musicBrainzId))
             {
-                var url = string.Format("http://www.musicbrainz.org/ws/2/artist/?query=arid:{0}", musicBrainzId);
+                var url = string.Format("https://www.musicbrainz.org/ws/2/artist/?query=arid:{0}", musicBrainzId);
 
                 var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, false, cancellationToken)
                             .ConfigureAwait(false);
@@ -35,7 +35,7 @@ namespace MediaBrowser.Providers.Music
                 // They seem to throw bad request failures on any term with a slash
                 var nameToSearch = searchInfo.Name.Replace('/', ' ');
 
-                var url = String.Format("http://www.musicbrainz.org/ws/2/artist/?query=artist:\"{0}\"", UrlEncode(nameToSearch));
+                var url = String.Format("https://www.musicbrainz.org/ws/2/artist/?query=artist:\"{0}\"", UrlEncode(nameToSearch));
 
                 var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
 
@@ -49,7 +49,7 @@ namespace MediaBrowser.Providers.Music
                 if (HasDiacritics(searchInfo.Name))
                 {
                     // Try again using the search with accent characters url
-                    url = String.Format("http://www.musicbrainz.org/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
+                    url = String.Format("https://www.musicbrainz.org/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
 
                     doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
 
@@ -63,7 +63,7 @@ namespace MediaBrowser.Providers.Music
         private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlDocument doc)
         {
             var ns = new XmlNamespaceManager(doc.NameTable);
-            ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#");
+            ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#");
 
             var list = new List<RemoteSearchResult>();
 

+ 6 - 6
MediaBrowser.Providers/Music/MusicExternalIds.cs

@@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.Music
 
         public string UrlFormatString
         {
-            get { return "http://musicbrainz.org/release-group/{0}"; }
+            get { return "https://musicbrainz.org/release-group/{0}"; }
         }
 
         public bool Supports(IHasProviderIds item)
@@ -41,7 +41,7 @@ namespace MediaBrowser.Providers.Music
 
         public string UrlFormatString
         {
-            get { return "http://musicbrainz.org/artist/{0}"; }
+            get { return "https://musicbrainz.org/artist/{0}"; }
         }
 
         public bool Supports(IHasProviderIds item)
@@ -64,7 +64,7 @@ namespace MediaBrowser.Providers.Music
 
         public string UrlFormatString
         {
-            get { return "http://musicbrainz.org/release/{0}"; }
+            get { return "https://musicbrainz.org/release/{0}"; }
         }
 
         public bool Supports(IHasProviderIds item)
@@ -87,7 +87,7 @@ namespace MediaBrowser.Providers.Music
 
         public string UrlFormatString
         {
-            get { return "http://musicbrainz.org/artist/{0}"; }
+            get { return "https://musicbrainz.org/artist/{0}"; }
         }
 
         public bool Supports(IHasProviderIds item)
@@ -110,7 +110,7 @@ namespace MediaBrowser.Providers.Music
 
         public string UrlFormatString
         {
-            get { return "http://musicbrainz.org/artist/{0}"; }
+            get { return "https://musicbrainz.org/artist/{0}"; }
         }
 
         public bool Supports(IHasProviderIds item)
@@ -133,7 +133,7 @@ namespace MediaBrowser.Providers.Music
 
         public string UrlFormatString
         {
-            get { return "http://musicbrainz.org/track/{0}"; }
+            get { return "https://musicbrainz.org/track/{0}"; }
         }
 
         public bool Supports(IHasProviderIds item)

+ 1 - 1
MediaBrowser.Providers/Omdb/OmdbImageProvider.cs

@@ -40,7 +40,7 @@ namespace MediaBrowser.Providers.Omdb
                 list.Add(new RemoteImageInfo
                 {
                     ProviderName = Name,
-                    Url = string.Format("http://img.omdbapi.com/?i={0}&apikey=82e83907", imdbId)
+                    Url = string.Format("https://img.omdbapi.com/?i={0}&apikey=82e83907", imdbId)
                 });
             }
 

+ 4 - 9
MediaBrowser.Providers/Omdb/OmdbItemProvider.cs

@@ -64,11 +64,9 @@ namespace MediaBrowser.Providers.Omdb
         {
             var episodeSearchInfo = searchInfo as EpisodeInfo;
 
-            var list = new List<RemoteSearchResult>();
-
             var imdbId = searchInfo.GetProviderId(MetadataProviders.Imdb);
 
-            var url = "http://www.omdbapi.com/?plot=full&r=json";
+            var url = "https://www.omdbapi.com/?plot=full&r=json";
             if (type == "episode" && episodeSearchInfo != null)
             {
                 episodeSearchInfo.SeriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out imdbId);
@@ -148,14 +146,13 @@ namespace MediaBrowser.Providers.Omdb
                     }
                 }
 
-                foreach (var result in resultList)
+                return resultList.Select(result =>
                 {
                     var item = new RemoteSearchResult
                     {
                         IndexNumber = searchInfo.IndexNumber,
                         Name = result.Title,
                         ParentIndexNumber = searchInfo.ParentIndexNumber,
-                        ProviderIds = searchInfo.ProviderIds,
                         SearchProviderName = Name
                     };
 
@@ -185,11 +182,9 @@ namespace MediaBrowser.Providers.Omdb
                         item.ImageUrl = result.Poster;
                     }
 
-                    list.Add(item);
-                }
+                    return item;
+                });
             }
-
-            return list;
         }
 
         public Task<MetadataResult<Trailer>> GetMetadata(TrailerInfo info, CancellationToken cancellationToken)

+ 1 - 1
MediaBrowser.Providers/Omdb/OmdbProvider.cs

@@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Omdb
 
             var imdbParam = imdbId.StartsWith("tt", StringComparison.OrdinalIgnoreCase) ? imdbId : "tt" + imdbId;
 
-            var url = string.Format("http://www.omdbapi.com/?i={0}&tomatoes=true", imdbParam);
+            var url = string.Format("https://www.omdbapi.com/?i={0}&tomatoes=true", imdbParam);
 
             using (var stream = await _httpClient.Get(new HttpRequestOptions
             {

+ 3 - 3
MediaBrowser.Providers/People/MovieDbPersonProvider.cs

@@ -97,7 +97,7 @@ namespace MediaBrowser.Providers.People
 
                     var requestCount = _requestCount;
 
-                    if (requestCount >= 30)
+                    if (requestCount >= 40)
                     {
                         //_logger.Debug("Throttling Tmdb people");
 
@@ -109,7 +109,7 @@ namespace MediaBrowser.Providers.People
                 }
             }
 
-            var url = string.Format(@"http://api.themoviedb.org/3/search/person?api_key={1}&query={0}", WebUtility.UrlEncode(searchInfo.Name), MovieDbProvider.ApiKey);
+            var url = string.Format(@"https://api.themoviedb.org/3/search/person?api_key={1}&query={0}", WebUtility.UrlEncode(searchInfo.Name), MovieDbProvider.ApiKey);
 
             using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
             {
@@ -234,7 +234,7 @@ namespace MediaBrowser.Providers.People
                 return;
             }
 
-            var url = string.Format(@"http://api.themoviedb.org/3/person/{1}?api_key={0}&append_to_response=credits,images,external_ids", MovieDbProvider.ApiKey, id);
+            var url = string.Format(@"https://api.themoviedb.org/3/person/{1}?api_key={0}&append_to_response=credits,images,external_ids", MovieDbProvider.ApiKey, id);
 
             using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
             {

+ 1 - 1
MediaBrowser.Providers/TV/FanArt/FanArtTvUpdatesPostScanTask.cs

@@ -19,7 +19,7 @@ namespace MediaBrowser.Providers.TV
 {
     class FanArtTvUpdatesPostScanTask : ILibraryPostScanTask
     {
-        private const string UpdatesUrl = "http://webservice.fanart.tv/v3/tv/latest?api_key={0}&date={1}";
+        private const string UpdatesUrl = "https://webservice.fanart.tv/v3/tv/latest?api_key={0}&date={1}";
 
         /// <summary>
         /// The _HTTP client

+ 1 - 1
MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs

@@ -31,7 +31,7 @@ namespace MediaBrowser.Providers.TV
         private readonly IFileSystem _fileSystem;
         private readonly IJsonSerializer _json;
 
-        private const string FanArtBaseUrl = "http://webservice.fanart.tv/v3/tv/{1}?api_key={0}";
+        private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3/tv/{1}?api_key={0}";
         // &client_key=52c813aa7b8c8b3bb87f4797532a2f8c
 
         internal static FanartSeriesProvider Current { get; private set; }

+ 1 - 1
MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs

@@ -16,7 +16,7 @@ namespace MediaBrowser.Providers.TV
 {
     public abstract class MovieDbProviderBase
     {
-        private const string EpisodeUrlPattern = @"http://api.themoviedb.org/3/tv/{0}/season/{1}/episode/{2}?api_key={3}&append_to_response=images,external_ids,credits,videos";
+        private const string EpisodeUrlPattern = @"https://api.themoviedb.org/3/tv/{0}/season/{1}/episode/{2}?api_key={3}&append_to_response=images,external_ids,credits,videos";
         private readonly IHttpClient _httpClient;
         private readonly IServerConfigurationManager _configurationManager;
         private readonly IJsonSerializer _jsonSerializer;

+ 1 - 1
MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.TV
 {
     public class MovieDbSeasonProvider : IRemoteMetadataProvider<Season, SeasonInfo>
     {
-        private const string GetTvInfo3 = @"http://api.themoviedb.org/3/tv/{0}/season/{1}?api_key={2}&append_to_response=images,keywords,external_ids,credits,videos";
+        private const string GetTvInfo3 = @"https://api.themoviedb.org/3/tv/{0}/season/{1}?api_key={2}&append_to_response=images,keywords,external_ids,credits,videos";
         private readonly IHttpClient _httpClient;
         private readonly IServerConfigurationManager _configurationManager;
         private readonly IJsonSerializer _jsonSerializer;

+ 2 - 2
MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs

@@ -24,7 +24,7 @@ namespace MediaBrowser.Providers.TV
 {
     public class MovieDbSeriesProvider : IRemoteMetadataProvider<Series, SeriesInfo>, IHasOrder
     {
-        private const string GetTvInfo3 = @"http://api.themoviedb.org/3/tv/{0}?api_key={1}&append_to_response=credits,images,keywords,external_ids,videos,content_ratings";
+        private const string GetTvInfo3 = @"https://api.themoviedb.org/3/tv/{0}?api_key={1}&append_to_response=credits,images,keywords,external_ids,videos,content_ratings";
         private readonly CultureInfo _usCulture = new CultureInfo("en-US");
 
         internal static MovieDbSeriesProvider Current { get; private set; }
@@ -438,7 +438,7 @@ namespace MediaBrowser.Providers.TV
 
         private async Task<RemoteSearchResult> FindByExternalId(string id, string externalSource, CancellationToken cancellationToken)
         {
-            var url = string.Format("http://api.themoviedb.org/3/tv/find/{0}?api_key={1}&external_source={2}",
+            var url = string.Format("https://api.themoviedb.org/3/tv/find/{0}?api_key={1}&external_source={2}",
                 id,
                 MovieDbProvider.ApiKey,
                 externalSource);

+ 2 - 2
MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs

@@ -26,12 +26,12 @@ namespace MediaBrowser.Providers.TV
         /// <summary>
         /// The server time URL
         /// </summary>
-        private const string ServerTimeUrl = "http://thetvdb.com/api/Updates.php?type=none";
+        private const string ServerTimeUrl = "https://thetvdb.com/api/Updates.php?type=none";
 
         /// <summary>
         /// The updates URL
         /// </summary>
-        private const string UpdatesUrl = "http://thetvdb.com/api/Updates.php?type=all&time={0}";
+        private const string UpdatesUrl = "https://thetvdb.com/api/Updates.php?type=all&time={0}";
 
         /// <summary>
         /// The _HTTP client

+ 4 - 4
MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs

@@ -53,9 +53,9 @@ namespace MediaBrowser.Providers.TV
             Current = this;
         }
 
-        private const string SeriesSearchUrl = "http://www.thetvdb.com/api/GetSeries.php?seriesname={0}&language={1}";
-        private const string SeriesGetZip = "http://www.thetvdb.com/api/{0}/series/{1}/all/{2}.zip";
-        private const string GetSeriesByImdbId = "http://www.thetvdb.com/api/GetSeriesByRemoteID.php?imdbid={0}&language={1}";
+        private const string SeriesSearchUrl = "https://www.thetvdb.com/api/GetSeries.php?seriesname={0}&language={1}";
+        private const string SeriesGetZip = "https://www.thetvdb.com/api/{0}/series/{1}/all/{2}.zip";
+        private const string GetSeriesByImdbId = "https://www.thetvdb.com/api/GetSeriesByRemoteID.php?imdbid={0}&language={1}";
 
         private string NormalizeLanguage(string language)
         {
@@ -1465,4 +1465,4 @@ namespace MediaBrowser.Providers.TV
             };
         }
     }
-}
+}

+ 1 - 1
MediaBrowser.Providers/TV/TvExternalIds.cs

@@ -42,7 +42,7 @@ namespace MediaBrowser.Providers.TV
 
         public string UrlFormatString
         {
-            get { return "http://thetvdb.com/index.php?tab=series&id={0}"; }
+            get { return "https://thetvdb.com/index.php?tab=series&id={0}"; }
         }
 
         public bool Supports(IHasProviderIds item)

+ 7 - 3
MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

@@ -68,9 +68,13 @@
     <Reference Include="ServiceStack.Api.Swagger">
       <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll</HintPath>
     </Reference>
-    <Reference Include="SocketHttpListener, Version=1.0.5908.28560, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\SocketHttpListener.1.0.0.29\lib\net45\SocketHttpListener.dll</HintPath>
+    <Reference Include="SimpleInjector, Version=3.1.3.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
+      <HintPath>..\packages\SimpleInjector.3.1.3\lib\net45\SimpleInjector.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="SocketHttpListener, Version=1.0.5955.1537, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\SocketHttpListener.1.0.0.30\lib\net45\SocketHttpListener.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />

+ 2 - 1
MediaBrowser.Server.Implementations/packages.config

@@ -8,5 +8,6 @@
   <package id="Mono.Nat" version="1.2.24.0" targetFramework="net45" />
   <package id="morelinq" version="1.4.0" targetFramework="net45" />
   <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
-  <package id="SocketHttpListener" version="1.0.0.29" targetFramework="net45" />
+  <package id="SimpleInjector" version="3.1.3" targetFramework="net45" />
+  <package id="SocketHttpListener" version="1.0.0.30" targetFramework="net45" />
 </packages>

+ 10 - 0
MediaBrowser.Server.Mono/Native/BaseMonoApp.cs

@@ -69,6 +69,11 @@ namespace MediaBrowser.Server.Mono.Native
 
         }
 
+        public void AllowSystemStandby()
+        {
+
+        }
+
         public List<Assembly> GetAssembliesWithParts()
         {
             var list = new List<Assembly>();
@@ -217,6 +222,11 @@ namespace MediaBrowser.Server.Mono.Native
             return GetInfo(Environment);
         }
 
+        public void LaunchUrl(string url)
+        {
+            throw new NotImplementedException();
+        }
+
         public static FFMpegInstallInfo GetInfo(NativeEnvironment environment)
         {
             var info = new FFMpegInstallInfo();

+ 6 - 1
MediaBrowser.Server.Startup.Common/ApplicationHost.cs

@@ -440,7 +440,7 @@ namespace MediaBrowser.Server.Startup.Common
             LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, this);
             RegisterSingleInstance(LibraryMonitor);
 
-            ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager);
+            ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer);
             RegisterSingleInstance(ProviderManager);
 
             SeriesOrderManager = new SeriesOrderManager();
@@ -1404,5 +1404,10 @@ namespace MediaBrowser.Server.Startup.Common
                 return externalDns;
             }
         }
+
+        public void LaunchUrl(string url)
+        {
+            NativeApp.LaunchUrl(url);
+        }
     }
 }

+ 15 - 44
MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs

@@ -15,87 +15,58 @@ namespace MediaBrowser.Server.Startup.Common.Browser
         /// </summary>
         /// <param name="page">The page.</param>
         /// <param name="appHost">The app host.</param>
-        /// <param name="logger">The logger.</param>
-        public static void OpenDashboardPage(string page, IServerApplicationHost appHost, ILogger logger)
+        public static void OpenDashboardPage(string page, IServerApplicationHost appHost)
         {
             var url = appHost.GetLocalApiUrl("localhost") + "/web/" + page;
 
-            OpenUrl(url, logger);
+            OpenUrl(appHost, url);
         }
 
         /// <summary>
         /// Opens the community.
         /// </summary>
-        /// <param name="logger">The logger.</param>
-        public static void OpenCommunity(ILogger logger)
+        public static void OpenCommunity(IServerApplicationHost appHost)
         {
-            OpenUrl("http://emby.media/community", logger);
+            OpenUrl(appHost, "http://emby.media/community");
         }
 
         /// <summary>
         /// Opens the web client.
         /// </summary>
         /// <param name="appHost">The app host.</param>
-        /// <param name="logger">The logger.</param>
-        public static void OpenWebClient(IServerApplicationHost appHost, ILogger logger)
+        public static void OpenWebClient(IServerApplicationHost appHost)
         {
-            OpenDashboardPage("index.html", appHost, logger);
+            OpenDashboardPage("index.html", appHost);
         }
 
         /// <summary>
         /// Opens the dashboard.
         /// </summary>
         /// <param name="appHost">The app host.</param>
-        /// <param name="logger">The logger.</param>
-        public static void OpenDashboard(IServerApplicationHost appHost, ILogger logger)
+        public static void OpenDashboard(IServerApplicationHost appHost)
         {
-            OpenDashboardPage("dashboard.html", appHost, logger);
+            OpenDashboardPage("dashboard.html", appHost);
         }
 
         /// <summary>
         /// Opens the URL.
         /// </summary>
         /// <param name="url">The URL.</param>
-        /// <param name="logger">The logger.</param>
-        private static void OpenUrl(string url, ILogger logger)
+        private static void OpenUrl(IServerApplicationHost appHost, string url)
         {
-            var process = new Process
-            {
-                StartInfo = new ProcessStartInfo
-                {
-                    FileName = url
-                },
-
-                EnableRaisingEvents = true,
-            };
-
-            process.Exited += ProcessExited;
-
             try
             {
-                process.Start();
+                appHost.LaunchUrl(url);
+            }
+            catch (NotImplementedException)
+            {
+                
             }
             catch (Exception ex)
             {
-                logger.ErrorException("Error launching url: {0}", ex, url);
-
-                Console.WriteLine("Error launching url: {0}", ex.Message);
+                Console.WriteLine("Error launching url: " + url);
                 Console.WriteLine(ex.Message);
-
-//#if !__MonoCS__
-//                System.Windows.Forms.MessageBox.Show("There was an error launching your web browser. Please check your default browser settings.");
-//#endif
             }
         }
-
-        /// <summary>
-        /// Processes the exited.
-        /// </summary>
-        /// <param name="sender">The sender.</param>
-        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
-        private static void ProcessExited(object sender, EventArgs e)
-        {
-            ((Process)sender).Dispose();
-        }
     }
 }

+ 15 - 16
MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs

@@ -27,28 +27,27 @@ namespace MediaBrowser.Server.Startup.Common.EntryPoints
             _timer = new PeriodicTimer(obj =>
             {
                 var now = DateTime.UtcNow;
-                if (_sessionManager.Sessions.Any(i => (now - i.LastActivityDate).TotalMinutes < 15))
+                var nativeApp = ((ApplicationHost)_appHost).NativeApp;
+
+                try
+                {
+                    if (_sessionManager.Sessions.Any(i => (now - i.LastActivityDate).TotalMinutes < 15))
+                    {
+                        nativeApp.PreventSystemStandby();
+                    }
+                    else
+                    {
+                        nativeApp.AllowSystemStandby();
+                    }
+                }
+                catch (Exception ex)
                 {
-                    KeepAlive();
+                    _logger.ErrorException("Error resetting system standby timer", ex);
                 }
 
             }, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
         }
 
-        private void KeepAlive()
-        {
-            var nativeApp = ((ApplicationHost)_appHost).NativeApp;
-
-            try
-            {
-                nativeApp.PreventSystemStandby();
-            }
-            catch (Exception ex)
-            {
-                _logger.ErrorException("Error resetting system standby timer", ex);
-            }
-        }
-
         public void Dispose()
         {
             if (_timer != null)

+ 1 - 1
MediaBrowser.Server.Startup.Common/EntryPoints/StartupWizard.cs

@@ -46,7 +46,7 @@ namespace MediaBrowser.Server.Startup.Common.EntryPoints
         /// </summary>
         private void LaunchStartupWizard()
         {
-            BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost, _logger);
+            BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost);
         }
 
         /// <summary>

+ 4 - 0
MediaBrowser.Server.Startup.Common/INativeApp.cs

@@ -93,6 +93,8 @@ namespace MediaBrowser.Server.Startup.Common
         /// </summary>
         void PreventSystemStandby();
 
+        void AllowSystemStandby();
+
         /// <summary>
         /// Gets the power management.
         /// </summary>
@@ -100,5 +102,7 @@ namespace MediaBrowser.Server.Startup.Common
         IPowerManagement GetPowerManagement();
 
         FFMpegInstallInfo GetFfmpegInstallInfo();
+
+        void LaunchUrl(string url);
     }
 }

+ 6 - 1
MediaBrowser.ServerApplication/MainStartup.cs

@@ -317,10 +317,15 @@ namespace MediaBrowser.ServerApplication
         {
             if (e.Reason == SessionSwitchReason.SessionLogon)
             {
-                BrowserLauncher.OpenDashboard(_appHost, _logger);
+                BrowserLauncher.OpenDashboard(_appHost);
             }
         }
 
+        public static void Invoke(Action action)
+        {
+            _serverNotifyIcon.Invoke(action);
+        }
+
         /// <summary>
         /// Starts the service.
         /// </summary>

+ 26 - 14
MediaBrowser.ServerApplication/Native/Standby.cs

@@ -1,4 +1,5 @@
-using System.Runtime.InteropServices;
+using System;
+using System.Runtime.InteropServices;
 
 namespace MediaBrowser.ServerApplication.Native
 {
@@ -7,11 +8,33 @@ namespace MediaBrowser.ServerApplication.Native
     /// </summary>
     public static class Standby
     {
-        public static void PreventSystemStandby()
+        public static void PreventSleepAndMonitorOff()
         {
-            SystemHelper.ResetStandbyTimer();
+            NativeMethods.SetThreadExecutionState(NativeMethods.ES_CONTINUOUS | NativeMethods.ES_SYSTEM_REQUIRED | NativeMethods.ES_DISPLAY_REQUIRED);
         }
 
+        public static void PreventSleep()
+        {
+            NativeMethods.SetThreadExecutionState(NativeMethods.ES_CONTINUOUS | NativeMethods.ES_SYSTEM_REQUIRED);
+        }
+
+        // Clear EXECUTION_STATE flags to allow the system to sleep and turn off monitor normally
+        public static void AllowSleep()
+        {
+            NativeMethods.SetThreadExecutionState(NativeMethods.ES_CONTINUOUS);
+        }
+
+        internal static class NativeMethods
+        {
+            // Import SetThreadExecutionState Win32 API and necessary flags
+            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+            public static extern uint SetThreadExecutionState(uint esFlags);
+            public const uint ES_CONTINUOUS = 0x80000000;
+            public const uint ES_SYSTEM_REQUIRED = 0x00000001;
+            public const uint ES_DISPLAY_REQUIRED = 0x00000002;
+        }
+
+        [Flags]
         internal enum EXECUTION_STATE : uint
         {
             ES_NONE = 0,
@@ -21,16 +44,5 @@ namespace MediaBrowser.ServerApplication.Native
             ES_AWAYMODE_REQUIRED = 0x00000040,
             ES_CONTINUOUS = 0x80000000
         }
-
-        public class SystemHelper
-        {
-            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
-            static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
-
-            public static void ResetStandbyTimer()
-            {
-                EXECUTION_STATE es = SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED);
-            }
-        }
     }
 }

+ 47 - 2
MediaBrowser.ServerApplication/Native/WindowsApp.cs

@@ -1,13 +1,17 @@
-using MediaBrowser.Common.Net;
+using System;
+using MediaBrowser.Common.Net;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Server.Startup.Common;
 using MediaBrowser.ServerApplication.Networking;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.IO;
 using System.Reflection;
+using System.Windows.Forms;
 using CommonIO;
 using MediaBrowser.Controller.Power;
 using MediaBrowser.Server.Startup.Common.FFMpeg;
+using OperatingSystem = MediaBrowser.Server.Startup.Common.OperatingSystem;
 
 namespace MediaBrowser.ServerApplication.Native
 {
@@ -134,7 +138,12 @@ namespace MediaBrowser.ServerApplication.Native
 
         public void PreventSystemStandby()
         {
-            Standby.PreventSystemStandby();
+            MainStartup.Invoke(Standby.PreventSleep);
+        }
+
+        public void AllowSystemStandby()
+        {
+            MainStartup.Invoke(Standby.AllowSleep);
         }
 
         public IPowerManagement GetPowerManagement()
@@ -156,6 +165,42 @@ namespace MediaBrowser.ServerApplication.Native
             return info;
         }
 
+        public void LaunchUrl(string url)
+        {
+            var process = new Process
+            {
+                StartInfo = new ProcessStartInfo
+                {
+                    FileName = url
+                },
+
+                EnableRaisingEvents = true,
+            };
+
+            process.Exited += ProcessExited;
+
+            try
+            {
+                process.Start();
+            }
+            catch (Exception ex)
+            {
+                _logger.ErrorException("Error launching url: {0}", ex, url);
+
+                throw;
+            }
+        }
+
+        /// <summary>
+        /// Processes the exited.
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
+        private static void ProcessExited(object sender, EventArgs e)
+        {
+            ((Process)sender).Dispose();
+        }
+
         private string[] GetDownloadUrls()
         {
             switch (Environment.SystemArchitecture)

+ 10 - 5
MediaBrowser.ServerApplication/ServerNotifyIcon.cs

@@ -36,10 +36,15 @@ namespace MediaBrowser.ServerApplication
             set
             {
                 Action act = () => notifyIcon1.Visible = false;
-                contextMenuStrip1.Invoke(act);
+                Invoke(act);
             }
         }
 
+        public void Invoke(Action action)
+        {
+            contextMenuStrip1.Invoke(action);
+        }
+
         public ServerNotifyIcon(ILogManager logManager,
             IServerApplicationHost appHost,
             IServerConfigurationManager configurationManager,
@@ -163,7 +168,7 @@ namespace MediaBrowser.ServerApplication
 
         void notifyIcon1_DoubleClick(object sender, EventArgs e)
         {
-            BrowserLauncher.OpenDashboard(_appHost, _logger);
+            BrowserLauncher.OpenDashboard(_appHost);
         }
 
         private void LocalizeText()
@@ -194,17 +199,17 @@ namespace MediaBrowser.ServerApplication
 
         void cmdBrowse_Click(object sender, EventArgs e)
         {
-            BrowserLauncher.OpenWebClient(_appHost, _logger);
+            BrowserLauncher.OpenWebClient(_appHost);
         }
 
         void cmdCommunity_Click(object sender, EventArgs e)
         {
-            BrowserLauncher.OpenCommunity(_logger);
+            BrowserLauncher.OpenCommunity(_appHost);
         }
 
         void cmdConfigure_Click(object sender, EventArgs e)
         {
-            BrowserLauncher.OpenDashboard(_appHost, _logger);
+            BrowserLauncher.OpenDashboard(_appHost);
         }
 
         void cmdRestart_Click(object sender, EventArgs e)

+ 9 - 0
MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj

@@ -128,6 +128,12 @@
     <Content Include="dashboard-ui\components\guestinviter\guestinviter.template.html">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
+    <Content Include="dashboard-ui\components\ironcardlist\ironcardlist.template.html">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\components\ironcardlist\ironcardlist.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
     <Content Include="dashboard-ui\components\metadataeditor\metadataeditor.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
@@ -146,6 +152,9 @@
     <Content Include="dashboard-ui\components\remotecontrolautoplay.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
+    <Content Include="dashboard-ui\components\scrollthreshold.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
     <Content Include="dashboard-ui\components\servertestermessage.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>

+ 2 - 2
Nuget/MediaBrowser.Common.Internal.nuspec

@@ -13,8 +13,8 @@
         <copyright>Copyright © Emby 2013</copyright>
         <dependencies>
             <dependency id="MediaBrowser.Common" version="3.0.645" />
-            <dependency id="NLog" version="4.2.3" />
-            <dependency id="SimpleInjector" version="3.1.2" />
+            <dependency id="NLog" version="4.3.1" />
+            <dependency id="SimpleInjector" version="3.1.3" />
         </dependencies>
     </metadata>
     <files>

+ 2 - 2
OpenSubtitlesHandler/Utilities.cs

@@ -32,7 +32,7 @@ namespace OpenSubtitlesHandler
     /// </summary>
     public sealed class Utilities
     {
-        private const string XML_RPC_SERVER = "http://api.opensubtitles.org/xml-rpc";
+        private const string XML_RPC_SERVER = "https://api.opensubtitles.org/xml-rpc";
 
         /// <summary>
         /// Compute movie hash
@@ -195,7 +195,7 @@ namespace OpenSubtitlesHandler
                 RequestContentBytes = request,
                 RequestContentType = "text/xml",
                 UserAgent = userAgent,
-                Host = "api.opensubtitles.org:80",
+                Host = "api.opensubtitles.org:443",
                 Url = XML_RPC_SERVER,
 
                 // Response parsing will fail with this enabled