فهرست منبع

Add api key functions

Luke Pulverenti 11 سال پیش
والد
کامیت
b5641013ce

+ 5 - 3
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Extensions;
+using MediaBrowser.Api.Playback.Hls;
+using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;
@@ -317,7 +318,7 @@ namespace MediaBrowser.Api.Playback
                 switch (qualitySetting)
                 {
                     case EncodingQuality.HighSpeed:
-                        param = "-preset ultrafast";
+                        param = "-preset superfast";
                         break;
                     case EncodingQuality.HighQuality:
                         param = "-preset superfast";
@@ -945,7 +946,8 @@ namespace MediaBrowser.Api.Playback
             }
 
             // Allow a small amount of time to buffer a little
-            if (state.IsInputVideo)
+            // But not with HLS because it already has it's own wait
+            if (state.IsInputVideo && TranscodingJobType != TranscodingJobType.Hls)
             {
                 await Task.Delay(500, cancellationTokenSource.Token).ConfigureAwait(false);
             }

+ 55 - 1
MediaBrowser.Api/SessionsService.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
+using MediaBrowser.Controller.Security;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Model.Session;
 using ServiceStack;
@@ -241,6 +242,25 @@ namespace MediaBrowser.Api
     {
     }
 
+    [Route("/Auth/Keys", "GET")]
+    public class GetApiKeys
+    {
+    }
+
+    [Route("/Auth/Keys/{Key}", "DELETE")]
+    public class RevokeKey
+    {
+        [ApiMember(Name = "Key", Description = "Auth Key", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
+        public string Key { get; set; }
+    }
+
+    [Route("/Auth/Keys", "POST")]
+    public class CreateKey
+    {
+        [ApiMember(Name = "App", Description = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
+        public string App { get; set; }
+    }
+
     /// <summary>
     /// Class SessionsService
     /// </summary>
@@ -253,19 +273,43 @@ namespace MediaBrowser.Api
 
         private readonly IUserManager _userManager;
         private readonly IAuthorizationContext _authContext;
+        private readonly IAuthenticationRepository _authRepo;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="SessionsService" /> class.
         /// </summary>
         /// <param name="sessionManager">The session manager.</param>
         /// <param name="userManager">The user manager.</param>
-        public SessionsService(ISessionManager sessionManager, IUserManager userManager, IAuthorizationContext authContext)
+        /// <param name="authContext">The authentication context.</param>
+        /// <param name="authRepo">The authentication repo.</param>
+        public SessionsService(ISessionManager sessionManager, IUserManager userManager, IAuthorizationContext authContext, IAuthenticationRepository authRepo)
         {
             _sessionManager = sessionManager;
             _userManager = userManager;
             _authContext = authContext;
+            _authRepo = authRepo;
+        }
+
+        public void Delete(RevokeKey request)
+        {
+            var task = _sessionManager.RevokeToken(request.Key);
+
+            Task.WaitAll(task);
         }
 
+        public void Post(CreateKey request)
+        {
+            var task = _authRepo.Create(new AuthenticationInfo
+            {
+                AppName = request.App,
+                IsActive = true,
+                AccessToken = Guid.NewGuid().ToString("N"),
+                DateCreated = DateTime.UtcNow
+
+            }, CancellationToken.None);
+
+            Task.WaitAll(task);
+        }
 
         public void Post(ReportSessionEnded request)
         {
@@ -274,6 +318,16 @@ namespace MediaBrowser.Api
             _sessionManager.Logout(auth.Token);
         }
 
+        public object Get(GetApiKeys request)
+        {
+            var result = _authRepo.Get(new AuthenticationInfoQuery
+            {
+                IsActive = true
+            });
+
+            return ToOptimizedResult(result);
+        }
+
         /// <summary>
         /// Gets the specified request.
         /// </summary>

+ 7 - 0
MediaBrowser.Controller/Session/ISessionManager.cs

@@ -276,6 +276,13 @@ namespace MediaBrowser.Controller.Session
         /// <returns>Task.</returns>
         Task RevokeUserTokens(string userId);
 
+        /// <summary>
+        /// Revokes the token.
+        /// </summary>
+        /// <param name="id">The identifier.</param>
+        /// <returns>Task.</returns>
+        Task RevokeToken(string id);
+        
         /// <summary>
         /// Determines whether the specified remote endpoint is local.
         /// </summary>

+ 21 - 1
MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs

@@ -255,6 +255,8 @@ namespace MediaBrowser.Providers.MediaInfo
                     AddDummyChapters(video, chapters);
                 }
 
+                NormalizeChapterNames(chapters);
+
                 await _encodingManager.RefreshChapterImages(new ChapterImageRefreshOptions
                 {
                     Chapters = chapters,
@@ -268,6 +270,25 @@ namespace MediaBrowser.Providers.MediaInfo
             }
         }
 
+        private void NormalizeChapterNames(List<ChapterInfo> chapters)
+        {
+            var index = 1;
+
+            foreach (var chapter in chapters)
+            {
+                TimeSpan time;
+
+                // Check if the name is empty and/or if the name is a time
+                // Some ripping programs do that.
+                if (string.IsNullOrWhiteSpace(chapter.Name) ||
+                    TimeSpan.TryParse(chapter.Name, out time))
+                {
+                    chapter.Name = string.Format(_localization.GetLocalizedString("LabelChapterName"), index.ToString(CultureInfo.InvariantCulture));
+                }
+                index++;
+            }
+        }
+
         private ChapterInfo GetChapterInfo(MediaChapter chapter)
         {
             var info = new ChapterInfo();
@@ -570,7 +591,6 @@ namespace MediaBrowser.Providers.MediaInfo
             {
                 chapters.Add(new ChapterInfo
                 {
-                    Name = "Chapter " + index,
                     StartPositionTicks = currentChapterTicks
                 });
 

+ 4 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json

@@ -233,5 +233,8 @@
 	"OptionBlockGames": "Games",
 	"OptionBlockLiveTvPrograms": "Live TV Programs",
 	"OptionBlockLiveTvChannels": "Live TV Channels",
-	"OptionBlockChannelContent": "Internet Channel Content"
+	"OptionBlockChannelContent": "Internet Channel Content",
+	"ButtonRevoke": "Revoke",
+	"MessageConfirmRevokeApiKey": "Are you sure you wish to revoke this api key? The application's connection to Media Browser will be abruptly terminated.",
+	"HeaderConfirmRevokeApiKey": "Revoke Api Key"
 }

+ 14 - 2
MediaBrowser.Server.Implementations/Localization/Server/server.json

@@ -849,7 +849,7 @@
 	"LabelXbmcMetadataEnablePathSubstitutionHelp2": "See path substitution.",
 	"LabelGroupChannelsIntoViews": "Display the following channels directly within my views:",
 	"LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.",
-	"LabelDisplayCollectionsView": "Display a Collections view to show movie collections",
+	"LabelDisplayCollectionsView": "Display a collections view to show movie collections",
 	"LabelXbmcMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs",
 	"LabelXbmcMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Xbmc skin compatibility.",
 	"TabServices": "Services",
@@ -870,5 +870,17 @@
 	"LabelImagesByName": "Images by name:",
 	"LabelTranscodingTemporaryFiles": "Transcoding temporary files:",
 	"HeaderLatestMusic": "Latest Music",
-	"HeaderBranding": "Branding"
+	"HeaderBranding": "Branding",
+	"HeaderApiKeys": "Api Keys",
+	"HeaderApiKeysHelp": "External applications are required to have an Api key in order to communicate with Media Browser. Keys are issued by logging in with a Media Browser account, or by manually granting the application a key.",
+	"HeaderApiKey": "Api Key",
+	"HeaderApp": "App",
+	"HeaderDevice": "Device",
+	"HeaderUser": "User",
+	"HeaderDateIssued": "Date Issued",
+	"LabelChapterName": "Chapter {0}",
+	"HeaderNewApiKey": "New Api Key",
+	"LabelAppName": "App name",
+	"LabelAppNameExample": "Example: Sickbeard, NzbDrone",
+	"HeaderNewApiKeyHelp": "Grant an application permission to communicate with Media Browser."
 }

+ 2 - 2
MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs

@@ -283,11 +283,11 @@ namespace MediaBrowser.Server.Implementations.Security
             }
 
             info.IsActive = reader.GetBoolean(6);
-            info.DateCreated = reader.GetDateTime(7);
+            info.DateCreated = reader.GetDateTime(7).ToUniversalTime();
 
             if (!reader.IsDBNull(8))
             {
-                info.DateRevoked = reader.GetDateTime(8);
+                info.DateRevoked = reader.GetDateTime(8).ToUniversalTime();
             }
          
             return info;

+ 12 - 7
MediaBrowser.Server.Implementations/Session/SessionManager.cs

@@ -1210,15 +1210,15 @@ namespace MediaBrowser.Server.Implementations.Session
         /// <returns>Task{SessionInfo}.</returns>
         /// <exception cref="System.UnauthorizedAccessException">Invalid user or password entered.</exception>
         /// <exception cref="UnauthorizedAccessException"></exception>
-        public async Task<AuthenticationResult> AuthenticateNewSession(string username, 
-            string password, 
-            string clientType, 
-            string appVersion, 
-            string deviceId, 
-            string deviceName, 
+        public async Task<AuthenticationResult> AuthenticateNewSession(string username,
+            string password,
+            string clientType,
+            string appVersion,
+            string deviceId,
+            string deviceName,
             string remoteEndPoint)
         {
-            var result = (IsLocalhost(remoteEndPoint) && string.Equals(clientType, "Dashboard", StringComparison.OrdinalIgnoreCase)) || 
+            var result = (IsLocalhost(remoteEndPoint) && string.Equals(clientType, "Dashboard", StringComparison.OrdinalIgnoreCase)) ||
                 await _userManager.AuthenticateUser(username, password).ConfigureAwait(false);
 
             if (!result)
@@ -1332,6 +1332,11 @@ namespace MediaBrowser.Server.Implementations.Session
             }
         }
 
+        public Task RevokeToken(string token)
+        {
+            return Logout(token);
+        }
+
         private bool IsLocalhost(string remoteEndpoint)
         {
             if (string.IsNullOrWhiteSpace(remoteEndpoint))

+ 20 - 6
MediaBrowser.Server.Implementations/Session/WebSocketController.cs

@@ -62,14 +62,28 @@ namespace MediaBrowser.Server.Implementations.Session
 
         void connection_Closed(object sender, EventArgs e)
         {
-            var capabilities = new SessionCapabilities
+            if (!GetActiveSockets().Any())
             {
-                PlayableMediaTypes = Session.PlayableMediaTypes,
-                SupportedCommands = Session.SupportedCommands,
-                SupportsMediaControl = SupportsMediaControl
-            };
+                try
+                {
+                    _sessionManager.ReportSessionEnded(Session.Id);
+                }
+                catch (Exception ex)
+                {
+                    _logger.ErrorException("Error reporting session ended.", ex);
+                }
+            }
+            else
+            {
+                var capabilities = new SessionCapabilities
+                {
+                    PlayableMediaTypes = Session.PlayableMediaTypes,
+                    SupportedCommands = Session.SupportedCommands,
+                    SupportsMediaControl = SupportsMediaControl
+                };
 
-            _sessionManager.ReportCapabilities(Session.Id, capabilities);
+                _sessionManager.ReportCapabilities(Session.Id, capabilities);
+            }
         }
 
         private IWebSocketConnection GetActiveSocket()

+ 2 - 2
MediaBrowser.XbmcMetadata/Savers/AlbumNfoSaver.cs

@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Generic;
 using System.Globalization;
@@ -14,8 +15,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
 {
     public class AlbumNfoSaver : BaseNfoSaver
     {
-        public AlbumNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager)
-            : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager)
+        public AlbumNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger) : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
         {
         }
 

+ 2 - 2
MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs

@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Logging;
 using MediaBrowser.XbmcMetadata.Configuration;
 using System.Collections.Generic;
 using System.Globalization;
@@ -14,8 +15,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
 {
     public class ArtistNfoSaver : BaseNfoSaver
     {
-        public ArtistNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager)
-            : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager)
+        public ArtistNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger) : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
         {
         }
 

+ 16 - 5
MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs

@@ -9,6 +9,7 @@ using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
 using MediaBrowser.XbmcMetadata.Configuration;
 using System;
 using System.Collections.Generic;
@@ -98,8 +99,9 @@ namespace MediaBrowser.XbmcMetadata.Savers
 
         }.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
 
-        protected BaseNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager)
+        protected BaseNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger)
         {
+            Logger = logger;
             UserDataManager = userDataManager;
             UserManager = userManager;
             LibraryManager = libraryManager;
@@ -112,6 +114,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
         protected ILibraryManager LibraryManager { get; private set; }
         protected IUserManager UserManager { get; private set; }
         protected IUserDataManager UserDataManager { get; private set; }
+        protected ILogger Logger { get; private set; }
 
         public string Name
         {
@@ -232,11 +235,11 @@ namespace MediaBrowser.XbmcMetadata.Savers
 
                 try
                 {
-                    AddCustomTags(xmlPath, tagsUsed, writer);
+                    AddCustomTags(xmlPath, tagsUsed, writer, Logger);
                 }
                 catch (FileNotFoundException)
                 {
-                    
+
                 }
 
                 writer.WriteEndElement();
@@ -950,7 +953,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
             return string.Equals(person.Type, type, StringComparison.OrdinalIgnoreCase) || string.Equals(person.Role, type, StringComparison.OrdinalIgnoreCase);
         }
 
-        private static void AddCustomTags(string path, List<string> xmlTagsUsed, XmlWriter writer)
+        private static void AddCustomTags(string path, List<string> xmlTagsUsed, XmlWriter writer, ILogger logger)
         {
             var settings = new XmlReaderSettings
             {
@@ -965,7 +968,15 @@ namespace MediaBrowser.XbmcMetadata.Savers
                 // Use XmlReader for best performance
                 using (var reader = XmlReader.Create(streamReader, settings))
                 {
-                    reader.MoveToContent();
+                    try
+                    {
+                        reader.MoveToContent();
+                    }
+                    catch (Exception ex)
+                    {
+                        logger.ErrorException("Error reading existing xml tags from {0}.", ex, path);
+                        return;
+                    }
 
                     // Loop through each element
                     while (reader.Read())

+ 2 - 2
MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs

@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Logging;
 using MediaBrowser.XbmcMetadata.Configuration;
 using System.Collections.Generic;
 using System.Globalization;
@@ -13,8 +14,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
 {
     public class EpisodeNfoSaver : BaseNfoSaver
     {
-        public EpisodeNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager)
-            : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager)
+        public EpisodeNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger) : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
         {
         }
 

+ 2 - 2
MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs

@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
 using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
@@ -14,8 +15,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
 {
     public class MovieNfoSaver : BaseNfoSaver
     {
-        public MovieNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager)
-            : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager)
+        public MovieNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger) : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
         {
         }
 

+ 2 - 1
MediaBrowser.XbmcMetadata/Savers/SeasonNfoSaver.cs

@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Logging;
 using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
@@ -12,7 +13,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
 {
     public class SeasonNfoSaver : BaseNfoSaver
     {
-        public SeasonNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager) : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager)
+        public SeasonNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger) : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
         {
         }
 

+ 2 - 2
MediaBrowser.XbmcMetadata/Savers/SeriesNfoSaver.cs

@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
 using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
@@ -13,8 +14,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
 {
     public class SeriesNfoSaver : BaseNfoSaver
     {
-        public SeriesNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager)
-            : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager)
+        public SeriesNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger) : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
         {
         }