mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-09-06 05:47:14 -04:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
28681ebce0
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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 =>
|
||||
|
@ -30,7 +30,7 @@ namespace MediaBrowser.Server.Implementations.Roku
|
||||
|
||||
public bool SupportsMediaRemoteControl
|
||||
{
|
||||
get { return true; }
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public bool IsSessionActive
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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",
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user