Bladeren bron

Merge remote-tracking branch 'upstream/master'

Tim Hobbs 11 jaren geleden
bovenliggende
commit
28681ebce0

+ 5 - 1
MediaBrowser.Api/LiveTv/LiveTvService.cs

@@ -39,6 +39,9 @@ namespace MediaBrowser.Api.LiveTv
         /// <value>The limit.</value>
         [ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
         public int? Limit { get; set; }
+
+        [ApiMember(Name = "IsFavorite", Description = "Filter by channels that are favorites, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
+        public bool? IsFavorite { get; set; }
     }
 
     [Route("/LiveTv/Channels/{Id}", "GET", Summary = "Gets a live tv channel")]
@@ -290,7 +293,8 @@ namespace MediaBrowser.Api.LiveTv
                 ChannelType = request.Type,
                 UserId = request.UserId,
                 StartIndex = request.StartIndex,
-                Limit = request.Limit
+                Limit = request.Limit,
+                IsFavorite = request.IsFavorite
 
             }, CancellationToken.None).Result;
 

+ 59 - 1
MediaBrowser.Dlna/DlnaManager.cs

@@ -20,13 +20,15 @@ namespace MediaBrowser.Dlna
         private readonly IXmlSerializer _xmlSerializer;
         private readonly IFileSystem _fileSystem;
         private readonly ILogger _logger;
+        private readonly IJsonSerializer _jsonSerializer;
 
-        public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem, IApplicationPaths appPaths, ILogger logger)
+        public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem, IApplicationPaths appPaths, ILogger logger, IJsonSerializer jsonSerializer)
         {
             _xmlSerializer = xmlSerializer;
             _fileSystem = fileSystem;
             _appPaths = appPaths;
             _logger = logger;
+            _jsonSerializer = jsonSerializer;
 
             //DumpProfiles();
         }
@@ -381,10 +383,66 @@ namespace MediaBrowser.Dlna
 
         public void CreateProfile(DeviceProfile profile)
         {
+            profile = ReserializeProfile(profile);
+
+            if (string.IsNullOrWhiteSpace(profile.Name))
+            {
+                throw new ArgumentException("Profile is missing Name");
+            }
+
+            var newFilename = _fileSystem.GetValidFilename(profile.Name) + ".xml";
+            var path = Path.Combine(UserProfilesPath, newFilename);
+
+            _xmlSerializer.SerializeToFile(profile, path);
         }
 
         public void UpdateProfile(DeviceProfile profile)
         {
+            profile = ReserializeProfile(profile);
+
+            if (string.IsNullOrWhiteSpace(profile.Id))
+            {
+                throw new ArgumentException("Profile is missing Id");
+            }
+            if (string.IsNullOrWhiteSpace(profile.Name))
+            {
+                throw new ArgumentException("Profile is missing Name");
+            }
+
+            var current = GetProfileInfosInternal().First(i => string.Equals(i.Info.Id, profile.Id, StringComparison.OrdinalIgnoreCase));
+
+            if (current.Info.Type == DeviceProfileType.System)
+            {
+                throw new ArgumentException("System profiles are readonly");
+            }
+
+            var newFilename = _fileSystem.GetValidFilename(profile.Name) + ".xml";
+            var path = Path.Combine(UserProfilesPath, newFilename);
+
+            if (!string.Equals(path, current.Path, StringComparison.Ordinal))
+            {
+                File.Delete(current.Path);
+            }
+
+            _xmlSerializer.SerializeToFile(profile, path);
+        }
+
+        /// <summary>
+        /// Recreates the object using serialization, to ensure it's not a subclass.
+        /// If it's a subclass it may not serlialize properly to xml (different root element tag name)
+        /// </summary>
+        /// <param name="profile"></param>
+        /// <returns></returns>
+        private DeviceProfile ReserializeProfile(DeviceProfile profile)
+        {
+            if (profile.GetType() == typeof(DeviceProfile))
+            {
+                return profile;
+            }
+
+            var json = _jsonSerializer.SerializeToString(profile);
+
+            return _jsonSerializer.DeserializeFromString<DeviceProfile>(json);
         }
 
         class InternalProfileInfo

+ 6 - 0
MediaBrowser.Model/LiveTv/ChannelQuery.cs

@@ -12,6 +12,12 @@ namespace MediaBrowser.Model.LiveTv
         /// <value>The type of the channel.</value>
         public ChannelType? ChannelType { get; set; }
 
+        /// <summary>
+        /// Gets or sets a value indicating whether this instance is favorite.
+        /// </summary>
+        /// <value><c>null</c> if [is favorite] contains no value, <c>true</c> if [is favorite]; otherwise, <c>false</c>.</value>
+        public bool? IsFavorite { get; set; }
+        
         /// <summary>
         /// Gets or sets the user identifier.
         /// </summary>

+ 11 - 3
MediaBrowser.Model/Session/PlayRequest.cs

@@ -39,14 +39,22 @@ namespace MediaBrowser.Model.Session
         /// <summary>
         /// The play now
         /// </summary>
-        PlayNow,
+        PlayNow = 0,
         /// <summary>
         /// The play next
         /// </summary>
-        PlayNext,
+        PlayNext = 1,
         /// <summary>
         /// The play last
         /// </summary>
-        PlayLast
+        PlayLast = 2,
+        /// <summary>
+        /// The play instant mix
+        /// </summary>
+        PlayInstantMix = 3,
+        /// <summary>
+        /// The play shuffle
+        /// </summary>
+        PlayShuffle = 4
     }
 }

+ 2 - 2
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -1297,7 +1297,7 @@ namespace MediaBrowser.Server.Implementations.Dto
         {
             var result = new List<MediaSourceInfo>
             {
-                GetVersionInfo(item, true)
+                GetVersionInfo(item)
             };
 
             return result;
@@ -1321,7 +1321,7 @@ namespace MediaBrowser.Server.Implementations.Dto
             };
         }
 
-        private MediaSourceInfo GetVersionInfo(Audio i, bool isPrimary)
+        private MediaSourceInfo GetVersionInfo(Audio i)
         {
             return new MediaSourceInfo
             {

+ 2 - 10
MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs

@@ -349,13 +349,13 @@ namespace MediaBrowser.Server.Implementations.IO
         {
             try
             {
-                Logger.Debug("Watcher sees change of type " + e.ChangeType + " to " + e.FullPath);
+                Logger.Debug("Changed detected of type " + e.ChangeType + " to " + e.FullPath);
 
                 ReportFileSystemChanged(e.FullPath);
             }
             catch (Exception ex)
             {
-                Logger.ErrorException("Exception in watcher changed. Path: {0}", ex, e.FullPath);
+                Logger.ErrorException("Exception in ReportFileSystemChanged. Path: {0}", ex, e.FullPath);
             }
         }
 
@@ -397,14 +397,6 @@ namespace MediaBrowser.Server.Implementations.IO
                         Logger.Debug("Ignoring change to {0}", path);
                         return true;
                     }
-
-                    // Go up another level
-                    parent = Path.GetDirectoryName(i);
-                    if (string.Equals(parent, path, StringComparison.OrdinalIgnoreCase))
-                    {
-                        Logger.Debug("Ignoring change to {0}", path);
-                        return true;
-                    }
                 }
 
                 return false;

+ 8 - 0
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -134,6 +134,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                         return number;
 
                     });
+
+                if (query.IsFavorite.HasValue)
+                {
+                    var val = query.IsFavorite.Value;
+
+                    channels = channels
+                        .Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite == val);
+                }
             }
 
             channels = channels.OrderBy(i =>

+ 1 - 1
MediaBrowser.Server.Implementations/Roku/RokuSessionController.cs

@@ -30,7 +30,7 @@ namespace MediaBrowser.Server.Implementations.Roku
 
         public bool SupportsMediaRemoteControl
         {
-            get { return true; }
+            get { return false; }
         }
 
         public bool IsSessionActive

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

@@ -3,6 +3,8 @@ using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Session;
@@ -564,7 +566,7 @@ namespace MediaBrowser.Server.Implementations.Session
 
             return playedToCompletion;
         }
-        
+
         /// <summary>
         /// Updates playstate position for an item but does not save
         /// </summary>
@@ -666,7 +668,7 @@ namespace MediaBrowser.Server.Implementations.Session
 
             var controllingSession = GetSession(controllingSessionId);
             AssertCanControl(session, controllingSession);
-            
+
             return session.SessionController.SendSystemCommand(command, cancellationToken);
         }
 
@@ -676,7 +678,7 @@ namespace MediaBrowser.Server.Implementations.Session
 
             var controllingSession = GetSession(controllingSessionId);
             AssertCanControl(session, controllingSession);
-            
+
             return session.SessionController.SendMessageCommand(command, cancellationToken);
         }
 
@@ -684,14 +686,22 @@ namespace MediaBrowser.Server.Implementations.Session
         {
             var session = GetSessionForRemoteControl(sessionId);
 
-            var items = command.ItemIds.Select(i => _libraryManager.GetItemById(new Guid(i)))
+            var user = session.UserId.HasValue ? _userManager.GetUserById(session.UserId.Value) : null;
+
+            var items = command.ItemIds.SelectMany(i => TranslateItemForPlayback(i, user))
                 .Where(i => i.LocationType != LocationType.Virtual)
                 .ToList();
 
-            if (session.UserId.HasValue)
+            if (command.PlayCommand == PlayCommand.PlayShuffle)
             {
-                var user = _userManager.GetUserById(session.UserId.Value);
+                items = items.OrderBy(i => Guid.NewGuid()).ToList();
+                command.PlayCommand = PlayCommand.PlayNow;
+            }
+
+            command.ItemIds = items.Select(i => i.Id.ToString("N")).ToArray();
 
+            if (user != null)
+            {
                 if (items.Any(i => i.GetPlayAccess(user) != PlayAccess.Full))
                 {
                     throw new ArgumentException(string.Format("{0} is not allowed to play media.", user.Name));
@@ -723,13 +733,34 @@ namespace MediaBrowser.Server.Implementations.Session
             return session.SessionController.SendPlayCommand(command, cancellationToken);
         }
 
+        private IEnumerable<BaseItem> TranslateItemForPlayback(string id, User user)
+        {
+            var item = _libraryManager.GetItemById(new Guid(id));
+
+            if (item.IsFolder)
+            {
+                var folder = (Folder)item;
+
+                var items = user == null ? folder.RecursiveChildren:
+                    folder.GetRecursiveChildren(user);
+
+                items = items.Where(i => !i.IsFolder);
+
+                items = items.OrderBy(i => i.SortName);
+
+                return items;
+            }
+
+            return new[] { item };
+        }
+
         public Task SendBrowseCommand(Guid controllingSessionId, Guid sessionId, BrowseRequest command, CancellationToken cancellationToken)
         {
             var session = GetSessionForRemoteControl(sessionId);
 
             var controllingSession = GetSession(controllingSessionId);
             AssertCanControl(session, controllingSession);
-            
+
             return session.SessionController.SendBrowseCommand(command, cancellationToken);
         }
 

+ 1 - 1
MediaBrowser.ServerApplication/ApplicationHost.cs

@@ -503,7 +503,7 @@ namespace MediaBrowser.ServerApplication
             var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger);
             RegisterSingleInstance<IAppThemeManager>(appThemeManager);
 
-            var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LogManager.GetLogger("DLNA"));
+            var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LogManager.GetLogger("DLNA"), JsonSerializer);
             RegisterSingleInstance<IDlnaManager>(dlnaManager);
 
             var collectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor);

+ 5 - 5
MediaBrowser.WebDashboard/Api/DashboardService.cs

@@ -401,9 +401,13 @@ namespace MediaBrowser.WebDashboard.Api
                                       "librarylist.js",
                                       "editorsidebar.js",
                                       "librarymenu.js",
-                                      //"chromecast.js",
+                                      "chromecast.js",
                                       "contextmenu.js",
 
+                                      "mediacontroller.js",
+                                      "mediaplayer.js",
+                                      "mediaplayer-video.js",
+
                                       "ratingdialog.js",
                                       "aboutpage.js",
                                       "allusersettings.js",
@@ -461,10 +465,6 @@ namespace MediaBrowser.WebDashboard.Api
                                       "loginpage.js",
                                       "logpage.js",
                                       "medialibrarypage.js",
-                                      "mediaplayer.js",
-
-                                      "mediaplayer-video.js",
-
                                       "metadataconfigurationpage.js",
                                       "metadataimagespage.js",
                                       "moviegenres.js",

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

@@ -587,6 +587,9 @@
     <Content Include="dashboard-ui\scripts\editorsidebar.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
+    <Content Include="dashboard-ui\scripts\mediacontroller.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
     <Content Include="dashboard-ui\scripts\mediaplayer-video.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>