diff options
| author | Tim Hobbs <jesus.tesh@gmail.com> | 2014-03-30 01:29:17 -0700 |
|---|---|---|
| committer | Tim Hobbs <jesus.tesh@gmail.com> | 2014-03-30 01:29:17 -0700 |
| commit | 28681ebce04769d65ca7be236b018fe3cee74367 (patch) | |
| tree | 81d651c2a9dc5e42bd71c0aed808438a627ae607 | |
| parent | 40d07e89ad1ace9647aeab82978e43077e0ce572 (diff) | |
| parent | a90d892ecab78a8f11fa7a4efda65ee70eceafe1 (diff) | |
Merge remote-tracking branch 'upstream/master'
12 files changed, 141 insertions, 31 deletions
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 96fe01ab3..abeaba910 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/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; diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index ec9ecb9ef..958188f37 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/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 diff --git a/MediaBrowser.Model/LiveTv/ChannelQuery.cs b/MediaBrowser.Model/LiveTv/ChannelQuery.cs index eb3b20ce3..9079ebacd 100644 --- a/MediaBrowser.Model/LiveTv/ChannelQuery.cs +++ b/MediaBrowser.Model/LiveTv/ChannelQuery.cs @@ -13,6 +13,12 @@ namespace MediaBrowser.Model.LiveTv 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> /// <value>The user identifier.</value> diff --git a/MediaBrowser.Model/Session/PlayRequest.cs b/MediaBrowser.Model/Session/PlayRequest.cs index 949274a5d..74d7a70a3 100644 --- a/MediaBrowser.Model/Session/PlayRequest.cs +++ b/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 } }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 1833b708f..2e0b3cb17 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/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 { diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 9279fd8d7..08add952a 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/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; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index db8786d62..b828dc0de 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/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 => diff --git a/MediaBrowser.Server.Implementations/Roku/RokuSessionController.cs b/MediaBrowser.Server.Implementations/Roku/RokuSessionController.cs index d806db1e0..7c8d71b4f 100644 --- a/MediaBrowser.Server.Implementations/Roku/RokuSessionController.cs +++ b/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 diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 9d405a175..4f748a6a8 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/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); } diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index b7e9017d6..d9d5e007e 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/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); diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 99afbbdd7..369fb2a07 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/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", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 6a8cc49b1..6c6487cc2 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/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>
|
