Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Tim Hobbs 2014-03-30 01:29:17 -07:00
commit 28681ebce0
12 changed files with 141 additions and 31 deletions

View file

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

View file

@ -20,13 +20,15 @@ namespace MediaBrowser.Dlna
private readonly IXmlSerializer _xmlSerializer; private readonly IXmlSerializer _xmlSerializer;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly ILogger _logger; 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; _xmlSerializer = xmlSerializer;
_fileSystem = fileSystem; _fileSystem = fileSystem;
_appPaths = appPaths; _appPaths = appPaths;
_logger = logger; _logger = logger;
_jsonSerializer = jsonSerializer;
//DumpProfiles(); //DumpProfiles();
} }
@ -381,10 +383,66 @@ namespace MediaBrowser.Dlna
public void CreateProfile(DeviceProfile profile) 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) 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 class InternalProfileInfo

View file

@ -12,6 +12,12 @@ namespace MediaBrowser.Model.LiveTv
/// <value>The type of the channel.</value> /// <value>The type of the channel.</value>
public ChannelType? ChannelType { get; set; } 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> /// <summary>
/// Gets or sets the user identifier. /// Gets or sets the user identifier.
/// </summary> /// </summary>

View file

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

View file

@ -1297,7 +1297,7 @@ namespace MediaBrowser.Server.Implementations.Dto
{ {
var result = new List<MediaSourceInfo> var result = new List<MediaSourceInfo>
{ {
GetVersionInfo(item, true) GetVersionInfo(item)
}; };
return result; 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 return new MediaSourceInfo
{ {

View file

@ -349,13 +349,13 @@ namespace MediaBrowser.Server.Implementations.IO
{ {
try 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); ReportFileSystemChanged(e.FullPath);
} }
catch (Exception ex) 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); Logger.Debug("Ignoring change to {0}", path);
return true; 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; return false;

View file

@ -134,6 +134,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return number; 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 => channels = channels.OrderBy(i =>

View file

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

View file

@ -3,6 +3,8 @@ using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Session; using MediaBrowser.Controller.Session;
@ -564,7 +566,7 @@ namespace MediaBrowser.Server.Implementations.Session
return playedToCompletion; return playedToCompletion;
} }
/// <summary> /// <summary>
/// Updates playstate position for an item but does not save /// Updates playstate position for an item but does not save
/// </summary> /// </summary>
@ -666,7 +668,7 @@ namespace MediaBrowser.Server.Implementations.Session
var controllingSession = GetSession(controllingSessionId); var controllingSession = GetSession(controllingSessionId);
AssertCanControl(session, controllingSession); AssertCanControl(session, controllingSession);
return session.SessionController.SendSystemCommand(command, cancellationToken); return session.SessionController.SendSystemCommand(command, cancellationToken);
} }
@ -676,7 +678,7 @@ namespace MediaBrowser.Server.Implementations.Session
var controllingSession = GetSession(controllingSessionId); var controllingSession = GetSession(controllingSessionId);
AssertCanControl(session, controllingSession); AssertCanControl(session, controllingSession);
return session.SessionController.SendMessageCommand(command, cancellationToken); return session.SessionController.SendMessageCommand(command, cancellationToken);
} }
@ -684,14 +686,22 @@ namespace MediaBrowser.Server.Implementations.Session
{ {
var session = GetSessionForRemoteControl(sessionId); 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) .Where(i => i.LocationType != LocationType.Virtual)
.ToList(); .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)) if (items.Any(i => i.GetPlayAccess(user) != PlayAccess.Full))
{ {
throw new ArgumentException(string.Format("{0} is not allowed to play media.", user.Name)); 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); 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) public Task SendBrowseCommand(Guid controllingSessionId, Guid sessionId, BrowseRequest command, CancellationToken cancellationToken)
{ {
var session = GetSessionForRemoteControl(sessionId); var session = GetSessionForRemoteControl(sessionId);
var controllingSession = GetSession(controllingSessionId); var controllingSession = GetSession(controllingSessionId);
AssertCanControl(session, controllingSession); AssertCanControl(session, controllingSession);
return session.SessionController.SendBrowseCommand(command, cancellationToken); return session.SessionController.SendBrowseCommand(command, cancellationToken);
} }

View file

@ -503,7 +503,7 @@ namespace MediaBrowser.ServerApplication
var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger); var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger);
RegisterSingleInstance<IAppThemeManager>(appThemeManager); 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); RegisterSingleInstance<IDlnaManager>(dlnaManager);
var collectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor); var collectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor);

View file

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

View file

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